【问题标题】:Tensorflow + Keras + Convolution2d: ValueError: Filter must not be larger than the input: Filter: (5, 5) Input: (3, 350)Tensorflow + Keras + Convolution2d:ValueError:过滤器不得大于输入:过滤器:(5、5)输入:(3、350)
【发布时间】:2016-10-04 09:14:48
【问题描述】:

我一直在尝试运行从here 获得的下面的代码,尽管我几乎没有更改图像大小(350,350 而不是 150、150),但仍然无法使其正常工作。我得到了我理解的上述过滤器错误(标题中),但我没有做错,所以我不明白这一点。它基本上说我不能有比输入更多的节点,对吗?

我最终能够通过更改这一行来破解我的解决方案:

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

用这个:

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

但我仍然想了解为什么会这样。

这是下面的代码以及我遇到的错误。不胜感激(我使用的是 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 -------------------------------------------------------------------------------------#

和错误:

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)

【问题讨论】:

  • Tensorflow 通常使用 NHWC 格式,这意味着形状被指定为 (batch_size, height, width, channels)。快速浏览一下 keras 文档 (keras.io/getting-started/sequential-model-guide),keras 的一个选项是将形状分别指定为(通道、高度、宽度)和 batch_size,在您的示例中也是如此。所以看起来你的例子是正确的,应该有效,而且修复没有意义。如果我是你,我会使用 pdb 单步执行调用堆栈,以找出错误的形状从 keras 传递到 tensorflow 的位置。
  • 谢谢,下周晚些时候我会看看并发布我的发现。
  • 另一种可能性是该示例适用于 Tensorflow 以外的某些框架,并且该框架指定了带有顺序的形状(通道、高度、宽度)。对于 Tensorflow,您可能确实需要更改顺序。但这也让我感到困惑,因为我认为 keras 应该可以跨不同的机器学习框架移植。
  • 查看更多:keras.io/backend您可以在此页面中搜索[batch, channels, height, width]。现在看起来确实需要为 Tensorflow 更改形状顺序,而 keras 似乎并没有在内部/自动处理它。顺便说一句,我对 keras 知之甚少;这里的一些 keras 专家肯定可以提供更好的建议。

标签: python-2.7 tensorflow convolution keras


【解决方案1】:

问题在于 input_shape() 的顺序会根据您使用的后端(tensorflow 或 theano)而变化。

我发现的最佳解决方案是在文件 ~/.keras/keras.json 中定义此顺序。

Try to use the theano order with tensorflow backend, or theano order with theano backend.

在你家创建keras目录并创建keras json:mkdir ~/.keras &amp;&amp; touch ~/.keras/keras.json

{
    "image_dim_ordering": "th", 
    "epsilon": 1e-07, 
    "floatx": "float32", 
    "backend": "tensorflow"
}

【讨论】:

  • ~/.keras/keras.json 很可能已经存在。修改它可能比创建一个新设置更好,因为您可能不想更改其他设置。
  • @pyan 我提到的用于创建 目录keras.json 的命令只有在没有 keras 时才会起作用。 json 文件。因此运行安全,不会修改现有文件。
【解决方案2】:

我自己在学习教程时遇到了同样的问题。正如@Yao Zhang 所指出的,错误是由input_shape 中的顺序引起的。有多种方法可以解决这个问题。

  • 选项1:更改input_shape中的顺序

你的代码行

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

应该改为

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

那应该没问题。

  • 选项 2:在您的层中指定 image_dim_ordering

  • 选项 3:通过将 ~/.keras/keras.json 中的 'tf' 更改为 'th' 来修改 keras 配置文件

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-27
    • 1970-01-01
    • 2018-10-29
    • 2015-07-15
    • 2023-03-15
    • 2021-07-03
    • 2017-07-16
    相关资源
    最近更新 更多