【问题标题】:ValueError: Negative dimension size caused by subtracting 2 from 1 for 'max_pooling3d_3/MaxPool3D'(op: 'MaxPool3D')with input shapes[?,1,60,60,128]ValueError:负尺寸大小由 1 减去 2 导致的 'max_pooling3d_3/MaxPool3D'(op: 'MaxPool3D')输入形状 [?,1,60,60,128]
【发布时间】:2020-10-08 07:31:32
【问题描述】:

我正在构建一个用于 3D 图像分割的 keras UNET 模型。

图像形状240, 240, 150

输入形状为240, 240, 150, 4, 335 >> 训练数据

输出形状应该是240, 240, 150, 335 >> 训练标签

我正在使用 Conv3D、MaxPooling3D、Conv3DTranspose 和连接层来构建模型

我在进行上采样的模型构建过程中遇到了这个错误

ValueError: Negative dimension size caused by subtracting 2 from 1 for 'max_pooling3d_3/MaxPool3D' (op: 'MaxPool3D') with input shapes: [?,1,60,60,128].

我搜索了一些解决方案,发现Layers padding='same'k.set_image_data_format('channels_last')

在上采样后进行连接时,我遇到了一个新错误

ValueError: A `Concatenate` layer requires inputs with matching shapes except for the concat axis. Got inputs shapes: [(None, 30, 30, 18, 256), (None, 30, 30, 19, 256)]

我目前在这两个错误之间循环,找不到确切的问题来解决如何解决它

这是我构建模型的代码

def build_unet_model(input_shape):
    inputs = Input(input_shape)

    conv1 = create_shared_convolution(inputs, 32, config.KERNEL_SIZE)
    block1 = down_convolution(conv1, config.POOL_SIZE)

    conv2 = create_shared_convolution(block1, 64, config.KERNEL_SIZE)
    block2 = down_convolution(conv2, config.POOL_SIZE)

    conv3 = create_shared_convolution(block2, 128, config.KERNEL_SIZE)
    block3 = down_convolution(conv3, config.POOL_SIZE)

    conv4 = create_shared_convolution(block3, 256, config.KERNEL_SIZE)
    block4 = down_convolution(conv4, config.POOL_SIZE)

    conv5 = create_shared_convolution(block4, 512, config.KERNEL_SIZE)  # mid_con
    up1 = concatenate_layers(create_up_convolution(conv5, 256, config.STRIDE_SIZE), conv4)

    conv6 = create_shared_convolution(up1, 256, config.KERNEL_SIZE)
    up2 = concatenate_layers(create_up_convolution(conv6, 128, config.STRIDE_SIZE), conv3)

    conv7 = create_shared_convolution(up2, 128, config.KERNEL_SIZE)
    up3 = concatenate_layers(create_up_convolution(conv7, 64, config.STRIDE_SIZE), conv2)

    conv8 = create_shared_convolution(up3, 64, config.KERNEL_SIZE)
    up4 = concatenate_layers(create_up_convolution(conv8, 32, config.STRIDE_SIZE), conv1)

    conv9 = create_shared_convolution(up4, 32, config.KERNEL_SIZE)
    outputs = create_output_layer(conv9, 4, (1, 1, 1))

    model = Model(inputs=[inputs], outputs=[outputs])
    print(model.summary())
    return model.compile(optimizer=AdaBound(lr=1e-5, final_lr=1), loss=utils.ce_dl_loss, metrics=['accuracy'])

这些是模型构建中使用的 5 个函数

def create_shared_convolution(input_layer, number_of_nets, kernel_size,
                              activation='relu', padding='same',
                              kernel_initializer=initializers.random_normal(stddev=0.01)):
    conv = Conv3D(number_of_nets, kernel_size, activation=activation, padding=padding,
                  kernel_initializer=kernel_initializer)(input_layer)

    conv = Conv3D(number_of_nets, kernel_size, activation=activation, padding=padding,
                  kernel_initializer=kernel_initializer)(conv)
    return conv

def down_convolution(input_layer, pool_size):
    return MaxPooling3D(pool_size=pool_size)(input_layer)


def create_up_convolution(input_layer, number_of_nets, stride_size, padding='same',
                          kernel_initializer=initializers.random_normal(stddev=0.01)):
    return Conv3DTranspose(number_of_nets, stride_size, strides=stride_size, padding=padding,
                           kernel_initializer=kernel_initializer)(input_layer)

def concatenate_layers(layer1, layer2):
    return merge.concatenate([layer1, layer2])


def create_output_layer(input_layer, number_of_nets, kernel_size, activation='relu',
                        kernel_initializer=initializers.random_normal(stddev=0.01)):
    conv = Conv3D(number_of_nets, kernel_size, activation=activation,
                  kernel_initializer=kernel_initializer)(input_layer)

    return Activation('softmax')(conv)

【问题讨论】:

  • 你能展示你的模型吗?
  • @ThomasSchillaci 我编辑了问题,请检查

标签: python image-processing keras deep-learning image-segmentation


【解决方案1】:

以下是对这两个错误的一些解释。

第一个是由于您的网络中的要素图太小。我没有您的网络架构的详细信息,但是如果您将大量最大池化层应用于您的输入(形状为 240、240、150),它可能最终在一个维度上只有一个值(可能类似于 ( N, N, 1))。在此之上添加其他最大池是不可能的,因为您在维度上没有足够的价值来执行它。这就是它引发负维度误差的原因。

第二个可能是由于最大池化层。当您应用第一个最大池时,没有任何问题:输出形状为 (120, 120, 75),因此对其进行上采样会返回 (240, 240, 150)。但是下一个最大池化(应用于 (120, 120, 75))将产生形状为 (60, 60, 37) 的输出,因为最后一个维度是奇数。对它进行上采样会得到 (120, 120, 74)。因此不匹配。解决此问题的方法是在维度为奇数时添加ZeroPadding 层,然后再连接它们。

【讨论】:

  • 我编辑了问题并添加了模型架构以防万一这将有助于找到问题
  • 我减少了层数并删除了 512 网络的层,我仍然遇到相同的错误但输入形状不同ValueError: A `Concatenate` layer requires inputs with matching shapes except for the concat axis. Got inputs shapes: [(None, 120, 120, 76, 64), (None, 120, 120, 77, 64)]
猜你喜欢
  • 2020-05-24
  • 1970-01-01
  • 2018-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-29
相关资源
最近更新 更多