-
添加输入梯度初始化为0的步骤
-
改进了梯度计算的实现方式,从使用
conv_element改为直接计算 -
实现了正确的梯度累加机制
-
优化了内存管理,减少了不必要的内存分配和释放
Matrix4d backward(Matrix4d grad_output) override { // 初始化梯度为 0 for (int b = 0; b < input_cache.batch; b++) { for (int c = 0; c < input_dim; c++) { for (int h = 0; h < input_cache.wid; h++) { for (int w = 0; w < input_cache.high; w++) { input_grad.matrix4d[b].matrix3d[c].matrix[h][w] = 0.0f; } } } } // 新的梯度计算实现 for (int h = 0; h < input_cache.wid; h++) { for (int w = 0; w < input_cache.high; w++) { float sum = 0.0f; for (int kh = 0; kh < kernel_size; kh++) { for (int kw = 0; kw < kernel_size; kw++) { int h_p = h + kh; int w_p = w + kw; sum += padded_grad.matrix[h_p][w_p] * rotated_kernel.matrix[kh][kw]; } } input_grad.matrix4d[batch_idx].matrix3d[in_c].matrix[h][w] += sum; } } }
- 添加了固定的测试输入数据
- 添加了固定的卷积核权重
- 添加了预期的梯度值
- 实现了梯度值的精确比较
- 添加了
is_close函数用于浮点数比较 - 添加了
set_kernel方法用于设置卷积核权重 - 完善了尺寸验证断言
-
梯度计算精度:
- 通过直接计算替代了原有的 conv_element 调用
- 确保了正确的梯度累加
-
内存管理:
- 优化了内存分配和释放流程
- 减少了中间变量的创建
-
测试验证:
- 添加了完整的单元测试
- 实现了精确的梯度值验证
- 设置卷积核:
conv2d conv_ptr = dynamic_cast<conv2d>(conv);
conv_ptr->set_kernel(&test_kernel[in_c][out_c][0][0], in_c, out_c);- 验证梯度:
if (!is_close(actual, expected)) {
std::cout << "Gradient mismatch at position [" << c << "][" << i << "][" << j << "]" << std::endl;
}-
内存管理:
- 确保正确释放所有分配的内存
- 使用完Matrix对象后要调用free_mat
-
精度控制:
- 使用 is_close 函数比较浮点数
- 可以通过调整 rtol 和 atol 参数控制精度要求