梯度矩阵dW的vectorize实现
这个向量化实现想了很久,一直看不懂代码,别人的博客也没解释具体为什么会是那样实现的,尤其是为什么最后是X去乘上一个矩阵得到梯度矩阵,看得我一脸懵逼,最后我自己画了个2*3的矩阵才终于知道为什么要这么实现了。下面是我的思路,总体思路是先按前面写非向量化时已经学习过的知识推出结果,即dW矩阵的具体解析式,然后再去凑怎么能实现这个矩阵。
有几点要注意:
- WiW_iWi是W矩阵的一列,W是3073*10的矩阵,每一列对应每一类的权重
- XiX_iXi是X矩阵的一行,不是一个数,与WiW_iWi一样是一个向量
- WyiW_{y_i}Wyi是当前样本正确分类对应的权重向量,也就是说随着样本不同i会变化,比如Wy2W_{y_2}Wy2为序号为2的样本的正确分类对应的权重
首先我们假设:
X.shape = (2,2)
W.shape = (2,3)
即X={x11x12x21x22}X=
\left\{
\begin{matrix}
x_{11}& x_{12} \\
x_{21} & x_{22} \\
\end{matrix}
\right\}
X={x11x21x12x22}
W={w11w12w13w21w22w23}W=
\left\{
\begin{matrix}
w_{11} & w_{12} & w_{13} \\
w_{21} & w_{22} & w_{23} \\
\end{matrix}
\right\}
W={w11w21w12w22w13w23}
margins = X.dot(W)+1,yi=j时不算,且先置0y_i=j时不算,且先置0yi=j时不算,且先置0
{X1W1−X1W2+10X1W3−X1W2+1X2W1−X2W3+1X2W2−X2W3+10}
\left\{
\begin{matrix}
X_1W_1-X_1W_2+1 & 0 & X_1W_3-X_1W2+1 \\
X_2W_1-X_2W_3+1& X_2W_2-X_2W_3+1 & 0 \\
\end{matrix}
\right\}
{X1W1−X1W2+1X2W1−X2W3+10X2W2−X2W3+1X1W3−X1W2+10}
LiL_iLi实际就是margins的一行大于0的单位相加的结果,我们这里假设全>0
而我们要求的梯度矩阵,则根据梯度的公式,对于margins的每一行,对于每一个元素,若XiWj−XiWyi+1>0X_iW_j-X_iW_{y_i}+1>0XiWj−XiWyi+1>0则对应的dWjdW_jdWj列加上XiX_iXi,注意,XiX_iXi为一个向量,即X的第i行
计算后得
dW={x11+x21−2x11+x21x11−2x21x12+x22−2x12+x22x12−2x22}dW=
\left\{
\begin{matrix}
x_{11}+x_{21} & -2x_{11}+x_{21} & x_{11}-2x_{21} \\
x_{12}+x_{22}& -2x_{12}+x_{22} & x_{12}-2x_{22}\\
\end{matrix}
\right\}dW={x11+x21x12+x22−2x11+x21−2x12+x22x11−2x21x12−2x22}
可以看出来dW应该是X与某个矩阵相乘后得到的矩阵,试了一下X好像不行,得用X.T
易得
dW=X.T.dot((1−2111−2))dW=X.T.dot(\left(
\begin{matrix}
1 & -2 & 1 \\
1& 1 & -2\\
\end{matrix}
\right))dW=X.T.dot((11−211−2))
我们可以发现每一行相加都得0,负数的绝对值为正数之和,且系数矩阵每行为1的位置正好对应XiWj−XiWyi+1>0X_iW_j-X_iW_{y_i}+1>0XiWj−XiWyi+1>0的位置,即margins>0的位置,负数位置正好对应yiy_iyi的位置,所以可以利用前面得到的margins矩阵直接构造出系数矩阵:
#coeffmat: coeff全名coefficient,即系数
#先把margins每行>0的数置为1,其余为0
coeffmat = np.zeros((num_train,num_class))#初始化一个和W同样shape的系数矩阵
coeffmat[margins>0]=1
#把margins每行为0的部分置为-sum(本行)
y_i = -np.sum(coeffmat,axis=1)
coeffmat[range(num_train),list(y)] = y_i
dW = X.T.dot(coeffmat)/num_train+reg*W #最后算上正则的求导与1/n的求导即可