【问题标题】:Keras Flatten Conv3D ValueError The input shape to Flatten is not fully definedKeras Flatten Conv3D ValueError Flatten 的输入形状未完全定义
【发布时间】:2018-12-29 21:51:16
【问题描述】:

我正在尝试使用基于 Marcin 的 PS3 示例的 Keras 和 Tensorflow 后端构建可变长度序列分类模型:https://stackoverflow.com/a/42635571/1203882

我收到一个错误:

ValueError: The shape of the input to "Flatten" is not fully defined (got (None, 1, 1, 32). Make sure to pass a complete "input_shape" or "batch_input_shape" argument to the first layer in your model.

我尝试在 Inception 层上放置一个输入形状,但错误仍然存​​在。我该如何纠正这个问题?

复制:

import numpy as np
import keras
from keras.utils import to_categorical
from keras.layers import TimeDistributed, Conv3D, Input, Flatten, Dense
from keras.applications.inception_v3 import InceptionV3
from random import randint
from keras.models import Model

HEIGHT = 224
WIDTH = 224
NDIMS = 3
NUM_CLASSES = 4

def input_generator():
    while True:
        nframes = randint(1,5)
        label = randint(0,NUM_CLASSES-1)
        x = np.random.random((nframes, HEIGHT, WIDTH, NDIMS))
        x = np.expand_dims(x, axis=0)
        y = keras.utils.to_categorical(label, num_classes=NUM_CLASSES)
        yield (x, y)

def make_model():
    layers = 32
    inp = Input(shape=(None, HEIGHT, WIDTH, NDIMS))
    cnn = InceptionV3(include_top=False, weights='imagenet')
    # cnn = InceptionV3(include_top=False, weights='imagenet', input_shape=(HEIGHT, WIDTH, NDIMS)) # same result
    td = TimeDistributed(cnn)(inp)
    c3da = Conv3D(layers, 3,3,3)(td)
    c3db = Conv3D(layers, 3,3,3)(c3da)
    flat = Flatten()(c3db)
    out = Dense(NUM_CLASSES, activation="softmax")(flat)
    model = Model(input=(None, HEIGHT, WIDTH, NDIMS), output=out)
    model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
    return model

if __name__ == '__main__':
    model = make_model()
    model.fit_generator(input_generator(), samples_per_epoch=5, nb_epoch=2, verbose=1)

【问题讨论】:

    标签: python keras


    【解决方案1】:

    不可能展平可变长度张量。如果可能的话,Keras 怎么知道最后一个全连接层的输入单元数量?模型的参数数量需要在图创建时定义。

    您的问题有两种可能的解决方案:

    a) 固定帧数:

    inp = Input(shape=(NFRAMES, HEIGHT, WIDTH, NDIMS))
    

    b) 在展平层之前聚合框架的尺寸。例如:

    from keras.layers import Lambda
    import keras.backend as K    
    
    def make_model():
        layers = 32
        inp = Input(shape=(None, HEIGHT, WIDTH, NDIMS))
        cnn = InceptionV3(include_top=False, weights='imagenet')
        # cnn = InceptionV3(include_top=False, weights='imagenet', input_shape=(HEIGHT, WIDTH, NDIMS)) # same result
        td = TimeDistributed(cnn)(inp)
        c3da = Conv3D(layers, 3,3,3)(td)
        c3db = Conv3D(layers, 3,3,3)(c3da)
        aggregated = Lambda(lambda x: K.sum(x, axis=1))(c3db)
        flat = Flatten()(aggregated)
        out = Dense(NUM_CLASSES, activation="softmax")(flat)
        model = Model(input=inp, output=out)
        model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
        return model
    

    注意 1:可能有更好的策略来聚合框架的维度。

    注意 2:keras.utils.to_categorical 的输入应该是标签列表:

    y = keras.utils.to_categorical([label], num_classes=NUM_CLASSES)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-23
      • 2019-07-06
      • 2019-04-01
      • 1970-01-01
      • 2019-01-24
      • 1970-01-01
      • 2017-11-03
      • 2017-08-14
      相关资源
      最近更新 更多