Tensorflow + Keras + Convolution2d: ValueError: O filtro não deve ser maior que a entrada: Filter: (5, 5) Input: (3, 350)

Eu tenho tentado executar o código abaixo do qual obtiveaqui e mesmo que eu mudei quase nada além do tamanho da imagem (350.350 em vez de 150, 150) ainda não é possível fazê-la funcionar. Estou recebendo o erro de filtro acima (no título) que compreendo, mas não estou fazendo errado, por isso não entendo isso. Basicamente, diz que não posso ter mais nós do que entradas, correto?

Consegui, eventualmente, abrir caminho para uma solução alterando esta linha:

model.add(Convolution2D(32, 5, 5, border_mode='valid', input_shape=(3, IMG_WIDTH, IMG_HEIGHT)))

com isso:

model.add(Convolution2D(32, 5, 5, border_mode='valid', input_shape=(IMG_WIDTH, IMG_HEIGHT, 3)))

mas ainda gostaria de entender por que isso funcionou.

Aqui está o código abaixo, juntamente com o erro que estou recebendo. Gostaria de receber ajuda (estou usando o 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 -------------------------------------------------------------------------------------#

e o erro:

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)

questionAnswers(2)

yourAnswerToTheQuestion