LSTM是一种时间递归神经网络,适合于处理和预测时间序列中间隔和延迟相对较长的重要事件。在自然语言处理、语言识别等一系列的应用上都取得了很好的效果。
《Long Short Term Memory Networks with Python》是澳大利亚机器学习专家Jason Brownlee的著作,里面详细介绍了LSTM模型的原理和使用。
该书总共分为十四个章节,具体如下:
第一章:什么是LSTMs?
第二章:怎么样训练LSTMs?
第三章:怎么样准备LSTMs的数据?
第四章:怎么样在Keras中开发LSTMs?
第五章:序列预测建模
第六章:如何开发一个Vanilla LSTM模型?
第七章:怎么样开发Stacked LSTMs?
第八章:开发CNN LSTM模型(本期内容)
第九章:开发Encoder-Decoder LSTMs
第十章:开发Bidirectional LSTMs
第十一章:开发生成LSTMs
第十二章:诊断和调试LSTMs(本期内容)
第十三章:怎么样用LSTMs做预测?(下周一发布)
第十四章:更新LSTMs模型
本文的作者对此书进行了翻译整理之后,分享给大家,本文是第十二期内容。
我们还将继续推出一系列的文章来介绍里面的详细内容,和大家一起来共同学习。
12.0 前言
12.0.1 课程目标
本课程的目标是学习怎么样调优LSTM超参数。完成本课程之后,你将会学到:怎么样开发一个针对你的LSTM模型学习能力的健壮的评估;
怎么样使用学习曲线来诊断你的LSTM模型的行为;
怎么样调整LSTM模型的框架、结构和学习行为。
12.0.2 课程概览
本课程被分为5个部分,它们是:评估LSTM模型;
诊断过拟合和欠拟合;
调优问题的框架;
调优模型结构;
调优学习行为。
让我们开始吧!
12.1 评估LSTM模型
在本章节中,你将发现用于开发对未知数据的LSTM模型的学习能力的文件估计的过程。
12.1.1 初学者的错误
你将模型拟合到你的训练数据并在测试数据集上进行评估,然后报告该学习能力。也许你用K折交叉验证来评估模型,然后报告模型的学习能力。这是初学者犯的错误。
看起来你做的是正确的事情,但是一个关键问题是你没有考虑过:深度学习模型是随机的。人工神经网络(如LSTM)在数据集上使用的随机性,例如在随机梯度下降期间每个训练周期的随机初始权重和数据的随机洗牌。这意味着,每次相同的模型适合于相同的数据,它可以给出不同的预测,进而具有不同的整体技能。
12.1.2 评估模型学习能力
我们没有所有可能的数据;如果我们做了,我们就不需要做预测。我们有一个有限的数据样本,从中我们需要发现最好的模型。
我通过将数据分割成两个部分,即对数据的第一部分进行模型或者特定模型配置,并使用拟合模型对其余部分进行预测,然后评估这些预测的技巧。这被称为训练-测试分割,我们使用这一技巧来估计模型在预测新数据时在实践中的表现。例如,这里有一些伪代码用于使用训练-测试分割来评估模型:train, test = random_split(data)
model = fit(train.X, train.y)
predictions = model.predict(test.X)
skill = compare(test.y, predictions)
表 12.1 评估模型技能的伪代码
如果你有很多的数据或者一个很慢的模型来训练,训练-测试分割是一个很好的方法,但是,由于数据中的随机性(模型的方差),模型的技能得分将是嘈杂的。这意味着相同的模型在不同数据上的拟合将会给不同模型技能分数。如果我们有资源,我们将会使用k折交叉验证。但是,在深度学习中使用大数据集合训练模型的速度慢,这通常是不可能的。
12.1.3 评估一个随机模型的技能
随机模型,如深度神经网络,添加一个额外的随机性来源。这种附加的随机性使得模型在学习时具有更高的灵活性,但可以使模型不太稳定(例如,当同一模型在同一数据上训练时会有不同的结果)。这是不同的模型方差,当不同的数据训练相同的模型时,给出不同的结果。
为了得到一个随机模型的技能的鲁棒估计,我们必须考虑这个额外的方差来源,我们必须控制它。一种稳健的方法是重复多次随机模型的评估实验。例如:scores = list()
for i in repeats:
train, test = random_split(data)
model = fit(train.X, train.y)
predictions = model.predict(test.X)
skill = compare(test.y, predictions)
scores.append(skill)
final_skill = mean(scores)
表 12.2 评估随机模型技能的伪代码
这是我推荐的用于评估深度学习模型的模型技能的伪代码。
12.1.4 神经网络有多步稳定?
这取决于你的问题,取决于网络,以及它的配置。我建议进行敏感性分析来找出答案。在同一数据上对同一模型进行多次评估(30,100次或者数千次),只改变了随机数生成器的种子。然后回顾所产生的技能得分的平均值和标准差。标准差(平均得分与平均分数的距离)会让你知道你的模型有多不稳定。
12.1.5 多少次循环?
我建议至少30次,或许100次,甚至是上千次,限制的因素只有你的时间和电脑的资源(例如,平均技能的标准错误)。更严格地说,我将推荐一个实验,该实验着眼于估计模型技能对重复次数和标准误差计算的影响(平均估计性能与真实基础种群平均值的差异)。
12.1.6 模型估计之后
评估你的模型是达到目的的一种手段。它帮助你选择使用哪个模型以及使用哪些超参数来配置它。一旦你选择了一个模型,你就必须初始化它。这包括将模型拟合在所有可能的数据上,并保存在以后用于预测新数据的位置上,我们不知道实际结果。在后面的章节中,我们将更详细地介绍模型最终的过程。
12.2 诊断欠拟合和过拟合
在本章节中,你将会发现如何在训练期间使用LSTM模型的学习曲线图来诊断多拟合和欠拟合。
12.2.1 在Keras中训练历史
你可以通过回顾模型的性能来了解模型的行为。通过调用fit()函数来训练LSTM模型。此函数返回一个名为history的变量,它包括损失的踪迹以及在编译模型期间指定的任何其他度量。这些分数记录在每一个周期的末尾。...
history = model.fit(...)
表 12.3 在拟合一个LSTM模型之后分配历史的例子
例如,如果你的模型被编译来优化对数损失(binary_crossentropy)并衡量每个周期的准确率,那么对数损失和准确率将被计算并记录在每个训练周期的历史轨迹中。每一个分数由调用fit()函数返回。默认情况下,当拟合模型被称为损失和准确率时,损失被称为acc。...
model.compile(loss= 'binary_crossentropy' , optimizer= adam , metrics=[ 'accuracy' ])
history = model.fit(X, Y, epochs=100)
print(history.history[ 'loss' ])
print(history.history[ 'acc' ])
表 12.4 在拟合LSTM模型之后打印历史的例子
Keras还允许你指定一个单独的验证数据集,同时也可以使用相同的损失和度量来评估模型。这可以通过在fit()函数上设置validation_split参数来实现,将训练数据的一部分用作验证数据集(特别是0到1之间的常量)。...
history = model.fit(X, Y, epochs=100, validation_split=0.33)
表 12.5 在训练数据子集计算验证损失的例子历史
这也可以通过设置验证数据参数和传递X和y数据集的元组来完成。...
history = model.fit(X, Y, epochs=100, validation_data=(valX, valY))
表 12.6 在新数据集上包含验证损失的例子历史
在验证数据集上评估的度量使用相同的名称和val_前缀。...
model.compile(loss= binary_crossentropy , optimizer= adam , metrics=[ accuracy ])
history = model.fit(X, Y, epochs=100, validation_split=0.33)
print(history.history[ 'loss' ])
print(history.history[ 'acc' ])
print(history.history[ 'val_loss' ])
print(history.history[ 'val_acc' ])
表 12.7 打印训练和验证损失和准确率的例子
12.2.2 诊断图
你的LSTM模型的训练历史可以用来诊断模型的行为。可以使用Matplotlib库绘制模型的性能。例如,你可以将训练损失和测试损失计分如下:from m