原文链接:http://tecdat.cn/?p=20335
在本文中,咱们将介绍三种进步循环神经网络性能和泛化能力的高级技术。咱们演示无关温度预测问题的三个概念,咱们应用建筑物屋顶上的传感器的工夫数据序列。
概述
在本文中,咱们将介绍三种进步循环神经网络性能和泛化能力的高级技术。在最初,您将理解无关将循环网络与 Keras 一起应用的大部分常识。您能够拜访来自建筑物屋顶上的传感器的工夫数据序列,例如温度,气压和湿度,这些数据点可用于预测最初一个数据点之后 24 小时的温度。这是一个相当具备挑战性的问题,它阐明了应用工夫序列时遇到的许多常见艰难。
咱们将介绍以下技术:
- _删除_层 / 每层的单位数(模型) 如 L1 或 L2 正则化所述, 适度简单的模型更有可能适度_拟合_,能够应用删除来抵制反复图层的过拟合。
- _重叠循环层_ —这减少了网络的示意能力(以更高的计算负荷为代价)。
- _双向循环层_ —这些_层_以不同的形式向循环网络提供雷同的信息,从而进步准确性。
温度预测问题
在本节的所有示例中,您将应用生物地球化学研究所的气象站记录的 天气工夫序列数据集。
在此数据集中,几年中每 10 分钟记录 14 个不同的量(例如空气温度,大气压力,湿度,风向等)。原始数据可追溯到 2003 年,但此示例仅限于 2009-2016 年的数据。该数据集非常适合学习应用数字工夫序列。您将应用它来构建一个模型,该模型将最近的一些数据(几天的数据点)作为输出,并预测将来 24 小时的气温。
下载并解压缩数据,如下所示:
unzip(
"climate.csv.zip",
exdir = "~/Downloads/climate"
)
咱们看一下数据。
library(tibble)
library(readr)
glimpse(data)
这是温度(摄氏度)随工夫变动的曲线图。在此图上,您能够分明地看到温度的年度周期。
ggplot(data, aes(x = 1:nrow(data), y = `degC`)) + geom_line()
这是温度数据的前 10 天变动图。因为数据每 10 分钟记录一次,因而您每天可取得 144 个数据点。
ggplot(data[1:1440,], aes(y = `degC`)) + geom_line()
如果您依据过来几个月的数据来尝试预测下个月的平均温度,因为数据的年度周期性牢靠,因而问题很容易解决。然而从几天的数据来看,温度更加凌乱。这个工夫序列每天都能够预测吗?
筹备数据
问题的确切表白如下:给定的数据能够追溯到 lookback
工夫步长(一个工夫步长为 10 分钟)并在每个steps
工夫步短处进行采样,您能够预测该delay
工夫步长中的温度 吗?应用以下参数值:
lookback = 1440
—察看将追溯到 10 天。steps = 6
—观测将在每小时一个数据点进行采样。delay = 144
—指标将是将来的 24 小时。
首先,您须要做两件事:
- 将数据预处理为神经网络能够应用格局。数据曾经是数字了,因而您无需进行任何向量化。然而数据中的每个工夫序列的度量尺度都不同(例如,温度通常在 -20 至 +30 之间,但以毫巴为单位的大气压约为 1,000)。您将独立地标准化每个工夫序列。
- 编写一个生成器函数,该函数将获取以后的浮点数据数组,并生成来自最近的过来以及未来的指标温度的成批数据。因为数据集中的样本是高度冗余的(样本 _N_ 和样本 _N_ + 1 将具备大多数雷同的工夫步长),因而显式调配每个样本会很节约。相同,您将应用原始数据即时生成样本。
生成器函数是一种非凡类型的函数,能够重复调用该函数以取得一系列值。
例如,sequence_generator()
上面的函数返回一个生成器函数,该 函数产生有限的数字序列:
gen <- sequence_generator(10)
gen()
[1] 10
gen()
[1] 11
生成器的以后状态value
是在函数内部定义的 变量。superassignment(<<-
)用于从函数外部更新此状态。
生成器函数能够通过返回值 NULL
来批示实现。
首先,将先前读取的 R 数据帧转换为浮点值矩阵(咱们抛弃蕴含文本工夫戳记的第一列):
data <- data.matrix(data[,-1])
而后,您能够通过减去每个工夫序列的平均值并除以标准差来预处理数据。您将应用前 200,000 个工夫步作为训练数据,因而仅在这部分数据上计算均值和标准差以进行标准化。
train_data <- data[1:200000,]
data <- scale(data, center = mean, scale = std)
您将应用的数据生成器的代码如下。它产生一个 list (samples, targets)
,其中 samples
是一批输出数据,并且 targets
是指标温度的对应数组。它采纳以下参数:
data
—原始的浮点数据数组。lookback
—是_输出数据应该_包含多少个_工夫_步。delay
—指标应该在将来多少步。min_index
和max_index
—data
数组中的索引,用于定义从中提取工夫步长。保留一部分数据用于验证和另一部分用于测试。shuffle
—随机整顿样本还是按工夫程序绘制样本。batch_size
—每批样品数。step
—采样数据的时间段(以工夫为单位)。您将其设置为 6,以便每小时绘制一个数据点。
当初,让咱们应用 abstract generator
函数实例化三个生成器:一个用于训练,一个用于验证以及一个用于测试。每个人都将查看原始数据的不同时间段:训练生成器查看前 200,000 个工夫步,验证生成器查看随后的 100,000 个工夫步,而测试生成器查看其余的工夫步。
lookback <- 1440
step <- 6
# 为了查看整个验证集,须要从 valu gen 中提取多少步骤
val_steps <- (300000 - 200001 - lookback) / batch_size
# 为了查看整个测试集,须要从 testu gen 中提取多少步骤
test_steps <- (nrow(data) - 300001 - lookback) / batch_size
常识性的非机器学习基准
在开始应用黑盒深度学习模型解决温度预测问题之前,让咱们尝试一种简略的常识性办法。它将用作健全性查看,并将建设一个基线,您必须超过它能力证实机器学习模型的有用性。当您要解决尚无已知解决方案的新问题时,此类常识性基准可能会很有用。一个经典的例子是不均衡的分类工作,其中某些类比其余类更为常见。如果您的数据集蕴含 90%的 A 类实例和 10%的 B 类实例,则分类工作的常识性办法是在提供新样本时始终预测“A”。此类分类器的总体准确度为 90%,因而,任何基于学习的办法都应超过 90%的分数,以证实其有用性。
在这种状况下,能够平安地假设温度工夫序列是间断的(今天的温度可能会靠近明天的温度)。因而,常识性的办法是始终预测从当初开始 24 小时的温度将等于当初的温度。咱们应用均匀绝对误差(MAE)指标评估这种办法:
mean(abs(preds - targets))
评估循环。
for (step in 1:val_steps) {preds <- samples[,dim(samples)[[2]],2]
mae <- mean(abs(preds - targets))
batch_maes <- c(batch_maes, mae)
}
print(mean(batch_maes))
MAE 为 0.29。因为温度数据已标准化为以 0 为核心并且标准偏差为 1。它的均匀绝对误差为 0.29 x temperature_std
摄氏度:2.57˚C。
celsius_mae <- 0.29 * std[[2]]
那是一个相当大的均匀绝对误差。
根本的机器学习办法
就像在尝试机器学习办法之前建设常识性基准很有用一样,在钻研简单且计算量大的模型之前,尝试简略的机器学习模型也很有用。
上面的清单显示了一个全连贯的模型,该模型首先将数据展平,而后在两个密集层中运行它。请留神,最初一个致密层上短少激活函数,这对于回归问题是很典型的。您将 MAE 用作损失函数。因为您评估的数据与通常办法完全相同,而且度量规范完全相同,因而后果能够间接比拟。
model_sequential() %>%
layer_flatten(input_shape = c(lookback / step, dim(data)[-1])) %>%
history <- model %>% fit_generator(
train_gen,
steps_per_epoch = 500,
epochs = 20,
validation_data = val_gen,
validation_steps = val_steps
)
让咱们显示验证和训练的损失曲线。
某些验证损失靠近无学习基准,但不牢靠。这首先显示了具备此基准的长处:事实证明,要实现这一指标并不容易。您的常识蕴含很多机器学习模型无法访问的有价值的信息。
您可能想晓得,如果存在一个简略的,性能良好的模型,为什么您正在训练的模型找不到并对其进行改良?因为这种简略的解决方案不是您的训练设置所须要的。您要在其中寻找解决方案的模型的空间曾经相当简单。当您正在寻找具备两层网络空间的简单模型解决方案时,即便在技术上是假如简略,性能良好的基准模型也可能无奈学习。通常,这是机器学习的一个相当大的局限性:除非对学习算法进行硬编码来寻找特定类型的简略模型,
基准模型
第一种全连贯的办法成果不好,但这并不意味着机器学习不适用于此问题。先前的办法首先使工夫序列平坦化,从而从输出数据中删除了工夫概念。咱们将尝试一个递归序列解决模型 - 它应该非常适合此类序列数据,因为与第一种办法不同,正是因为它利用了数据点的工夫程序。
您将应用 Chung 等人开发的 GRU 层。在 2014 年。GRU 层应用与 LSTM 雷同的原理工作,然而它们有所简化,因而运行起来更高效。在机器学习中到处都能够看到计算复杂度和效率之间的折衷。
model_sequential() %>%
layer_gru(units = 32, input_shape = list(NULL, dim(data)[[-1]])) %>%
layer_dense(units = 1)
model %>% fit_generator(
train_gen,
steps_per_epoch = 500,
epochs = 20,
后果如下图所示。您能够超过基线模型,证实了机器学习的价值以及循环网络的优越性。
验证 MAE 转化为非标准化后的均匀绝对误差为 2.35˚C。
抛弃(dropout)反抗适度拟合
从训练和验证曲线能够显著看出该模型是过拟合的:训练和验证损失在通过几个期间后开始呈现较大差别。您曾经相熟了应答这种景象的经典技术:抛弃(dropout),它随机将图层的输出单元清零,以便突破该图层所裸露的训练数据中的偶尔相关性。然而,如何在循环网络中正确利用 dropout 并不是一个简略的问题。道在递归层之前利用 dropout 会妨碍学习,而不是帮忙进行正则化。2015 年,Yarin Gal 作为其博士学位论文的一部分 在贝叶斯深度学习中,确定了应用递归网络进行 dropout 的正确办法:应在每个工夫步上利用雷同的 dropout 模式,而不是随工夫步长随机变动的 dropout 模式。
Yarin Gal 应用 Keras 进行了钻研,并帮忙将这种模型间接构建到 Keras 循环层中。Keras 中的每个循环图层都有两个与 dropout 相干的参数:dropout
,一个浮点数,用于指定图层输出单元的 dropout 率;以及 recurrent_dropout
,用于指定循环单元的 dropout 率。因为应用失落 dropout 进行正则化的网络始终须要更长的工夫能力齐全收敛,因而您须要两倍的工夫训练网络。
model_sequential() %>%
layer_gru(units = 32, dropout = 0.2, recurrent_dropout = 0.2,
下图显示了后果。在前 20 个期间中,您不再适度拟合。然而,只管您的评估分数较为稳固,但您的最佳分数并没有比以前低很多。
重叠循环图层
因为您不再须要思考适度拟合的问题,而是仿佛遇到了性能瓶颈,所以您应该思考减少网络的容量。回忆一下通用机器学习工作流程的形容:在过拟合成为次要阻碍之前,最好减少网络容量,这通常是个好主见(假如您曾经采取了根本步骤来加重过拟合的状况,例如应用抛弃)。只有您的拟合度不会太差,就很可能会呈现容量有余的状况。
通常,通过减少层中的单元数或增加更多层来减少网络容量。递归层重叠是构建性能更弱小的递归网络的经典办法:例如,以后为 Google Translate 算法提供能源的是七个大型 LSTM 层的重叠。
为了在 Keras 中将递归层重叠在一起,所有中间层都应返回其残缺的输入序列(3D 张量),而不是最初一个工夫步的输入。
model_sequential() %>%
layer_gru(units = 32,
dropout = 0.1,
recurrent_dropout = 0.5,
return_sequences = TRUE,
input_shape = list(NULL, dim(data)[[-1]])) %>%
layer_gru(units = 64, activation = "relu",
dropout = 0.1,
recurrent_dropout = 0.5) %>%
下图显示了后果。您能够看到,增加的图层的确改善了后果,只管成果不显著。您能够得出两个论断:
- 因为不须要适度拟合的问题,所以能够平安地减少图层大小以寻求验证损失的改善。然而,这具备不可疏忽的计算成本。
- 增加层并没有很大的帮忙,因而此时您可能会看到网络容量减少带来的收益递加。
应用双向 RNN
本节介绍的最初一种技术称为 _双向 RNN_。双向 RNN 是常见的 RNN 变体,在某些工作上能够提供比惯例 RNN 更高的性能。它在自然语言解决中常常应用 - 您能够将其称为用于深度语言解决的深度学习“瑞士军刀”。
RNN 特地依赖于程序或工夫的:它们按程序解决输出序列的工夫步长,重新排列工夫步长能够齐全扭转 RNN 从序列中提取的示意模式。这正是它们在序列问题(例如温度预测问题)上体现良好的起因。双向 RNN 利用 RNN 的序列敏感性:它蕴含应用两个惯例 RNN(例如 layer_gru
和 layer_lstm
),每个 RNN 都沿一个方向(按工夫程序)解决输出序列,而后合并它们的示意模式。通过双向解决序列,双向 RNN 能够捕捉被单向 RNN 疏忽的模式。
值得注意的是,本节中的 RNN 层已按工夫程序解决了序列。训练与本节第一个试验中应用雷同的单 GRU 层网络,您将取得如下所示的后果。
结果表明在这种状况下,按工夫程序进行的解决至关重要。因为:底层的 GRU 层通常更容易记住最近的过来,天然地,较新的天气数据点比旧数据点对问题的预测能力强。因而,该层的工夫程序版本必将胜过逆序版本。对于包含自然语言在内的许多其余问题,状况并非如此:从直觉上讲,单词在了解句子中的重要性通常并不取决于其在句子中的地位。让咱们在 LSTM IMDB 示例中尝试雷同的技巧。
# 作为特色思考的单词数量
max_features <- 10000
c(c(x_train, y_train), c(x_test, y_test)) %<-% imdb
# 反转序列
x_train <- lapply(x_train, rev)
x_test <- lapply(x_test, rev)
model <- keras_model_sequential() %>%
layer_embedding(input_dim = max_features, output_dim = 128) %>%
layer_lstm(units = 32) %>%
您取得的性能简直与按工夫顺序排列的 LSTM 雷同。值得注意的是,在这样的文本数据集上,逆序解决与按工夫程序解决一样无效,这证实了以下假如:只管单词程序 在了解语言中_的确很_重要,_但_ 您应用的程序并不重要。重要的是,通过逆向序列训练的 RNN 将学习与原始序列训练的 RNN 不同的表达方式。在机器学习中,_不同_ _的示意_ 总是值得开发的:它们提供了一个新的视角来查看您的数据,捕捉了其余办法脱漏的数据方面,因而能够帮忙进步工作的性能。
双向 RNN 利用此思维来改良按工夫顺序排列的 RNN 的性能。
在 Keras 中实例化双向 RNN。让咱们在 IMDB 情绪剖析工作上尝试一下。
model <- keras_model_sequential() %>%
layer_embedding(input_dim = max_features, output_dim = 32) %>%
bidirectional(layer_lstm(units = 32)
model %>% compile(
optimizer = "rmsprop",
loss = "binary_crossentropy",
它的性能比您在上一节中尝试过的惯例 LSTM 稍好,达到了 89%以上的验证精度。它仿佛也能够更快地过拟合,这并不奇怪,因为双向层的参数是按工夫顺序排列的 LSTM 的两倍。通过一些正则化,双向办法可能会在此工作上表现出色。
当初让咱们在温度预测工作上尝试雷同的办法。
model_sequential() %>%
bidirectional(layer_gru(units = 32), input_shape = list(NULL, dim(data)[[-1]])
model %>% fit_generator(
train_gen,
steps_per_epoch = 500,
epochs = 40,
这和惯例的 layer_gru
一样好。起因很容易了解:所有预测能力都必须来自网络中按工夫顺序排列的局部,因为家喻户晓,按工夫顺序排列的局部在此工作上的体现严重不足,在这种状况下,最近的样本比过来的样本重要得多。
更进一步
为了进步温度预测问题的性能,您能够尝试其余许多办法:
- 调整重叠设置中每个循环图层的单位数。
- 调整
RMSprop
优化器应用的学习率。 - 尝试应用
layer_lstm
代替layer_gru
。 - 尝试在循环层的顶部应用更大的紧密连接的回归变量:即,更大的密集层,甚至一叠密集层。
- 不要遗记最终在测试集上运行性能最佳的模型(就验证 MAE 而言),否则,您将开发适度拟合验证集的构造。
咱们能够提供一些准则,倡议在给定问题上可能起作用或不起作用的因素,然而最终,每个问题都是惟一的;您必须凭教训评估不同的策略。以后没有实践能够提前精确地告诉您应该如何最佳地解决问题。您必须迭代。
最受欢迎的见解
1. 用于 NLP 的 Python:应用 Keras 的多标签文本 LSTM 神经网络分类
2.Python 中利用长短期记忆模型 LSTM 进行工夫序列预测剖析 – 预测电力耗费数据
3.python 在 Keras 中应用 LSTM 解决序列问题
4.Python 中用 PyTorch 机器学习分类预测银行客户散失模型
5.R 语言多元 Copula GARCH 模型工夫序列预测
6. 在 r 语言中应用 GAM(狭义相加模型)进行电力负荷工夫序列剖析
7.R 语言中 ARMA,ARIMA(Box-Jenkins),SARIMA 和 ARIMAX 模型用于预测工夫序列数
8.R 语言预计时变 VAR 模型工夫序列的实证钻研剖析案例
9. 用狭义加性模型 GAM 进行工夫序列剖析