You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CNN最大池化层引发负维度尺寸错误求助

CNN最大池化层引发负维度尺寸错误求助

嗨,我看了你的代码和错误信息,这个问题其实是两个常见的小bug导致的,咱们一步步来解决:

首先看错误核心:Negative dimension size caused by subtracting 2 from 1,意思是你的特征图某个维度已经缩小到1了,再用2x2的最大池化窗口去处理,就会算出负数维度,直接报错。

第一个问题:卷积层堆叠错误

你的conv_block函数里,第二个Conv2D层的输入写的是inputs而不是上一层的输出x!这就导致两个卷积层是并行作用在同一个输入上,第一个卷积层的结果直接被覆盖了,完全没起到堆叠提取特征的作用,还可能让特征图的维度变化不符合预期。

修复这个很简单,把第二个Conv2D的输入改成x就行:

def conv_block(inputs, n_filter, regularizer, common_args):
    x = tf.keras.layers.Conv2D(filters=n_filter,
                               kernel_size=3,
                               strides=1,
                               padding='same',
                               activation='relu',
                               kernel_regularizer=regularizer,
                               **common_args)(inputs)
    # 这里把inputs改成x,让第二个卷积层接在第一个的输出后面
    x = tf.keras.layers.Conv2D(filters=n_filter,
                               kernel_size=3,
                               strides=1,
                               padding='same',
                               activation='relu',
                               kernel_regularizer=regularizer,
                               **common_args)(x)
    x = tf.keras.layers.MaxPooling2D((2, 2))(x)
    return x

第二个问题:输入数据的维度可能不对

从错误信息里的输入形状[?,128,10,1](NCHW格式,对应NHWC的(None,10,1,128))来看,你的特征图宽度已经变成1了,这说明你的输入数据可能没按照预期的(40,40,7)格式传入。比如可能不小心把通道维度放在了中间,变成了(40,7,40),这样经过两次池化后,宽度维度就会从7→3→1,第三次池化就炸了。

你可以先验证一下输入数据的形状:

# 取一个训练样本看看形状
for sample in train_dataset.take(1):
    print("样本形状:", sample.shape)

正常应该输出(40,40,7)(未batch的情况)或者(64,40,40,7)(已batch的情况)。如果维度不对,用tf.transpose调整:

# 比如如果当前是(7,40,40),转成(40,40,7)
adjusted_sample = tf.transpose(sample, perm=[1,2,0])

如果你的数据是channels_first格式,也可以在模型里统一指定:在Conv2D和MaxPooling2D层里加上data_format="channels_first",同时输入层改成Input(shape=(n_bands, img_size, img_size))。

修复后验证维度变化

修复完上面两个问题,咱们算一下特征图的尺寸变化:

  • 初始输入:40x40x7
  • 第一次conv_block:两次卷积后还是40x40x32,池化后变成20x20x32
  • 第二次conv_block:两次卷积后20x20x64,池化后10x10x64
  • 第三次conv_block:两次卷积后10x10x128,池化后5x5x128
  • Flatten后是55128=3200,完全没问题,不会出现负维度。

按照上面的步骤改完,应该就能顺利训练了!

备注:内容来源于stack exchange,提问作者riskiem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 12:03:20