基于Numpy构建CNN的批量处理与梯度下降实现疑问
《Grokking Deep Learning》第10章CNN代码疑问解答
1. 批量处理中两次除以batch_size的必要性
这里的双重除法是为了让梯度尺度匹配Softmax的数值稳定性要求,同时完成损失的归一化:
- 首先,
layer_2.shape[0]确实等于batch_size,两次除以batch_size等价于除以batch_size²。第一次除法是对批量内的样本损失做平均,得到单样本的平均梯度;第二次除法是因为代码里的损失计算没有提前做维度归一化,最终是为了把梯度的量级压到合适范围。 - 移除一次后,梯度尺度会直接放大128倍,导致Softmax层的输入值过大,触发exp函数溢出;同时爆炸的梯度会让模型参数更新完全偏离正确方向,根本无法学习特征,所以精度卡在接近随机猜测的8.7%(MNIST共10类,随机精度约10%)。
2. 梯度更新中加减号的差异与逻辑
核心看梯度的符号定义和损失函数的优化方向:
- 你之前学的公式
delta = target_output - real_output; weight += input*delta*alpha里,delta其实是损失函数对输出的负梯度(比如平方损失的导数是2*(real-output),取反后就是target-real),所以用加号是沿着负梯度方向更新,也就是往损失减小的方向走。 - 书中代码里的
k_update是损失函数对核参数的正梯度(即导数本身),所以用kernels -= alpha*k_update本质是一样的——都是沿着负梯度方向更新参数。 - 改成加号后还能达到86%的精度,是因为初期随机初始化的参数刚好让反向传播的梯度符号被抵消,但这是偶然情况,后续训练很可能出现精度波动、无法收敛到最优值的问题,正确的做法必须严格匹配梯度符号和更新方向。
内容的提问来源于stack exchange,提问作者Jason Jia
相关产品推荐
相关产品推荐

