I am getting an error of Negative dimension size when I am keeping height and width of the input image anything below 362X362. I am surprised because this error is generally caused because of wrong input dimensions. I did not find any reason why number or rows and columns can cause an error. Below is my code-
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)
Replace this:
x = MaxPooling2D(pool_size=(2, 2))(x)
with this:
x = MaxPooling2D((2,2), padding='same')(x)
to prevent dimension during downsampling.
The problem here has different reasons in keras and TF.
In keras: change the input shape accoring to the backend framework in use or change the dim_ordering=(tf/th)
In tensorflow: goto the the code line where error is raised and change the padding='valid' parameter to padding='same'.If the parameter doesn't exist then add as in the example below.
model.add(MaxPooling2D((2,2), strides=(2,2), padding='same'))
more info on the topic can be found here - https://www.tensorflow.org/api_docs/python/tf/keras/layers/MaxPool2D
InceptionV3
downsamples the input image very aggressively. For the input 362x362
image, base_model.output
tensor is (?, 9, 9, 2048)
- that is easy to see if you write
base_model.summary()
After that, your model downsamples the (?, 9, 9, 2048)
tensor even further (like in this question):
(?, 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!
You can prevent the conv layer from reducing the tensor size by adding padding='same'
parameter, even that will make the error disappear. Or by simply reducing the number of downsamples.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With