因为目前我们可以简单的把神经网络看成是由一层一层的逻辑回归堆叠而成,而逻辑回归的cost function对于w,b的偏导数我们已经求解过了。再根据链式求导法则,我们只要从后向前来依次求解每层的w,b的偏导数dw,db。也就是后项传播法则。从而可以求解整个神经网络的dw,db。你可以参看这篇文章来了解如何对逻辑回归求解dw,db。

我们把之前求解的逻辑回归的dw,db值拿过来:
\begin{pmatrix} x1(\hat{y}-y),x2(\hat{y}-y),(\hat{y}-y) \end{pmatrix}
上边这个梯度值是针对只有两个feature: x1,x2,后来我们知道了如何向量化来处理,所以我们也可以这样来向量化的定义:
dW = X(\hat{Y}-Y)
dB = \hat{Y}-Y

对于上图中的W^{[2]},B^{[2]},大写的W,B,A,X 分别对应w,b,a,x的向量。这里的dW,dB等都是对Loss function 的W,B求导。
dW^{[2]} = A^{[1]}(A^{[2]}-Y)
dB^{[2]} = A^{[2]}-Y
与之前逻辑回归不同的是,这里我们需要对隐藏层的A求导,也就是dA。
dA^{[1]} = W^{[2]}(A^{[2]}-Y)
因为A^{[1]}=sigmoid(Z^{[1]}),而且
\frac{\mathrm{d} {A^{[1]}}}{\mathrm{d} {Z^{[1]}}}=A^{[1]}(1-A^{[1]})
所以dZ^{[1]} = dA^{[1]}A^{[1]}(1-A^{[1]})
而对于W^{[1]},B^{[1]}
dW^{[1]} = XdZ^{[1]}
dB^{[1]} = dZ^{[1]}

对于上边这个简单的两层神经网络我们求解完了。利用这些公式我们应该就可以开始我们的代码编写了。不过我认为现在是时候来总结一个更加通用的规则了。不用对每一个具体神经网络每次人工求解这些导数值了。它可以适应任意隐藏层,对任一层包括输入和输出层都可以有任意多的神经元。

也许在上边这个两层的神经网络求导过程中你已经有些感觉了。我们要做的就是:
1. 把Loss Function的对于输出层的A^{[out]}独立出来,这样对最后一层W^{[out]}B^{[out]}的求解就和其他层没有什么区别了。
2. 对于input层,因为没有前继层,所以它的X就相当于其他层的A。

同样,一下的dW,dB..都是Loss function对W,B..来求导的。
首先对于Loss Function:L(A^{[out]},Y)=-(Y\log{A^{[out]}}+(1-Y)\log(1-A^{[out]}))

 d{A^{[out]}}=-\frac{y}{A^{[out]}}+\frac{1-y}{1-A^{[out]}}

和之前的逻辑回归定义不一样,我们用Y来表示输出向量,意味着我们的神经网络输出节点可能有多个。而且用A^{[out]}来代替\hat{y}
接下来我们来看dA^{[n]}的求导。其中n不是输出层。
 d{A^{[n]}}=dZ^{[n+1]}{W^{[n+1]}}^T .
dZ^{[n]} = dA^{[n]}\frac{\mathrm{d} A}{\mathrm{d} Z} = dA^{[n]}\frac{e^{-z}}{{(1+e^{-z})}^2} =  dA^{[n]}*A^{[n]}*(1-A^{[n]})
dW^{[n]} = -\frac{1}m{A^{[n-1]}}^TdZ^{[n]}m 为训练集条目数
dB^{[n]} = -\frac{1}mdZ^{[n]}

有了这些公式我们可以开始用梯度下降来实现一个神经网络了。因为X,W,B,A等都代表向量,所以每一层的神经元就可以是任意数。而我们公式中的n让我们的神经网络的层数也可以扩展到任意层。下一篇文章我们就来自己实现一个手写识别的神经网络。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

%d 博主赞过: