我们应该如何规范 LSTM 模型?

人工智能 循环神经网络 长短期记忆 过拟合 正则化 辍学
2021-11-09 04:30:17

如果我是正确的,LSTM 层有五个参数用于正则化。

为了处理过度拟合,我会从

  1. 减少层数
  2. 减少隐藏单元
  3. 应用 dropout 或正则化器。

kernel_regularizerrecurrent_regularizerbias_regularizeractivity_regularizer_dropoutrecurrent_dropout

他们在 Keras 的网站上有自己的定义,但是任何人都可以分享更多关于如何减少过度拟合的经验吗?

这五个参数是如何使用的?例如,哪些参数最常用,应该输入什么样的值??

3个回答

除非您有大量数据,否则一个 LSTM 层就足够了。层中的节点数量也是如此。先从小处开始,从 5 到 10 个节点开始递增,直到性能合理为止。

一旦你有一个模型工作,如果你认为它可以通过减少训练数据的过度拟合来提高性能,你可以应用正则化。您可以通过查看学习曲线或压缩验证集和测试集的错误来检查这一点。

在我的实验中,我使用了 L1 和 L2 正则化器以及 dropout。这些都可以混合在一起,实际上同时使用 L1 和 L2 被称为 ElasticNet。

我倾向于在 上应用正则化器,kernel_regularizer因为这会影响输入的权重。基本上是特征选择。

L1 和 L2 的值可以从默认值(对于 tensorflow)0.01 开始,并根据您认为合适的方式更改它或阅读其他研究论文所做的事情。

Dropout 可以从 0.1 开始,然后递增,直到没有性能提升。这基本上是一个百分比,因此 0.1 将删除大约 10% 的节点。

寻找最佳正则化器与任何其他超参数优化相同,主要是反复试验。

如果是上面提到的,那可能是在 lstm 网络的背景下。我建议使用 keras 调谐器贝叶斯优化器并将 l1 或 l2 数字作为内核空间的参数。通过这种方式,您可以找到最佳值,并且是超调的好方法。请记住,如果我没记错的话,参数或内核的范围越大,您需要的计算机能力就越高。

from tensorflow import keras
import keras_tuner as kt

def model1(hp):
  model=Sequential()
  model.add(keras.layers.LSTM(units=hp.Int('units',min_value=40, max_value=800, step=20),
                              dropout=hp.Float('droput',min_value=0.15, max_value=0.99, step=0.05),
                              recurrent_dropout=hp.Float('redroput',min_value=0.05, max_value=0.99, step=0.05),
                              activation='relu',
                              return_sequences=True,
                              input_shape=(30,1)))
  Attention()
  model.add(keras.layers.LSTM(units=hp.Int('units',min_value=40, max_value=800, step=20),
                              dropout=hp.Float('droput',min_value=0.15, max_value=0.99, step=0.05),
                              activation='relu',return_sequences=True))
  Attention()
  model.add(keras.layers.LSTM(units=hp.Int('units',min_value=40, max_value=800, step=20), activation='relu'))
  model.add(keras.layers.Dense(1))
  
  model.compile(loss='mean_squared_error',optimizer=tf.keras.optimizers.Adam(hp.Choice('learning_rate', values=[1e-2, 1e-3, 1e-4, 1e-7, 1e-10])))
  return model

bayesian_opt_tuner = kt.BayesianOptimization(
    model1,
    objective='val_loss',
    max_trials=200,
    executions_per_trial=1,
    project_name='timeseries_bayes_opt_POC',
    overwrite=True,)

xval=X_test
bayesian_opt_tuner.search(x=X_train ,y=X_train, 
             epochs=300,
             #validation_data=(xval ,xval),
             validation_split=0.95,
             validation_steps=30,  
             steps_per_epoch=30,
             callbacks=[tf.keras.callbacks.EarlyStopping(monitor='val_loss', 
                              patience=4,
                              verbose=1,
                              restore_best_weights=True),
                        tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', 
                                   factor=0.1, 
                                   patience= 2, 
                                   verbose=1, 
                                   min_delta=1e-5, 
                                   mode='min')]
             )
This is where the magic happens. Something I composed myself. If interested holla 

正则化试图阻止学习复杂信息,因此我们希望从实际学习中消除模型以记忆训练数据。我们不想学习不能很好地泛化到测试数据的训练数据的非常具体的精确点。

辍学,辍学的想法是,在训练期间,我们随机将隐藏神经元的一些激活设置为零,概率为 0.5。这个想法非常强大,因为它允许网络降低其容量,它也使得网络无法通过网络建立这些记忆通道,它试图只记住数据,因为在每次迭代中 50% 的数据将被消灭,因此它不仅将被迫更好地泛化,而且将被迫通过网络拥有多个通道,并为其预测建立更强大的表示。

提前停止,当网络在训练期间提高其性能时,会出现训练数据开始偏离测试数据的点,在某个时候,网络将开始在其训练数据上比其测试数据做得更好,什么这基本上意味着网络开始记住一些训练数据,这就是你不想要的,所以我们可以做的是我们可以确定测试数据开始增加并偏离训练数据的这个拐点,所以我们可以提前停止网络,并确保我们的测试准确性尽可能低。