Skip to content

深度学习中的矩阵求导基础


本文根据合集·深度学习中的数学by齐宪标系列视频整理。

在本文中,用小写字母表示标量,用粗体小写字母表示向量,用粗体大写字母表示矩阵。

导数的定义

在高等数学和数学分析的课程中,我们知道一元函数 y=f(x) 的导数定义为

dydx=limh0f(x+h)f(x)h

而对于多元函数,则会引入方向导数和梯度的概念。

梯度与方向导数

给定一个多元函数

y=f(x)=f(x1,x2,,xn)(xRn)

其梯度为 f(x) 定义为

f(x)=[yx1yx2yxn]

简单来说,梯度即为以单位正交向量为基底,yx 各分量的导数的线性组合。对于多元函数而言,其梯度是一个和 x 同样维度的向量。

而方向导数是指函数在某一点处,在某一给定方向上的变化率,是一个标量。它定义为

Dvf(x)=f(x)v

Jacobian 矩阵

对于一簇多元函数(也称为向量函数,即定义域和值域都是向量的集合的函数)

y=f(x)=[f1(x)f2(x)fm(x)](xRn,yRm)

其各个函数的梯度组合成一个矩阵,称为 Jacobian 矩阵,记为 J(x)。它定义为

J(x)=[y1x1y1x2y1xny2x1y2x2y2xnymx1ymx2ymxn]=[f1(x)f2(x)fm(x)]

是一个 m×n 的矩阵,其中 m 是输出的维度,n 是输入的维度。

WARNING

注意

Jacobian 矩阵的维度是 m×n,而不是 n×m。这意味着,Jacobian 矩阵不能用来直接表示向量函数的导数和梯度——Jacobian 矩阵的转置才能表示向量函数的导数和梯度。

实际上,向量函数的求导运算是一种从函数到函数的映射。用形式化的语言表达就是

:RnRmRnRn×m

Hessian 矩阵

给定一个多元函数

y=f(x)=f(x1,x2,,xn)(xRn)

其 Hessian 矩阵定义为

H(x)=2f(x)=x(yx)=[2yx122yx1x22yx1xn2yx2x12yx222yx2xn2yxnx12yxnx22yxn2]

导数的链式求导法则

对于复合函数

f(x)=fnfn1f2f1(x)=fn(fn1(f2(f1(x))))

其链式求导法则为

df(x)dx=df(x)dfn(x)dfn(x)dfn1(x)df2(x)df1(x)df1(x)dx

不过,如果自变量是一个向量或者矩阵,那么由于矩阵乘法不满足交换律,于是就存在分母表达式和分子表达式两种形式。

分母表达式和分子表达式

这里的分子和分母指的是原微商式中的分子和分母,即 df(x)dx。顾名思义,分母/分子表达式的含义就是先求含分母/分子的那一项,即

df(x)dx=df(x)dfn(x)dfn(x)dfn1(x)df2(x)df1(x)=df1(x)dxdf2(x)df1(x)dfn(x)dfn1(x)

其中,(1) 式是分子表达式,(2) 是分母表达式。由此可见,分子表达式是先求外层函数,然后逐层深入求导;分母表达式是先求内层函数,然后逐层向外求导。

在深度学习中,为了方便,一般采用分母表达式来表示导数。稍后我们就会看到这种表达方式的方便之处。

多项式向量函数的导数

多项式向量函数是指,每个因变量 y1,y2,,ym 都是关于自变量 x1,x2,,xn 和常数的线性函数的函数。本小节主要讨论一次多项式和二次多项式向量函数的导数计算,只需要理解齐次式的导数计算即可。

一次齐次式

y=Wx(xRn,yRm)yx=[y1x1y2x1ymx1y1x2y2x2ymx2y1xny2xnymxn]=W

注意到,f:RnRm 是一个将向量从 n 维映射到 m 维的向量函数。所以,这里的 WRm×n,恰好是其 Jacobian 矩阵的转置。

INFO

常用线性函数求导公式

Wxx=WWxW=x

二次齐次式(二次型)

y=xWx(xRn,yR)=[x1x2xn][w11w12w1nw21w22w2nwn1wn2wnn][x1x2xn]=i=1nj=1nwijxixjyx=[x1i=1nj=1nwijxixjx2i=1nj=1nwijxixjxni=1nj=1nwijxixj]=[x1[w11x12+(w12x1x2++w1nx1xn)+(w21x2x1++wn1xnx1)]x2[w22x22+(w21x2x1++w2nx2xn)+(w12x1x2++wn2xnx2)]xn[wnnxn2+(wn1xnx1++wn(n1)xnxn1)+(w1nx1xn++w(n1)nxn1xn)]]=[2w11x1+(w12x2++w1nxn)+(w21x2++wn1xn)2w22x2+(w21x1++w2nxn)+(w12x1++wn2xn)2wnnxn+(wn1x1++wn(n1)xn1)+(w1nx1++w(n1)nxn1)]=[i=1nwi1xii=1nwi2xii=1nwinxi]+[j=1nw1jxjj=1nw2jxjj=1nwnjxj]=[w11w21wn1w12w22wn2w1nw2nwnn][x1x2xn]+[w11w12w1nw21w22w2nwn1wn2wnn][x1x2xn]=(W+W)x

常见神经网络层的导数计算

全连接层

一层全连接层的函数表达式为

y=Wx+b(xRn,yRm)

它是一个典型的一次多项式向量函数,其导数为

dydx=W

一般地,全连接层的参数矩阵 W 是可学习的参数,需要通过梯度下降法来更新,就不可避免地需要对其求导数。显然

dydW=x

激活函数

以 ReLU 为例,其函数表达式为

ReLU(x)=max(0,x)

其导函数为

ddxReLU(x)={1x>00x0

对于一簇多元函数 y=ReLU(x),其 Jacobian 矩阵为

J(x)=diag(x>0)

它是一个对角线上的元素可能为 0 或 1,而其他元素均为 0 的矩阵。

INFO

对角矩阵

diag([x1x2xn])=[x1000x2000xn]

卷积层

待补充。

自注意力层

待补充。

归一化层

不论是 BatchNorm 还是 LayerNorm,其函数形式都相同,都是将任何特征分布转化为均值为 0,方差为 1 的特征分布。

y=xμσ2+εγ+β(xRn,yRn)

其中,γ,βRn 是可学习的参数,都是

分子是用线性代数表示为

(1)xμ=[100010001][x1x2xn][1ni=1nxi1ni=1nxi1ni=1nxi]=[100010001][x1x2xn]1n[111111111][x1x2xn]=Ix1n11x=(I1n11)x

其中,I 是单位矩阵,1 是元素全为 1 的列向量。

分母的被开方数用线性代数表示为

(2)σ2+ε=xμ22+ε=(xμ)(xμ)+ε=x(I1n11)(I1n11)x+ε=x(I1n11)(I1n11)x+ε=x(I2n11+1n21111)x+ε=x(I2n11+1n11)x+ε=x(I1n11)x+ε

其结果其实是一个标量。

(1),(2) 两式的结果可知,原函数解析式可化为

y=I1n11×xxx+εγ+β

因此,其 Jacobian 矩阵为

J(x)=I1n11×[Ixx+ε(xx+εxxx+ε)]×diag(γ)=I1n11×(xx+ε)1x(xx+ε)32×diag(γ)

深度神经网络的导数计算

我们以 Feed Forward 网络为例,其网络结构为

用解析式表示就是

{ g=Winx+bin h=ReLU(g) y=Wouth+bout

反向传播算法是从后向前计算导数的。我们可以很容易算出 y 对参数矩阵 Wout 的导数为

dydWout=h

在 DNN 训练过程中,中间状态是需要存储在显存中的。可以认为,这里的 x,h,g,y 都是已知的。参数矩阵从后向前通过梯度下降算法进行更新,即先更新 Wout,bout,再更新 Win,bin

现在计算 y 对参数矩阵 Win 的导数。由求导链式法则的分母表达式,有

dydWin=dgdWin×dhdg×dydh=x×diag(g>0)×Wout

对偏置 bin,bout 的求导是类似的,本文不再赘述。

小结

深度学习中的矩阵求导,主要是利用导数的链式法则,让输出对深度神经网络中的参数矩阵进行求导。在求导过程中,主要涉及两种情况:一是直接对参数矩阵求导,二是对输入中间状态进行求导。采用分母表达式进行求导,可以按照神经网络的顺序进行,较为方便和直观。

最近更新