考虑一个三层的神经网络如下:
并且给参数赋上初值。只考虑一个训练数据X=(0.05,0.10)及Y=(0.01,0.99),将系数w和b向量化,输入层与隐藏层之间的系数记为W1是2*2的系数矩阵, b1是2*1的列向量,隐藏层与输出层之间的系数为W2也是2*2的矩阵,b2是2*1的列向量,输入记为x和y都是2*1的向量。
则前馈的计算过程为:
这里的激活函数选为sigmoid函数
loss函数记为:
为了更新W1,b1,W2,b2,需要计算E关于它们的梯度。为了符号的简单,记:
不加证明地得到BP算法的四个核心公式:
注意,这里的
表示输入x。
学习率记为alpha,则可以根据上述四个式子更新权重,详细代码如下:
# -*- coding: utf-8 -*- """ Created on Sat Sep 15 19:58:51 2018 @author: hasee """ import numpy as np def sigmoid(x): return 1/(1+np.exp(-x)) def sigmoid_der(x): return sigmoid(x)*(1-sigmoid(x)) class BPNetWork(object): def __init__(self): self.alpha=0.5 #学习率 self.W1=np.array([[0.15,0.20],[0.25,0.30]]) #输入层到卷积层的系数矩阵 self.b1=np.array([[0.35],[0.35]]) self.W2=np.array([[0.40,0.45],[0.50,0.55]]) self.b2=np.array([[0.90],[0.60]]) self.input=np.array([[0.05],[0.10]]) self.output=np.array([[0.05],[0.9]]) def feedfoward(self): Z1=np.matmul(self.W1,self.input)+self.b1 A1=sigmoid(Z1) Z2=np.matmul(self.W2,A1)+self.b2 A2=sigmoid(Z2) return Z1,A1,Z2,A2 def propogate(self): z1,a1,z2,a2=self.feedfoward() delta2=-(self.output-a2)*sigmoid_der(z2) self.W2-=(self.alpha)*np.matmul(delta2,np.transpose(a1)) self.b2-=self.alpha*delta2 delta1=np.matmul(np.transpose(self.W2),delta2)*sigmoid_der(z2) self.W1-=self.alpha*np.matmul(np.transpose(self.input),delta1) self.b1-=self.alpha*delta1 if __name__ == '__main__': BP=BPNetWork() BP.__init__() for i in range(10000): BP.propogate() if i%100==0: _,_,_,a2=BP.feedfoward() print(a2)