网络说明
前向传递函数
单个神经节点的前向传递为:
outputN=sigmoid(∑i=0n(outputiN−1∗Wi)+b)outputN=ReLU(∑i=0n(outputiN−1∗WiN)+b)
output^N = sigmoid(\sum_{i=0}^n(output_i^{N-1} * W^i) + b)\\
output^N = ReLU(\sum_{i=0}^n(output_i^{N-1} * W^N_i) + b)
outputN=sigmoid(i=0∑n(outputiN−1∗Wi)+b)outputN=ReLU(i=0∑n(outputiN−1∗WiN)+b)
因此其单层的前行传递代码为
# output1 = F(output0,weight0,bias0,active_mode)
output1 = ReLU(np.dot(weight0, output0) + bias0) if active_mode == "ReLU" else sigmoid(np.dot(weight0, output0) + bias0)
将三层的前行传递函数串联将构成前向传递函数
def forward(input, weight0, bias0, weight1, bias1, weight2, bias2, active_mode)
前向传递函数参数讲解
input
:为模型输入,在本项目中为,4*4转换为16*1的数据,所以input.shape
因该为(16, 1)
input = input.reshape(-1, 1) #将4x4矩阵展开为16x1列向量
print(input.shape)
weight0
:为第一层隐藏层的输入权重,大小为num_hidden_layer0 * input.shape[0]
为(16*16)的二维矩阵
初始化用np.random.randn(num_hidden_layer0, input.shape[0])
生成。=注意.randn
和.rand
区别=
bias0
:为第一层隐藏层的输入偏执,大小为num_hidden_layer0 * 1
为16*1
初始化用np.random.randn(num_hidden_layer0 , 1)
生成
同理其他参数。
反向传播函数
我们采用预测输出output
与我们给定的target(img
)进行对比,做均方误差。我们的目标是最小化均方误差 (MSE)。
MSE=∑i=0n(outputiN−imgi)2n+1
MSE = \frac{\sum_{i=0}^n{(output^N_i - img_i)^2}}{n+1}
MSE=n+1∑i=0n(outputiN−imgi)2
imgimgimg为目标值(实际值),outputoutputoutput为模型预测值,因为outputoutputoutput为第N层输出所以output=outputNoutput = output^Noutput=outputN
所以首先对每个预测值outputiNoutput^N_ioutputiN 计算均方误差 MSEMSEMSE 对outputiNoutput^N_ioutputiN的导数
d_output_layer = 均方误差(MSEMSEMSE)对模型的预测输出outputiNoutput^N_ioutputiN的导数
MSE′=∑i=0n∂MSEdoutputiN=∑i=0n2∗outputiN−imgin+1
MSE^\prime =\sum_{i=0}^n{ \frac{\partial_{MSE}}{\mathrm{d}_{output^N_i}}} = \sum_{i=0}^n{2 * \frac{output^N_i - img_i}{n+1}}
MSE′=i=0∑ndoutputiN∂MSE=i=0∑n2∗n+1outputiN−imgi
又因为在神经节点中
outputiN=sigmoid(∑i=0n(outputiN−1∗Wi)+b)
output^N_i = sigmoid(\sum_{i=0}^n(output_i^{N-1} * W_i) + b)
outputiN=sigmoid(i=0∑n(outputiN−1∗Wi)+b)
所以
∂outputNdWi=doutputNd{∑i=0n(outputiN−1∗Wi)+b}∗d{∑i=0n(outputiN−1∗Wi)+b}Wi其中:doutputNd{∑i=0n(outputiN−1∗Wi)+b}=激活函数的导数d{∑i=0n(outputiN−1∗Wi)+b}Wi=outputiN−1
\frac{\partial_{output^N}}{\mathrm{d}_{W_i}} = \frac{\mathrm{d}_{output^N}}{\mathrm{d}_\{\sum_{i=0}^n(output_i^{N-1} * W_i) + b\}}* \frac{\mathrm{d}_\{\sum_{i=0}^n(output_i^{N-1} * W_i) + b\}}{W_i}\\
其中:\frac{\mathrm{d}_{output^N}}{\mathrm{d}_\{\sum_{i=0}^n(output_i^{N-1} * W_i) + b\}}=激活函数的导数\\
\frac{\mathrm{d}_\{\sum_{i=0}^n(output_i^{N-1} * W_i) + b\}}{W_i} = output_i^{N-1}
dWi∂outputN=d{∑i=0n(outputiN−1∗Wi)+b}doutputN∗Wid{∑i=0n(outputiN−1∗Wi)+b}其中:d{∑i=0n(outputiN−1∗Wi)+b}doutputN=激活函数的导数Wid{∑i=0n(outputiN−1∗Wi)+b}=outputiN−1
又因为
Y=Sigmoid(x)=11+e−xY′=Y∗(1−Y)
Y = Sigmoid(x) = \frac {1 }{1 + e^{-x}}\\
Y^\prime = Y * ( 1 - Y )
Y=Sigmoid(x)=1+e−x1Y′=Y∗(1−Y)
所以
∂outputNdWi=激活函数的导数∗outputiN−1=outputN∗(1−outputN)∗outputiN−1
\frac{\partial_{output^N}}{\mathrm{d}_{W_i}} = 激活函数的导数 * output_i^{N-1} = output^N * (1-output^N) *output_i^{N-1}
dWi∂outputN=激活函数的导数∗outputiN−1=outputN∗(1−outputN)∗outputiN−1
同理
∂outputNdb=激活函数的导数∗1=outputN∗(1−outputN)∗1
\frac{\partial_{output^N}}{\mathrm{d}_{b}} = 激活函数的导数 * 1 = output^N * (1-output^N) *1
db∂outputN=激活函数的导数∗1=outputN∗(1−outputN)∗1
所以可知均方误差 MSEMSEMSE 对最后一层的输入权重WiW_iWi和bbb的导数为:
∂MSEdWi=∂MSEdoutputiN∗∂outputiNdWj=2∗outputiN−imgin+1∗outputiN∗(1−outputiN)∗outputjN−1∂MSEdb=∂MSEdoutputiN∗∂outputiNdb=2∗outputiN−imgin+1∗outputiN∗(1−outputiN)∗1
\frac{\partial_{MSE}}{\mathrm{d}_{W_i}} =\frac{\partial_{MSE}}{\mathrm{d}_{output^N_i}}*\frac{\partial_{output^N_i}}{\mathrm{d}_{W_j}}= 2 * \frac{output^N_i - img_i}{n+1}*output^N_i * (1-output^N_i) *output_j^{N-1}\\
\frac{\partial_{MSE}}{\mathrm{d}_{b}} =\frac{\partial_{MSE}}{\mathrm{d}_{output^N_i}}*\frac{\partial_{output^N_i}}{\mathrm{d}_{b}}=2 * \frac{output^N_i - img_i}{n+1}*output^N_i * (1-output^N_i) * 1
dWi∂MSE=doutputiN∂MSE∗dWj∂outputiN=2∗n+1outputiN−imgi∗outputiN∗(1−outputiN)∗outputjN−1db∂MSE=doutputiN∂MSE∗db∂outputiN=2∗n+1outputiN−imgi∗outputiN∗(1−outputiN)∗1
根据我们所计算的MSEMSEMSE和对输入权重WiW_iWi和bbb的导数,我们可以计算出输入权重WiW_iWi和bbb在MSEMSEMSE减小方向上的梯度gradweightgrad_weightgradweight和gradbiasgrad_biasgradbias。
然后结合学习率learningratelearning_ratelearningrate对输入权重WiW_iWi和bbb进行修正
# 使用梯度下降法更新输出层的权重和偏置
weight -= learning_rate * grad_weight # 更新输出层的权重
bias -= learning_rate * grad_bias # 更新输出层的偏置
又因为由上面可知,对于每一层 Sigmoid的反向传递函数
∂outputNdWiN=outputN∗(1−outputN)∗outputiN−1∂outputNdbN=outputN∗(1−outputN)∗1
\frac{\partial_{output^N}}{\mathrm{d}_{W^N_i}} = output^N * (1-output^N) *output_i^{N-1}\\
\frac{\partial_{output^N}}{\mathrm{d}_{b^N}} = output^N * (1-output^N) *1
dWiN∂outputN=outputN∗(1−outputN)∗outputiN−1dbN∂outputN=outputN∗(1−outputN)∗1
根据求导的链式法则
均方误差 MSEMSEMSE 对倒数第二层的输入权重WiN−1W^{N-1}_iWiN−1和$ b^{N-1} $的导数为
∂MSEdWiN−1=WN∗∂MSEdoutputiN∗激活函数的导数N∗∂outputiN−2dWjN−1=WN∗∂MSEdoutputiN∗激活函数的导数N∗激活函数的导数N−1∗outputjN−2∂MSEdbN−1=WN∗∂MSEdoutputiN∗激活函数的导数N∗∂outputiN−2dbN−1=WN∗∂MSEdoutputiN∗激活函数的导数N∗激活函数的导数N−1∗1其中激活函数N=outputN∗(1−outputN)
\frac{\partial_{MSE}}{\mathrm{d}_{W^{N-1}_i}} =W^N *\frac{\partial_{MSE}}{\mathrm{d}_{output^N_i}}* 激活函数的导数^N*\frac{\partial_{output^{N-2}_i}}{\mathrm{d}_{W^{N-1}_j}}\\
= W^N *\frac{\partial_{MSE}}{\mathrm{d}_{output^N_i}}* 激活函数的导数^N* 激活函数的导数^{N-1}*output_j^{N-2}\\
\frac{\partial_{MSE}}{\mathrm{d}_{b^{N-1}}} =W^N *\frac{\partial_{MSE}}{\mathrm{d}_{output^N_i}}* 激活函数的导数^N *\frac{\partial_{output^{N-2}_i}}{\mathrm{d}_{b^{N-1}}}\\
= W^N *\frac{\partial_{MSE}}{\mathrm{d}_{output^N_i}}* 激活函数的导数^N* 激活函数的导数^{N-1}*1\\
其中激活函数^N = output^N * (1-output^N)
dWiN−1∂MSE=WN∗doutputiN∂MSE∗激活函数的导数N∗dWjN−1∂outputiN−2=WN∗doutputiN∂MSE∗激活函数的导数N∗激活函数的导数N−1∗outputjN−2dbN−1∂MSE=WN∗doutputiN∂MSE∗激活函数的导数N∗dbN−1∂outputiN−2=WN∗doutputiN∂MSE∗激活函数的导数N∗激活函数的导数N−1∗1其中激活函数N=outputN∗(1−outputN)
均方误差 MSEMSEMSE 对倒数第三层同理,在一层基础上修改