深度学习的训练本质是优化损失,优化的方式是计算梯度,然后通过优化算法更新参数 ,常见的优化算法SGD/Momentum/Adagrad/RMSProp/Adam等,本文总结一下梯度的计算。
利用微分求梯度的方法计算量太大,而误差反向传播算法的出现提高了计算效率,误差反向传播算法(BP)主要基于链式法则。
链式法则是求复合函数的导数:
例如多元复合函数 f = x 2 y f=x^2y f=x2y,可以看作 f ( x , y ) = p ( x ) q ( y ) f(x,y)=p(x)q(y) f(x,y)=p(x)q(y),其中 p ( x ) = x 2 p(x)=x^2 p(x)=x2, q ( y ) = y q(y)=y q(y)=y
∂ f ∂ x = ∂ f ∂ p ∗ ∂ p ∂ x = q ∗ 2 x = 2 x y \frac{\partial{f}}{\partial{x}}=\frac{\partial{f}}{\partial{p}}*\frac{\partial{p}}{\partial{x}}=q*2x=2xy ∂x∂f=∂p∂f∗∂x∂p=q∗2x=2xy
∂ f ∂ y = ∂ f ∂ q ∗ ∂ q ∂ y = p ∗ 1 = x 2 \frac{\partial{f}}{\partial{y}}=\frac{\partial{f}}{\partial{q}}*\frac{\partial{q}}{\partial{y}}=p*1=x^2 ∂y∂f=∂q∂f∗∂y∂q=p∗1=x2
有了偏导数,当y的梯度已知,各变量的梯度=偏导数*y的梯度,因此有几点常用如下
1.如果是由a + b = y,则反向传播时a b 的梯度相等,且等于y的梯度
2.如果是a * b = y,则反向传播时a b 的梯度分别为b a,如果是矩阵运算会涉及到矩阵转换
3.max操作梯度只有传播到取最大值的一路
逻辑回归流程如下
这里激活函数为sigmoid a = 1 1 + e x p ( − x ) a=\frac{1}{1+exp(-x)} a=1+exp(−x)1
d a d z = 1 ( 1 + e − x ) 2 ∗ e − x = 1 1 + e − x ∗ e − x 1 + e − x = 1 1 + e − x ∗ ( 1 − 1 1 + e − x ) \frac{da}{dz}=\frac{1}{(1+e^{-x})^2}*e^{-x}=\frac{1}{1+e^{-x}}*\frac{e^{-x}}{1+e^{-x}}=\frac{1}{1+e^{-x}}*(1-\frac{1}{1+e^{-x}}) dzda=(1+e−x)21∗e−x=1+e−x1∗1+e−xe−x=1+e−x1∗(1−1+e−x1)
d a d z = y ∗ ( 1 − y ) \frac{da}{dz}=y*(1-y) dzda=y∗(1−y)
先求L(a,y)关于a的导数 d L ( a , y ) d a = − y / a + ( 1 − y ) / ( 1 − a ) \frac{dL(a,y)}{da}=-y/a+(1-y)/(1-a) dadL(a,y)=−y/a+(1−y)/(1−a)
因为 d L ( a , y ) d z = ( d L d a ) ∗ ( d a d z ) \frac{dL(a,y)}{dz}=(\frac{dL}{da})*(\frac{da}{dz}) dzdL(a,y)=(dadL)∗(dzda)
所以有 d z = d L ( a , y ) d z = ( d L d a ) ∗ ( d a d z ) = [ − y / a + ( 1 − y ) / ( 1 − a ) ] ∗ a ( 1 − a ) d z = a − y dz=\frac{dL(a,y)}{dz}=(\frac{dL}{da})*(\frac{da}{dz})=[-y/a+(1-y)/(1-a)]*a(1-a)\\ dz=a-y dz=dzdL(a,y)=(dadL)∗(dzda)=[−y/a+(1−y)/(1−a)]∗a(1−a)dz=a−y
进一步推导w和b
d w 1 = 1 m ∑ i m x 1 ( i ) ( a ( i ) − y ( i ) ) d w 2 = 1 m ∑ i m x 2 ( i ) ( a ( i ) − y ( i ) ) d b = 1 m ∑ i m ( a ( i ) − y ( i ) ) dw_1=\frac{1}{m}\sum_i^mx_1^{(i)}(a^{(i)}-y^{(i)})\\ dw_2=\frac{1}{m}\sum_i^mx_2^{(i)}(a^{(i)}-y^{(i)})\\ db=\frac{1}{m}\sum_i^m(a^{(i)}-y^{(i)}) dw1=m1i∑mx1(i)(a(i)−y(i))dw2=m1i∑mx2(i)(a(i)−y(i))db=m1i∑m(a(i)−y(i))
趁热打铁,我们把矩阵形式的梯度推导一下,先放结果。假设 D = w x D=wx D=wx
d W = d D . d o t ( X . T ) d X = W . T . d o t ( d D ) dW=dD.dot(X.T)\\ dX=W.T.dot(dD) dW=dD.dot(X.T)dX=W.T.dot(dD)
a*b 表示矩阵对应位置相乘
a.dot(b) 表示矩阵内积
一元微积分中的微分 d f df df与导数的全微分公式 f ′ ( x ) f'(x) f′(x) d f = f ′ ( x ) d x df=f'(x)dx df=f′(x)dx
多元微积分中的微分 d f df df与梯度的全微分公式 ∂ f ∂ x \frac{\partial{f}}{\partial{x}} ∂x∂f: d f = ∑ i = 1 n ∂ f ∂ x i d x i = ( ∂ f ∂ x ) T d x df=\sum_{i=1}^{n}\frac{\partial{f}}{\partial{x_i}}dx_i=(\frac{\partial{f}}{\partial{x}})^Tdx df=i=1∑n∂xi∂fdxi=(∂x∂f)Tdx
从多元微积分的全微分公式可以看到全微分df等于梯度向量(n,1)与微分向量dx(n,1)的内积
类似的,微分df和矩阵导数 ∂ f ∂ X \frac{\partial f}{\partial X} ∂X∂f(标量对矩阵的导数):
d f = ∑ i = 1 m ∑ j = 1 n ∂ f ∂ X i j d X i j = t r ( ( ∂ f ∂ X ) T d X ) df=\sum_{i=1}^{m}\sum_{j=1}^{n}\frac{\partial{f}}{\partial{X_{ij}}}dX_{ij}=tr((\frac{\partial{f}}{\partial{X}})^TdX) df=i=1∑mj=1∑n∂Xij∂fdXij=tr((∂X∂f)TdX)
tr表示矩阵的迹(tarce),是方阵对角线元素之和,满足性质:对尺寸相同的矩阵A,B有
t r ( A T B ) = ∑ i , j A i j B i j tr(A^TB)=\sum_{i,j}A_{ij}B{ij} tr(ATB)=i,j∑AijBij
举个例子理解下
常用的微分的运算法则:
逐元素是指针对矩阵单个元素求函数值或者求导
X = [ x 1 , x 2 ] X=[x_1,x_2] X=[x1,x2], d ( s i n X ) = [ cos x 1 d x 1 , cos x 2 d x 2 ] = cos X ⊙ d X d(sinX)=[\cos x_1dx_1,\cos x_2dx_2]=\cos X\odot dX d(sinX)=[cosx1dx1,cosx2dx2]=cosX⊙dX
迹技巧
#正向传播
Z_1 = np.dot(W_1.T,X) + b_1 # 维度N1*M ,N1表示第一隐层的神经元数
A_1 = sigmoid(Z_1) # 维度N1*M
Z_2 = np.dot(W_2.T,A_1) + b_2 # 维度N2*M ,N2表示输出层的神经元数
A_2 = sigmoid(Z_2) # 维度N2*M ,本例中N2=1
L = cross_entropy(A_2,Y) # 标量
矩阵形式的损失函数 L = ( − ( Y ⊙ l o g ( A 2 ) ) − ( ( 1 − Y ) ⊙ l o g ( 1 − A 2 ) ) I L=(-(Y\odot log(A_2))-((1-Y)\odot log(1-A_2))I L=(−(Y⊙log(A2))−((1−Y)⊙log(1−A2))I
这里矩阵I是个全为1的(M,1)的矩阵,作用于前面(1,M)的损失求和
接下来使用迹技巧将 d W dW dW换到最右侧
d L = t r ( d L ) = t r ( ( ( A 2 − Y ) ⊙ d Z 2 ) I ) dL=tr(dL)=tr(((A_2-Y)\odot dZ_2)I) dL=tr(dL)=tr(((A2−Y)⊙dZ2)I)
因为 ( A 2 − Y ) ⊙ d Z 2 (A_2-Y)\odot dZ_2 (A2−Y)⊙dZ2与 I T I^T IT尺寸相同,所以有
d L = t r ( d L ) = t r ( ( ( A 2 − Y ) ⊙ d Z 2 ) I ) = t r ( I ( ( A 2 − Y ) ⊙ d Z 2 ) ) = t r ( ( I T ) T ( ( A 2 − Y ) ⊙ d Z 2 ) ) dL=tr(dL)=tr(((A_2-Y)\odot dZ_2)I)=tr(I((A_2-Y)\odot dZ_2))=tr((I^T)^T((A_2-Y)\odot dZ_2)) dL=tr(dL)=tr(((A2−Y)⊙dZ2)I)=tr(I((A2−Y)⊙dZ2))=tr((IT)T((A2−Y)⊙dZ2))
由法则 t r ( A T ( B ⊙ C ) ) = t r ( ( A ⊙ B ) T C ) tr(A^T(B \odot C))=tr((A \odot B)^TC) tr(AT(B⊙C))=tr((A⊙B)TC)得:
d L = t r ( ( I T ) T ( ( A 2 − Y ) ⊙ d Z 2 ) ) = t r ( [ ( I T ) ⊙ ( A 2 − Y ) ] T d Z 2 ) dL=tr((I^T)^T((A_2-Y)\odot dZ_2))=tr([(I^T)\odot (A_2-Y)]^TdZ_2) dL=tr((IT)T((A2−Y)⊙dZ2))=tr([(IT)⊙(A2−Y)]TdZ2)
由 d L = t r ( ( ∂ L ∂ Z 2 ) T d Z 2 ) dL=tr((\frac{\partial L}{\partial {Z_2}})^TdZ_2) dL=tr((∂Z2∂L)TdZ2)比较上式得出:
∂ L ∂ Z 2 = ( I T ) ⊙ ( A 2 − Y ) = A 2 − Y \frac{\partial L}{\partial {Z_2}}=(I^T)\odot (A_2-Y)=A_2-Y ∂Z2∂L=(IT)⊙(A2−Y)=A2−Y
所以 d Z 2 = A 2 − Y dZ_2=A_2-Y dZ2=A2−Y
矩阵求导与矩阵微分
神经网络的反向传播算法中矩阵的求导方法
未完待续…