2016-10-04 85 views
4

我一直在嘗試運行下面的代碼,我從here得到,甚至儘管除了圖像大小(350,350而不是150,150)之外,我幾乎沒有改變任何東西,但仍然無法使其工作。我得到了上面的過濾器錯誤(在標題中),但我沒有做錯,所以我不明白這一點。它基本上說我不能有比輸入更多的節點,對嗎?Tensorflow + Keras + Convolution2d:ValueError:過濾器不能大於輸入:過濾器:(5,5)輸入:(3,350)

我能夠最終通過改變這一行我路劈死的解決方案:

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) 
+0

Tensorflow通常使用NHWC格式,這意味着被指定爲(的batch_size,高度,寬度,通道的形狀)。從快速瀏覽keras文檔(https:// keras。io/getting-started/sequential-model-guide /),keras的一個選項是分別指定形狀(通道,高度,寬度)和batch_size,在您的示例中也是如此。所以看起來你的例子是正確的,應該已經工作了,修復沒有意義。如果我是你,我會使用pdb來遍歷調用堆棧,找出錯誤的形狀從keras到tensorflow的位置。 –

+0

謝謝,下週晚些時候我會看看並發表我的發現。 –

+0

另一種可能性是該示例僅適用於Tensorflow以外的某個框架,並且此框架指定了順序(通道,高度,寬度)的形狀。對於Tensorflow,您可能確實需要更改訂單。但是這讓我感到困惑,因爲我認爲keras應該可以跨不同的機器學習框架進行移植。 –

回答

7

問題是,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 && touch ~/.keras/keras.json

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

〜/ .keras/keras.json可能已經存在。修改它可能比創建新的更好,因爲可能有其他設置不想更改。 – pyan

+0

@pyan我提到創建一個**目錄**和** keras.json **的命令,它只有在沒有** keras.json **文件時纔會起作用。因此運行是安全的,並且不會修改現有文件。 – psylo

5

正好遇到了同樣的問題我自己,當我下面的教程。正如@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' 到 '日' 修改keras配置文件