python - 实现一般的反向传播
问题描述
我正在尝试为具有任意激活函数的全连接层实现反向传播方法。我理解算法背后的一般思想和数学,但我在理解矢量化形式时遇到了困难......
我需要帮助了解元素的预期尺寸
已知尺寸:
- 输入 - 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
解决方案
我相信,您的代码中存在轻微的混淆:您编写的是激活前self.z
的线性输出,但出于某种原因,使用它来计算您调用的激活导数。它应该使用激活值。然后,假设您计算了该值(我称它为不与我的其他混合),试试这个:dz
prime
dz
dz = dy * prime
dW = np.dot(dz, self.z.T)
db = np.sum(dz, axis=1, keepdims=True)
d = np.dot(self.W.T, dz)
推荐阅读
- c - 如果 bar() 和 foo() 互斥,如何在 foo() 中运行 bar()
- powershell - SYSTEM用户和登录用户之间的Powershell交互
- docker - 在 Docker Swarm 模式下拥有更多副本有什么影响?
- sql - 空白值的总和
- javascript - napchart.com 是如何构建的
- sql - 使用触发器删除后如何从另一个表中插入数据
- php - Laravel ID 主自动增量替代
- java - 我应该在 JOOQ 上禁用 UInteger 类型吗?
- symfony - 自定义 FOSUserBundle 的注册表单时未将新字段添加到数据库
- javascript - Javascript:如何从 Promise for 循环中返回一个值?