反向传播全卷积方法及TensorFlow中无FULL padding的实现问询
在TensorFlow中实现反向传播的全卷积(针对conv3d无FULL padding的解决方案)
核心思路
反向传播计算∂L/∂X时,需要的是180度旋转后的滤波器与损失梯度∂L/∂O的全卷积。由于TensorFlow的tf.nn.conv3d仅支持SAME和VALID padding,我们可以通过手动给输入梯度添加padding + 旋转滤波器 + VALID卷积来模拟全卷积效果。
具体实现步骤
1. 180度旋转滤波器
全卷积要求先对滤波器做180度旋转(即反转每个空间维度)。对于3D滤波器,需反转深度、高度、宽度三个维度:
# original_filter 形状为 [filter_depth, filter_height, filter_width, in_channels, out_channels] rotated_filter = tf.reverse(original_filter, axis=[0, 1, 2])
2. 给损失梯度∂L/∂O添加padding
全卷积需要在输入梯度的每个空间维度两侧填充(滤波器尺寸-1)长度的零,确保卷积时覆盖所有可能的重叠区域:
# 获取滤波器各维度尺寸 filter_d, filter_h, filter_w = original_filter.shape[0], original_filter.shape[1], original_filter.shape[2] # 定义padding规则:batch和通道维度不填充,空间维度两侧各填充(filter_size-1) padding_config = [ [0, 0], # batch维度 [filter_d - 1, filter_d - 1], # depth维度 [filter_h - 1, filter_h - 1], # height维度 [filter_w - 1, filter_w - 1], # width维度 [0, 0] # 通道维度 ] # 对∂L/∂O进行padding padded_dL_dO = tf.pad(dL_dO, padding_config, mode='CONSTANT')
3. 执行VALID卷积得到∂L/∂X
用旋转后的滤波器对padding后的梯度执行VALID卷积,结果就是全卷积的输出(即∂L/∂X):
dL_dX = tf.nn.conv3d( input=padded_dL_dO, filters=rotated_filter, strides=[1, 1, 1, 1, 1], # 步长与正向卷积一致 padding='VALID' )
尺寸验证
假设:
- 正向输入X的形状:
[batch_size, X_d, X_h, X_w, in_channels] - 正向输出O的形状(VALID padding):
[batch_size, O_d, O_h, O_w, out_channels],其中O_d = X_d - filter_d + 1
经过上述步骤后,∂L/∂X的形状为:[batch_size, O_d + 2*(filter_d-1) - filter_d + 1, ...] = [batch_size, X_d, X_h, X_w, in_channels],与输入X的形状完全匹配,符合反向传播的梯度要求。
内容的提问来源于stack exchange,提问作者abdoah
相关产品推荐
相关产品推荐

