话不多说先用numpy表示出数据集

Y=['色泽','根蒂','敲声','纹理','脐部','触感','密度','含糖率','好瓜与否']
D=np.array([[2,1,2,3,3,1,0.697,0.406,1],\
[3,1,1,3,3,1,0.774,0.376,1],\
[3,1,2,3,3,1,0.634,0.264,1],\
[2,1,1,3,3,1,0.608,0.318,1],\
[1,1,2,3,3,1,0.556,0.215,1],\
[2,2,2,3,2,0,0.403,0.237,1],\
[3,2,2,2,2,0,0.481,0.149,1],\
[3,2,2,3,2,1,0.437,0.211,1],\
[3,2,1,2,2,1,0.666,0.091,0],\
[2,3,3,3,1,0,0.243,0.267,0],\
[1,3,3,1,1,1,0.245,0.057,0],\
[1,1,2,1,1,0,0.343,0.099,0],\
[2,2,2,2,3,1,0.639,0.161,0],\
[1,2,1,2,3,1,0.657,0.198,0],\
[3,2,2,3,2,0,0.360,0.370,0],\
[1,1,2,1,1,1,0.593,0.042,0],\
[2,1,1,2,2,1,0.719,0.103,0]])
lamuda=0.1
v=np.ones(shape=(8,8))
b=np.ones(shape=(8))
gama=np.ones(shape=(8))
w=np.ones(shape=(2,8))
y=np.ones(shape=(2))
sita=np.ones(shape=(2))

其中属性值的数字化图方便一律使用了值而不是向量,具体对应关系如下:

色泽:浅白 1,青绿 2,乌黑 3

根蒂:蜷缩 1,稍蜷 2,硬挺 3

敲声:沉闷 1,浊响 2,清脆 3

纹理:模糊 1,稍糊 2,清晰 3

脐部:平坦 1,稍凹 2,凹陷 3

触感:硬滑 1,软粘 0

敢使用值的原因也是这些属性基本都是存在一定的强弱关系的(清晰度、蜷曲度、凹陷度等),所以放心大胆123

先编写一个初始化函数对每个阈值和连接权进行初始化,各数组命名参考书上的图5.7。使用的是8输入8隐层2输出的网络结构,那么对于好瓜应该输出(1,0),坏瓜输出(0,1)

def initial():
for i in range(8):
for j in range(8):
v[i,j]=random.random()
gama[i]=random.random() for i in range(2):
for j in range(8):
w[i,j]=random.random()
sita[i]=random.random()
return

然后做主函数,主体和书上P104的图5.8一样,每个函数的内容后面再说,跳出条件依然先设置是循环一定的次数。

num=100
while(num):
num-=1
for k in range(16):#遍历每个输入
Y(k)
G(k)
ee()
ref(k)
print(v)
print(b)
print(gama)
print(w)
print(y)
print(sita)

Y(k)的作用是根据当前遍历到的第k个样本的属性值计算输出y,分两步走,先修改每个隐层神经元的输出,再修改每个输出神经元的输出,代码如下:

def Y(a):
for i in range(8):#修改每个隐层输出
b[i]=sigmoidb(a,i)
for i in range(2):
y[i]=sigmoidy(a,i)
return

sigmoidb与sigmoidy的作用就是求当前神经元的输出,累加输入与权重的乘积后减去阈值,然后返回sigmoid函数结果,注意sigmoid函数中的-次方。

def sigmoidb(a,c):
s=0
for i in range(8):#遍历第a个样本每个属性值
s=s+v[i,c]*D[a,i]
s=gama[c]-s
return 1/(1+math.exp(s)) def sigmoidy(a,c):
s=0
for i in range(8):
s=s+w[c,i]*b[i]
s=sita[c]-s
return 1/(1+math.exp(s))

回到主函数,下一步是更新两组推导出来的辅助计算的参数g和e,为了防止与之后要加的误差计算命名冲突就把e的更新函数改成了ee

更新方式很简单,按照书上现成的公式跑一跑就行了,具体推导过程可以自己试着写一下,难度还好。这里有个问题就是y的估计值,为了方便计算在原本的数据集中加了一列

在其中好瓜添加值0,坏瓜添加值1,与原本标记相反。代码中就表现为G中的样子。

def G(a):
for i in range(2):
g[i]=y[i]*(1-y[i])*(D[a,8+i]-y[i])
return

def ee():
for i in range(8):
s=b[i]*(1-b[i])
for j in range(2):
s=s*w[j,i]*g[j]
e[i]=s
return

然后就是根据公式更新连接权、阈值:

def ref(k):
for i in range(8):
for j in range(2):
w[j,i]=w[j,i]+lamuda*g[j]*b[i]
for i in range(2):
sita[i]=sita[i]-lamuda*g[i]
for i in range(8):
gama[i]=gama[i]-lamuda*e[i]
for j in range(8):
v[i,j]=v[i,j]+lamuda*e[j]*D[k,i]
return

主体大致就这样,循环完之后输出看一下参数就行。出现溢出的话多半是sigmoid里次方符号不对,这个计算应该没有特别大或者特别小的情况。

然后为了看眼误差,写个误差验算函数:

def E(k):
s=0
for i in range(2):
s=s+(y[i]-D[k,8+i])*(y[i]-D[k,8+i])
s/=2
return s

加到主函数里面,写个输出

print('第',100-num,'次',k,'样本误差:',E(k))

输出结果就不放了,可以看到误差是震荡的,而且似乎始终保持在0.16以上

这时候就要用到累积BP了。为了实现累计BP,我们要稍微修改一下前面的更新过程,如何修改呢?

先来看一下5.16,我们要用这个式子来代替5.4的式子套入到5.6-5.15的推到过程中去,来得到新的参数更新估计式。

5.16其实就是对所有样例的Ek做一个求平均,那么代入到5.10可以得到,新的参数更新估计式只要带上一个求平均的过程即可。

再看5.15,可以看到需要平均的项恰好也是gj,那就照原样计算就行。

首先更改一下主函数的结构,把eh和参数更新放到i的循环中,添加一个误差判别跳出,能得到一个较好的结果,记得修改函数的参数:

initial()
num=1000
avr()
Ee=1
while(num):
num-=1
set()
for k in range(16):#遍历每个输入
Y(k)
G(k)
ee()
ref()
aa=E()
if(aa>Ee):
print(aa)
break
Ee=aa

然后对G(k)做个手脚,使其最终得到所有样本的平均值:

def G(a):
for i in range(2):
g[i]=g[i]+y[i]*(1-y[i])*(D[a,8+i]-y[i])
if(a==15):
g[i]/=16
return

ee不用动,但为了计算△Vih,我们需要求一下所有样本属性的平均值,存放到一个数组里:

def avr():
for i in range(8):
avra[i]=0
for j in range(16):
avra[i]+=D[j,i]
avra[i]/=16
return

同时在程序开始时将g数组置零:

def set():
for i in range(2):
g[i]=0
return

修改更新函数:

def ref():
for i in range(8):
for j in range(2):
w[j,i]=w[j,i]+lamuda*g[j]*b[i]
for i in range(2):
sita[i]=sita[i]-lamuda*g[i]
for i in range(8):
gama[i]=gama[i]-lamuda*e[i]
for j in range(8):
v[i,j]=v[i,j]+lamuda*e[j]*avra[i]
return

修改求误差函数:

def E():
s=0
for j in range (16):
Y(j)
for i in range(2):
s=s+(y[i]-D[k,8+i])*(y[i]-D[k,8+i])/2
s/=16
return s

搞定,运行后可以看到误差最终停在0.12左右(但不及时跳出会稳定在0.25左右)。

西瓜书 5.5 编写过程(标准BP与累计BP)的更多相关文章

  1. 决策树ID3原理及R语言python代码实现(西瓜书)

    决策树ID3原理及R语言python代码实现(西瓜书) 摘要: 决策树是机器学习中一种非常常见的分类与回归方法,可以认为是if-else结构的规则.分类决策树是由节点和有向边组成的树形结构,节点表示特 ...

  2. 串口调试助手vc源程序及其详细编写过程

    串口调试助手vc源程序及其详细编写过程   目次: 1.建立项目 2.在项目中插入MSComm控件 3.利用ClassWizard定义CMSComm类控制变量 4.在对话框中添加控件 5.添加串口事件 ...

  3. Mol Cell Proteomics. |马臻| psims-一个用于编写HUPO-PSI标准下的mzML和mzIdentML的python库

    大家好,本周分享的是发表在MCP(MOLECULAR&CRLLULAR PROTEOMICS)上的一篇关于质谱数据处理和识别的文章,题目是psims - A Declarative Write ...

  4. LASSO回归与L1正则化 西瓜书

    LASSO回归与L1正则化 西瓜书 2018年04月23日 19:29:57 BIT_666 阅读数 2968更多 分类专栏: 机器学习 机器学习数学原理 西瓜书   版权声明:本文为博主原创文章,遵 ...

  5. Selenium2学习-018-WebUI自动化实战实例-016-自动化脚本编写过程中的登录验证码问题

    日常的 Web 网站开发的过程中,为提升登录安全或防止用户通过脚本进行黄牛操作(宇宙最贵铁皮天朝魔都的机动车牌照竞拍中),很多网站在登录的时候,添加了验证码验证,而且验证码的实现越来越复杂,对其进行脚 ...

  6. 利用Gulp实现JSDoc 3的文档编写过程中的实时解析和效果预览

    ### 利用Gulp实现JSDoc 3的文档编写过程中的实时解析和效果预览 http://segmentfault.com/a/1190000002583569

  7. ARM Linux驱动篇 学习温度传感器ds18b20的驱动编写过程

    ARM Linux驱动篇 学习温度传感器ds18b20的驱动编写过程 原文地址:http://www.cnblogs.com/NickQ/p/9026545.html 一.开发板与ds18b20的入门 ...

  8. python实现简单决策树(信息增益)——基于周志华的西瓜书数据

    数据集如下: 色泽 根蒂 敲声 纹理 脐部 触感 好瓜 青绿 蜷缩 浊响 清晰 凹陷 硬滑 是 乌黑 蜷缩 沉闷 清晰 凹陷 硬滑 是 乌黑 蜷缩 浊响 清晰 凹陷 硬滑 是 青绿 蜷缩 沉闷 清晰 ...

  9. 【lombok】使用lombok注解,在代码编写过程中可以调用到get/set方法,但是在编译的时候无法通过,提示找不到get/set方法

    错误如题:使用lombok注解,在代码编写过程中可以调用到get/set方法,但是在编译的时候无法通过,提示找不到get/set方法 报错如下: 解决方法: 1.首先查看你的lombok插件是否下载安 ...

  10. 朴素贝叶斯python代码实现(西瓜书)

    朴素贝叶斯python代码实现(西瓜书) 摘要: 朴素贝叶斯也是机器学习中一种非常常见的分类方法,对于二分类问题,并且数据集特征为离散型属性的时候, 使用起来非常的方便.原理简单,训练效率高,拟合效果 ...

随机推荐

  1. linux安装Elasticsearch的单节点

    一.基础环境 操作系统环境:Red Hat Enterprise Linux Server release 6.4 (Santiago) ES版本:elasticsearch-7.8.0-linux- ...

  2. 直播平台搭建源码,canvas 画一条波浪线 进度条

    直播平台搭建源码,canvas 画一条波浪线 进度条 <template>  <view>    <canvas :style="{'width': width ...

  3. 杂:pthread_cond_timedwait导致死锁

    地球人都知道1:pthread_cond_timedwait使用时,需要对[条件]加锁.[条件]也是一种线程共享资源. 地球人都知道2:1个互斥锁不应该管理2类及以上的多线程共享资源 1+2=下面这样 ...

  4. char 与 string 互转 byte与string互转 list<string>与string[]互转 char与byte互转

    class Program    {        static void Main(string[] args)        {                                   ...

  5. A、创建模式(5种)

    设计模式的分类总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式. ...

  6. thirty-two(模型点击展示)react-three-fiber

    模型点击蒙版展示 点击展示目的(用户需要看见模型中更加多的内容信息) 使用技术 ThreeJs.React-three-fiber.React-three-drei.React.css 整体思路:   ...

  7. Vue中使用model属性

    model属性接收两个参数 类型:{ prop?: string, event?: string } prop 也就是调用该组件的父组件中使用v-model指令绑定的属性 event 对应的是修改pr ...

  8. Twig

    {{ dump() }}{{ dump(variable_name) }}List available variables (at top level): {{ dump(_context|keys) ...

  9. PLSQL中文乱码问题(显示问号)解决办法

    select userenv('language') from dual; 在环境变量的系统变量中添加配置: NLS_LANG SIMPLIFIED CHINESE_CHINA.ZHS16GBK 这个 ...

  10. css制作仿商城侧边导航

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...