如何使用for循环创建Keras多LSTM层?

时间:2018-08-12 18:41:56

标签: python tensorflow keras lstm

我正在尝试使用 for循环this教程在 Keras 中实现多层LSTM,以便能够优化数量层,这显然是一个超参数。在本教程中,作者使用skopt来代替hyper-parameter optimization。我使用Functional API创建了模型。为简单起见,我将input_tensor的形状更改为任意值。我的模型是:

from keras.layers.core import Dense
from keras.layers import LSTM, Input
from keras.models import Model

from keras.optimizers import RMSprop
from keras.initializers import glorot_uniform, glorot_normal, RandomUniform


input_tensor = Input(shape=(10, 20))

def create_model(learning_rate, num_lstm_layers, num_lstm_units, activation):
    init = glorot_normal(seed=None)
    init1 = RandomUniform(minval=-0.05, maxval=0.05)

    x = Input(shape=(10, 20))


    for i in range(num_lstm_layers):

        name = 'layer_lstm_{0}'.format(i+1)

        if( (i==0) and (num_lstm_layers==1) ):
            x = LSTM(units=num_lstm_units, dropout=0.2, recurrent_dropout=0.2, 
                    return_sequences=False, kernel_initializer=init, 
                    activation=activation, name=name)(x)
        elif(i != (num_lstm_layers-1) ):
            x = LSTM(units=num_lstm_units, dropout=0.2, recurrent_dropout=0.2,  
                    return_sequences=True, kernel_initializer=init, 
                    activation=activation, name=name)(x)
        else:
            x = LSTM(units=num_lstm_units, dropout=0.2, recurrent_dropout=0.2,  
                    return_sequences=False, kernel_initializer=init, 
                    activation=activation, name=name)(x)
    x = Dense(1, activation='linear', kernel_initializer= init1)(x)

    model = Model(input_tensor, x)

    optimizer = RMSprop(lr=learning_rate, rho=0.9, epsilon=None, decay=0.0)
    model.compile(loss='mean_squared_error', optimizer=optimizer, metrics=['mse'] )

    return model      

每当我尝试使模型适合数据时,都会遇到此错误:

  

ValueError:变量layer_lstm_1_14 / kernel /的初始化程序来自   在控制流构造(例如循环或条件)中。什么时候   在循环或条件内创建变量,请使用lambda作为   初始化程序。

到目前为止,我知道应该在某个地方添加一个lambda函数或keras Lambda layer。 另外,我在单独的python脚本中测试了模型,如下所示:

model = create_model(learning_rate=1e-3, num_lstm_layers=3, num_lstm_units=64, activation='linear')

但是它再次给了我这个错误:

  

ValueError:图形已断开:无法获得张量的值   层上的Tensor(“ input_2:0”,shape =(?, 10,20),dtype = float32)   “ input_2”。可以顺利访问以下先前的层:   []

我还尝试创建模型的Sequential版本。但是遇到了同样的错误。

EDIT1:if( i==0):到if( (i==0) and (num_lstm_layers==1) ):编辑了if语句,然后按照André的建议进行了更改,便可以使用for循环创建LSTM模型。

1 个答案:

答案 0 :(得分:3)

正如我在评论中所说,我并不担心您的for循环,而是担心输入。我不确定100%,但是认为您应该尝试删除

input_tensor = Input(shape=(10, 20)) 

...,位于create_model(...)函数之前,并如下编辑其中一个的创建:

input_tensor = x = Input(shape=(10, 20))

继续阅读,您说您得到Graph disconnected: cannot obtain value for tensor。绝对听起来您输入没有连接。我建议所做的更改应连接您的输入和输出(分别是Model(...)的第一个和第二个参数)。