反向传播,课程看完了就是链式法则求导,没做笔记,做作业的时候记一下。
核心还是看最后的数学补充。
全连接网络的反向传播
out=xW+b
已知 dout=∂out∂L ,反向传播要求 dx, dW, db ,shape应该分别和 x W b 相同。
dx=∂x∂L=∂out∂L∂x∂out=dout⋅WT
下面的说法可能不够正确、不够简洁,仅供参考
矩阵求导的结果就是对应的雅可比矩阵。经常很难想清楚到底是左乘、右乘,要不要求转置等等。
一个比较好的方法是把所有变量的 shape 写出来。
x=dx: (n, m)
W=dW: (m, d)
out=dout=xW: (n, d)
b=db: (1, d)
根据链式法则,dx 一定是 dout 和 W 的乘积。看shape就直接写出来:
(n, m) = (n, d) · (d, m) => dx=dout⋅WT
同理可以写出:
(m, d) = (m, n) · (n, d) => dW=xT⋅dout
对于 db,在参与计算的时候自动进行了广播,变成了 (n, d) ,可以有:
(n, d) = (n, d) => db′=dout
最后计算 db 的时候要把每行的 n 个元素加起来:
db = np.sum(dout, axis=0, keepdims=True)
ReLU的反向传播
公式:
ReLU(x)=max(0,x)={x0if x>0if x≤0
分段函数分段求导:
dxdReLU(x)={10if x>0if x≤0
数学补充
1 雅可比矩阵(Jacobian)
雅可比矩阵是一个函数的一节偏导数矩阵。
设:
y=f(x)∈Rm,x∈Rn
这里的 x 和 y 都是向量,即(1, n) 或 (n,1)的形状
那么 雅可比矩阵 是:
J=∂x∂y=∂x1∂y1⋮∂x1∂ym⋯⋱⋯∂xn∂y1⋮∂xn∂ym∈Rm×n
每行是一个输出变量 yi 对所有输入变量 xj 的偏导,表示的是 ∇yi。
其实很好理解,y1=w1x1+w2x2+⋯+xn ,矩阵的第一行就是 y1 相对于 x1, x2, …, xn 的倒数。
以一个具体例子为例:
z=xW+b
∂x∂z 就是 z 对 x 的雅可比矩阵。
我们先设定具体形状:
-
x∈R1×D:输入是一个样本的特征行向量
-
W∈RD×M:权重矩阵(D 输入维度,M 输出维度)
-
b∈R1×M:偏置(广播加法)
-
那么:
z=xW+b∈R1×M
写成分量形式:
zj=i=1∑DxiWi,j+bj,j=1,…,M
所以:
∂xi∂zj=Wi,j
直观的看,W的展开为:
W=W1,1W2,1⋮WD,1W1,2W2,2⋮WD,2⋯⋯⋱⋯W1,MW2,M⋮WD,M∈RD×M
而雅可比矩阵是:
∂x∂z=∂x1∂z1∂x1∂z2⋮∂x1∂zM∂x2∂z1∂x2∂z2⋮∂x2∂zM⋯⋯⋱⋯∂xD∂z1∂xD∂z2⋮∂xD∂zM=W1,1W1,2⋮W1,MW2,1W2,2⋮W2,M⋯⋯⋱⋯WD,1WD,2⋮WD,M=WT∈RM×D
2 np中axis、keepdims的简单理解
一个矩阵shape = (n, m)
keepdims = True 时,对他的axis=0进行计算,就是把 shape[0] 变成 1,(1, m);对axis=1进行计算,就是把 shape[1] 变成 1,(n, 1)
keepdims = False时,直接变成一维向量,结果分别为(m,) 和 (n,)
对 a.shape=(2, 3):
| 操作 | 含义 | 输出形状 |
|---|
| np.sum(a, axis=0) | 每列相加 | (3,) |
| np.sum(a, axis=1) | 每行相加 | (2,) |
| np.sum(a, axis=0, keepdims=True) | 每列相加并保留“行”维度 | (1, 3) |
| np.sum(a, axis=1, keepdims=True) | 每行相加并保留“列”维度 | (2, 1) |