CNN输出层偏置更新时损失值上升问题排查及修正
CNN输出层反向传播偏置导数问题排查与优化
问题背景
我正在用Python实现卷积神经网络(CNN)的反向传播,当前仅针对输出层开发,编写了计算偏置(biases)导数的代码。使用交叉熵计算损失,在无隐藏层的情况下测试简单螺旋数据集(含x、y输入,3个类别),但每次将批次传入模型进行传播后,损失值都会上升。
初始实现代码
反向传播函数(偏置导数计算)
def back_prop(self, learning_rate, d_values = None, desired_outputs = None): self.d_biases = np.zeros((desired_outputs.size, self.biases.size)) self.d_weights = np.zeros((desired_outputs.size, *self.weights.shape)) # 判断是否为输出层以选择导数计算方式 if self.is_output_layer: # 计算输出层所有偏置对损失的导数 self.d_biases = np.array([[float(softmax(self.output)[i][x] - 1) if desired_outputs[i] == x else float(softmax(self.output)[i][x]) for x in range(self.biases.size)] for i in range(desired_outputs.size)]) self.d_biases *= learning_rate self.d_biases = np.sum(self.d_biases, axis = 0, keepdims = True) # 更新参数 self.biases += self.d_biases
说明:desired_outputs是训练批次的类别索引数组,self.output是按批次×类别组织的二维数组。
交叉熵损失计算函数
def check_loss(self, target_indices): target_percents = self.output[range(len(self.output)),target_indices] target_percents = np.clip(target_percents, 1e-7, 1-1e-7) self.losses = -np.log(target_percents) return np.mean(self.losses)
说明:target_indices与desired_outputs为同一变量,check_loss()与back_prop()分属不同类,但两者的self.output值一致。
疑问
我认为输出层中偏置的导数应为该神经元的softmax激活值减去对应预测值,但排查后未发现逻辑问题,想知道损失上升的原因。
修复后的代码
我修改了偏置更新方式(改为减法),并调整了梯度计算逻辑,现在损失值已正常下降。修改后的代码如下:
def back_prop(self, learning_rate, d_values = None, desired_outputs = None): # 判断是否为输出层以选择导数计算方式 if self.is_output_layer: # 计算输出层所有偏置对损失的导数 self.d_biases = softmax(self.output) self.d_biases[range(desired_outputs.size), desired_outputs] -= 1 self.d_biases *= learning_rate self.d_biases = np.sum(self.d_biases, axis = 0, keepdims = True) # 后续将补充权重导数计算 # 更新参数 self.biases -= self.d_biases return self.biases
优化建议征集
目前代码已正常运行,欢迎提供进一步的优化建议。
内容的提问来源于stack exchange,提问作者James Ward
相关产品推荐
相关产品推荐

