喀拉拉邦的截断的反向传播,每批一个序列

时间:2018-11-08 09:14:31

标签: python keras deep-learning backpropagation

如果我正确理解,要在喀拉拉邦执行TBPTT,我们必须将序列分成k个时间步的较小部分。根据keras的文档,要在整个序列的所有部分重用LSTM的状态,我们必须使用有状态参数:

  

您可以将RNN层设置为“有状态”,这意味着针对一批中的样本计算出的状态将被重复用作下一批次中的样本的初始状态。假设不同连续批次中的样品之间是一对一的映射。

因此,如果我正确理解了第一批的第一个样本是第一序列的1s部分,第二批的第一个样本是1序列的第二部分,依此类推。我有125973个长度为1000的序列我将其分为40个k = 25个时间步长的序列。因此,我的模型应训练40个批次,其中包含25个时间步长的125973个序列。我的问题是我的GPU的内存(quadro K2200,我很穷),批处理大小为125973似乎太大了。我想知道是否可以将LSTM的状态保持在同一批次中,并在批次之间进行重置,因此我应该将批次大小设置为40和125973。

这是我的模特:

model = Sequential()
model.add(Embedding(len(char_to_num), 200, mask_zero=True, batch_input_shape=(batch_size, k)))
model.add(Dropout(0.5))
model.add(LSTM(512, activation='relu', return_sequences=True, stateful=True))
model.add(Dropout(0.5))
model.add(TimeDistributed(Dense(len(char_to_num), activation='softmax')))

model.compile(loss='sparse_categorical_crossentropy', optimizer='adam')
model.summary()

1 个答案:

答案 0 :(得分:2)

到目前为止,您的批量大小是灵活的,它必须除以 P = 125973。如果没有这样的数字(例如,因为 P 是素数),则只需添加每个填充有千个零的虚拟序列。如果添加了虚拟序列,请确保在训练期间通过向 model.fit() 添加适当的“sample_weights”nd-array(其中真实序列用“1”屏蔽,虚拟序列用“0”屏蔽)来忽略它们,并且调用 model.compile(.., sample_weight_mode='temporal').

然后,要在批次之间重置状态,请使用 keras 回调:

# N must be divisible by batch_size
N = 40*126000  # number of time series snippets (sequences + dummies)
batch_size = 50  # processing 50 sequences at a time

class StateResetter(tf.keras.callbacks.Callback):
    def on_train_batch_end(self, batch, logs={}):
        # reset states if we processed a set of sequences
        if (batch+1) % 40 == 0:
            self.model.get_layer('my_lstm_layer').reset_states()

# input_data.shape = (N, 25, num_features)
model.fit(input_data, labels, batch_size=batch_size, 
          callbacks=[StateResetter], sample_weight=sample_weight)

我想您应该能够弄清楚如何相应地调整 input_data。