python-2.7 - que - maxpooling2d
Tensorflow+Keras+Convolution2d: ValueError: El filtro no debe ser mayor que la entrada: Filter:(5, 5) Input:(3, 350) (2)
Acabo de encontrar el mismo problema, cuando estaba siguiendo un tutorial. Como señala @Yao Zhang, el error es causado por el orden en input_shape
. Hay varias formas de resolver el problema.
- Opción 1: cambiar el orden en
input_shape
La línea de tu código
model.add(Convolution2D(32, 5, 5, border_mode=''valid'', input_shape=(3, IMG_WIDTH, IMG_HEIGHT)))
debe cambiarse a
model.add(Convolution2D(32, 5, 5, border_mode=''valid'', input_shape=(IMG_WIDTH, IMG_HEIGHT, 3)))
que debería estar bien entonces
Opción 2: especifique
image_dim_ordering
en sus capasOpción 3: modifique el archivo de configuración de keras cambiando ''tf'' a ''th'' en su ~ / .keras / keras.json
He intentado ejecutar el código que obtuve a continuación y aunque he cambiado casi nada más que el tamaño de la imagen (350,350 en lugar de 150, 150) todavía no puedo hacerlo funcionar. Recibo el error de filtro anterior (en el título) que comprendo, pero no lo estoy haciendo mal, así que no entiendo esto. Básicamente dice que no puedo tener más nodos que entradas, ¿correcto?
Pude finalmente abrirme camino a una solución cambiando esta línea:
model.add(Convolution2D(32, 5, 5, border_mode=''valid'', input_shape=(3, IMG_WIDTH, IMG_HEIGHT)))
con este:
model.add(Convolution2D(32, 5, 5, border_mode=''valid'', input_shape=(IMG_WIDTH, IMG_HEIGHT, 3)))
pero aún me gustaría entender por qué funcionó.
Aquí está el código a continuación junto con el error que recibo. Agradecería algo de ayuda (estoy usando Python Anaconda 2.7.11).
# IMPORT LIBRARIES --------------------------------------------------------------------------------#
import glob
import tensorflow
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Convolution2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from settings import RAW_DATA_ROOT
# GLOBAL VARIABLES --------------------------------------------------------------------------------#
TRAIN_PATH = RAW_DATA_ROOT + "/train/"
TEST_PATH = RAW_DATA_ROOT + "/test/"
IMG_WIDTH, IMG_HEIGHT = 350, 350
NB_TRAIN_SAMPLES = len(glob.glob(TRAIN_PATH + "*"))
NB_VALIDATION_SAMPLES = len(glob.glob(TEST_PATH + "*"))
NB_EPOCH = 50
# FUNCTIONS ---------------------------------------------------------------------------------------#
def baseline_model():
"""
The Keras library provides wrapper classes to allow you to use neural network models developed
with Keras in scikit-learn. The code snippet below is used to construct a simple stack of 3
convolution layers with a ReLU activation and followed by max-pooling layers. This is very
similar to the architectures that Yann LeCun advocated in the 1990s for image classification
(with the exception of ReLU).
:return: The training model.
"""
model = Sequential()
model.add(Convolution2D(32, 5, 5, border_mode=''valid'', input_shape=(3, IMG_WIDTH, IMG_HEIGHT)))
model.add(Activation(''relu''))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Convolution2D(32, 5, 5, border_mode=''valid''))
model.add(Activation(''relu''))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Convolution2D(64, 5, 5, border_mode=''valid''))
model.add(Activation(''relu''))
model.add(MaxPooling2D(pool_size=(2, 2)))
# Add a fully connected layer layer that converts our 3D feature maps to 1D feature vectors
model.add(Flatten())
model.add(Dense(64))
model.add(Activation(''relu''))
# Use a dropout layer to reduce over-fitting, by preventing a layer from seeing twice the exact
# same pattern (works by switching off a node once in a while in different epochs...). This
# will also serve as out output layer.
model.add(Dropout(0.5))
model.add(Dense(8))
model.add(Activation(''softmax''))
# Compile model
model.compile(loss=''categorical_crossentropy'',
optimizer=''adam'',
metrics=[''accuracy''])
return model
def train_model(model):
"""
Simple script that uses the baseline model and returns a trained model.
:param model: model
:return: model
"""
# Define the augmentation configuration we will use for training
TRAIN_DATAGEN = ImageDataGenerator(
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
# Build the train generator
TRAIN_GENERATOR = TRAIN_DATAGEN.flow_from_directory(
TRAIN_PATH,
target_size=(IMG_WIDTH, IMG_HEIGHT),
batch_size=32,
class_mode=''categorical'')
TEST_DATAGEN = ImageDataGenerator(rescale=1. / 255)
# Build the validation generator
TEST_GENERATOR = TEST_DATAGEN.flow_from_directory(
TEST_PATH,
target_size=(IMG_WIDTH, IMG_HEIGHT),
batch_size=32,
class_mode=''categorical'')
# Train model
model.fit_generator(
TRAIN_GENERATOR,
samples_per_epoch=NB_TRAIN_SAMPLES,
nb_epoch=NB_EPOCH,
validation_data=TEST_GENERATOR,
nb_val_samples=NB_VALIDATION_SAMPLES)
# Always save your weights after training or during training
model.save_weights(''first_try.h5'')
# END OF FILE -------------------------------------------------------------------------------------#
y el error:
Using TensorFlow backend.
Training set: 0 files.
Test set: 0 files.
Traceback (most recent call last):
File "/Users/christoshadjinikolis/GitHub_repos/datareplyuk/ODSC_Facial_Sentiment_Analysis/src/model/__init__.py", line 79, in <module>
model = baseline_model()
File "/Users/christoshadjinikolis/GitHub_repos/datareplyuk/ODSC_Facial_Sentiment_Analysis/src/model/training_module.py", line 31, in baseline_model
model.add(Convolution2D(32, 5, 5, border_mode=''valid'', input_shape=(3, IMG_WIDTH, IMG_HEIGHT)))
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/keras/models.py", line 276, in add
layer.create_input_layer(batch_input_shape, input_dtype)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/keras/engine/topology.py", line 370, in create_input_layer
self(x)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/keras/engine/topology.py", line 514, in __call__
self.add_inbound_node(inbound_layers, node_indices, tensor_indices)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/keras/engine/topology.py", line 572, in add_inbound_node
Node.create_node(self, inbound_layers, node_indices, tensor_indices)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-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 "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/keras/layers/convolutional.py", line 466, in call
filter_shape=self.W_shape)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/keras/backend/tensorflow_backend.py", line 1579, in conv2d
x = tf.nn.conv2d(x, kernel, strides, padding=padding)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/tensorflow/python/ops/gen_nn_ops.py", line 394, in conv2d
data_format=data_format, name=name)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/tensorflow/python/framework/op_def_library.py", line 703, in apply_op
op_def=op_def)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/tensorflow/python/framework/ops.py", line 2319, in create_op
set_shapes_for_outputs(ret)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/tensorflow/python/framework/ops.py", line 1711, in set_shapes_for_outputs
shapes = shape_func(op)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/tensorflow/python/framework/common_shapes.py", line 246, in conv2d_shape
padding)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/tensorflow/python/framework/common_shapes.py", line 184, in get2d_conv_output_size
(row_stride, col_stride), padding_type)
File "/Users/christoshadjinikolis/anaconda/lib/python2.7/site-packages/tensorflow/python/framework/common_shapes.py", line 149, in get_conv_output_size
"Filter: %r Input: %r" % (filter_size, input_size))
ValueError: Filter must not be larger than the input: Filter: (5, 5) Input: (3, 350)
El problema es que el orden de input_shape () cambia dependiendo del backend que esté utilizando (tensorflow o theano).
La mejor solución que encontré fue definir este orden en el archivo ~/.keras/keras.json
.
Try to use the theano order with tensorflow backend, or theano order with theano backend.
Crea el directorio keras en tu casa y crea el keras json: mkdir ~/.keras && touch ~/.keras/keras.json
{
"image_dim_ordering": "th",
"epsilon": 1e-07,
"floatx": "float32",
"backend": "tensorflow"
}