版权声明:原创文章未经博主允许不得转载O(-_-)O!!! https://blog.csdn.net/u013894072/article/details/83586044
正向传播
如上图所示,这是一个全连接的三层神经网络,之所以说这个是3层,是因为包含了2个隐藏层、1个输出层。输入层在这里我们不把他当做神经网络中的一层看待。
由于本人经验有限,对于每个公式转置的标记掌握不纯熟,在这里就不写了(如果各位介意…那么来打我呀)。到了具体的任务,必须要分析每一步中每个矩阵、数组的维度再进行拼接操作。
这里,我们假设输入数据为
a[0],输出为
Y。
我们先看hidden layer 1,记 权重参数为
W[1],偏置为
b[1],则线性加权值为
Z[1]=W[1]a[0]+b[1],激活值
a[1]=G[1](Z[1]),
G[1]为第一层激活函数
hidden layer 2同理:权重参数为
W[2],偏置为
b[2],则线性加权值为
Z[2]=W[2]a[1]+b[2],激活值
a[2]=G[2](Z[2]),
G[2]为第二层激活函数
output layer同理:权重参数为
W[3],偏置为
b[3],则线性加权值为
Z[3]=W[3]a[2]+b[3],激活值
a[3]=G[3](Z[3]),
G[3]为第三层激活函数
最后我们得到的
a[3]=Yhat,
Yhat也是对真实值
Y的一个近似预测。我们的目的就是不断地使这个预测与真实值之间的误差越来越小。
上述就为正向传播的过程
反向传播
我们定义损失函数
Jloss=F(Y,Yhat),此处的
F可以是交叉熵损失函数,也可以是平方损失函数,需要根据具体的任务定义。
下面按照梯度下降及导数的链式法则,我们有以下式子成立(
G[L]′表示激活函数的导数):
dYhat=da[3]=∂a[3]∂Jloss
dZ[3]=da[3]∗G[3]′(Z[3])
dW[3]=dZ[3]∗a[2]
db[3]=dZ[3]
所以对于第三层的参数W和b,我们用一般用如下方法更新(还有许多其他的下降方法,可见:常见的几种优化算法),
λn是学习速率:
W[3]=W[3]−λ3∗dW[3]
b[3]=b[3]−λ3∗db[3]
上面就完成了输出层权重的更新,当误差传播到第二层隐藏层时,此时激活值
a[2]的变化
da[2]可由上层的误差传播而来:
da[2]=da[3]∗G[3]′(Z[3])∗a[2],即da[2]=dZ[3]∗a[2]
所以对于第二层的反向传播就可以推出
dZ[2]=da[2]∗G[2]′(Z[2])
dW[2]=dZ[2]∗a[1]
db[2]=dZ[2]
则
W[2]=W[2]−λ2∗dW[2]
b[2]=b[2]−λ2∗db[2]
所以对于第一层的反向传播就推出
da[1]=dZ[2]∗a[2]
dZ[1]=da[1]∗G[1]′(Z[1])
dW[1]=dZ[1]∗a[0]
db[1]=dZ[1]
则
W[1]=W[1]−λ1∗dW[1]
b[1]=b[1]−λ1∗db[1]
综上所述,第L层的迭代公式为
da[L−1]=dZ[L]∗a[L]
dZ[L]=da[L]∗G[L]′(Z[L])
dW[L]=dZ[L]∗a[L−1]
db[L]=dZ[L]
W[L]=W[L]−λL∗dW[L]
b[L]=b[L]−λL∗db[L]
在编写代码时,正向传播中需要保存的缓存变量有
a[L]、Z[L]
参考文献
[1].http://www.cnblogs.com/southtonorth/p/9512559.html
[2].吴恩达深度学习课程