Recibo un error de tamaño de dimensión negativa cuando mantengo la altura y el ancho de la imagen de entrada por debajo de 362X362. Estoy sorprendido porque este error generalmente se debe a dimensiones de entrada incorrectas. No encontré ninguna razón por la cual el número o las filas y columnas puedan causar un error. A continuación se muestra mi código-
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)Reemplace esto:
x = MaxPooling2D(pool_size=(2, 2))(x)con este:
x = MaxPooling2D((2,2), padding='same')(x)para evitar la dimensión durante la reducción de resolución.
InceptionV3 reduce la muestra de la imagen de entrada de forma muy agresiva. Para la imagen de entrada de 362x362 , el tensor base_model.output es (?, 9, 9, 2048) ; eso es fácil de ver si escribes
base_model.summary() Después de eso, su modelo reduce la muestra del tensor (?, 9, 9, 2048) aún más (como en esta pregunta ):
(?, 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! Puede evitar que la capa de conversión reduzca el tamaño del tensor agregando el parámetro padding='same' , incluso eso hará que el error desaparezca. O simplemente reduciendo el número de downsamples.
El problema aquí tiene diferentes motivos en keras y TF.
En keras: cambie la forma de entrada de acuerdo con el marco de back-end en uso o cambie dim_ordering=(tf/th)
En tensorflow: vaya a la línea de código donde se genera el error y cambie el parámetro padding='valid' a padding='same'. Si el parámetro no existe, agréguelo como en el siguiente ejemplo.
model.add(MaxPooling2D((2,2), strides=(2,2), padding='same'))Puede encontrar más información sobre el tema aquí: https://www.tensorflow.org/api_docs/python/tf/keras/layers/MaxPool2D