【翻译2】The 5 Step Life-Cycle for Long Short-Term Memory Models in Keras

目录

  • Step 1. Define Network
  • Step 2. Compile Network
  • Step 3. Fit Network
  • Step 4. Evaluate Network
  • Step 5. Make Predictions
  • End-to-End Worked Example
  • Further Reading
  • Summary

文章讲解目标:

  • 如何定义,编译,拟合,并评估一个 Keras 中的 LSTM 神经网络。
  • 如何为回归和分类序列预测问题选择标准缺省值。
  • 如何将所有这些结合起来开发和运行一个 LSTM 循环神经网络。

原文链接

Step 1. Define Network

第一步是定义神经网络。

神经网络在 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)

网络的第一层必须定义期望的输入数量。输入必须是三维的,包括样本,时间步和特征

  • Samples: 这些是数据中的行(rows)。
  • Timesteps: 这些是特征过去的观察结果,例如滞后变量。These are the past observations for a feature, such as lag variables.
  • Features: 这些是数据中的列(columns)。

假设数据作为NumPy数组加载,则可以使用NumPy中的reshape()函数将2D数据集转换为3D数据集。如果想要列成为一个特征的时间步(If you would like columns to become timesteps for one feature, ),则可以使用:

data = data.reshape((data.shape[0], data.shape[1], 1))

如果希望二维数据中的列成为一个时间步的特征(If you would like columns in your 2D data to become features with one timestep, ),则可以使用:

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层可以具有所需的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))

可以将顺序模型视为一条管道,输入原始数据,而另一端则输出预测。

这在Keras中是一个有用的容器,因为传统上与一个层相连的点可以被分离并添加为单独的层,清楚地显示它们在数据从输入转换为预测中的作用。

例如,可以对一层中的神经元的累加信号进行转换的激活函数可以被提取出来并添加到序列当中,成为一种叫做激活层的层状对象。

model = Sequential()
model.add(LSTM(5, input_shape=(2,1)))
model.add(Dense(1))
model.add(Activation('sigmoid'))

对输出层来说激活函数的选择是最重要的,因为它将定义预测将采用的形式。

例如,下面是一些常见的预测模型问题类型以及你在输出层可以采用的结构和标准激活函数。

  • 回归-Regression: 线性激活函数(linear),并且神经元数量与输出数量相匹配。
  • 二分类-Binary Classification(2 class): Logistic激活函数(sigmoid),输出层有一个神经元。
  • 多类分类-Multiclass Classification(>2 class): Softmax激活函数(softmax),每个类值有一个输出神经元,假设是一个one-hot编码模式。

Step 2. Compile Network

一旦定义好网络,我们必须编译它。
编译是一个高效的步骤。它将我们定义的层的简单序列转换为一系列高效的矩阵变换,以一种可以在GPU或CPU上执行的格式,具体取决于Keras是如何配置。

可以将编译看作是网络的预计算步骤。在定义模型之后总是需要它。

编译需要指定许多参数,这些参数专门 为训练你的网络而定制。特别是用于训练网络的优化算法和用于评估网络是否已被优化算法实现误差最小化的损失函数。

例如,下面是一个编译定义好的模型案例,它指定随机梯度下降(sgd)优化算法和均方差(man_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')

预测建模问题的类型限制了可以使用的损失函数的类型。
例如,下面是一些针对不同预测模型类型的标准损失函数。

  • Regression: 均方差(mean_squared_error)
  • Binary Classification(2 class): 对数损失(Logarithmic Loss),也称为交叉熵(cross entropy)或二进制交叉熵(binary_crossentropy)
  • Multiclass Classification(>2 class): 多类对数损失(Multiclass Logarithmic Loss)或分类交叉熵(categorical_crossentropy)

最常见的优化算法是随机梯度下降(stochastic gradient descent),但Keras也支持一套其他最先进的优化算法,这些算法在很少或没有配置的情况下也能很好的工作。
最常用的整体表现更好的优化算法是:

  • Stochastic Gradient Descent : 随机梯度下降(sgd),需要调整学习速率和动量。
  • ADAM: 这需要调整学习速率。
  • RMSprop: 同上。

最后,除了损失函数,你还可以指定在拟合模型时要收集的指标。通常,要收集的最有用的额外指标是分类问题的准确率。要收集的指标可以数组中通过名称确定。
例如:

model.compile(optimizer='sgd', loss='mean_squared_error', metrics=['accuracy'])

Step 3. Fit Network

一旦网络编译完成,就可以进行拟合,这意味着在训练数据集上调整权重。

拟合网络需要指定训练数据,包含输入模式的矩阵,X,和一个匹配的输出模式的数组,Y

网络通过反向传播算法进行训练,并且在编译模型的时候通过指定的优化算法和损失函数进行优化。

反向传播算法需要神经网络对训练数据集进行特定次数的训练。

每个epoch都可以划分称为批(batch)的输入-输出组。这定义了在一个epoch中权值更新之前网络所暴露出的模式的数量。这也是一种效率优化,确保一次不会加载太多的输入模式到内存中。

拟合网络的小例子如下:

history = model.fit(X, y, batch_size=10, epochs=100)

拟合之后,将返回一个历史对象,该对象提供了模型在训练期间性能的概况。这包含拟合模型时的损失和其他指定的附加指标,在每个epoch都会记录。

默认情况下,每一次epoch会在命令行上显示一个进度条。这可能会给你带来太多噪音,或者可能给你的环境造成问题,例如你在一个交互式环境或者IDE中。

你可以减少显示的信息量到仅剩每个epoch的loss,通过将verbose参数设置为2。你可以通过将verbose参数设置为1关闭所有的信息输出。

例如:

history = model.fit(X, y, batch_size=10, epochs=100, verbose=0)

Step 4. Evaluate Network

一旦训练好模型,就可以对其进行评估。

神经网络可以根据训练数据进行评估,但是这不能对这个神经网络作为预测模型的性能提供有用信息,因为它之前已经看到了所有数据。

我们可以在一个单独的数据集上评估网络的性能,这个数据集在测试过程中是看不到的。这将提供一个神经网络在将来预测看不到的数据的性能的评估。

这个模型评估所有训练模式的loss,以及编译模型时指定的一些其他指标,像分类精度。返回一个评估指标的列表。

例如,对于用精度指标编译的模型,我们可以像下面在一个新的数据集上评估它:

loss, accuracy = model.evaluate(X, y)

与拟合模型一样,将显示冗长的信息输出以反映评估模型的进度。我们可以将verbose参数设置为0来关闭它。

loss, accuracy = model.evaluate(X, y, verbose=0)

Step 5. Make Predictions

一旦我们对拟合模型的性能满意,我们 可以用它在新的数据上预测。
例如:

predictions = model.predict(X)

预测结果将以神经网络输出层提供的格式返回。

在回归问题的情况下,这些预测可以直接采用问题的形式,通过线性激活函数提供。

对于二分类问题,预测结果可能是第一类的概率数组,可以通过四舍五入转换为1或0.

对于多分类问题,结果可能是概率数组的形式(假设有一个one hot编码输出变量),这个形式可能需要使用 argmax() NumPy 函数来转换为单个类输出。

另外,对于分类问题,我们可以使用 predict_classes() 函数,它将自动将未明确的预测转化为明确的整型值。

predictions = model.predict_classes(X)

通过对网络的拟合和评估,提供了详细输出以显示模型预测进展情况。我们可以通过将 verbose 参数设置为0来关闭它。

predictions = model.predict(X, verbose=0)

End-to-End Worked Example

让我们将所有内容结合成为一个小的工作示例。

这个例子将运用一个简单的问题,学习一个10个数字的序列。我们将展示给神经网络1个数字,例如0.0,并期望它会预测0.1。然后展示0.1,并期望它会预测0.2,以此类推直到0.9。

  1. **Define Network:**我们将构造一个LSTM神将网络,在可见层有1个输入步长和
    1个输入特征,在LSTM隐层有10个存储单元,全连接输出层有1个神经元,并且是线性(默认)激活函数。
  2. Compile Network: 我们将使用具有默认配置和均方误差损失函数的高效ADAM优化算法,因为它是一个回归问题。
  3. **Fit Network:**我们将网络拟合成具有1000个 epoch 并使用和训练集模式相同数量的批处理大小。我们也将关闭所有详细输出。
  4. **Evaluate Network:**我们将在训练集上评估网络。通常我们会在测试或者验证数据集上评估网络。
  5. **Make Predictions:**我们将对训练集输入数据进行预测。同样,通常我们会对不知道正确答案的数据进行预测。

下面提供了完整代码:

# 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]

Further Reading

  • Keras documentation for Sequential Models.
  • Keras documentation for LSTM Layers.
  • Keras documentation for optimization algorithms.
  • Keras documentation for loss functions.

Summary

在这篇文章中,你学习了使用Keras库的一个LSTM循环神经网络的5个生命周期。

特别的,学习了:

  • 对于Keras库中的LSTM神经网络如何定义,编译,拟合,评估和预测。
  • 对于分类和回归问题如何选择激活函数和输出层配置。
  • 如何编写和运行你的第一个Keras中的LSTM模型。

你可能感兴趣的:(【翻译2】The 5 Step Life-Cycle for Long Short-Term Memory Models in Keras)