如何在LSTM中有效使用批量规范化?

时间:2018-01-31 14:49:03

标签: r tensorflow keras recurrent-neural-network batch-normalization

我正在尝试使用R中的keras在LSTM中使用批量规范化。在我的数据集中,目标/输出变量是Sales列,数据集中的每一行都记录每天的Sales在一年(2008-2017)。数据集如下所示:

Sales data

我的目标是基于这样的数据集构建LSTM模型,该模型应该能够在训练结束时提供预测。我正在根据2008 - 2016年的数据训练这个模型,并使用2017年数据的一半作为验证,其余作为测试集。

以前,我尝试使用dropout和提前停止来创建模型。这看起来如下:

mdl1 <- keras_model_sequential()
mdl1 %>%
  layer_lstm(units = 512, input_shape = c(1, 3), return_sequences = T ) %>%  
  layer_dropout(rate = 0.3) %>%
  layer_lstm(units = 512, return_sequences = FALSE) %>%
  layer_dropout(rate = 0.2) %>%
  layer_dense(units = 1, activation = "linear")

mdl1 %>% compile(loss = 'mse', optimizer = 'rmsprop')

该模型如下所示

___________________________________________________________
Layer (type)               Output Shape         Param #    
===========================================================
lstm_25 (LSTM)             (None, 1, 512)       1056768    
___________________________________________________________
dropout_25 (Dropout)       (None, 1, 512)       0          
___________________________________________________________
lstm_26 (LSTM)             (None, 512)          2099200    
___________________________________________________________
dropout_26 (Dropout)       (None, 512)          0          
___________________________________________________________
dense_13 (Dense)           (None, 1)            513        
===========================================================
Total params: 3,156,481
Trainable params: 3,156,481
Non-trainable params: 0
___________________________________________________________

为了训练模型,早期停止与验证集一起使用。

mdl1.history <- mdl1 %>% 
  fit(dt.tr, dt.tr.out, epochs=500, shuffle=F,
      validation_data = list(dt.val, dt.val.out),
      callbacks = list(
        callback_early_stopping(min_delta = 0.000001,  patience = 10, verbose = 1)
      ))

除此之外,我还想使用批量标准化来加速培训。根据我的理解,要使用批量规范化,我需要将数据分成批次,并将layer_batch_normalization应用于每个隐藏层的输入。模型层如下所示:

batch_size <- 32
mdl2 <- keras_model_sequential()
mdl2 %>%
  layer_batch_normalization(input_shape = c(1, 3), batch_size = batch_size) %>%

  layer_lstm(units = 512, return_sequences = T) %>%
  layer_dropout(rate = 0.3) %>%
  layer_batch_normalization(batch_size = batch_size) %>%

  layer_lstm(units = 512, return_sequences = F) %>%
  layer_dropout(rate = 0.2) %>%
  layer_batch_normalization(batch_size = batch_size) %>%

  layer_dense(units = 1, activation = "linear")

mdl2 %>% compile(loss = 'mse', optimizer = 'rmsprop')

此模型如下所示:

______________________________________________________________________________
Layer (type)                                    Output Shape       Param #    
==============================================================================
batch_normalization_34 (BatchNormalization)     (32, 1, 3)         12         
______________________________________________________________________________
lstm_27 (LSTM)                                  (32, 1, 512)       1056768    
______________________________________________________________________________
dropout_27 (Dropout)                            (32, 1, 512)       0          
______________________________________________________________________________
batch_normalization_35 (BatchNormalization)     (32, 1, 512)       2048       
______________________________________________________________________________
lstm_28 (LSTM)                                  (32, 1, 512)       2099200    
______________________________________________________________________________
dropout_28 (Dropout)                            (32, 1, 512)       0          
______________________________________________________________________________
batch_normalization_36 (BatchNormalization)     (32, 1, 512)       2048       
______________________________________________________________________________
dense_14 (Dense)                                (32, 1, 1)         513        
==============================================================================
Total params: 3,160,589
Trainable params: 3,158,535
Non-trainable params: 2,054
______________________________________________________________________________

训练模型看起来像以前一样。唯一的区别在于训练和验证数据集,它们的大小是batch_size的倍数(此处为32),通过重新采样从最后一批到最后一批的数据。

但是,mdl1的效果要比mdl2好得多,如下所示。

models

我不确定我做错了什么,因为我开始使用keras(和一般的实用神经网络)。此外,第一个模型的表现也不是那么好;任何关于如何改进的建议都会很棒。

2 个答案:

答案 0 :(得分:2)

LSTM中的批量标准化不是那么容易实现。一些论文https://arxiv.org/pdf/1603.09025.pdf给出了一些令人惊讶的结果,称为循环批归一化。作者遵循以下等式

BATCH-NORMALIZED LSTM

不幸的是,该模型尚未在keras中实现,而仅在tensorflow https://github.com/OlavHN/bnlstm

中实现

但是,使用激活功能后的(默认)批处理规范化,我能够在没有居中和移动的情况下获得良好的结果。这种方法不同于上面在c_t和h_t之后应用BN的论文,也许值得一试。

model = Sequential()
model.add(LSTM(neurons1,
               activation=tf.nn.relu,
               return_sequences=True,
               input_shape=(timesteps, data_dim)))
model.add(BatchNormalization(momentum=m, scale=False, center=False))
model.add(LSTM(neurons2,
               activation=tf.nn.relu))
model.add(BatchNormalization(momentum=m, scale=False, center=False))
model.add(Dense(1))

答案 1 :(得分:0)

我正在使用Keras和Python但我可以尝试R.在fit方法中,文档说如果省略它默认为32。在当前版本中不再如此,因为它可以在source code中看到。我认为你应该这样试试,至少这种方式适用于Python:

mdl2 <- keras_model_sequential()
mdl2 %>%
  layer_input(input_shape = c(1, 3))  %>%

  layer_batch_normalization() %>%
  layer_lstm(units = 512, return_sequences = T, dropout=0.3) %>%

  layer_batch_normalization() %>%
  layer_lstm(units = 512, return_sequences = F, dropout=0.2) %>%

  layer_batch_normalization() %>%
  layer_dense(units = 1, activation = "linear")

mdl2 %>% compile(loss = 'mse', optimizer = 'rmsprop')
mdl2.history <- mdl2 %>% 
  fit(dt.tr, dt.tr.out, epochs=500, shuffle=F,
      validation_data = list(dt.val, dt.val.out),
      batch_size=32,
      callbacks = list(
        callback_early_stopping(min_delta = 0.000001,  patience = 10, verbose = 1)
      ))