J'utilise Keras avec Tensorflow en tant que backend, voici mon code:
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])
et erreur 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].
Tout d’abord, j’ai vu quelques réponses indiquant que le problème se posait avec la version Tensorflow
; j’ai donc mis à niveau Tensorflow
vers 0.12.0
, Mais j’existe toujours, c’est que le problème avec le réseau ou j’ai oublié quelque chose, que devrait input_shape
Ressemble à?
Mettre à jour Voici ./keras/keras.json
:
{
"image_dim_ordering": "tf",
"epsilon": 1e-07,
"floatx": "float32",
"backend": "tensorflow"
}
Votre problème vient du image_ordering_dim
dans keras.json
.
De doc de traitement d'image Keras :
dim_ordering: Un des {"th", "tf"}. Le mode "tf" signifie que les images doivent avoir une forme (échantillons, hauteur, largeur, canaux), le mode "th" signifie que les images doivent avoir une forme (échantillons, canaux, hauteur, largeur). Par défaut, la valeur image_dim_ordering trouvée dans votre fichier de configuration Keras se trouve dans ~/.keras/keras.json. Si vous ne le définissez jamais, alors ce sera "tf".
Keras mappe l'opération de convolution sur le serveur choisi (flux de tensio ou flux de tensor). Cependant, les deux moteurs ont fait des choix différents pour la commande des dimensions. Si votre lot d'images contient N images de taille HxW avec canaux C, l'éditeur utilise l'ordre NCHW tandis que tensorflow utilise l'ordre NHWC.
Keras vous permet de choisir l'ordre que vous préférez et fera la conversion pour mapper au backend derrière. Mais si vous choisissez image_ordering_dim="th"
il attend une commande à la Theano (NCHW, celle que vous avez dans votre code) et si image_ordering_dim="tf"
il attend une commande de type tensorflow (NHWC).
Depuis votre image_ordering_dim
est réglé sur "tf"
, si vous modifiez vos données selon le style tensorflow, cela devrait fonctionner:
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)
et
input_shape=(img_cols, img_rows, 1)
FWIW, j’ai eu cette erreur à plusieurs reprises avec quelques valeurs de strides ou kernel_size mais pas toutes, avec les commandes backend et image_ordering déjà définies en tant que tensorflow, et elles ont toutes disparu lorsque j’ai ajouté padding="same"
Ajoutez simplement ceci:
from keras import backend as K
K.set_image_dim_ordering('th')
J'ai rencontré le même problème, mais il a été résolu en modifiant la fonction 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"))
`
J'ai aussi le même problème. Cependant, chaque couche de Conv3D que j'utilise réduit la taille de l'entrée. Ainsi, l'inclusion d'un paramètre padding = 'same' lors de la déclaration de la couche Conv2D/3D a résolu le problème. Voici le code de démonstration
model.add(Conv3D(32,kernel_size=(3,3,3),activation='relu',padding='same'))
Réduire également la taille du filtre peut également résoudre le problème.