我想知道是否有人知道如何设置 LSTM 模型的种子,以便我们可以获得可重现的模型?在这种情况下,每次运行代码时,我的 MSE 和 RMSE 总是不断变化。
到目前为止,我的代码如下:
######################################################################################
import tensorflow as tf
import random as rn
os.environ['PYTHONHASHSEED'] = '0'
# Setting the seed for numpy-generated random numbers
np.random.seed(37)
# Setting the seed for python random numbers
rn.seed(1254)
# Setting the graph-level random seed.
tf.random.set_seed(89)
from keras import backend as K
session_conf = tf.compat.v1.ConfigProto(
intra_op_parallelism_threads=1,
inter_op_parallelism_threads=1)
#Force Tensorflow to use a single thread
sess = tf.compat.v1.Session(graph=tf.compat.v1.get_default_graph(), config=session_conf)
tf.compat.v1.keras.backend.set_session(sess)
######################################################################################
# define model
#reset_seeds()
model = Sequential()
model.add(LSTM(200, activation='relu', input_shape=(n_steps, n_features)))
model.add(Dense(1))
model.compile(optimizer='adam', loss='mse')
# fit model
#reset_seeds()
model.fit(X, y, epochs=50, verbose=0, shuffle=False)
model.reset_states()
#reset_seeds()
yhat = model.predict(X, verbose=0)
m = yhat.shape[0]
print("MSE: ", (1/m) * np.sum(np.square(np.subtract(y, yhat))))
print("RMSE: ", np.sqrt((1/m) * np.sum(np.square(np.subtract(y, yhat)))))
我遵循了谷歌上的许多指南,但我就是找不到一个可以让我的 LSTM 模型可重现的指南。谢谢!
首先,LSTM(ANN 的常用参数集)的权重之间存在差异,默认情况下,它们也由 Glorot 初始化,也称为 Xavier 初始化器(如问题中提到的)。
一个不同的方面是细胞状态和 LSTM 的初始循环输入的状态。它们由通常表示为
initial_state
的矩阵初始化。
留给我们的问题是,如何初始化这个
initial_state
:
- 如果初始化的影响较低,那么零状态初始化是一种很好的做法
初始化 RNN 状态的默认方法是使用零状态。这通常效果很好,特别是对于诸如语言建模之类的序列到序列任务,其中受初始状态显着影响的输出比例很小。
- 每批中的零状态初始化可能会导致过度拟合
每个批次的零初始化将导致以下结果:序列到序列模型的早期步骤(即状态重置后立即的损失)将比后面步骤的损失更大,因为历史记录较少。因此,它们在学习过程中对梯度的贡献会相对较高。但如果所有状态重置都与零状态相关,则模型可以(并且将会)学习如何精确补偿这一点。随着状态重置与总观测值的比率增加,模型参数将越来越多地调整到该零状态,这可能会影响后续时间步骤的性能。
- 我们还有其他选择吗?
一个简单的解决方案是使初始状态变得有噪声(以减少第一个时间步的损失)。在这里查看详细信息和其他想法
我也有这个问题,但我仍然不明白如何设置 LSTM 模型的种子以设置我的模型可重现。 (在 keras 中重新训练后,它应该具有相同的指标)