Keras Maxpooling2d layer gives ValueError

Question:

I am trying to replicate VGG16 model in keras, the following is my code:

model = Sequential()
model.add(ZeroPadding2D((1,1),input_shape=(3,224,224)))
model.add(Convolution2D(64, 3, 3, activation='relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Convolution2D(64, 3, 3, activation='relu'))
model.add(MaxPooling2D((2,2), strides=(2,2)))
model.add(ZeroPadding2D((1,1)))
model.add(Convolution2D(128, 3, 3, activation='relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Convolution2D(128, 3, 3, activation='relu'))
model.add(MaxPooling2D((2,2), strides=(2,2))) ###This line gives error
model.add(ZeroPadding2D((1,1)))
model.add(Convolution2D(256, 3, 3, activation='relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Convolution2D(256, 3, 3, activation='relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Convolution2D(256, 3, 3, activation='relu'))
model.add(MaxPooling2D((2,2), strides=(2,2)))
model.add(ZeroPadding2D((1,1)))
model.add(Convolution2D(512, 3, 3, activation='relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Convolution2D(512, 3, 3, activation='relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Convolution2D(512, 3, 3, activation='relu'))
model.add(MaxPooling2D((2,2), strides=(2,2)))
model.add(ZeroPadding2D((1,1)))
model.add(Convolution2D(512, 3, 3, activation='relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Convolution2D(512, 3, 3, activation='relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Convolution2D(512, 3, 3, activation='relu'))
model.add(MaxPooling2D((2,2), strides=(2,2)))
model.add(Flatten())
model.add(Dense(4096, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(4096, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1000, activation='softmax'))

The maxpooling2d layer gives an error at the line which is commented

The error says:

ValueError: Negative dimension size caused by subtracting 2 from 1 for 'MaxPool_7' (op: 'MaxPool') with input shapes: [?,1,112,128].

What might be the reason behind this? How to solve this?

Edit:
A more detailed error log:


ValueError Traceback (most recent call
last) in ()
12 model.add(Convolution2D(128, 3, 3, activation=’relu’))
13
—> 14 model.add(MaxPooling2D((2,2), strides=(2,2)))
15
16 model.add(ZeroPadding2D((1,1)))

/usr/local/lib/python2.7/dist-packages/keras/models.pyc in add(self,
layer)
306 output_shapes=[self.outputs[0]._keras_shape])
307 else:
–> 308 output_tensor = layer(self.outputs[0])
309 if type(output_tensor) is list:
310 raise Exception(‘All layers in a Sequential model ‘

/usr/local/lib/python2.7/dist-packages/keras/engine/topology.pyc in
call(self, x, mask)
512 if inbound_layers:
513 # this will call layer.build() if necessary
–> 514 self.add_inbound_node(inbound_layers, node_indices, tensor_indices)
515 input_added = True
516

/usr/local/lib/python2.7/dist-packages/keras/engine/topology.pyc in
add_inbound_node(self, inbound_layers, node_indices, tensor_indices)
570 # creating the node automatically updates self.inbound_nodes
571 # as well as outbound_nodes on inbound layers.
–> 572 Node.create_node(self, inbound_layers, node_indices, tensor_indices)
573
574 def get_output_shape_for(self, input_shape):

/usr/local/lib/python2.7/dist-packages/keras/engine/topology.pyc in
create_node(cls, outbound_layer, inbound_layers, node_indices,
tensor_indices)
147
148 if len(input_tensors) == 1:
–> 149 output_tensors = to_list(outbound_layer.call(input_tensors[0], mask=input_masks[0]))
150 output_masks = to_list(outbound_layer.compute_mask(input_tensors[0], input_masks[0]))
151 # TODO: try to auto-infer shape if exception is raised by get_output_shape_for

/usr/local/lib/python2.7/dist-packages/keras/layers/pooling.pyc in
call(self, x, mask)
160 strides=self.strides,
161 border_mode=self.border_mode,
–> 162 dim_ordering=self.dim_ordering)
163 return output
164

/usr/local/lib/python2.7/dist-packages/keras/layers/pooling.pyc in
_pooling_function(self, inputs, pool_size, strides, border_mode, dim_ordering)
210 border_mode, dim_ordering):
211 output = K.pool2d(inputs, pool_size, strides,
–> 212 border_mode, dim_ordering, pool_mode=’max’)
213 return output
214

/usr/local/lib/python2.7/dist-packages/keras/backend/tensorflow_backend.pyc
in pool2d(x, pool_size, strides, border_mode, dim_ordering, pool_mode)
1699 1700 if pool_mode == ‘max’:
-> 1701 x = tf.nn.max_pool(x, pool_size, strides, padding=padding) 1702 elif pool_mode == ‘avg’: 1703
x = tf.nn.avg_pool(x, pool_size, strides, padding=padding)

/usr/local/lib/python2.7/dist-packages/tensorflow/python/ops/nn_ops.pyc
in max_pool(value, ksize, strides, padding, data_format, name) 1391
padding=padding, 1392
data_format=data_format,
-> 1393 name=name) 1394 1395

/usr/local/lib/python2.7/dist-packages/tensorflow/python/ops/gen_nn_ops.pyc
in _max_pool(input, ksize, strides, padding, data_format, name)
1593 result = _op_def_lib.apply_op(“MaxPool”, input=input,
ksize=ksize, 1594 strides=strides,
padding=padding,
-> 1595 data_format=data_format, name=name) 1596 return result 1597

/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/op_def_library.pyc
in apply_op(self, op_type_name, name, **keywords)
747 op = g.create_op(op_type_name, inputs, output_types, name=scope,
748 input_types=input_types, attrs=attr_protos,
–> 749 op_def=op_def)
750 outputs = op.outputs
751 return _Restructure(ops.convert_n_to_tensor(outputs),

/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.pyc
in create_op(self, op_type, inputs, dtypes, input_types, name, attrs,
op_def, compute_shapes, compute_device) 2388
original_op=self._default_original_op, op_def=op_def) 2389 if
compute_shapes:
-> 2390 set_shapes_for_outputs(ret) 2391 self._add_op(ret) 2392
self._record_op_seen_by_control_dependencies(ret)

/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.pyc
in set_shapes_for_outputs(op) 1783 raise RuntimeError(“No
shape function registered for standard op: %s” 1784
% op.type)
-> 1785 shapes = shape_func(op) 1786 if shapes is None: 1787 raise RuntimeError(

/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/common_shapes.pyc
in call_cpp_shape_fn(op, input_tensors_needed, debug_python_shape_fn)
594 status)
595 except errors.InvalidArgumentError as err:
–> 596 raise ValueError(err.message)
597
598 # Convert TensorShapeProto values in output_shapes.

ValueError: Negative dimension size caused by subtracting 2 from 1 for
‘MaxPool_7’ (op: ‘MaxPool’) with input shapes: [?,1,112,128].

Asked By: Pranay Mathur

||

Answers:

Quoting an answer mentioned in github, you need to specify the dimension ordering:

Keras is a wrapper over Theano or Tensorflow libraries. Keras uses the setting variable image_dim_ordering to decide if the input layer is Theano or Tensorflow format. This setting can be specified in 2 ways –

  1. specify 'tf' or 'th' in ~/.keras/keras.json like so – image_dim_ordering: 'th'. Note: this is a json file.
  2. or specify the image_dim_ordering in your model like so: model.add(MaxPooling2D(pool_size=(2, 2), dim_ordering="th"))

Update: Apr 2020 Keras 2.2.5 link seems to have an updated API where dim_ordering is changed to data_format so:

keras.layers.MaxPooling2D(pool_size=(2, 2), strides=None, padding='valid', data_format='channels_first') to get NCHW or use channels_last to get NHWC

Appendix: image_dim_ordering in 'th' mode the channels dimension (the depth) is at index 1 (e.g. 3, 256, 256). In 'tf' mode is it at index 3 (e.g. 256, 256, 3). Quoting @naoko from comments.

Answered By: Srikar Appalaraju

You are using the input shape as (3,x,y) should change it to input_shape=x,y,3

Answered By: hello

For keras with TensorFlow try following:

model.add(ZeroPadding2D((1, 1), input_shape=(img_rows, img_cols, channel)))
Answered By: user1662255

i also encountered the same problem while loading a per-trained VGG model. so i just took the transpose of the test images. the actual command is given below:

kerasImage = kerasImage.transpose(1,2,0)

Answered By: Khan

The accepted answer works. But you can also do the following:

    model.add(MaxPooling2D((2, 2), name='block1_pool', data_format='channels_last')

Keras assumes input to be (width, height, channels) for TensorFlow backend and (channel, width, height) for Theano backend. Since your input_shape=(3,224,224), specifying data_format='channels_last' should do the trick.

Answered By: Anakin

Adding dim_ordering solved error for me:

model.add(MaxPooling2D(pool_size=(2, 2), dim_ordering="th"))
Answered By: rishirich76

I faced the same issue, I solved it by changing my padding: ‘valid’ to padding:’SAME’: I guess its enough to add a parameter padding:’ same’

model.add(MaxPooling2D((2,2), strides=(2,2), padding='same'))
Answered By: megh_sat