原文: https://machinelearningmastery.com/5-step-life-cycle-long-short-term-memory-models-keras/
使用 Keras 在 Python 中创建和评估深度学习神经网络非常容易,但您必须遵循严格的模型生命周期。
在这篇文章中,您将发现在 Keras 中创建,训练和评估长期短期记忆(LSTM)循环神经网络的分步生命周期,以及如何使用训练有素的模型做出预测。
阅读这篇文章后,你会知道:
- 如何在 Keras 中定义,编译,拟合和评估 LSTM。
- 如何为回归和分类序列预测问题选择标准默认值。
- 如何将它们联系起来,在 Keras 开发和运行您的第一个 LSTM 循环神经网络。
让我们开始吧。
- 2017 年 6 月更新:修复输入大小调整示例中的拼写错误。
Keras 长期短期记忆模型的 5 步生命周期 照片由 docmonstereyes 拍摄,保留一些权利。
下面概述了我们将要研究的 Keras LSTM 模型生命周期中的 5 个步骤。
- 定义网络
- 编译网络
- 适合网络
- 评估网络
- 作出预测
本教程假定您已安装 Python SciPy 环境。您可以在此示例中使用 Python 2 或 3。
本教程假设您安装了 TensorFlow 或 Theano 后端的 Keras v2.0 或更高版本。
本教程还假设您安装了 scikit-learn,Pandas,NumPy 和 Matplotlib。
接下来,让我们看看标准时间序列预测问题,我们可以将其用作此实验的上下文。
如果您在设置 Python 环境时需要帮助,请参阅以下帖子:
第一步是定义您的网络。
神经网络在 Keras 中定义为层序列。这些层的容器是 Sequential 类。
第一步是创建 Sequential 类的实例。然后,您可以创建层并按照它们应连接的顺序添加它们。由存储器单元组成的 LSTM 复现层称为 LSTM()。通常跟随 LSTM 层并用于输出预测的完全连接层称为 Dense()。
例如,我们可以分两步完成:
model = Sequential()
model.add(LSTM(2))
model.add(Dense(1))
但是我们也可以通过创建一个层数组并将其传递给 Sequential 的构造函数来一步完成。
layers = [LSTM(2), Dense(1)]
model = Sequential(layers)
网络中的第一层必须定义预期的输入数量。输入必须是三维的,包括样本,时间步和特征。
- 样品。这些是数据中的行。
- 时间步。这些是过去对特征的观察,例如滞后变量。
- 功能。这些是数据中的列。
假设您的数据作为 NumPy 数组加载,您可以使用 NumPy 中的 reshape()函数将 2D 数据集转换为 3D 数据集。如果您希望列成为一个功能的时间步长,您可以使用:
data = data.reshape((data.shape[0], data.shape[1], 1))
如果您希望 2D 数据中的列成为具有一个时间步长的要素,则可以使用:
data = data.reshape((data.shape[0], 1, data.shape[1]))
您可以指定 input_shape 参数,该参数需要包含时间步数和要素数的元组。例如,如果我们有两个时间步长和一个特征用于单变量时间序列,每行有两个滞后观察值,则将指定如下:
model = Sequential()
model.add(LSTM(5, input_shape=(2,1)))
model.add(Dense(1))
可以通过将 LSTM 层添加到 Sequential 模型来栈式 LSTM 层。重要的是,在栈式 LSTM 层时,我们必须为每个输入输出一个序列而不是一个值,以便后续的 LSTM 层可以具有所需的 3D 输入。我们可以通过将 return_sequences 参数设置为 True 来完成此操作。例如:
model = Sequential()
model.add(LSTM(5, input_shape=(2,1), return_sequences=True))
model.add(LSTM(5))
model.add(Dense(1))
将 Sequential 模型视为一个管道,将原始数据输入到最后,预测从另一个输出。
这在 Keras 中是一个有用的容器,因为传统上与层相关的关注点也可以拆分并作为单独的层添加,清楚地显示它们在从输入到预测的数据转换中的作用。
例如,可以提取转换来自层中每个神经元的求和信号的激活函数,并将其作为称为激活的层状对象添加到 Sequential 中。
model = Sequential()
model.add(LSTM(5, input_shape=(2,1)))
model.add(Dense(1))
model.add(Activation('sigmoid'))
激活函数的选择对于输出层是最重要的,因为它将定义预测将采用的格式。
例如,下面是一些常见的预测性建模问题类型以及可以在输出层中使用的结构和标准激活函数:
- 回归:线性激活函数,或“线性”,以及与输出数量匹配的神经元数量。
- 二分类(2 类):Logistic 激活函数,或'sigmoid',以及一个神经元输出层。
- 多分类(> 2 类):假设单热编码输出模式,Softmax 激活函数或'softmax',以及每类值一个输出神经元。
一旦我们定义了网络,我们就必须编译它。
编译是一个效率步骤。它将我们定义的简单层序列转换为高效的矩阵变换系列,其格式应在 GPU 或 CPU 上执行,具体取决于 Keras 的配置方式。
将编译视为网络的预计算步骤。定义模型后始终需要它。
编译需要指定许多参数,专门用于训练您的网络。具体地,用于训练网络的优化算法和用于评估由优化算法最小化的网络的损失函数。
例如,下面是编译定义模型并指定随机梯度下降(sgd)优化算法和均值误差(mean_squared_error)损失函数的情况,用于回归类型问题。
model.compile(optimizer='sgd', loss='mean_squared_error')
或者,可以在作为编译步骤的参数提供之前创建和配置优化程序。
algorithm = SGD(lr=0.1, momentum=0.3)
model.compile(optimizer=algorithm, loss='mean_squared_error')
预测性建模问题的类型对可以使用的损失函数的类型施加约束。
例如,下面是不同预测模型类型的一些标准损失函数:
- 回归:均值平方误差或'mean_squared_error'。
- 二分类(2 类):对数损失,也称为交叉熵或“binary_crossentropy”。
- 多分类(> 2 类):多类对数损失或'categorical_crossentropy'。
最常见的优化算法是随机梯度下降,但 Keras 还支持一套其他最先进的优化算法,这些算法在很少或没有配置的情况下都能很好地工作。
也许最常用的优化算法因为它们通常具有更好的表现:
- 随机梯度下降或'sgd',需要调整学习速度和动量。
- ADAM 或'adam',需要调整学习率。
- RMSprop 或'rmsprop',需要调整学习率。
最后,除了损失函数之外,您还可以指定在拟合模型时收集的度量标准。通常,要收集的最有用的附加度量标准是分类问题的准确率。要收集的度量标准由数组中的名称指定。
例如:
model.compile(optimizer='sgd', loss='mean_squared_error', metrics=['accuracy'])
一旦网络被编译,它就可以适合,这意味着在训练数据集上调整权重。
安装网络需要指定训练数据,包括输入模式矩阵 X 和匹配输出模式数组 y。
使用反向传播算法训练网络,并根据编译模型时指定的优化算法和损失函数进行优化。
反向传播算法要求网络训练指定数量的时期或暴露于训练数据集。
每个迭代可以被划分为称为批次的输入 - 输出模式对的组。这定义了在一个迭代内更新权重之前网络所接触的模式数。它也是一种效率优化,确保一次不会将太多输入模式加载到内存中。
拟合网络的最小例子如下:
history = model.fit(X, y, batch_size=10, epochs=100)
适合后,将返回历史对象,该对象提供训练期间模型表现的摘要。这包括损失和编译模型时指定的任何其他指标,记录每个迭代。
训练可能需要很长时间,从几秒到几小时到几天,具体取决于网络的大小和训练数据的大小。
默认情况下,每个迭代的命令行上都会显示一个进度条。这可能会给您带来太多噪音,或者可能会给您的环境带来问题,例如您使用的是交互式笔记本电脑或 IDE。
通过将详细参数设置为 2,可以减少每个时期显示的信息量。您可以通过将详细设置为 1 来关闭所有输出。例如:
history = model.fit(X, y, batch_size=10, epochs=100, verbose=0)
一旦网络被训练,就可以对其进行评估。
可以在训练数据上评估网络,但是这不会提供作为预测模型的网络表现的有用指示,因为它之前已经看到了所有这些数据。
我们可以在测试期间看不到的单独数据集上评估网络的表现。这将提供对网络表现的估计,以便对未来看不见的数据做出预测。
该模型评估所有测试模式的损失,以及编译模型时指定的任何其他指标,如分类准确率。返回评估指标列表。
例如,对于使用精度度量编制的模型,我们可以在新数据集上对其进行评估,如下所示:
loss, accuracy = model.evaluate(X, y)
与拟合网络一样,提供详细输出以了解评估模型的进度。我们可以通过将 verbose 参数设置为 0 来关闭它。
loss, accuracy = model.evaluate(X, y, verbose=0)
一旦我们对拟合模型的表现感到满意,我们就可以使用它来预测新数据。
这就像使用新输入模式数组调用模型上的 predict()函数一样简单。
For example:
predictions = model.predict(X)
预测将以网络输出层提供的格式返回。
在回归问题的情况下,这些预测可以是直接问题的格式,由线性激活函数提供。
对于二分类问题,预测可以是第一类的概率数组,其可以通过舍入转换为 1 或 0。
对于多分类问题,结果可以是概率数组的形式(假设单热编码输出变量),可能需要使用 argmax()NumPy 函数将其转换为单个类输出预测。
或者,对于分类问题,我们可以使用 predict_classes()函数,该函数会自动将 uncrisp 预测转换为清晰的整数类值。
predictions = model.predict_classes(X)
与拟合和评估网络一样,提供详细输出以给出模型预测的进度的概念。我们可以通过将 verbose 参数设置为 0 来关闭它。
predictions = model.predict(X, verbose=0)
让我们将所有这些与一个小例子结合起来。
这个例子将使用一个学习 10 个数字序列的简单问题。我们将向网络显示一个数字,例如 0.0,并期望它预测为 0.1。然后显示它 0.1 并期望它预测 0.2,依此类推到 0.9。
- 定义网络:我们将构建一个 LSTM 神经网络,在可见层有 1 个输入时间步长和 1 个输入特征,LSTM 隐藏层有 10 个存储单元,在完全连接的输出层有 1 个神经元线性(默认)激活功能。
- 编译网络:我们将使用具有默认配置和均方误差丢失函数的高效 ADAM 优化算法,因为它是一个回归问题。
- 适合网络:我们将使网络适合 1,000 个时期,并使用等于训练集中模式数量的批量大小。我们还将关闭所有详细输出。
- 评估网络。我们将在训练数据集上评估网络。通常,我们会在测试或验证集上评估模型。
- 制作预测。我们将对训练输入数据做出预测。同样,通常我们会对我们不知道正确答案的数据做出预测。
完整的代码清单如下。
# Example of LSTM to learn a sequence
from pandas import DataFrame
from pandas import concat
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
# create sequence
length = 10
sequence = [i/float(length) for i in range(length)]
print(sequence)
# create X/y pairs
df = DataFrame(sequence)
df = concat([df.shift(1), df], axis=1)
df.dropna(inplace=True)
# convert to LSTM friendly format
values = df.values
X, y = values[:, 0], values[:, 1]
X = X.reshape(len(X), 1, 1)
# 1\. define network
model = Sequential()
model.add(LSTM(10, input_shape=(1,1)))
model.add(Dense(1))
# 2\. compile network
model.compile(optimizer='adam', loss='mean_squared_error')
# 3\. fit network
history = model.fit(X, y, epochs=1000, batch_size=len(X), verbose=0)
# 4\. evaluate network
loss = model.evaluate(X, y, verbose=0)
print(loss)
# 5\. make predictions
predictions = model.predict(X, verbose=0)
print(predictions[:, 0])
运行此示例将生成以下输出,显示 10 个数字的原始输入序列,对整个序列做出预测时网络的均方误差损失以及每个输入模式的预测。
输出间隔开以便于阅读。
我们可以看到序列被很好地学习,特别是如果我们将预测舍入到第一个小数位。
[0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
4.54527471447e-05
[ 0.11612834 0.20493418 0.29793766 0.39445466 0.49376178 0.59512401
0.69782174 0.80117452 0.90455914]
- 顺序模型的 Keras 文档。
- LSTM 层的 Keras 文档。
- Keras 优化算法文档。
- Keras 损失函数文档。
在这篇文章中,您使用 Keras 库发现了 LSTM 循环神经网络的 5 步生命周期。
具体来说,你学到了:
- 如何在 Keras 中为 LSTM 网络定义,编译,拟合,评估和预测。
- 如何为分类和回归问题选择激活函数和输出层配置。
- 如何在 Keras 开发和运行您的第一个 LSTM 模型。
您对 Keras 的 LSTM 型号有任何疑问,或者关于这篇文章? 在评论中提出您的问题,我会尽力回答。