keras中的segnet:新数组的总大小必须保持不变错误

Sal*_* A. 4 python machine-learning neural-network deep-learning keras

我正在用Python实现segnet。以下是代码。

img_w = 480
img_h = 360
pool_size = 2

def build_model(img_w, img_h, pool_size):
    n_labels = 12

    kernel = 3

    encoding_layers = [
        Conv2D(64, (kernel, kernel), input_shape=(img_h, img_w, 3), padding='same'),
        BatchNormalization(),
        Activation('relu'),
        Convolution2D(64, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),
        MaxPooling2D(pool_size = (pool_size,pool_size)),

        Convolution2D(128, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),
        Convolution2D(128, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),
        MaxPooling2D(pool_size = (pool_size,pool_size)),

        Convolution2D(256, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),
        Convolution2D(256, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),
        Convolution2D(256, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),
        MaxPooling2D(pool_size = (pool_size,pool_size)),

        Convolution2D(512, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),
        Convolution2D(512, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),
        Convolution2D(512, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),
        MaxPooling2D(pool_size = (pool_size,pool_size)),

        Convolution2D(512, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),
        Convolution2D(512, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),
        Convolution2D(512, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),
        MaxPooling2D(pool_size = (pool_size,pool_size)),
    ]

    autoencoder = models.Sequential()
    autoencoder.encoding_layers = encoding_layers

    for l in autoencoder.encoding_layers:
        autoencoder.add(l)

    decoding_layers = [
        UpSampling2D(),
        Convolution2D(512, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),
        Convolution2D(512, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),
        Convolution2D(512, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),

        UpSampling2D(),
        Convolution2D(512, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),
        Convolution2D(512, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),
        Convolution2D(256, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),

        UpSampling2D(),
        Convolution2D(256, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),
        Convolution2D(256, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),
        Convolution2D(128, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),

        UpSampling2D(),
        Convolution2D(128, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),
        Convolution2D(64, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),

        UpSampling2D(),
        Convolution2D(64, (kernel, kernel), padding='same'),
        BatchNormalization(),
        Activation('relu'),
        Convolution2D(n_labels, (1, 1), padding='valid', activation="sigmoid"),
        BatchNormalization(),
    ]
    autoencoder.decoding_layers = decoding_layers
    for l in autoencoder.decoding_layers:
        autoencoder.add(l)

    autoencoder.add(Reshape((n_labels, img_h * img_w)))
    autoencoder.add(Permute((2, 1)))
    autoencoder.add(Activation('softmax'))



    return autoencoder

model = build_model(img_w, img_h, pool_size)
Run Code Online (Sandbox Code Playgroud)

但是它返回我错误。

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-21-051f06a53a14> in <module>()
----> 1 model = build_model(img_w, img_h, pool_size)

<ipython-input-20-c37fd94c8641> in build_model(img_w, img_h, pool_size)
    119         autoencoder.add(l)
    120 
--> 121     autoencoder.add(Reshape((n_labels, img_h * img_w)))
    122     autoencoder.add(Permute((2, 1)))
    123     autoencoder.add(Activation('softmax'))
    ValueError: total size of new array must be unchanged
Run Code Online (Sandbox Code Playgroud)

我看不到任何错误原因。当我将img_w和img_h更改为256时,此错误已解决,但问题是不是图像大小或原始数据集,因此我无法使用它。如何解决呢?一点帮助和见识将不胜感激。

Mar*_*jko 6

问题是您执行了(2, 2)5次降采样,因此,让我们跟踪形状:

(360, 480) -> (180, 240) -> (90, 120) -> (45, 60) -> (22, 30) -> (11, 15)
Run Code Online (Sandbox Code Playgroud)

现在进行上采样:

(11, 15) -> (22, 30) -> (44, 60) -> (88, 120) -> (176, 240) -> (352, 480)
Run Code Online (Sandbox Code Playgroud)

因此,当您尝试reshape使用原始形状输出时-由于模型不匹配而引起了问题。

可能的解决方案:

  1. 调整图片的大小,使两个输入尺寸都可以被32(例如(352, 480)或)整除(384, 480)

  2. ZeroPadding2D(((1, 0), (0, 0)))在第三次升采样后添加,将形状从更改(44, 60)(45, 60),这将使您的网络以良好的输出形状结束。

其他事宜:

请确定最后一个MaxPooling2D后面是第一个Upsampling2D。这可能是一个问题,因为这是您网络的无用瓶颈。

  • 你是对的。那正是问题所在。仅仅一行就浪费了我一整天! (2认同)