向量与矩阵微分

最基本的微分是建立在一元函数上的。对于函数 𝑓(𝑥):,我们有导数的定义:

𝑓(𝑥+)=𝑓(𝑥)+𝑓(𝑥)+𝑜()

对于一元函数,我们可以将 𝑓 看作是一个标量,但这种处理绝非平凡的。处理多元函数时,更恰当的理解方式应当是将微分视作一个描述函数误差项的线性映射。例如,对于 𝑓(𝑥):𝑛,我们有

𝑓(𝑥+)=𝑓(𝑥)+𝐷𝑥𝑓()+𝑜()

这里面的 𝐷𝑥𝑓:𝑛 是一个线性映射,称为 𝑓𝑥 处的微分。根据 Riesz 表示定理,任何从 𝑛 的线性映射都可以表示为内积的形式,因此在标准的内积定义下,我们可以找到一个向量 𝛁𝑥𝑓𝑛,使得对于任意 𝑛,都有

𝐷𝑥𝑓()=𝛁𝑥𝑓,=(𝛁𝑥𝑓)𝑇

这里面的 𝛁𝑥𝑓 定义为该多元函数的梯度。在这种定义下,梯度的每个分量都对应着函数对该分量的偏导数。 这也被称为一阶微分的形式不变性

d𝑓=𝑖𝜕𝑓𝜕𝑥𝑖d𝑥𝑖

这种思路可以推广到向量值函数 𝑓(𝑥):𝑛𝑚。在这种情况下,微分 𝐷𝑥𝑓:𝑛𝑚 仍然是一个线性映射,因此可以表示为一个矩阵的形式。我们定义雅可比矩阵 𝐽𝑥𝑓{𝑚×𝑛},使得对于任意 𝑛,都有

𝜕𝒇𝜕𝒙=𝜕(𝑓1,𝑓2,,𝑓𝑚)𝜕(𝑥1,𝑥2,,𝑥𝑛)=𝐷𝑥𝑓()=𝐽𝑥𝑓

那么根据以上的推导我们可以得出 Jacobian 矩阵的组成为

𝐽𝑥𝑓=(𝛁𝑥𝑓1𝑇𝛁𝑥𝑓2𝑇𝛁𝑥𝑓𝑚𝑇)

这里面的 𝑓𝑖𝑓 的第 𝑖 个分量函数。以上这些应当都是多元微积分中应当熟悉的部分,并不构成理解上的难度。但是神经网络的处理中往往需要遇到矩阵函数,即输入/输出或者二者均为矩阵的函数。对于矩阵函数,机器学习领域中的一个惯例时对矩阵微分采用所谓分母布局(denominator layout),也就是分母决定列向量形式,分子决定行向量形式。11 比如先前提到的梯度则为分母布局、其转置(Jacobian)可以视作分子布局例如,对于矩阵函数 𝑓(𝑋):𝑝×𝑞,可以定义其梯度 𝛁𝑋𝑓𝑝×𝑞 满足

(𝛁𝑋𝑓)ij=𝜕𝑓𝜕𝑋ij

,使得对于任意矩阵 𝐻𝑝×𝑞,都有

𝐷𝑋𝑓(𝐻)=𝛁𝑋𝑓,𝐻𝐹=trace((𝛁𝑋𝑓)𝑇𝐻)

这里面的 .,.𝐹 是 Frobenius 内积,定义为矩阵对应元素乘积之和。而更广义地,对于矩阵函数 𝑓(𝑋):𝑝×𝑞𝑚,可以定义其微分满足

𝑓(𝑋+𝐻)=𝑓(𝑋)+𝐽(𝑋)𝐻+𝑜(𝐻𝐹)

根据先前定义,对应的 Jacobian 矩阵 𝐽(𝑋)𝑚×𝑝×𝑞 应当是一个三维张量22 这里切换回了分子布局,主要是张量采用什么布局其实无所谓,其关于矩阵 𝑋 的线性映射定义为

𝐽(𝑋)ijk=𝜕𝑓𝑖𝜕𝑋jk𝛿𝑖=(𝐽𝐻)𝑖=𝑗=1𝑝𝑘=1𝑞𝐽ijk𝐻jk

常见矩阵函数的微分

在理解了矩阵微分的定义后,我们可以推导一些常见矩阵函数的微分形式,这些形式在神经网络的反向传播中会频繁使用。以下微分如果没有特殊说明,我们考虑的都是标准的数学定义上的微分,也就是 Jacobi 矩阵(分子布局)。

𝒛=𝑊𝒙

我们想求得 𝜕𝒛𝜕𝒙。这是一个 𝑛𝑚 的函数,则其 Jacobian 矩阵形状为 𝑚×𝑛。根据定义,我们有

𝜕𝒛𝜕𝒙ij=𝜕𝑧𝑖𝜕𝑥𝑗=𝜕𝑘=1𝑛𝑊ik𝑥𝑘𝜕𝑥𝑗=𝑊ij

因此

𝜕𝒛𝜕𝒙=𝑊

𝒛=𝒙𝑊

这里 𝒛,𝒙 都是行向量。我们想求得 𝜕𝒛𝜕𝒙。这是一个 𝑛𝑚 的函数,则其 Jacobian 矩阵形状为 𝑚×𝑛。类似的推导我们可以得到这里也可以注意到 𝑧𝑇=𝑊𝑇𝑥𝑇 进而转化为前一种情况

𝜕𝒛𝜕𝒙=𝑊𝑇

这里 𝑓: 是一个标量函数,逐元素作用在向量 𝒙 上。我们想求得 𝜕𝒛𝜕𝒙。这是一个 𝑛𝑛 的函数,则其 Jacobian 矩阵形状为 𝑛×𝑛。根据定义,我们有

𝜕𝒛𝜕𝒙ij=𝜕𝑧𝑖𝜕𝑥𝑗=𝜕𝑓(𝑥𝑖)𝜕𝑥𝑗={𝑓(𝑥𝑖)if 𝑖=𝑗0if 𝑖𝑗

因此有

𝜕𝒛𝜕𝒙=(𝑓(𝑥1)𝑓(𝑥2)𝑓(𝑥𝑛))=diag(𝑓(𝒙))

𝒛=𝑊𝒙,𝐽=𝐽(𝑧)

这里 𝐽:𝑚 是一个标量函数,我们想求得 𝜕𝐽𝜕𝑊 的分母布局形式利用分母布局可以直接得到梯度形式,在进行梯度下降时更加方便。由链式法则有

𝜕𝐽𝜕𝑊=𝜕𝐽𝜕𝒛𝜕𝒛𝜕𝑊

这里 𝐽=𝐽(𝒛)𝑊 无关,我们可以先求得 𝜕𝐽𝜕𝒛,这是一个 𝑚 的函数,因此根据定义令其梯度为 𝜹=𝛁𝑧𝐽𝑚 这里用梯度是因为我们约定了分母布局。我们随即分别考虑 𝜕𝒛𝜕𝑊ij,每个分量是一个 𝑚 的函数,因此其微分应当是一个简单的向量。根据定义我们有

𝒛𝑘=𝑙=1𝑚𝑊kl𝒙𝑙(𝜕𝒛𝜕𝑊ij)𝑘=𝜕𝒛𝑘𝜕𝑊ij=𝜕𝑙=1𝑚𝑊kl𝒙𝑙𝜕𝑊ij={𝒙𝑗if 𝑘=𝑖0if 𝑘𝑖

也就是

𝜕𝒛𝜕𝑊𝑖𝑗=[00𝑥𝑗00] 𝑖th element

因此根据链式法则我们有

𝜕𝐽𝜕𝑊ij=𝜹𝑇𝜕𝒛𝜕𝑊𝑖𝑗=𝜹𝑖𝒙𝑗

因此我们可以得到最终的结果

𝜕𝐽𝜕𝑊=𝜹𝒙𝑇

交叉熵损失 𝐽=CE(𝒚,𝒚̂),𝒚̂=softmax(𝜽)

这里 𝒚 是真实标签, 𝒚̂ 是预测标签,𝜽 是模型的线性输出。我们想求得 𝜕𝐽𝜕𝜽。根据链式法则有

𝜕𝐽𝜕𝜽=𝜕𝐽𝜕𝒚̂𝜕𝒚̂𝜕𝜽
𝐽=𝑖=1𝑚𝒚𝑖log𝒚̂𝑖(𝜕𝐽𝜕𝒚̂)𝑖=𝜕𝐽𝜕𝒚̂𝑖=𝒚𝑖𝒚̂𝑖
𝒚̂𝑖=exp(𝜽𝑖)𝑗=1𝑚exp(𝜽𝑗)(𝜕𝒚̂𝜕𝜽)ij=𝜕𝒚̂𝑖𝜕𝜽𝑗={𝒚̂𝑖(1𝒚̂𝑖)if 𝑖=𝑗𝒚̂𝑖𝒚̂𝑗if 𝑖𝑗
(𝜕𝐽𝜕𝜽)𝑖=𝑗=1𝑚𝜕𝐽𝜕𝒚̂𝑗𝜕𝒚̂𝑗𝜕𝜽𝑖=𝑗=1𝑚(𝒚𝑗𝒚̂𝑗)𝜕𝒚̂𝑗𝜕𝜽𝑖=𝒚𝑖(1𝒚̂𝑖)+𝑗𝑖𝒚𝑗𝒚̂𝑖=𝒚𝑖+𝒚̂𝑖𝑗=1𝑚𝒚𝑗=𝒚̂𝑖𝒚𝑖

因此我们最终得到

𝜕𝐽𝜕𝜽=𝒚̂𝒚or𝛁𝜽𝐽=(𝒚̂𝒚)𝑇