————矩阵求导与神经网络反向传播

矩阵求导

关于矩阵求导,其实严格意义上来说仅仅只是一种求导的矩阵表示形式,其本质还是和普通多元函数求导过程是一致的。将矩阵的各个元素拆分开来,将矩阵运算写成各个元素之间的运算,矩阵变换可以变成多元函数,这样矩阵求导过程就可以与多元函数求导过程联系起来了。要理解矩阵求导运算,最主要的其实是理解矩阵导数的表示,将矩阵导数的拆分形式与多元函数求导联系起来。 
本文主要参考《Matrix cookbook》和wiki上面的内容,下面简单介绍一下矩阵求导的相关内容,为后面介绍前馈神经网络FNN的反向传播过程做铺垫。

矩阵求导的表示形式之一:值函数对向量/矩阵变量的导数

下面表达式中,yy表示一个实值函数,xx表示一个向量变量,那么他们的矩阵求导含义为: 

yx=yx1yx2yxn∂y∂x=[∂y∂x1∂y∂x2⋯∂y∂xn]

yy 表示一个实值函数, XX 表示一个矩阵变量: 
yX=yx11yx21yxp1yx12yx22yxp2yx1qyx2qyxpq∂y∂X=[∂y∂x11∂y∂x12⋯∂y∂x1q∂y∂x21∂y∂x22⋯∂y∂x2q⋯⋯⋯⋯∂y∂xp1∂y∂xp2⋯∂y∂xpq]

上面给出了矩阵求导的表示形式的具体含义,很容易理解。下面给出几个例子, aa 是实数, ββ xx 是向量, AA BB CC 是与 xx 无关的矩阵: 
βTxx=β∂βTx∂x=β

xTxx=x∂xTx∂x=x

xTAxx=(A+AT)x∂xTAx∂x=(A+AT)x

如果你能发现这三个式子左边的分子都是一个数,分母都是一个向量,那么你应该很容易理解这几个等式。是在不能理解就自己把左右两边的矩阵运算拆分开来,然后使用多元函数求导的过程将左右两边分别表示出来就行了。以第一个为例: 
βTx=i=1nβixiβTx=∑i=1nβixi

βTxx=βTxx1βTxx2βTxxn=ni=1βixix1ni=1βixix2ni=1βixixn=β1β2βn=β∂βTx∂x=[∂βTx∂x1∂βTx∂x2⋯∂βTx∂xn]=[∂∑i=1nβixi∂x1∂∑i=1nβixi∂x2⋯∂∑i=1nβixi∂xn]=[β1β2⋯βn]=β

这样就能很清楚的理解矩阵矩阵求导的表示形式的具体含义了。

矩阵求导的表示形式之二:向量函数对值/向量/矩阵变量的导数

下面表达式中,yy表示一个向量函数,xx表示一个值变量,那么他们的矩阵求导含义为: 

yx=y1xy2xynx∂y∂x=[∂y1∂x∂y2∂x⋯∂yn∂x]

接下来是向量函数 yy 对向量变量 xx 的导数含义为: 
yx=y1x1y2x2ymxny1x2y2x2ymx2y1xny2xnymxn∂y∂x=[∂y1∂x1∂y1∂x2⋯∂y1∂xn∂y2∂x2∂y2∂x2⋯∂y2∂xn⋯⋯⋯⋯∂ym∂xn∂ym∂x2⋯∂ym∂xn]

以一个最为简单的例子为例: 
y=Wxy=Wx

那么: 
yx=W∂y∂x=W

最后向量函数 yy 对矩阵变量 WW 的导数是一个张量,具体形状为: 
yW=y1W11y1W21y1Wm1y1W12y1W22y1Wm2y1W2ny1W2ny1Wmny2W11y2W21y2Wm1y2W12y2W22y2Wm2y2W2ny2W2ny2WmnykW11ykW21ykWm1ykW12ykW22ykWm2ykW2nykW2nykWmn∂y∂W=[∂y1∂W11∂y1∂W12⋯∂y1∂W2n∂y1∂W21∂y1∂W22⋯∂y1∂W2n⋯⋯⋯⋯∂y1∂Wm1∂y1∂Wm2⋯∂y1∂Wmn][∂y2∂W11∂y2∂W12⋯∂y2∂W2n∂y2∂W21∂y2∂W22⋯∂y2∂W2n⋯⋯⋯⋯∂y2∂Wm1∂y2∂Wm2⋯∂y2∂Wmn]⋯[∂yk∂W11∂yk∂W12⋯∂yk∂W2n∂yk∂W21∂yk∂W22⋯∂yk∂W2n⋯⋯⋯⋯∂yk∂Wm1∂yk∂Wm2⋯∂yk∂Wmn]

同样举出一个例子说明这个形式的含义: l=f(y)l=f(y) 其中, yy mm 维向量,然后 y=Wxy=Wx WW mnm∗n 的矩阵, xx nn 维向量。然后 ly∂l∂y mm 维向量, yW∂y∂W mmnm∗m∗n 维张量,最后根据链式法则有 lW=lyyW∂l∂W=∂l∂y∂y∂W ,很显然最后的结果 lW∂l∂W 应该是一个 mnm∗n 为的矩阵,而等式另外边为 mm 维向量乘上 mmnm∗m∗n 维张量,其结果为 mnm∗n 维矩阵。将这个过程拆开来看: 
yW=yW11yW21yWm1yW12yW22yWm2yW1nyW2nyWmn=mi=1ly1y1W11mi=1ly1y1W21mi=1ly1y1Wm1mi=1ly1y1W12mi=1ly1y1W22mi=1ly1y1Wm2mi=1ly1y1W1nmi=1ly1y1W2nmi=1ly1y1Wmn∂y∂W=[∂y∂W11∂y∂W12⋯∂y∂W1n∂y∂W21∂y∂W22⋯∂y∂W2n⋯⋯⋯⋯∂y∂Wm1∂y∂Wm2⋯∂y∂Wmn]=[∑i=1m∂l∂y1∂y1∂W11∑i=1m∂l∂y1∂y1∂W12⋯∑i=1m∂l∂y1∂y1∂W1n∑i=1m∂l∂y1∂y1∂W21∑i=1m∂l∂y1∂y1∂W22⋯∑i=1m∂l∂y1∂y1∂W2n⋯⋯⋯⋯∑i=1m∂l∂y1∂y1∂Wm1∑i=1m∂l∂y1∂y1∂Wm2⋯∑i=1m∂l∂y1∂y1∂Wmn]

矩阵求导的表示形式之三:矩阵函数对值/向量/矩阵变量的导数

首先矩阵函数YY对值变量xx的导数含义为: 

Yx=y11xy21xyp1xy12xy22xyp2xy1qxy2qxypqx∂Y∂x=[∂y11∂x∂y12∂x⋯∂y1q∂x∂y21∂x∂y22∂x⋯∂y2q∂x⋯⋯⋯⋯∂yp1∂x∂yp2∂x⋯∂ypq∂x]

这个也很容易理解,然后矩阵函数对向量变量的导数是形式上是一个张量,矩阵函数对矩阵变量的导数是一个四阶张量。 
这些导数的形式很少用到,但实际上本质还是一样的: 矩阵求导本质上是多元函数求导的矩阵表示形式,其函数由矩阵运算定义,其导数形式是为了同样满足矩阵运算而定义的。 还是那句话,如果不理解矩阵求导过程,直接把矩阵运算转化成基本的多元函数运算,用多元函数求导方法写出其形式就很容易理解了。

当然,上面几个仅仅是非常简单的矩阵求导,更复杂的涉及到求迹(对角线上元素的和)tr(A)tr(A)、行列式det(A)det(A)等就需要去参照《Matrix Cookbook》中的内容自行理解了。了解到上面的内容已经足够让我们来理解神经网络的反向传播了。

神经网络反向传播

讲到神经网络的反向传播首先不得不提一下求导的链式法则:实际上神经网络本质上可以说是一堆向量操作加上激活函数,也可以说是一堆线性函数操作加上激活函数,整个过程最终都可以展开成一个无比大的函数。为了比较好表述神经网络的每一层的正向计算以及反向传播,才表述为矩阵计算与链式法则计算梯度,其本质还是非常简单的多元函数求导。

链式法则

链式法则是多元函数求导基本,通常意义上的链式法则表述如下: 

z=f(x,y)x=g(u,v)y=h(u,v)z=f(x,y)x=g(u,v)y=h(u,v)

那么就有: 
zu=zxxu+zyyuzv=zxxv+zyyv∂z∂u=∂z∂x∂x∂u+∂z∂y∂y∂u∂z∂v=∂z∂x∂x∂v+∂z∂y∂y∂v

这个看起来是不是很简单,理解偏导和梯度的含义就应该很容易理解这个过程。那么接下来,重头戏来了:上面过程中 yy 可以是 xx 的函数,甚至可以是 xx 。来我们先举一个简单的例子来看: 
z=xxx=u+vz=xxx=u+v

对于这样一个例子,我们先把上面式子中指数项的 xx 记做 yy ,那么上面的式子就转化为: 
z=xyx=u+vy=u+vz=xyx=u+vy=u+v

接下来我们来根据链式法则来求导: 
zu=zxxu+zyyu=yxy1xu+xyln(x)yu=(u+v)u+v+(u+v)u+vln(u+v)∂z∂u=∂z∂x∂x∂u+∂z∂y∂y∂u=yxy−1∂x∂u+xyln(x)∂y∂u=(u+v)u+v+(u+v)u+vln(u+v)

zv=zxxv+zyyv=yxy1xv+xyln(x)yv=(u+v)u+v+(u+v)u+vln(u+v)∂z∂v=∂z∂x∂x∂v+∂z∂y∂y∂v=yxy−1∂x∂v+xyln(x)∂y∂v=(u+v)u+v+(u+v)u+vln(u+v)

额,是不是很神奇: dxxdx=xx+xxln(x)dxxdx=xx+xxln(x) 这个式子也可以通过将两个 xx 看做不同的 xx 分别求偏导然后求全微分而得到其导数,当且仅当原函数可微时才能这样做。 
好吧,上面这些内容其实是一些题外话,我们真正需要了解的是:在矩阵操作中,我们可以把例如 y=Wx+by=Wx+b 这样的矩阵操作看做是多元函数

全连接层的反向传播

一层全连接层的神经网络的本质是一个output=f(input)output=f(input)的多元函数,例如一般来说一层全连接以xx表示输入向量,yy表示输出向量,那么一层全连接神经网络可数学表示为: 

y=σ(Wx+b)y=σ(Wx+b)

其中 WW bb 是参数,前者是映射矩阵,后者是偏置向量, σσ 表示激活函数,这是一个数值函数,也就是对矩阵/向量中的每一个值做这样一个函数映射,常用的激活函数有如下几种: 
sigmoid 激活函数:
y=11+exy=11+e−x

sigmoid 激活函数的导数: 
y=(11+ex)=ex(1+ex)2=1+ex1(1+ex)2=11+ex(111+ex)=y(1y)y′=(11+e−x)′=e−x(1+e−x)2=1+e−x−1(1+e−x)2=11+e−x(1−11+e−x)=y(1−y)

tanh 激活函数:
y=exexex+exy=ex−e−xex+e−x

tanh 激活函数的导数: 
y=(exexex+ex)=(ex+ex)2(exex)2(ex+ex)2=1(exex)2(ex+ex)2=1y2y′=(ex−e−xex+e−x)′=(ex+e−x)2−(ex−e−x)2(ex+e−x)2=1−(ex−e−x)2(ex+e−x)2=1−y2

relu 激活函数:
y={x,0,x>0x<=0y={x,x>00,x<=0

relu 激活函数的导数: 
y={1,0,x>0x<=0y′={1,x>00,x<=0

从上面这三种常用激活函数的导数可以看出,激活函数反向求导都非常简单直接。然后,我们将从两种角度来给出全连接层反向传播的导数:矩阵形式和多元函数形式。

全连接层的反向传播的矩阵形式

神经网络反向传播时,我们已知的是ly∂l∂y,也就是前面层传过来的lossloss对于当前层输出的梯度,然后一方面我们需要知道lossloss对于参数的梯度lW∂l∂Wlb∂l∂b,而另一方面我们也需要知道lossloss对于输入的梯度lx∂l∂x,以便于参数向前面层传播,更新前面层的参数。假设我们以sigmoidsigmoid函数作为激活函数: 

y=σ(Wx+b)y=σ(Wx+b)

利用链式法则我们有: 
lW=lyy(Wx+b)(Wx+b)W=ly(y(1y))xT∂l∂W=∂l∂y∂y∂(Wx+b)∂(Wx+b)∂W=∂l∂y∘(y∘(1−y))xT

lb=lyy(Wx+b)(Wx+b)b=ly(y(1y))∂l∂b=∂l∂y∂y∂(Wx+b)∂(Wx+b)∂b=∂l∂y∘(y∘(1−y))

lx=lyy(Wx+b)(Wx+b)x=ly(y(1y))W∂l∂x=∂l∂y∂y∂(Wx+b)∂(Wx+b)∂x=∂l∂y∘(y∘(1−y))W

其中 表示矩阵对应值相乘。

全连接层的反向传播的多元函数形式

接下来给出全连接层的多元函数形式: 

y=σ(Wx+b)y=σ(Wx+b)

y=y1y2ymy=[y1y2⋯ym]

则有: 
yi=σ(j=1nWijxj+bi),i=1,2,...,myi=σ(∑j=1nWijxj+bi),i=1,2,...,m

那么有:( WijWij 只影响 yiyi bibi 只影响 yiyi 。) 
lWij=lyiyi(1yi)xj,i=1,2,...,m,j=1,2,...n∂l∂Wij=∂l∂yiyi(1−yi)xj,i=1,2,...,m,j=1,2,...n

lbi=lyiyi(1yi),i=1,2,...,m∂l∂bi=∂l∂yiyi(1−yi),i=1,2,...,m

( xjxj 影响 y1,y2,...,ymy1,y2,...,ym
lxj=i=1mlyiyi(1yi)Wij,j=1,2,...,n∂l∂xj=∑i=1m∂l∂yiyi(1−yi)Wij,j=1,2,...,n

把上面的东西写进矩阵里面就有: 
lW=ly1y1(1y1)x1ly2y2(1y2)x1lymym(1ym)x1ly1y1(1y1)x2ly2y2(1y2)x2lymym(1ym)x2ly1y1(1y1)xnly2y2(1y2)xnlymym(1ym)xn=ly1y1(1y1)ly2y2(1y2)lymym(1ym)[x1x2xn]=ly1ly2lymy1y2ym1y11y21ym[x1x2xn]=ly(y(1y))xT∂l∂W=[∂l∂y1y1(1−y1)x1∂l∂y1y1(1−y1)x2⋯∂l∂y1y1(1−y1)xn∂l∂y2y2(1−y2)x1∂l∂y2y2(1−y2)x2⋯∂l∂y2y2(1−y2)xn⋯⋯⋯⋯∂l∂ymym(1−ym)x1∂l∂ymym(1−ym)x2⋯∂l∂ymym(1−ym)xn]=[∂l∂y1y1(1−y1)∂l∂y2y2(1−y2)⋯∂l∂ymym(1−ym)][x1x2⋯xn]=[∂l∂y1∂l∂y2⋯∂l∂ym]∘[y1y2⋯ym]∘[1−y11−y2⋯1−ym][x1x2⋯xn]=∂l∂y∘(y∘(1−y))xT


lb=ly1y1(1y1)ly2y2(1y2)lymym(1ym)ly1y1(1y1)ly2y2(1y2)lymym(1ym)ly1y1(1y1)ly2y2(1y2)lymym(1ym)=ly1ly2lymy1y2ym1y11y21ym=ly(y(1y))∂l∂b=[∂l∂y1y1(1−y1)∂l∂y1y1(1−y1)⋯∂l∂y1y1(1−y1)∂l∂y2y2(1−y2)∂l∂y2y2(1−y2)⋯∂l∂y2y2(1−y2)⋯⋯⋯⋯∂l∂ymym(1−ym)∂l∂ymym(1−ym)⋯∂l∂ymym(1−ym)]=[∂l∂y1∂l∂y2⋯∂l∂ym]∘[y1y2⋯ym]∘[1−y11−y2⋯1−ym]=∂l∂y∘(y∘(1−y))


lx=mi=1lyiyi(1yi)Wi1mi=1lyiyi(1yi)Wi2mi=1lyiyi(1yi)Win=[ly1y1(1y1)ly2y2(1y2)lymym(1ym)]W11W21Wm1W12W22Wm2W1nW2nWmn=[ly(y(1y))]TW∂l∂x=[∑i=1m∂l∂yiyi(1−yi)Wi1∑i=1m∂l∂yiyi(1−yi)Wi2⋯∑i=1m∂l∂yiyi(1−yi)Win]=[∂l∂y1y1(1−y1)∂l∂y2y2(1−y2)⋯∂l∂ymym(1−ym)][W11W12⋯W1nW21W22⋯W2n⋯⋯⋯⋯Wm1Wm2⋯Wmn]=[∂l∂y∘(y∘(1−y))]TW

最后一个貌似转置行列有些对应不上,哈哈哈!!!

猜你喜欢

转载自blog.csdn.net/hellocsz/article/details/80900143
今日推荐