在学习《深度学习入门:基于 Python 的理论与实现》153页的代码时,我对SoftmaxWithLoss层的反向传播实现产生了疑问,
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18class SoftmaxWithLoss: def __init__(self): self.loss = None # 损失 self.y = None # softmax的输出 self.t = None # 监督数据(one-hot vector) def forward(self, x, t): self.t = t self.y = softmax(x) self.loss = cross_entropy_error(self.y, self.t) return self.loss #反向传播代码实现 def backward(self, dout=1): batch_size = self.t.shape[0] dx = (self.y - self.t) / batch_size # 为什么要除以批数量 return dx
回顾书上给的计算图,图1中,反向输出的结果是没有除以batch_size的。为什么该层的反向传递值要除以批数量呢?
分割线--------------------------------------------------------------------------------------------------
思考后我突然意识到,图1中的计算图是batch_size=1的情况,而在代码1中,batch_size不等于1,在实现cross_entropy_error层时,一定对输出结果Loss进行了处理 (Loss/batch_size),因此 图1是不完整的,导致反向输出结果是不完整的。
交叉熵计算过程源码如下
复制代码
1
2
3
4
5
6
7
8
9
10
11
12def cross_entropy_error(y, t): if y.ndim == 1: t = t.reshape(1, t.size) y = y.reshape(1, y.size) # 监督数据是one-hot-vector的情况下,转换为正确解标签的索引 if t.size == y.size: t = t.argmax(axis=1) batch_size = y.shape[0] return -np.sum(np.log(y[np.arange(batch_size), t] + 1e-7)) / batch_size # 根据批数量求得平均值
分割线--------------------------------------------------------------------------------------------------
因此,完整的计算图见图2。 图2中反向输出结果符合代码1的backward函数。(注:新增计算图部分理论上属于交叉熵误差层,为方便补充单列出来)
问题解决。
最后
以上就是外向奇异果最近收集整理的关于Softmax-with-Loss层反向传播的值除以批的大小的全部内容,更多相关Softmax-with-Loss层反向传播内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复