tf.nn.conv2d卷积(3,3,64,64)输入输出(3,2,32,64)形状原因
问题成因
这个异常输出和SAME填充设置无关,是数据格式理解错误+步长参数匹配错误+输入张量维度构造错误三个问题共同导致的,步长设置确实是诱因之一,但核心是对接口维度顺序的认知偏差。
具体错误拆解
1. 未遵循tf.nn.conv2d默认的维度顺序规则
tf.nn.conv2d默认采用NHWC数据格式,要求传入的4维输入、步长、输出的维度顺序严格对应:
- 输入张量维度顺序:
[batch_size, in_height, in_width, in_channels] - 卷积核张量维度顺序:
[kernel_height, kernel_width, in_channels, out_channels] strides参数要求传长度为4的列表,依次对应上述4个维度的步长,固定格式为[1, stride_h, stride_w, 1](batch和通道维度步长必须为1)- 输出张量维度顺序:
[batch_size, out_height, out_width, out_channels]
SAME填充模式下,空间维度的输出尺寸计算公式为:out_spatial = ceil(input_spatial / stride_spatial)
2. 输入张量维度构造不符合接口要求
你传入的输入、卷积核形状均为(3,3,64,64),结合实际输出(3,2,32,64)倒推,TensorFlow按默认规则解析维度的结果为:
- batch_size=3(对应输入第一维)
- in_height=3(对应输入第二维)
- in_width=64(对应输入第三维)
- in_channels=64(对应输入第四维)
其中卷积核被解析为3x3大小、64输入通道、64输出通道,这部分形状是符合接口要求的。
你预期输出空间尺寸为2x2,说明你误以为输入的前两个维度是高、宽(大小均为3),但实际上你传入的宽度维度值为64,本质是构造输入张量时把本该属于通道/batch的维度错放到了宽度位置,也没有正确设置batch维度的大小。
3. 步长参数的作用维度和预期不匹配
你设置步长为2时,传入的strides实际为[1,2,2,1],对应作用在输入的高度、宽度维度:
- 高度维度输入值为3,步长2,SAME填充下输出为
ceil(3/2)=2 - 宽度维度输入值为64,步长2,SAME填充下输出为
ceil(64/2)=32 - batch维度值3、输出通道值64保持不变
最终输出形状刚好就是你得到的(3,2,32,64),完全符合接口的计算逻辑。
修正方法
如果你预期得到空间尺寸2x2、64通道的输出,按以下步骤调整即可:
- 重构输入张量,根据选用的数据格式补全正确的batch维度:
- 用默认
NHWC格式时,输入形状调整为[your_batch_size, 3, 3, 64] - 若要用
NCHW(通道在前)格式,输入形状调整为[your_batch_size, 64, 3, 3],同时调用接口时指定data_format='NCHW',strides对应改为[1,1,2,2]
- 用默认
- 保持卷积核形状
(3,3,64,64)不变,strides按对应数据格式传参,padding保持SAME即可。
以NHWC格式、batch_size=1为例,调用代码参考:# 输入形状(1,3,3,64),卷积核形状(3,3,64,64) output = tf.nn.conv2d( input=x, filters=kernel, strides=[1,2,2,1], padding='SAME' ) # 输出形状为(1,2,2,64),符合预期
内容的提问来源于stack exchange,提问作者thehospitalrule
相关产品推荐
相关产品推荐

