keras 中 Stateful LSTM 的 Batch Size

数据挖掘 深度学习 喀拉斯 lstm
2021-10-06 04:17:53

我的模型定义如下:

## defining the model
batch_size = 1

def my_model():

   
   input_x = Input(batch_shape=(batch_size, look_back, 4), name='input')
   drop = Dropout(0.5)
   
   lstm_1 = LSTM(100, return_sequences=True, batch_input_shape=(batch_size, look_back, 4), name='3dLSTM', stateful=True)(input_x)
   lstm_1_drop = drop(lstm_1)
   lstm_2 = LSTM(100, batch_input_shape=(batch_size, look_back, 4), name='2dLSTM', stateful=True)(lstm_1_drop)
   lstm_2_drop = drop(lstm_2)

   y1 = Dense(1, activation='relu', name='op1')(lstm_2_drop)
   y2 = Dense(1, activation='relu', name='op2')(lstm_2_drop)
   
   model = Model(inputs=input_x, outputs=[y1,y2])
   model.compile(loss='mse', optimizer='adam',metrics=['mse'])
   model.summary()
   return model

model = my_model()

它是一个批量大小 = 1 的有状态 LSTM 模型。我的model.fit样子是这样的:

# Train the model
history = model.fit(
    x_train,
    [y_11_train,y_22_train],
    epochs=1, 
    batch_size=batch_size, 
    verbose=0, 
    shuffle=False)

model.reset_states()

我的模型运行良好并输出结果。batch_size但是当模型处于无状态状态时,我无法像我们可以做的那样灵活地增加或改变。对于更大尺寸的数据集,模型似乎永远在训练,因为batch_size这里只有 1。而且我们知道我们不能随机设置任何batch_size值,stateful LSTM因为它需要是一个可分割的因素。

我浏览了一些博客,这些博客描述了batch_size通过使用不同的批量大小进行训练和使用Keras API 参考中的get_weights()和函数进行预测的变化: https ://machinelearningmastery.com/use-different-batch-sizes-training-predicting-python- keras/,似乎仍然是这里使用的较少。set_weights()batch_size

我的问题是:我们不能在有状态 LSTM 中使用像 32、64、128 这样的批量大小吗?如果是,那么我如何在上面给定的模型中实现它,如果不是,那么有什么替代方案?

寻找有价值的建议。

发布编辑

在有状态的 LSTMmodel.reset_states()中,应该在每个 epoch 之后,因此我在每个 epoch 之后以以下方式设置状态的重置:

for i in range(100):
    start = time.time()
    history = model.fit(x_train, [y_11_train,y_22_train], epochs=1, batch_size=batch_size, verbose=0, shuffle=False)
    model.reset_states()

    print("Epoch",i, time.time()-start,"s")
2个回答

我这样解决了这个问题:

我意识到我需要找到HCF的长度的(最大公因数)为此,我编写了一个简单的python 代码,它的输出是.x_trainx_testHCFbatch_size

因此,不同大小的数据集将具有不同的批量大小。

以下是我用来查找的代码HCF

def computeHCF(x, y):
    if x > y:
        smaller = y
    else:
        smaller = x
    for i in range(1, smaller+1):
        if((x % i == 0) and (y % i == 0)):
            hcf = i

    return hcf

batch_size= computeHCF(x_train.shape[0], x_test.shape[0])

batch_size 在定义模型、拟合模型(model.fit(..))和预测(model.predict(...))时使用它。

NOTE: We need to specify batch size while predicting the model. As:

model.predict(x_test, batch_size=batch_size)

希望这对某人有帮助!

正如您所提到的,关键部分是批量大小必须是一个值,该值无余数地除以(我相信)trainvalidation测试集大小。

可以找到这两个数据集维度的最大公倍数(又名最大公因数),这就是有状态 LSTM 中的最大批量大小。如果不清楚,请查看这个简单的解释。

您可以尝试一个简单的循环,例如:

for batch_size in range(128):
    try:
        model.train(...)
        print('Trained with batch size: {}'.format(batch_size))
    except:
        print('Couldn't use batch size: {}'.format(batch_size))

只需将 #epochs 设置为 1 并将迭代次数设置为较小的值,或者尽你所能减少每个循环所花费的时间,因为你实际上并不关心结果。