误差逆传播(BP)算法

采用《机器学习》西瓜训练集3.0作为训练数据。
使用xlrd包从excel输入西瓜训练集
先是根据西瓜书54页,将离散属性连续化。然后初始化两组权值和阈值,取零到一之间随机数
隐层神经元个数设置为输入层+3个,学习率设置为0.3

西瓜训练集3.0
import numpy as np
import xlrd as xl
import random
import math

data=xl.open_workbook('watermelon.xlsx')

table = data.sheet_by_name('Sheet1')
m=table.nrows
n=table.ncols-1#编号不算

dataset={}
for mmp in range(m):
    dataset[mmp]=table.row_values(mmp)


for mma in range(m):#编号不要,删掉,不知道为什么np.delete报错
    del dataset[mma][0]

#p54,相同类型属性和不同属性
attributeSet={}
attributeSet['浅白']=0
attributeSet['青绿']=0.5
attributeSet['乌黑']=1
attributeSet['蜷缩']=0
attributeSet['稍蜷']=0.5
attributeSet['硬挺']=1
attributeSet['沉闷']=0
attributeSet['浊响']=0.5
attributeSet['清脆']=1
attributeSet['模糊']=0
attributeSet['稍糊']=0.5
attributeSet['清晰']=1
attributeSet['凹陷']=0
attributeSet['稍凹']=0.5
attributeSet['平坦']=1
attributeSet['硬滑']=0
attributeSet['软粘']=1
attributeSet['否']=0
attributeSet['是']=1


for i in range(m):
    for j in range(n):
        if dataset[i][j] in attributeSet:
            dataset[i][j]=attributeSet[dataset[i][j]]


Y={}#这是判断结果(好瓜坏瓜)
for k in range(m):
    Y[k]=dataset[k][n-1]
print(dataset[0][0])
X=np.zeros(shape=(m,n-1),dtype=float)
for l in range(m):
    for l2 in range(n-1):
        X[l][l2]=dataset[l][l2]
print(X)#X是属性转换为值得数组(不带结果)

n=n-1#X不带结果列方向降一维度
d=n#输入神经元个数
l=1#输出神经元个数
q=d+3#隐层神经元个数,随便定的,具体多少无定论

theta=[random.random() for i in range(l)]   #输出节点阈值
gamma=[random.random() for i in range(q)]   #输入节点阈值
v=np.zeros(shape=(d,q),dtype=float)
w=np.zeros(shape=(q,l),dtype=float)
for i in range(d):
    for j in range(q):
        v[i][j]=random.random()
for i in range(q):
    for j in range(l):
        w[i][j]=random.random()

eta=0.3    #学习率
maxIter=500 #训练次数

def sigmoid(iX,dimension):
    if dimension==1:
        for i in range(len(iX)):
            iX[i] = 1 / (1 + math.exp(-iX[i]))
    else:
        for i in range(len(iX)):
            iX[i] = sigmoid(iX[i],dimension-1)
    return iX


while(maxIter>0):
    maxIter-=1
    sumE=0
    
    a11,a22=np.shape(v)
    for i in range(m):
        alpha=np.dot(X[i],v)#p101
        b=sigmoid(alpha-gamma,1)#b=f(alpha-gamma)
        beta=np.dot(b,w)
        predictY=sigmoid(beta-theta,1)   #p102--5.3
        E = ((predictY-Y[i])*(predictY-Y[i]))/2    #5.4
        sumE+=E#5.16
        #p104
        g=predictY*(1-predictY)*(Y[i]-predictY)#shape=1*l p103--5.10
        e=b*(1-b)*((np.dot(w,g.T)).T) #shape=1*q , p104--5.15
        w+=eta*np.dot(b.reshape((q,1)),g.reshape((1,l)))#5.11
        theta-=eta*g#5.12
        v+=eta*np.dot(X[i].reshape((d,1)),e.reshape((1,q)))#5.13
        gamma-=eta*e#5.14

def predict(iX):
    alpha = np.dot(iX, v)  # p101
    b=sigmoid(alpha-gamma,2)#b=f(alpha-gamma), shape=m*q
    beta = np.dot(b, w)
    predictY=sigmoid(beta - theta,2)
    return predictY
    
print(predict(X))

本来BP算法是自己闷头写的,然而写了老半天总有bug解决不了,最后还是参考了https://blog.csdn.net/qdbszsj/article/details/79110888的算法。对比我自己写的,这位老哥在求和上用了很多向量点积操作,我之前就没这个意识,都是手工一个个循环乘法,循环层次又长又臭还可读性差,有时间再慢慢改吧=_=

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值