Отрицательный размер размера, вызванный вычитанием 3 из 1 для 'Conv2D'
Я использую Keras с Tensorflow как backend, вот мой код:
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])
и ошибка 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].
Сначала я увидел несколько ответов, проблема с версией Tensorflow
, поэтому я обновляю Tensorflow
до 0.12.0
, но все еще существует, это проблема с сетью или что-то мне не хватает, что должно выглядеть input_shape
?
Обновление
Здесь ./keras/keras.json
:
{
"image_dim_ordering": "tf",
"epsilon": 1e-07,
"floatx": "float32",
"backend": "tensorflow"
}
Ответы
Ответ 1
Ваша проблема связана с image_ordering_dim
в keras.json
.
Из документа Обработка изображений Keras:
dim_ordering: один из {"th", "tf"}. Режим "tf" означает, что изображения должны иметь форму (образцы, высота, ширина, каналы), режим "th" означает, что изображения должны иметь форму (образцы, каналы, высота, ширина). По умолчанию используется значение image_dim_ordering, найденное в вашем конфигурационном файле Keras по адресу ~/.keras/keras.json. Если вы никогда не устанавливаете это, то это будет "TF".
Keras отображает операцию свертки на выбранный бэкэнд (theano или тензорный поток). Однако оба бэкэнда сделали разные варианты для упорядочения размеров. Если ваш пакет изображений состоит из N изображений размером HxW с каналами C, theano использует порядок NCHW, а тензор потока - порядок NHWC.
Keras позволяет вам выбирать, какой порядок вы предпочитаете, и будет выполнять преобразование для сопоставления с бэкэндами позади. Но если вы выберете image_ordering_dim="th"
он ожидает упорядочения в стиле Theano (NCHW, тот, который у вас есть в вашем коде), а если image_ordering_dim="tf"
он ожидает упорядочения в стиле тензорного потока (NHWC).
Так как ваш image_ordering_dim
установлен в "tf"
, если вы измените ваши данные в стиль тензорного потока, он должен работать:
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)
Ответ 2
FWIW, я неоднократно получал эту ошибку с некоторыми значениями strides или kernel_size, но не со всеми, с backend и image_ordering, уже установленными как tensorflow, и они все исчезли, когда я добавил padding="same"
Ответ 3
Просто добавьте это:
from keras import backend as K
K.set_image_dim_ordering('th')
Ответ 4
Я столкнулся с той же проблемой, но она была решена путем изменения функции 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"))
'
Ответ 5
У меня такая же проблема. Тем не менее, каждый слой Conv3D, который я использую, уменьшает размер ввода. Таким образом, включение одного параметра padding = 'same' во время объявления слоя Conv2D/3D решило проблему. Вот демо-код
model.add(Conv3D(32,kernel_size=(3,3,3),activation='relu',padding='same'))
Уменьшение размера фильтра также может решить проблему.