摘要
Affine 仿射层, 又称 Linear 线性变换层, 常用于神经网络结构中的全连接层. 本文给出了 Affine 层的两种定义及相关的反向传播梯度.
相关
配套代码, 请参考文章 :
Python和PyTorch对比实现affine/linear(仿射/线性)变换函数及全连接层的反向传播
系列文章索引 : https://blog.csdn.net/oBrightLamp/article/details/85067981
正文
1. Affine 的一种定义
考虑一个输入向量 x, Affine 层的权重为 k 维向量 w, 偏置为标量 b, 则 :
使用 X 表示 m 行 k 列的矩阵, 偏置为标量 b, 则一次仿射变换为 :
更一般的, 若使用 W 表示 n 行 k 列的矩阵, 偏置为向量 b , 则 n 次仿射变换为 :
使用求和符号表示 A 矩阵中的元素 :
取其中一项展开作为示例 :
2. 梯度的定义
三维XYZ空间中的梯度定义:
式中, $i, j, k$是三个两两相互垂直的单位向量, 或 $i, j, k$ 是正交单位向量组, 或 $i, j, k$ 是一组线性无关的单位向量, 这三种说法是等价的.
推广到 $t$ 维向量空间 $V$, 若 $t$ 个向量 $I_1, I_2, I_3,\cdots, I_t$ 是一组两两正交的单位向量, 或单位向量组 $I_1, I_2, I_3,\cdots, I_t$ 线性无关, 那么, 该向量空间 $V$ 中的梯度可定义为 :
梯度的定义可以在 <高等数学> 中找到, 正交和线性无关的定义可以在 <线性代数> 中找到.线性代数>高等数学>
3. 反向传播中的梯度求导
若 X 矩阵经过 affine 层变换得到 A 矩阵, 往前 forward 传播得到误差值 error (标量 e ), 求 e 关于 X 的梯度:
3.1 损失值 e 对 A 矩阵的梯度
首先, 我们说求梯度, 究竟是在求什么? 答 : 一个让损失值 e 变小的最快的方向.
比如, e 对 A 的梯度矩阵 :
为了书写方便, 记 :
所有的 $a_{ij}’$ 都是已知的, 是上游的 forward 函数帮我们算好的. 只要矩阵 A 中所有的元素按照这个矩阵等比例的更新, 那么就是使 e 值减少最快的方向. 梯度本身的定义并不是一个矩阵, 而是一个向量 :
这个写法和上面的矩阵写法是等价的. 利用矩阵求导的写法求梯度, 求的是方向导数, 或者单位向量的系数, 和普通的矩阵求导有区别.
3.2 A 矩阵的元素关于 X 的梯度
根据矩阵乘法行乘列的定义, 矩阵 $X$ 和 $W^T$ 中的第 $j$ 列向量相乘, 将降维得到一个新的列向量, 作为矩阵 A 中的第 $j$ 列向量, 即 :
上面的 $:,j$ 符号表示取矩阵中 $j$ 列的所有行, 结果是一个列向量. 参考的是 numpy 的记法. 矩阵 A 中任意元素的梯度 :
为了书写方便, 记 :
3.3 关于 X 的反向传播
按照矩阵元素的定义 :
根据 <高等数学> 中介绍的复合函数求导法则, 知 : $$ \frac {\partial e}{\partial x_{pq}} =\sum_{i = 1}^{i=m}\sum_{j =1}^{j =n} \frac {\partial e}{\partial a_{ij}}\frac {\partial a_{ij}}{\partial x_{pq}} =\sum_{i = 1}^{i=m}\sum_{j =1}^{j =n} a_{ij}' x_{ij|pq}'\\ $$高等数学>
删除零项 :
这个结果恰好满足矩阵乘法的定义, 分解成矩阵 :
所以, 损失值 e 对 X 的梯度矩阵为 :
矩阵 $\nabla e_{(A)}$ 已在前面求得.
3.4 关于 W 的反向传播
参考上例求解 :
这个结果恰好满足矩阵乘法的定义, 分解成矩阵 :
所以, 损失值 e 对 W 的梯度矩阵为 :
矩阵 $\nabla e_{(A)}$ 已在前面求得.
3.5 关于 e 对 b 的梯度
参考上例求解 :
所以, 损失值 e 对 b 的梯度矩阵为 :
矩阵 $\nabla e_{(A)}$ 已在前面求得. 式中的 $axis=0$ 表示对矩阵的第一维求和, 参考的是 numpy 的记法.
4. Affine 的另一种定义
上文中, W 矩阵经过转置 $W^T$ 后再参与 Affine 运算.
在目前流行的教材中, 将 W 直接进行 Affine 运算的定义也很多.
4.1 关于 X 的反向传播
4.2 关于 W 的反向传播
4.3 关于 e 对 b 的梯度
同上: 全文完.