我试图关注一本关于深度学习的书,但我发现网络的仿射层有些令人困惑。假设我有一个接受一些手写数字(0 ~ 9
)图像(mnist)的网络,这些图像被压平成一维数组,例如np.array([123, 255, 0, ...])
并输出每个可能输出的分数,例如np.array([0., 0., 0.3, 0., 0., 0.6, 0., 0., 0., 0.1])
(因此图片可能是数字5
)。
这是我对仿射层的实现:
class AffineLayer(object):
...
def backward(self, dy):
dx = np.dot(dy, self._W.T)
self._dW = np.dot(self._x.T, dy) # Question related part
self._db = np.sum(dy, axis=0)
dx = dx.reshape(self._original_x_shape)
return dx
...
以下是一些解释:
self._W
是权重矩阵。self._dW = np.dot(self._x.T, y) # Question related part
。此行来自平等:
X * W + B = Y
(N,2) matrix product (2,3) (1,3) (N,3).
符号(2,)
来自X.shape
numpy.array
等。为了简化我的问题,我选择了这些尺寸编号。
术语结束,现在问题出现了:
通过一些数学(省略),我们可以得到反向传播中使用的相等性,(因此在代码中使用
self._dW = np.dot(self._x.T, y)
):
d L T d L
--- == X * ---
d W d Y
(2,3) (2,N) * (N,3).
请注意,无论我如何调整
N
,即批量的大小,dL/dW
的维度,L的权重矩阵的偏导数,都会赢得&#t改变,它总是(2,3)
。这是否意味着这些
N
批次的总效果被合并/压缩到dL/dW
?这与我如何实现输出层有关,例如: softmax-cross-entropy层作为最后一层。我目前的结论是,N
批处理意味着进行反向传播N
次,并且需要将dL/dW
除以N
来平均/摊销总数class SoftmaxCrossEntropy(object): ... def backward(self, dout=1): batch_size = self._t.shape[0] # one-hot if self._t.size == self._y.size: dx = (self._y - self._t) / batch_size # <-- why divided by N here? else: # not one-hot dx = self._y * 1 dx[np.arange(batch_size), self._t] -= 1 dx = dx / batch_size # <-- why divided by N here? return dx ...
该批次的影响。但是现在看起来我只需要做一次,并且分区应该是#34;在第一步&#34;。
我也找到了似乎在最后一步mnielsen/neural-networks-and-deep-learning - GitHub划分它的版本,供参考。
由于softmax-cross-entropy层类是网络的最后一层,因此在反向传播中它将成为第一步&#34;第一步&#34;正如我上面提到的那样:
{{1}}
答案 0 :(得分:0)
这是否意味着将这N批输入的效果合并/压缩到dW中?
由于X
的第i行是与第i个展平图像相关的1-d数组。如果我将X
转换为
T
X ,
然后是代表那些展平图像的列。如果N
增加,尽管
结果的维度(dW
)不会改变,计算每个元素的中间步骤
T d L
dW = X * ---
d Y ,
增加,这意味着
N
dW = Sum ( pixel_info * class_scores_deriv. )
i,j n=1 i,n n,j ,
N
是批次
大小。显然,每个class_scores_derivative_(n,j)
“加入”dW_(i,j)
的确定,但这意味着需要按batch_size = N
划分,因为上面的总和不是该批次的平均效果,而是我的需要dW
来表示该批次的平均影响。如果我划分class_scores_deriv.
的每个元素,即行
dx = (self._y - self._t) / batch_size
,然后
N 1
Sum ( pixel_info * --- class_scores_deriv. )
n=1 i,n N n,j
1 N
= --- Sum ( pixel_info * class_scores_deriv. )
N n=1 i,n n,j
1
= --- dW
N ,
这是我想要的真实dW
。
所以答案(我希望)应该是
整个批次确定dW,但为了压缩它,需要
SoftmaxCrossEntropy::backward(self, dout=1)
中的分区。