机器学习:神经网络正向传播与反向传播的向量化推导


虽然吴恩达推荐在第一次实现神经网络的时候用 for循环挨个挨个传入样本正向传播反向传播,每次累加误差与隐藏层的成绩来计算梯度,但我不满意呀,妥妥能向量化的东西,怎么能用 for循环呢?我直接进行一个向量化神经网络传播的推导。

向量化终极技巧

当你不知道矩阵该怎么运算的时候,直接把线性式按照遵循矩阵运算规则的形式替换一下,一般就是对的。

神经网络架构

这里使用的是吴恩达机器学习ex4里的架构:
在这里插入图片描述
分为三层,输入层、隐藏层与输出层。输入层为400个单元分别对应手写数字图片中的400个像素,隐藏层有25个单元,输出层有10个单元对应10个数字。

输入矩阵 X X X为5000×400的矩阵,包含5000张手写数字图片,每张图片有20×20=400个像素。
X = [ − ( x ( 1 ) ) T − − ( x ( 2 ) ) T − ⋮ − ( x ( m ) ) T − ] X=\left[\begin{matrix} -(x^{(1)})^T-\\ -(x^{(2)})^T-\\ \vdots\\ -(x^{(m)})^T-\\ \end{matrix}\right] X=(x(1))T(x(2))T(x(m))T

对于答案矩阵 y y y,我们需要处理一下, y y y本来是m×1的列向量, y ( i ) y^{(i)} y(i)为第 i i i张图片上的数字。现在我们要把它转化成与我们神经网络的输出相同的格式,即若第 i i i张图片上是4,则我们期望的神经网络输出是
a ( 3 ) = [ 0 0 0 1 0 0 0 0 0 0 ] a^{(3)}= \left[\begin{matrix} 0\\ 0\\ 0\\ 1\\ 0\\ 0\\ 0\\ 0\\ 0\\ 0\\ \end{matrix}\right] a(3)=0001000000
由此,我们把列向量 y y y转换成 m × s L m\times s_L m×sL的矩阵,包含m个样本我们期望的神经网络输出。

参数矩阵遵循原定义, Θ ( l ) = s l + 1 × ( s l + 1 ) \Theta^{(l)}=s_{l+1}\times(s_l+1) Θ(l)=sl+1×(sl+1),为 l + 1 l+1 l+1层从 l l l层转移的权值。

正向传播

向前传播比较简单,因为每一层的激励矩阵都是 m × s l m\times s_l m×sl的,我们首先在左侧为矩阵加上偏置(一列1),矩阵变为 m × ( s l + 1 ) m\times(s_l+1) m×(sl+1)的,要传播到下一层,就乘以参数矩阵的转置再通过逻辑函数,即
a ( l + 1 ) = g ( [ 1 a ( l ) ] Θ ( l ) ) a^{(l+1)}=g([1\quad a^{(l)}]\Theta^{(l)}) a(l+1)=g([1a(l)]Θ(l))
因为只有一个隐藏层,所以传播两次就到了输出层,得到一个 m × s L m\times s_L m×sL的矩阵。

反向传播

代价函数

正好我们的目标矩阵 y y y也是 m × s L m\times s_L m×sL的,两个矩阵之间每行元素都对应一个样本,所以我们套用代价函数公式:
J ( Θ ) = − 1 m ∑ i = 1 m ∑ k = 1 K [ y k ( i ) log ⁡ ( ( h Θ ( x ( i ) ) ) k ) + ( 1 − y k ( i ) ) log ⁡ ( 1 − ( h Θ ( x ( i ) ) ) k ) ] + λ 2 m ∑ l = 1 L − 1 ∑ i = 1 s l ∑ j = 1 s l + 1 ( Θ j i ( l ) ) 2 J(\Theta)=-\frac{1}{m}\sum_{i=1}^m\sum_{k=1}^K[y_k^{(i)}\log((h_\Theta(x^{(i)}))_k)+(1-y_k^{(i)})\log(1-(h_\Theta(x^{(i)}))_k)]+\frac{\lambda}{2m}\sum_{l=1}^{L-1}\sum_{i=1}^{s_l}\sum_{j=1}^{s_{l+1}}(\Theta_{ji}^{(l)})^2 J(Θ)=m1i=1mk=1K[yk(i)log((hΘ(x(i)))k)+(1yk(i))log(1(hΘ(x(i)))k)]+2mλl=1L1i=1slj=1sl+1(Θji(l))2
这里 y k ( i ) y_k^{(i)} yk(i) h Θ ( x ( i ) ) k h_\Theta(x^{(i)})_k hΘ(x(i))k都是对应相乘的,很显然我们这里要改成矩阵形式的话就应该使用点乘,求和用sum函数,所以有
J ( Θ ) = − 1 m [ sum ( y . ∗ log ⁡ ( a ( 3 ) ) ) + sum ( ( 1 − y ) . ∗ ( log ⁡ ( 1 − a ( 3 ) ) ) ) ] + λ 2 m ∑ l = 1 L − 1 ∑ i = 1 s l ∑ j = 1 s l + 1 ( Θ j i ( l ) ) 2 J(\Theta)=-\frac{1}{m}[\text{sum}(y.*\log(a^{(3)}))+\text{sum}((1-y).*(\log(1-a^{(3)})))]+\frac{\lambda}{2m}\sum_{l=1}^{L-1}\sum_{i=1}^{s_l}\sum_{j=1}^{s_{l+1}}(\Theta_{ji}^{(l)})^2 J(Θ)=m1[sum(y.log(a(3)))+sum((1y).(log(1a(3))))]+2mλl=1L1i=1slj=1sl+1(Θji(l))2
后面的正则项直接按项平方后求和即可,注意偏置项不参与正则化,如果用矩阵整个运算的话,要记得把第一列减掉。

误差传播

为了计算梯度,我们先算误差。输出层的误差很好求,直接 a ( 3 ) a^{(3)} a(3) y y y相减再转置一下
δ ( 3 ) = ( a ( 3 ) − y ) T \delta^{(3)}=(a^{(3)}-y)^T δ(3)=(a(3)y)T
得到一个 s L × m s_L\times m sL×m的矩阵。之所以要转置,是因为之前在推单个样本的反向传播时, δ \delta δ都是 s L × 1 s_L\times 1 sL×1的列向量,为了更好的套用公式,所以转置一下让每个样本的 δ \delta δ仍为列向量。

误差传播公式为
δ ( l ) = ( ( Θ ( l ) ) T δ ( l + 1 ) ) . ∗ a ( l ) . ∗ ( 1 − a ( l ) ) \delta^{(l)}=((\Theta^{(l)})^T\delta^{(l+1)}).*a^{(l)}.*(1-a^{(l)}) δ(l)=((Θ(l))Tδ(l+1)).a(l).(1a(l))
Θ ( l ) \Theta^{(l)} Θ(l) s l + 1 × ( s l + 1 ) s_{l+1}\times(s_l+1) sl+1×(sl+1)的矩阵,所以完美符合上面的公式,我们把 Θ ( l ) \Theta^{(l)} Θ(l)转置一下跟 δ ( l + 1 ) \delta^{(l+1)} δ(l+1)相乘,得到一个 ( s l + 1 ) × m (s_l+1)\times m (sl+1)×m的矩阵。至于后面的点乘部分,加上了偏置项的 a ( l ) a^{(l)} a(l) m × ( s l + 1 ) m\times (s_l+1) m×(sl+1)的,我们转置一下再按位相乘即可。这样我们就完成了一次误差的反向传播!

但是,还有一件很重要的事情,我们是不计算偏置项的误差的,因为偏置项都恒为 + 1 +1 +1,改变的是系数矩阵,所以我们要去掉除 δ ( L ) \delta^{(L)} δ(L)外所有误差矩阵的第一行,最后 δ ( l ) \delta^{(l)} δ(l) s l × m s_l\times m sl×m的。

计算梯度

要计算梯度,先计算 Δ ( l ) \Delta^{(l)} Δ(l),单个样本的计算式为
Δ ( l ) : = Δ ( l ) + δ ( l + 1 ) ( a ( l ) ) T \Delta^{(l)}:=\Delta^{(l)}+\delta^{(l+1)}(a^{(l)})^T Δ(l):=Δ(l)+δ(l+1)(a(l))T
这里 δ ( l + 1 ) \delta^{(l+1)} δ(l+1) a ( l ) a^{(l)} a(l)都是列向量,所以需要转置一下 a ( l ) a^{(l)} a(l),但在上面的计算中 a ( l ) a^{(l)} a(l) m × ( s l + 1 ) m\times (s_l+1) m×(sl+1)的矩阵, δ ( l + 1 ) \delta^{(l+1)} δ(l+1) s l + 1 × m s_{l+1}\times m sl+1×m的矩阵,正好每个样本的 δ ( l + 1 ) \delta^{(l+1)} δ(l+1)竖着放, a ( l ) a^{(l)} a(l)横着放,所以我们不需要转置,直接相乘即可,还顺便完成了求和工作,即
Δ ( l ) = δ ( l + 1 ) a ( l ) \Delta^{(l)}=\delta^{(l+1)}a^{(l)} Δ(l)=δ(l+1)a(l)
非常的简洁。

有了 Δ \Delta Δ,剩下的工作就很简单了,由
∂ ∂ Θ i j ( l ) J ( Θ ) = D i j ( l ) = { 1 m ( Δ i j ( l ) + λ Θ i j ( l ) ) j ≠ 0 1 m Δ i j ( l ) j = 0 \frac{\partial}{\partial\Theta_{ij}^{(l)}}J(\Theta)=D_{ij}^{(l)}=\left\{ \begin{aligned} &\frac{1}{m}(\Delta_{ij}^{(l)}+\lambda\Theta_{ij}^{(l)})&&j\not=0\\ &\frac{1}{m}\Delta_{ij}^{(l)}&&j=0\\ \end{aligned}\right. Θij(l)J(Θ)=Dij(l)=m1(Δij(l)+λΘij(l))m1Δij(l)j=0j=0
我们将 Δ \Delta Δ矩阵除以 m m m,再给需要正则化的参数加上正则项,就得到了梯度。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShadyPi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值