200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > 深度学习笔记(二):简单神经网络 后向传播算法及实现

深度学习笔记(二):简单神经网络 后向传播算法及实现

时间:2021-03-12 10:54:06

相关推荐

深度学习笔记(二):简单神经网络 后向传播算法及实现

在之前的深度学习笔记(一):logistic分类中,已经描述了普通logistic回归以及如何将logistic回归用于多类分类。在这一节,我们再进一步,往其中加入隐藏层,构建出最简单的神经网络

2.简单神经网络及后向传播算法

2.1 大概描述和公式表达

神经网络的大概结构如图所示,

从左往右,分别是输入层,隐藏层,输出层,分别记为x,h,y. 从输入层到隐藏层的矩阵记为Whx, 偏置向量bh; 从隐藏层到输出层的矩阵记为Wyh, 偏置向量为by. 那么根据之前logistic分类的公式稍作扩展,不难得到

hz=Whxx+bhha=σ(hz)yz=Wyhha+byya=σ(yz)

其实就是两层logistic分类的堆叠,将前一个分类器的输出作为后一个的输入。得到输出ya以后的判断方法也比较类似,哪项最高就判定属于哪一类。真正值得写一下的是神经网络中的后向算法。按照传统的logistic分类,只能做到根据误差来更新Wyh和by那么如何来更新从输入层到隐藏层的参数Whx和bh呢?这就要用到后向算法了。所谓后向算法,就是指误差由输出层逐层往前传递,进而逐层更新参数矩阵和偏执向量。后向算法的核心其实就4个字:链式法则。首先来看Wyh和by的更新

C=12(ya−y)2∂C∂yz=C′σ′(yz)=(ya−y).×a.×(1−a)∂C∂Wyh=∂C∂yz∂yz∂Wyh=C′σ′(yz)hTa∂C∂by=∂C∂yz∂yz∂by=C′σ′(yz)

其实在上面的公式中,已经用到了链式法则。 类似的,可以得到

∂C∂ha=∂C∂yz∂yz∂ha=WTyh[C′σ′(yz)]∂C∂Whx=∂C∂ha∂ha∂W=[∂C∂haσ′(hz)]xT∂C∂bh=∂C∂ha∂ha∂bh=[∂C∂haσ′(hz)]

可以看到,在Whx和bh的计算中都用到了∂C∂ha这可以看成由输出层传递到中间层的误差。那么在获得了各参数的偏导数以后,就可以对参数进行修正了

Wyh:=Wyh−η∂C∂Wyhby:=by−η∂C∂byWhx:=Whx−η∂C∂Whxbh:=bh−η∂C∂bh

2.2 神经网络的简单实现

为了加深印象,我自己实现了一个神经网络分类器,分类效果如下图所示

上图中,左上角显示的是实际的分类,右上角显示的是分类器判断出的各点分类。靠下的图显示的是分类器的判断准确率随迭代次数的变化情况。可以看到,经过训练以后,分类器的判断准确率还是可以的。

下面是代码部分

import numpy as npimport matplotlib.pyplot as pltimport randomimport math# 构造各个分类def gen_sample():data = []radius = [0,50]for i in range(1000): # 生成10k个点catg = random.randint(0,1) # 决定分类r = random.random()*10arg = random.random()*360len = r + radius[catg]x_c = math.cos(math.radians(arg))*leny_c = math.sin(math.radians(arg))*lenx = random.random()*30 + x_cy = random.random()*30 + y_cdata.append((x,y,catg))return datadef plot_dots(data):data_asclass = [[] for i in range(2)]for d in data:data_asclass[int(d[2])].append((d[0],d[1]))colors = ['r.','b.','r.','b.']for i,d in enumerate(data_asclass):# print(d)nd = np.array(d)plt.plot(nd[:,0],nd[:,1],colors[i])plt.draw()def train(input, output, Whx, Wyh, bh, by):"""完成神经网络的训练过程:param input: 输入列向量, 例如 [x,y].T:param output: 输出列向量, 例如[0,1,0,0].T:param Whx:x->h 的参数矩阵:param Wyh:h->y 的参数矩阵:param bh:x->h 的偏置向量:param by:h->y 的偏置向量:return:"""h_z = np.dot(Whx, input) + bh # 线性求和h_a = 1/(1+np.exp(-1*h_z))# 经过sigmoid激活函数y_z = np.dot(Wyh, h_a) + byy_a = 1/(1+np.exp(-1*y_z))c_y = (y_a-output)*y_a*(1-y_a)dWyh = np.dot(c_y, h_a.T)dby = c_yc_h = np.dot(Wyh.T, c_y)*h_a*(1-h_a)dWhx = np.dot(c_h,input.T)dbh = c_hreturn dWhx,dWyh,dbh,dby,c_ydef test(train_set, test_set, Whx, Wyh, bh, by):train_tag = [int(x) for x in train_set[:,2]]test_tag = [int(x) for x in test_set[:,2]]train_pred = []test_pred = []for i,d in enumerate(train_set):input = train_set[i:i+1,0:2].Ttag = predict(input,Whx,Wyh,bh,by)train_pred.append(tag)for i,d in enumerate(test_set):input = test_set[i:i+1,0:2].Ttag = predict(input,Whx,Wyh,bh,by)test_pred.append(tag)# print(train_tag)# print(train_pred)train_err = 0test_err = 0for i in range(train_pred.__len__()):if train_pred[i]!=int(train_tag[i]):train_err += 1for i in range(test_pred.__len__()):if test_pred[i]!=int(test_tag[i]):test_err += 1# print(test_tag)# print(test_pred)train_ratio = train_err / train_pred.__len__()test_ratio = test_err / test_pred.__len__()return train_err,train_ratio,test_err,test_ratiodef predict(input,Whx,Wyh,bh,by):# print('-----------------')# print(input)h_z = np.dot(Whx, input) + bh # 线性求和h_a = 1/(1+np.exp(-1*h_z))# 经过sigmoid激活函数y_z = np.dot(Wyh, h_a) + byy_a = 1/(1+np.exp(-1*y_z))# print(y_a)tag = np.argmax(y_a)return tagif __name__=='__main__':input_dim = 2output_dim = 2hidden_size = 200Whx = np.random.randn(hidden_size, input_dim)*0.01Wyh = np.random.randn(output_dim, hidden_size)*0.01bh = np.zeros((hidden_size, 1))by = np.zeros((output_dim, 1))data = gen_sample()plt.subplot(221)plot_dots(data)ndata = np.array(data)train_set = ndata[0:800,:]test_set = ndata[800:1000,:]train_ratio_list = []test_ratio_list = []for times in range(10000):i = times%train_set.__len__()input = train_set[i:i+1,0:2].Ttag = int(train_set[i,2])output = np.zeros((2,1))output[tag,0] = 1dWhx,dWyh,dbh,dby,c_y = train(input,output,Whx,Wyh,bh,by)if times%100==0:train_err,train_ratio,test_err,test_ratio = test(train_set,test_set,Whx,Wyh,bh,by)print('times:{t}\t train ratio:{tar}\t test ratio: {ter}'.format(tar=train_ratio,ter=test_ratio,t=times))train_ratio_list.append(train_ratio)test_ratio_list.append(test_ratio)for param, dparam in zip([Whx, Wyh, bh, by],[dWhx,dWyh,dbh,dby]):param -= 0.01*dparamfor i,d in enumerate(ndata):input = ndata[i:i+1,0:2].Ttag = predict(input,Whx,Wyh,bh,by)ndata[i,2] = tagplt.subplot(222)plot_dots(ndata)# plt.figure()plt.subplot(212)plt.plot(train_ratio_list)plt.plot(test_ratio_list)plt.show()12345678910111213141516171819222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119111221231241251261271281291301311321331341351361371381391401411421431441234567891011121314151617181922232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811911122123124125126127128129130131132133134135136137138139140141142143144

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。