将卷积层的输出重塑为哪些维度?

数据挖掘 Python 神经网络 喀拉斯 卷积
2022-02-23 15:07:01

我有一个卷积网络,取自这个github,在build.py. 因为它是在过时的 keras 版本中制作的,所以我正在尝试将其重写为 2.1.4 版本。我走了很长一段路,但我(希望)最后一步遇到了一些麻烦。下面我发布了我现在拥有的代码,但我需要做的是最终的重塑。我收到了错误ValueError: total size of new array must be unchanged,根据这个答案我收到了这个错误,因为我的输出形状与我想要重塑的形状不对应。但是我的高度和宽度都是 32 的因数,所以我不明白这个问题。网络的最后一层(批量标准化)返回(Bat (None, 0, 256, 2). 根据我发现的代码,我必须使用

autoencoder.add(Reshape((n_labels, img_h*img_w))

这将是(2, (256 * 256))这听起来不正确,256 * 256 部分非常大,但我不完全理解重塑功能。毕竟我是从 github 获取的,所以它应该是正确的,但是随着新 keras 版本的引入,符号可以改变。

有人可以阐明这种重塑的作用,并可能建议我需要重塑哪些维度?


这是我正在使用的整个模型:

from keras import models
from keras.layers.core import Activation, Reshape, Permute
from keras.layers.convolutional import Conv2D, MaxPooling2D, UpSampling2D
from keras.layers.normalization import BatchNormalization
import json

img_w = 256
img_h = 256
n_labels = 2

kernel = 3

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

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

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

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

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

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

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

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

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

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

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

    UpSampling2D(),
    Conv2D(64, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),
    Conv2D(n_labels, (1, 1), padding='valid'),
    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'))

with open('model_5l.json', 'w') as outfile:
    outfile.write(json.dumps(json.loads(autoencoder.to_json()), indent=2))

1个回答

您的数据格式不是默认数据格式。

默认情况下,Conv2DMaxPooling2DUpSampling2Dexpect 形式的输入[batch, height, width, channels]您的输入格式为[batch, channels, height, width].

因此,您的算法尝试将卷积、池化和上采样应用于channelsandheight维度,而不是按预期应用于heightand维度。width修复很简单:将选项添加data_format='channels_first'到所有卷积、池化和上采样层。(或更改您的数据格式)。