web-dev-qa-db-fra.com

Dimension de dimension négative provoquée par la soustraction de 3 de 1 pour 'Conv2D'

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"
}
38
ᴀʀᴍᴀɴ

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)
73
Benoit Seguin

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"

22
Jacquot

Ajoutez simplement ceci:

from keras import backend as K
K.set_image_dim_ordering('th')
18
Shrish Trivedi

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"))
`
2
Vakkalagadda Tarun

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.

0