Keras – 超参数调优模型的初始状态

我编写了一个LSTM模型来预测序列数据。

def get_model(config, num_features, output_size):    opt = Adam(learning_rate=get_deep(config, 'hp.learning_rate'), beta_1=get_deep(config, 'hp.beta_1'))    inputs = Input(shape=[None, num_features], dtype=tf.float32, ragged=True)    layers = LSTM(get_deep(config, 'hp.lstm_neurons'), activation=get_deep(config, 'hp.lstm_activation'))(        inputs.to_tensor(), mask=tf.sequence_mask(inputs.row_lengths()))    layers = BatchNormalization()(layers)    if 'dropout_rate' in config['hp']:        layers = Dropout(get_deep(config, 'hp.dropout_rate'))(layers)    for layer in get_deep(config, 'hp.dense_layers'):        layers = Dense(layer['neurons'], activation=layer['activation'])(layers)        layers = BatchNormalization()(layers)        if 'dropout_rate' in layer:            layers = Dropout(layer['dropout_rate'])(layers)    layers = Dense(output_size, activation='sigmoid')(layers)    model = Model(inputs, layers)    model.compile(loss='mse', optimizer=opt, metrics=['mse'])    model.summary()    return model

我已经调整了一些层的参数,使用了AWS SageMaker。在验证模型时,我多次运行了一个特定配置的模型。大多数时候结果相似,但有一次运行的效果明显优于其他几次,这让我认为模型的初始状态对于获得最佳性能可能至关重要。

正如这个视频中所建议的,权重初始化可以提供一些性能提升。我在网上搜索并找到了层权重初始化器,但我不确定应该调整哪些范围。


更新:正如一些评论/回答中建议的那样,我使用固定种子来“锁定”模型结果:

# 将`python`内置的伪随机生成器设置为固定值random.seed(seed_value)# 将`numpy`的伪随机生成器设置为固定值np.random.seed(seed_value)# 将`tensorflow`的伪随机生成器设置为固定值tf.random.set_seed(seed_value)

每次新的训练结果都可以复制,但是不同的种子可能会产生比其他种子更好的结果。那么我该如何找到/调整最佳种子呢?


回答:

…这让我认为模型的初始状态对于获得最佳性能可能至关重要……正如这个视频中所建议的,权重初始化可以提供一些性能提升。我在网上搜索并找到了层权重初始化器,但我不确定应该调整哪些范围。

首先,在那个视频中,除了状态或权重初始化器之外,所有其他因素如学习率、调度、优化器、批次大小、损失函数、模型深度等都是你应该尝试调整以找到最佳组合(我们稍后会讨论种子的作用)。通常,我们不需要调整默认的权重或状态初始化器,因为这些是当前最好的;而且通常,这种状态初始化是一个研究问题。

其次,中,ConvolutionDenseRNN-GRU/LSTM的默认权重初始化器是glorot_uniform,也称为Xavier均匀初始化器。默认的偏置初始化器是zeros。如果你查看LSTM源代码(在你的情况下),你会发现它们。关于这一点,根据文档

[-limit, limit]范围内的均匀分布中抽取样本,其中limit = sqrt(6 / (fan_in + fan_out))fan_in是权重张量中的输入单元数量,fan_out是输出单元数量)。

现在,你可能已经注意到这个初始化器继承自VarianceScaling;与GlorotUniform相同,GlorotNormal, LecunNormal, LecunUniform, HeNormal, HeUniform等也是继承自它的。对于VarianceScaling这里列出了支持的参数。例如,从技术上讲,以下两个是相同的。

# 如果你想尝试各种初始化器 - # 使用VarianceScaling传递适当的参数。 # 即。tf.keras.layers.LSTM(..., kernel_initializer=initializer)# 但建议坚持使用glorot_uniform(默认)initializer = tf.keras.initializers.VarianceScaling(scale=1.,                                                     mode='fan_avg', seed=101,                                                    distribution='uniform')print(initializer(shape=(2, 2)))initializer = tf.keras.initializers.GlorotUniform(seed=101)print(initializer(shape=(2, 2)))tf.Tensor([[-1.0027379  1.0746485] [-1.2234    -1.1489409]], shape=(2, 2), dtype=float32)tf.Tensor([[-1.0027379  1.0746485] [-1.2234    -1.1489409]], shape=(2, 2), dtype=float32)

简而言之,你可以使用tf.keras.initializers.VarianceScaling(在页面底部)进行尝试。此外,你可以通过定义可调用函数或通过子类化Initializer类来创建自己的初始化器。例如:

def conv_kernel_initializer(shape, dtype=None):  kernel_height, kernel_width, _, out_filters = shape  fan_out = int(kernel_height * kernel_width * out_filters)  return tf.random.normal(      shape, mean=0.0, stddev=np.sqrt(2.0 / fan_out), dtype=dtype)def dense_kernel_initializer(shape, dtype=None):  init_range = 1.0 / np.sqrt(shape[1])  return tf.random.uniform(shape, -init_range, init_range, dtype=dtype)

这里有一篇关于权重初始化的好文章,你可能会喜欢阅读。但同样,最好还是使用默认的初始化器。

第三,对于设置不同的种子值和不同的超参数集等,我最好留下我之前的一个回答这里,主要是第一张图表可能会对你的实验有帮助。我遵循的一个方法是保持我的种子相同(比如前5次实验),然后改变另一个因素并记录结果。经过5次迭代后,我们希望能得到一些最佳组合,并进一步探索。


更新

查找/调整种子。在寻找查找最佳种子的方法之前,必须理解种子不是需要与其他超参数(如学习率、调度器、优化器等)一起调整的超参数

这里有一个场景,假设你使用种子42随机将数据分为两部分:训练集(70%)和测试集(30%),然后在训练集上训练后,你在模型的测试集上评估并获得了80分。然后你将种子改为101,再次进行相同的操作,但这次你得到了50分。现在,这并不意味着选择种子42更好;但这仅仅意味着你的模型不稳定,很可能在未见过的数据上表现不佳。这实际上是一个众所周知的问题,如果有人随机分割他们的数据集进行训练和测试。为什么会发生这种情况?因为当你随机分割数据时,可能存在类分布的不匹配。请查看以下两个非常相关的讨论:

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注