原文链接: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 <- 1440step <- 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.57C。
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.35C。
抛弃(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进行工夫序列剖析