Negative dimension size caused by subtracting 3 from 1 for 'Conv2D'


I’m using Keras with Tensorflow as backend , here is my code:

import numpy as np
import tensorflow as tf
tf.python.control_flow_ops = tf

import os
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.utils import np_utils

batch_size = 128
nb_classes = 10
nb_epoch = 12

img_rows, img_cols = 28, 28

nb_filters = 32

nb_pool = 2

nb_conv = 3

(X_train, y_train), (X_test, y_test) = mnist.load_data()


X_train = X_train.reshape(X_train.shape[0], 1, img_rows, img_cols)
X_test = X_test.reshape(X_test.shape[0], 1, img_rows, img_cols)

X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train /= 255
X_test /= 255

print('X_train shape:', X_train.shape)
print(X_train.shape[0], 'train samples')
print(X_test.shape[0], 'test samples')

Y_train = np_utils.to_categorical(y_train, nb_classes)
Y_test = np_utils.to_categorical(y_test, nb_classes)

model = Sequential()

model.add(Convolution2D(nb_filters, nb_conv, nb_conv,
input_shape=(1, img_rows, img_cols)))
model.add(Convolution2D(nb_filters, nb_conv, nb_conv))

model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool)))


model.compile(loss='categorical_crossentropy', optimizer='adadelta', metrics=["accuracy"]), Y_train, batch_size=batch_size, nb_epoch=nb_epoch,
verbose=1, validation_data=(X_test, Y_test))

score = model.evaluate(X_test, Y_test, verbose=0)

print('Test score:', score[0])
print('Test accuracy:', score[1])

and Trackback error:

Using TensorFlow backend.
('X_train shape:', (60000, 1, 28, 28))
(60000, 'train samples')
(10000, 'test samples')
Traceback (most recent call last):
  File "", line 154, in <module>
    input_shape=(1, img_rows, img_cols)))
  File "/usr/local/lib/python2.7/dist-packages/keras/", line 276, in add
    layer.create_input_layer(batch_input_shape, input_dtype)
  File "/usr/local/lib/python2.7/dist-packages/keras/engine/", line 370, in create_input_layer
  File "/usr/local/lib/python2.7/dist-packages/keras/engine/", line 514, in __call__
    self.add_inbound_node(inbound_layers, node_indices, tensor_indices)
  File "/usr/local/lib/python2.7/dist-packages/keras/engine/", line 572, in add_inbound_node
    Node.create_node(self, inbound_layers, node_indices, tensor_indices)
  File "/usr/local/lib/python2.7/dist-packages/keras/engine/", line 149, in create_node
    output_tensors = to_list([0], mask=input_masks[0]))
  File "/usr/local/lib/python2.7/dist-packages/keras/layers/", line 466, in call
  File "/usr/local/lib/python2.7/dist-packages/keras/backend/", line 1579, in conv2d
    x = tf.nn.conv2d(x, kernel, strides, padding=padding)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/ops/", line 396, in conv2d
    data_format=data_format, name=name)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/", line 759, in apply_op
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/", line 2242, in create_op
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/", line 1617, in set_shapes_for_outputs
    shapes = shape_func(op)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/", line 1568, in call_with_requiring
    return call_cpp_shape_fn(op, require_shape_fn=True)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/", line 610, in call_cpp_shape_fn
    debug_python_shape_fn, require_shape_fn)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/", line 675, in _call_cpp_shape_fn_impl
    raise ValueError(err.message)
ValueError: Negative dimension size caused by subtracting 3 from 1 for 'Conv2D' (op: 'Conv2D') with input shapes: [?,1,28,28], [3,3,28,32].

First I saw some answers that problem is with Tensorflow version so I upgrade Tensorflow to 0.12.0, but still exist , is that problem with network or I missing something, what should input_shape looks like?

Here is ./keras/keras.json:

    "image_dim_ordering": "tf", 
    "epsilon": 1e-07, 
    "floatx": "float32", 
    "backend": "tensorflow"


Your issue comes from the image_ordering_dim in keras.json.

From Keras Image Processing doc:

dim_ordering: One of {“th”, “tf”}. “tf” mode means that the images should have shape (samples, height, width, channels), “th” mode means that the images should have shape (samples, channels, height, width). It defaults to the image_dim_ordering value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be “tf”.

Keras maps the convolution operation to the chosen backend (theano or tensorflow). However, both backends have made different choices for the ordering of the dimensions. If your image batch is of N images of HxW size with C channels, theano uses the NCHW ordering while tensorflow uses the NHWC ordering.

Keras allows you to choose which ordering you prefer and will do the conversion to map to the backends behind. But if you choose image_ordering_dim="th" it expects Theano-style ordering (NCHW, the one you have in your code) and if image_ordering_dim="tf" it expects tensorflow-style ordering (NHWC).

Since your image_ordering_dim is set to "tf", if you reshape your data to the tensorflow style it should work:

X_train = X_train.reshape(X_train.shape[0], img_cols, img_rows, 1)
X_test = X_test.reshape(X_test.shape[0], img_cols, img_rows, 1)


input_shape=(img_cols, img_rows, 1)

Answered By – Benoit Seguin

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published