Keras fit_generator提高使用该模型之前,必须先对其进行编译错误

时间:2018-10-09 12:24:43

标签: keras lstm

我尝试通过Keras构建CNN + LSTM模型,以训练用于视频分类任务的模型。首先,使用模拟数据“ fit()” api构建并训练了一个简单的模型,它也有效!

但是实际上,用于训练该模型的是视频数据集,它是如此之大以至于无法加载到内存中。因此,我需要一个生成器,在这里,我还要编写一个模拟生成器,该生成器可以生成形状与模拟数据方法相同的数据。另外,fit_generator API代替了fit。

运行train_gen函数时,出现以下错误:

File "lstm.py", line 48, in <module>
    train_gen()
  File "lstm.py", line 45, in train_gen
    model.fit_generator(data_generator.mock_generator(batch_size=32, num_classes=16), steps_per_epoch=1000, epochs=20)
  File "/usr/local/lib/python2.7/dist-packages/keras/legacy/interfaces.py", line 91, in wrapper
    return func(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 1415, in fit_generator
    initial_epoch=initial_epoch)
  File "/usr/local/lib/python2.7/dist-packages/keras/engine/training_generator.py", line 39, in fit_generator
    model._make_train_function()
  File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 485, in _make_train_function
    raise RuntimeError('You must compile your model before using it.')
RuntimeError: You must compile your model before using it.

我试图通过在堆栈溢出和Google中进行搜索来解决此问题,但未找到确切的解决方案。通过指定LSTM input_shapeoutput size或添加model.compile(),可以解决一些类似的问题。

以下代码段是可运行的,并且与上述代码完全相同。

import keras
from keras.models import Sequential
from keras.layers import Input, Embedding, LSTM, Dense, Reshape
from keras.layers import Dense, Dropout, Flatten, Activation
from keras.layers.normalization import BatchNormalization
from keras.layers.wrappers import Bidirectional

from keras.optimizers import Adam
import numpy as np
import os, random

os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"   # see issue #152
os.environ["CUDA_VISIBLE_DEVICES"] = ""

use_dropout = True
metrics = ['accuracy']

#mock data generator
def mock_generator(batch_size, input_length, input_dims, num_classes=16):
    while True:
        yield np.random.random((batch_size, input_length, input_dims)), keras.utils.to_categorical(np.random.randint(num_classes, size=(batch_size, 1)), num_classes=num_classes)

#mock data with shape as data generator
def mock_data(batch_size, input_length, input_dims, num_classes=16):
    if True:
        return np.random.random((batch_size, input_length, input_dims)), keras.utils.to_categorical(np.random.randint(num_classes, size=(batch_size, 1)), num_classes=num_classes)

#construct model, lstm units is fixed
def bi_lstm(input_shape, num_classes=16):
    model = Sequential()
    model.add(Bidirectional(LSTM(100, return_sequences=True, activation='relu', input_shape=input_shape), merge_mode='concat'))
    model.add(Bidirectional(LSTM(100, activation='relu', input_shape=(input_shape[0],100), return_sequences=False), merge_mode='concat'))
    if use_dropout:
        model.add(Dropout(0.5))
    model.add(Dense(num_classes))
    model.add(BatchNormalization())
    model.add(Activation('softmax'))
    optimizer = Adam(lr=1e-5, decay=1e-6)
    model.compile(loss='categorical_crossentropy', optimizer=optimizer,
                           metrics=metrics)
    return model

#fit api run successfully
def train():
    input_length=10
    input_dims=128
    num_classes=10
    model = bi_lstm((input_length, input_dims), num_classes)
    x_train, y_train = mock_data(32, input_length, input_dims, num_classes)
    model.fit(x_train, y_train, epochs=20, batch_size=32)

#fit_generator api raise error!
def train_gen():
    input_length=10
    input_dims=128
    num_classes=10
    model = bi_lstm((input_length, input_dims), num_classes)
    generator = mock_generator(32, input_length, input_dims, num_classes)
    model.fit_generator(generator, steps_per_epoch=1000, epochs=20)

#test mock generator function
def test_mock_gen():
    result  = mock_generator(32,10,128,16)
    for i in range(2):
        x, y = result.next()
        print x.shape
        print y.shape

if __name__ == '__main__':
    train()
    train_gen()
    #test_mock_gen()

1 个答案:

答案 0 :(得分:0)

您得到的错误无法更明确地表明:模型已在train()函数上声明为本地对象,并且不知道通过函数train_gen()。将模型定义为全局变量(例如,在main中),它将起作用。