两段Python实现神经网络小批次更新的代码是否等价?
两段代码不等价,核心逻辑存在本质差异
- 第一段是标准小批量梯度下降(MBGD)实现:
代码先初始化全零的梯度累加容器nabla_b、nabla_w,遍历小批量内所有样本,将每个样本反向传播得到的梯度逐元素累加,最终得到的是整个小批量所有样本的梯度总和,后续再除以小批量样本数得到平均梯度用于参数更新,完全符合小批量梯度下降的数学定义。
对应代码:def update_mini_batch(self, mini_batch): nabla_b = [np.zeros(b.shape) for b in self.biases] nabla_w = [np.zeros(w.shape) for w in self.weights] for x, y in mini_batch: delta_nabla_b, delta_nabla_w = self.backprop(x, y) nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)] nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)] - 第二段代码本质是单样本随机梯度下降(SGD):
代码在每次遍历样本时,会直接用当前样本的反向传播梯度覆盖nabla_b、nabla_w,循环结束后得到的仅为小批量内最后一个样本的单样本梯度,完全没有累加整批样本的梯度信息,和小批量梯度下降的逻辑完全不同。
对应代码:for x, y in mini_batch: nabla_b, nabla_w = self.backprop(x, y) - 观测到两段代码都能正常运行、效果接近的原因:
单样本SGD本身就是可行的优化算法,只要数据集是随机打乱的,每次取小批量最后一个样本也等价于随机采样单样本更新,训练过程也会出现收敛趋势,所以容易误以为逻辑等价。但如果固定所有随机种子(数据集打乱顺序、参数初始化等),两段代码的训练过程和最终结果会有明显差异。
内容的提问来源于stack exchange,提问作者Essam
相关产品推荐
相关产品推荐

