Keras长短期记忆模型的5步生命周期
使用Keras在Python中创建和评估深度学习神经网络非常容易,但你必须遵循严格的模型生命周期。
在这篇文章中,你将了解在Keras中创建、训练和评估长期短期记忆(LSTM)递归神经网络的逐步生命周期,以及如何使用经过训练的模型进行预测。
读完这篇文章,你就会知道:
- 如何在Keras中定义、编译、拟合和评估LSTM。
- 如何为回归和分类序列预测问题选择标准默认值。
- 如何将这一切联系在一起,在Keras开发和运行你的第一个LSTM递归神经网络。
我们开始吧。
概述
下面是我们将要了解的Keras中LSTM模型生命周期中的5个步骤的概述。
- 定义网络。
- 编译网络。
- 拟合网络。
- 评估网络。
- 做出预测。
环境
本教程假设你已经安装了Python SciPy环境。在本例中,你可以使用Python2或Python3。
本教程假设你安装了Keras v2.0或更高版本以及TensorFlow或Theano后端。
本教程还假设你已经安装了SCRICKIT-Learning、Pandas、NumPy和Matplotlib。
接下来,让我们来看一个标准的时间序列预测问题,我们可以用它作为这个实验的背景。
如果你需要帮助设置Python环境,请参阅此帖子:
步骤1.定义网络
第一步是定义你的网络。
在Keras中,神经网络被定义为一系列层。这些层的容器是Sequential类。
第一步是创建Sequential类的实例。然后,你可以创建图层并按应连接的顺序添加它们。由内存单元组成的LSTM递归层称为LSTM()。通常位于LSTM层之后并用于输出预测的完全连接层称为密集()。
例如,我们可以分两步完成此操作:
model = Sequential() model.add(LSTM(2)) model.add(Dense(1))
但是,我们也可以通过创建层的数组并将其传递给Sequential的构造函数,在一步中完成此操作。
layers = [LSTM(2), Dense(1)] model = Sequential(layers)
网络中的第一层必须定义预期的输入数量。输入必须是三维的,由样本、时间步长和要素组成。
- 样本。这些是数据中的行。
- 时间步长。这些是对某个要素的过去观察,例如滞后变量。
- 特征。这些是数据中的列。
假设你的数据作为NumPy数组加载,则可以使用NumPy中的reshape()函数将二维数据集转换为三维数据集。如果希望列成为一个功能的时间点,可以使用:
data = data.reshape((data.shape[0], data.shape[1], 1))
如果希望二维数据中的列通过一个时间步长成为要素,则可以使用:
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层添加到顺序模型来堆叠LSTM层。重要的是,当堆叠LSTM层时,我们必须为每个输入输出一个序列而不是单个值,以便后续的LSTM层可以具有所需的三维输入。我们可以通过将return_sequences参数设置为True来实现这一点。例如:
model = Sequential() model.add(LSTM(5, input_shape=(2,1), return_sequences=True)) model.add(LSTM(5)) model.add(Dense(1))
把顺序模型想象成一条管道,你的原始数据在一端输入,预测在另一端输出。
这在Keras中是一个有用的容器,因为传统上与层相关联的关注点也可以被拆分并作为单独的层添加,清楚地显示了它们在将数据从输入转换为预测的过程中所起的作用。
例如,可以提取变换来自层中每个神经元的求和信号的激活函数,并将其作为称为激活的层状对象添加到序列中。
model = Sequential() model.add(LSTM(5, input_shape=(2,1))) model.add(Dense(1)) model.add(Activation('sigmoid'))
激活函数的选择对于输出层是最重要的,因为它将定义预测将采用的格式。
例如,下面是一些常见的预测性建模问题类型,以及你可以在输出层中使用的结构和标准激活函数:
- 回归:线性激活函数,或“linear”,以及与输出数量匹配的神经元数量。
- 二分类(2类):Logistic激活函数,或“sigmoid”,一个神经元作为输出层。
- 多类分类(>2类):Softmax激活函数,或“softmax”,每个类值一个输出神经元,假定为一热编码输出模式。
步骤2.编译网络
一旦我们定义了我们的网络,我们就必须编译它。
编译是一个高效的步骤。它将我们定义的简单层序列转换为一系列高效的矩阵变换,其格式将在你的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'])
步骤3.Fit网络
一旦网络被编译,它就可以进行拟合,这意味着调整训练数据集上的权重。
拟合网络需要指定训练数据,既有输入模式矩阵X,也有匹配输出模式阵列Y。
网络使用反向传播算法进行训练,并根据编译模型时指定的优化算法和损失函数进行优化。
反向传播算法要求网络被训练特定数目的epoch或暴露于训练数据集。
每个epoch可以被划分成称为批次的输入-输出模式对的组。这定义了在epoch内更新权重之前网络所暴露的模式的数量。这也是一个效率优化,确保一次不会加载太多的输入模式到内存中。
拟合网络的最小示例如下:
history = model.fit(X, y, batch_size=10, epochs=100)
一旦匹配,就会返回一个历史对象,该对象提供模型在训练期间的性能摘要。这既包括损失,也包括在编译模型时指定的任何附加指标,记录了每个时期。
训练可能需要很长时间,从几秒钟到几小时到几天不等,具体取决于网络的大小和训练数据的大小。
默认情况下,每个epoch的进度条显示在命令行上。这可能会给你带来太多噪音,或者可能会给你的环境带来问题,例如,如果你使用的是交互式笔记本或IDE。
通过将verbose参数设置为2,可以将每个epoch显示的信息量减少到仅损失。通过将verbose设置为1,可以关闭所有输出。例如:
history = model.fit(X, y, batch_size=10, epochs=100, verbose=0)
步骤4.评估网络
一旦网络经过训练,就可以对其进行评估。
可以根据训练数据来评估网络,但是这不会提供作为预测模型的网络性能的有用指示,因为它以前已经看到了所有这些数据。
我们可以在测试过程中看不到的单独数据集上评估网络性能。这将提供对网络在预测未来不可见数据方面的性能的估计。
该模型评估所有测试模式的损失,以及编译模型时指定的任何其他指标,如分类准确性。将返回评估指标列表。
例如,对于使用精度度量编译的模型,我们可以在新数据集上对其进行评估,如下所示:
loss, accuracy = model.evaluate(X, y)
与拟合网络一样,提供详细的输出以了解评估模型的进度。我们可以通过将详细参数设置为0来关闭此功能。
loss, accuracy = model.evaluate(X, y, verbose=0)
步骤5.做出预测
一旦我们对拟合模型的性能感到满意,我们就可以使用它对新数据进行预测。
这与使用一组新输入模式对模型调用predict()函数一样简单。
例如:
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个epoch,并使用等于训练集中模式数量的批量大小。我们还将关闭所有详细输出。
- 评估网络。我们将在训练数据集上评估网络。通常,我们会在测试或验证集上评估模型。
- 做出预测。我们将对训练输入数据进行预测。同样,我们通常会对我们不知道正确答案的数据进行预测。
下面提供了完整的代码清单。
# 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递归神经网络的5步生命周期。
具体地说,你了解到:
- 如何在Keras中定义、编译、拟合、评估和预测LSTM网络。
- 如何为分类和回归问题选择激活函数和输出层配置。
- 如何在Keras中开发和运行你的第一个LSTM模型。