深度学习入门之反向传播算法

引言

在神经网络中,为了更有效的计算梯度,需要用到反向传播算法。我们先从链式求导法则开始。

链式求导法

先介绍下链式求导法则,在后面的反向传播算法中会用到。

y = g ( x ) , z = h ( y ) y = g(x),z=h(y)

那么 d z d x = d z d y d y d x \frac{dz}{dx} = \frac{dz}{dy}\frac{dy}{dx} ;

x = g ( s ) , y = h ( s ) , z = k ( x , y ) x=g(s) ,y = h(s), z = k(x,y)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tCHUNDUb-1577369599077)(_v_images/20191226202915321_20747.png)]

改变了s会改变x和y,从而改变了z。

d z d s = z x d x d s + z y d y d s \frac{dz}{ds} = \frac{\partial{z}}{\partial{x}}\frac{dx}{ds} + \frac{\partial{z}}{\partial{y}}\frac{dy}{ds}

注意,如果改变s会改变多个变量,它们的关系也是成立的。

损失函数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dnxvSeRt-1577369599078)(_v_images/20191226203608959_23215.png)]

假设给定一组参数 θ \theta ,把一个训练数据 x n x^n 代入NN(神经网络)中,会得到输出 y n y^n

C n C^n 是输出 y n y^n 和实际 y ^ n \hat{y}^n 距离函数,值越大代表越距离远,也就是效果越不好。

那在神经网络训练算法中,损失函数定义为:

L ( θ ) = n = 1 N C n ( θ ) L(\theta) = \sum^{N}_{n=1}C^n(\theta)

如果把损失函数对参数 w w 做微分的话,得到

L ( θ ) w = n = 1 N C n ( θ ) w \frac{\partial L(\theta)}{\partial w} = \sum^{N}_{n=1}\frac{\partial C^n(\theta)}{\partial w}

只要计算出某一笔数据对 w w 的微分,就可以得到 L ( θ ) L(\theta) w w 的微分。

在这里插入图片描述

假设我们先考虑这个神经元。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Eth5wURE-1577369599079)(_v_images/20191226204431854_16296.png)]

假设只有两个输入 x 1 , x 2 x_1,x_2 ,计算 z = x 1 w 1 + x 2 w 2 + b z = x_1w_1 + x_2w_2 + b 得到 z z 后再代入激活函数,经过多次运算会得到最终的输出 y 1 , y 2 y_1,y_2

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nKqVbw2D-1577369599079)(_v_images/20191226204622410_15098.png)]

现在问题是如何计算损失(距离函数) C C w w 的偏微分 C w \frac{\partial C}{\partial w}

利用链式求导法

C w = C z z w \frac{\partial C}{\partial w} = \frac{\partial C}{\partial z} \frac{\partial z}{\partial w}

计算 z w \frac{\partial z}{\partial w} 的过程叫做正向过程(Forward pass);计算 C z \frac{\partial C}{\partial z} 的过程叫做反向过程(Backward pass)

正向过程

z = x 1 w 1 + x 2 w 2 + b z = x_1w_1 + x_2w_2 + b

z w 1 = x 1 z w 2 = x 2 \frac{\partial z}{\partial w_1} = x_1 \\ \frac{\partial z}{\partial w_2} = x_2 \\
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I2a9Z4Ic-1577369599079)(_v_images/20191226205915655_32463.png)]

如上图所示,假设输入是 1 , 1 1,-1 ,上面蓝色神经元的参数: w 1 = 1 , w 2 = 2 , b = 1 w_1=1,w_2=-2,b=1 ,激活函数是Sigmoid函数;
下面蓝色神经元的参数: w 1 = 1 , w 2 = 1 , b = 0 w_1=-1,w_2=1,b=0

对下面的神经元来说,计算 w 2 w_2 的偏微分,可以很快得出 z w = 1 \frac{\partial z}{\partial w} = -1 ,也就是输入 x 2 ( 1 ) x_2(-1) ,随着从前往后计算每个神经元的输出,整个过程就可以很快结束,因此叫正向过程。

反向过程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PYFLvzls-1577369599079)(_v_images/20191226210813603_16863.png)]

困难的是如何计算 C z \frac{\partial C}{\partial z}

a = 1 1 + e z a = \frac{1}{1+e^{-z}}

假设激活函数是Sigmoid函数 a = σ ( z ) a=\sigma(z) ,然后得到的函数值 a a 会乘上某个权重(比如 w 3 w_3 )再加上其他值得到 z z^\prime (注意这里只是一个符号,不是 z z 的导数); a a 也会乘上权重(比如 w 4 w_4 )再加上其他东西得到 z z^{\prime\prime} (注意这里只是一个符号,不是 z z 的二阶导数);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IwHcHWyr-1577369599080)(_v_images/20191226211217380_32053.png)]

C z = C a a z \frac{\partial C}{\partial z} = \frac{\partial C}{\partial a} \frac{\partial a}{\partial z}

可以这样理解, z z 通过影响 a a 来影响 C C

a z = σ ( z ) z = σ ( z ) \frac{\partial a}{\partial z} = \frac{\partial \sigma(z)}{\partial z} = \sigma^\prime(z)

那就剩下

C a = C z z a + C z z a \frac{\partial C}{\partial a} = \frac{\partial C}{\partial z^\prime}\frac{\partial z^\prime}{\partial a} + \frac{\partial C}{\partial z^{\prime\prime}}\frac{\partial z^{\prime\prime}}{\partial a}

改变了 a a 会改变 z z^{\prime} z z^{\prime\prime} ,从而改变了 C C

我们先计算简单的

z = a w 3 + z^{\prime} = aw_3 + \cdots


z a = w 3 \frac{\partial z^{\prime}}{\partial a} = w_3

同理

z a = w 4 \frac{\partial z^{\prime\prime}}{\partial a} = w_4

现在难点就是 C z \frac{\partial C}{\partial z^\prime} C z \frac{\partial C}{\partial z^{\prime\prime}}

我们这里先假装我们知道这两项的值。然后整理下原来的式子:

C z = σ ( z ) [ w 3 C z + w 4 C z ] \frac{\partial C}{\partial z} = \sigma^\prime(z)[w_3\frac{\partial C}{\partial z^\prime} + w_4\frac{\partial C}{\partial z^{\prime\prime}}]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I7cjk4Ly-1577369599080)(_v_images/20191226214024450_27012.png)]

假设有另外一个特殊的神经元,它是上图的样子,输入就是 C z \frac{\partial C}{\partial z^\prime} C z \frac{\partial C}{\partial z^{\prime\prime}} ,它们分别乘以 w 3 w_3 w 4 w_4 ,然后求和得到的结果再乘上 σ ( z ) \sigma^\prime(z)
就得到了 C z \frac{\partial C}{\partial z}

z z 在正向传播的过程中已经知道了,因此这里的 σ ( z ) \sigma^\prime(z) 是一个常数。

说了这么多,还是没说怎么计算 C z \frac{\partial C}{\partial z^\prime} C z \frac{\partial C}{\partial z^{\prime\prime}} 啊。别急,下面就开始计算。

这里要分两种情况考虑:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BiSbf5tC-1577369599080)(_v_images/20191226214926144_15098.png)]

情形一: 红色的两个神经元就是输出层,它们能直接得到输出。

根据链式法则有:

C z = y 1 z C y 1 \frac{\partial C}{\partial z^\prime} = \frac{\partial y_1}{\partial z^\prime}\frac{\partial C}{\partial y_1}

只要知道激活函数是啥就能计算出 y 1 z \frac{\partial y_1}{\partial z^\prime}

C y 1 \frac{\partial C}{\partial y_1} 也可以根据我们选取的损失函数简单的计算出来。

同理 C z \frac{\partial C}{\partial z^{\prime\prime}} 的计算也一样

情形二:红色的不是输出层

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RM7wSAxA-1577369599081)(_v_images/20191226220033042_12662.png)]

红色的是中间层,它们的激活函数的值会当成下一层的输入继续参数计算。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UefOrgCj-1577369599081)(_v_images/20191226220203239_4057.png)]

如果我们知道 C z a \frac{\partial C}{\partial z_a} C z b \frac{\partial C}{\partial z_b}

同理(回顾一下上面那个特殊的神经元)我们就可以计算 C z \frac{\partial C}{\partial z^{\prime}}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p2J9i11V-1577369599081)(_v_images/20191226220512917_26589.png)]

问题就会这样反复循环下去,我们不停的看下一层,直到遇到了输出层。然后就可以由输出层往前计算出整个NN的所有的参数。

那我们为何不换个角度考虑问题,我们直接先算输出层的偏微分,然后依次往前计算。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ORibfTTy-1577369599081)(_v_images/20191226221214641_7228.png)]

这就是反向传播算法的思想。

发布了131 篇原创文章 · 获赞 38 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/yjw123456/article/details/103723505
今日推荐