Estoy usando Keras con Tensorflow como backend, aquí está mi código:

import numpy as np
np.random.seed(1373) 
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()

print(X_train.shape[0])

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,
border_mode='valid',
input_shape=(1, img_rows, img_cols)))
model.add(Activation('relu'))
model.add(Convolution2D(nb_filters, nb_conv, nb_conv))
model.add(Activation('relu'))

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

model.add(Flatten())
model.add(Dense(128))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(nb_classes)) 
model.add(Activation('softmax')) 

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


model.fit(X_train, 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])

Y error de Trackback:

Using TensorFlow backend.
60000
('X_train shape:', (60000, 1, 28, 28))
(60000, 'train samples')
(10000, 'test samples')
Traceback (most recent call last):
  File "mnist.py", line 154, in <module>
    input_shape=(1, img_rows, img_cols)))
  File "/usr/local/lib/python2.7/dist-packages/keras/models.py", line 276, in add
    layer.create_input_layer(batch_input_shape, input_dtype)
  File "/usr/local/lib/python2.7/dist-packages/keras/engine/topology.py", line 370, in create_input_layer
    self(x)
  File "/usr/local/lib/python2.7/dist-packages/keras/engine/topology.py", line 514, in __call__
    self.add_inbound_node(inbound_layers, node_indices, tensor_indices)
  File "/usr/local/lib/python2.7/dist-packages/keras/engine/topology.py", 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/topology.py", line 149, in create_node
    output_tensors = to_list(outbound_layer.call(input_tensors[0], mask=input_masks[0]))
  File "/usr/local/lib/python2.7/dist-packages/keras/layers/convolutional.py", line 466, in call
    filter_shape=self.W_shape)
  File "/usr/local/lib/python2.7/dist-packages/keras/backend/tensorflow_backend.py", line 1579, in conv2d
    x = tf.nn.conv2d(x, kernel, strides, padding=padding)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/ops/gen_nn_ops.py", line 396, in conv2d
    data_format=data_format, name=name)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/op_def_library.py", line 759, in apply_op
    op_def=op_def)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.py", line 2242, in create_op
    set_shapes_for_outputs(ret)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.py", line 1617, in set_shapes_for_outputs
    shapes = shape_func(op)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.py", 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/common_shapes.py", 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/common_shapes.py", 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].

Primero vi algunas respuestas de que el problema es con la versión Tensorflow, así que actualizo Tensorflow a 0.12.0, pero aún existe, si ese problema con la red o me falta algo, ¿qué debería {{X3} } ¿parece?

Actualizar Aquí está ./keras/keras.json:

{
    "image_dim_ordering": "tf", 
    "epsilon": 1e-07, 
    "floatx": "float32", 
    "backend": "tensorflow"
}
46
ᴀʀᴍᴀɴ 14 ene. 2017 a las 18:27

6 respuestas

La mejor respuesta

Su problema proviene de image_ordering_dim en keras.json.

Del documento de Keras Image Processing:

dim_ordering: uno de {"th", "tf"}. El modo "tf" significa que las imágenes deben tener forma (muestras, altura, ancho, canales), el modo "th" significa que las imágenes deben tener forma (muestras, canales, altura, ancho). Su valor predeterminado es el valor de image_dim_ordering que se encuentra en su archivo de configuración de Keras en ~ / .keras / keras.json. Si nunca lo configura, será "tf".

Keras asigna la operación de convolución al backend elegido (theano o tensorflow). Sin embargo, ambos backends han hecho diferentes elecciones para ordenar las dimensiones. Si su lote de imágenes es de N imágenes de tamaño HxW con canales C, theano usa el orden NCHW mientras que el tensorflow usa el orden NHWC.

Keras te permite elegir qué orden prefieres y hará la conversión para asignar a los backends detrás. Pero si elige image_ordering_dim="th", espera un pedido de estilo Theano (NCHW, el que tiene en su código) y si image_ordering_dim="tf" espera un pedido de estilo de tensorflow (NHWC).

Como su image_ordering_dim está configurado en "tf", si cambia la forma de sus datos al estilo de flujo de tensor, debería funcionar:

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)

Y

input_shape=(img_cols, img_rows, 1)
78
Zain Rizvi 22 may. 2018 a las 00:36

FWIW, recibí este error repetidamente con algunos valores de strides o kernel_size pero no todos, con el backend y el image_ordering ya configurados como tensorflow, y todos desaparecieron cuando agregué padding="same"

26
Jacquot 24 ene. 2018 a las 09:13

Proporcione el tamaño del filtro usando paréntesis como:

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

Funcionará en mi caso y también cambiará el X_train, X_test como este:

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)
0
סטנלי גרונן 22 ene. 2020 a las 20:16

Yo también tengo el mismo problema. Sin embargo, cada capa Conv3D, que estoy usando, está reduciendo el tamaño de la entrada. Entonces, incluir un parámetro padding = 'same' durante la declaración de la capa Conv2D / 3D resolvió el problema. Aquí está el código de demostración

model.add(Conv3D(32,kernel_size=(3,3,3),activation='relu',padding='same'))

También reducir el tamaño del filtro también puede resolver el problema.

En realidad, la capa Conv3D o Conv2D reduce los datos de entrada. Pero cuando su próxima capa no recibe ninguna entrada o entrada de tamaño que no sea apropiada para esa capa, entonces se produce este error. Al rellenar estamos haciendo que la salida de Conv3Dor2D permanezca del mismo tamaño de entrada para que la siguiente capa obtenga la entrada deseada

2
avijit bhattacharjee 23 dic. 2019 a las 08:12

Me enfrenté al mismo problema, pero se resolvió cambiando la función conv2d:

`
if K.image_data_format=='channels_first':
    x_train = x_train.reshape(x_train.shape[0], 1,img_cols,img_rows)
    x_test = x_test.reshape(x_test.shape[0], 1,img_cols,img_rows)
    input_shape = (1,img_cols,img_rows)
else:
    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)
model.add(Convolution2D(32,(3, 3), input_shape = input_shape, activation="relu"))
`
2
Vakkalagadda Tarun 9 dic. 2018 a las 05:44

Solo agrega esto:

from keras import backend as K
K.set_image_dim_ordering('th')
18
Shrish Trivedi 7 jul. 2017 a las 07:10