ValueError: Negative dimension size caused by subtracting 2 from 1 for 'max_pooling2d_6/MaxPool' (op: 'MaxPool') with input shapes: [?,1,1,64]

aaa*_*aaa 4 python neural-network deep-learning conv-neural-network keras

当我将输入图像的高度和宽度保持在362X362以下时,出现负尺寸大小错误。我很惊讶,因为此错误通常是由于错误的输入尺寸引起的。我没有发现数字或行和列会导致错误的任何原因。以下是我的代码-

batch_size = 32
num_classes = 7
epochs=50
height = 362
width = 362

train_datagen = ImageDataGenerator(
        rotation_range=40,
        width_shift_range=0.2,
        height_shift_range=0.2,
        rescale=1./255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True,
        fill_mode='nearest')

test_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(
    'train',
        target_size=(height, width),
        batch_size=batch_size,
        class_mode='categorical')

validation_generator = test_datagen.flow_from_directory(
     'validation',
        target_size=(height, width),
        batch_size=batch_size,
        class_mode='categorical')

base_model = InceptionV3(weights='imagenet', include_top=False, input_shape=
(height,width,3))

x = base_model.output
x = Conv2D(32, (3, 3), use_bias=True, activation='relu') (x) #line2
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Conv2D(64, (3, 3), activation='relu') (x) #line3
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Flatten()(x)
x = Dense(batch_size, activation='relu')(x) #line1
x = (Dropout(0.5))(x)
predictions = Dense(num_classes, activation='softmax')(x)
model = Model(inputs=base_model.input, outputs=predictions)

for layer in base_model.layers:
    layer.trainable = False

model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=
['accuracy'])

model.fit_generator(
        train_generator,
        samples_per_epoch=128,
        nb_epoch=epochs,
        validation_data=validation_generator,
        verbose=2)

for i, layer in enumerate(base_model.layers):
    print(i, layer.name)

for layer in model.layers[:309]:
    layer.trainable = False
for layer in model.layers[309:]:
    layer.trainable = True

from keras.optimizers import SGD
model.compile(optimizer=SGD(lr=0.0001, momentum=0.9), 
loss='categorical_crossentropy', metrics=['accuracy'])

model.save('my_model.h5')
model.fit_generator(
        train_generator,
        samples_per_epoch=512,
        nb_epoch=epochs,
        validation_data=validation_generator,
        verbose=2)
Run Code Online (Sandbox Code Playgroud)

小智 18

替换这个:

x = MaxPooling2D(pool_size=(2, 2))(x)
Run Code Online (Sandbox Code Playgroud)

有了这个:

x = MaxPooling2D((2,2), padding='same')(x)
Run Code Online (Sandbox Code Playgroud)

以防止下采样期间的维度。


小智 6

这里的问题在keras和TF中有不同的原因。

在keras中:根据使用的后端框架更改输入形状或更改dim_ordering=(tf/th)

在tensorflow中:转到引发错误的代码行,并将 padding='valid' 参数更改为 padding='same'。如果该参数不存在,则按以下示例添加。

model.add(MaxPooling2D((2,2), strides=(2,2), padding='same'))
Run Code Online (Sandbox Code Playgroud)

有关该主题的更多信息可以在这里找到 - https://www.tensorflow.org/api_docs/python/tf/keras/layers/MaxPool2D


Max*_*xim 5

InceptionV3非常积极地对输入图像进行降采样。对于输入362x362图像,base_model.output张量是(?, 9, 9, 2048)-很容易看出您是否写

base_model.summary()
Run Code Online (Sandbox Code Playgroud)

之后,您的模型(?, 9, 9, 2048)会进一步对张量进行下采样(例如此问题):

(?, 9, 9, 2048)  # input
(?, 7, 7, 32)    # after 1st conv-2d
(?, 3, 3, 32)    # after 1st max-pool-2d
(?, 1, 1, 64)    # after 2nd conv-2d
error: can't downsample further!
Run Code Online (Sandbox Code Playgroud)

您可以通过添加padding='same'参数来防止conv层减小张量大小,即使那样会使错误消失。或者通过简单地减少下采样的数量。