我正在尝试使用任意激活函数实现全连接层的反向传播方法。我理解算法背后的一般思想和数学,但是对于向量化形式有困难...
我需要帮助理解元素的预期维度。
已知大小:
- 输入 - self.X 的大小为 (N,128) - 权重 - self.W 的大小为 (128,10) - 偏置 - self.b 的大小为 (128,10) - 输出 - self.y 的大小为 (N,10) - 线性输出(激活之前)- self.z 的大小为 (N,10)
未知大小:
当 N=1 时(示例数量)
- dy - 下一层的梯度 - 应该是什么大小? - dz - 激活函数的导数 - 应该是什么大小? - self.d - 当前层的梯度 - 应该是什么大小?
以下是我的代码:
我需要帮助理解元素的预期维度。
已知大小:
- 输入 - self.X 的大小为 (N,128) - 权重 - self.W 的大小为 (128,10) - 偏置 - self.b 的大小为 (128,10) - 输出 - self.y 的大小为 (N,10) - 线性输出(激活之前)- self.z 的大小为 (N,10)
未知大小:
当 N=1 时(示例数量)
- dy - 下一层的梯度 - 应该是什么大小? - dz - 激活函数的导数 - 应该是什么大小? - self.d - 当前层的梯度 - 应该是什么大小?
以下是我的代码:
def backward(self, dy):
if self.activator == 'relu':
dz = np.zeros((self.z.shape[0], self.z.shape[1]))
dz[self.z>0] = 1
elif self.activator == 'sigmoid':
dz = self.z * (1 - self.z)
elif self.activator == 'soft-max':
s = self.z.reshape(-1, 1)
dz = np.diagflat(s) - np.dot(s, s.T)
elif self.activator == 'none':
dz = 1
self.d = np.dot((dz * dy), self.W.T) # the error of the layer
self.W_grad = np.dot(self.X.T, dy) # The weight gradient of the layer
self.b_grad = np.sum(dy, axis=0).reshape(1, -1) # The bias gradient of the layer
dW = np.dot(dz, self.X.T)
吗?线性输出的导数是输入。 - Mark.Ff'(z)
(您所称之为prime
). - PeterdW
中的顺序:它完全取决于前向传递。我通常会像这样将其乘到左边:self.W * ...
。如果你将其乘到右边,你可以翻转它。 - Maxim