6.3 循环神经网络的高级用法
本节将介绍提高循环神经网络的性能和泛化能力的三种高级技巧。学完本节,你将会掌握 用 Keras 实现循环网络的大部分内容。我们将在温度预测问题中介绍这三个概念。在这个问题中, 数据点时间序列来自建筑物屋顶安装的传感器,包括温度、气压、湿度等,你将要利用这些数 据来预测最后一个数据点24小时之后的温度。这是一个相当有挑战性的问题,其中包含许多处 理时间序列时经常遇到的困难。
我们将会介绍以下三种技巧。
循环 dropout(recurrent dropout)。这是一种特殊的内置方法,在循环层中使用 dropout来降低过拟合。
堆叠循环层(stacking recurrent layers)。这会提高网络的表示能力(代价是更高的计算负荷)。
双向循环层(bidirectional recurrent layer)。将相同的信息以不同的方式呈现给循环网络,可以提高精度并缓解遗忘问题。
6.3.1 温度预测问题
到目前为止,我们遇到的唯一一种序列数据就是文本数据,比如 IMDB 数据集和路透社 数据集。但除了语言处理,其他许多问题中也都用到了序列数据。在本节的所有例子中,我 们将使用一个天气时间序列数据集,它由德国耶拿的马克思 • 普朗克生物地球化学研究所的气象站记录。
在这个数据集中,每 10 分钟记录 14 个不同的量(比如气温、气压、湿度、风向等),其中包含多年的记录。原始数据可追溯到 2003 年,但本例仅使用 2009—2016 年的数据。这个数据集非常适合用来学习处理数值型时间序列。我们将会用这个数据集来构建模型,输入最近的一 些数据(几天的数据点),可以预测 24 小时之后的气温。
(1)下载数据集
https://s3.amazonaws.com/keras-datasets/jena_climate_2009_2016.csv.zip
(2) 观察耶拿天气数据集的数据
import os
data_dir = 'D:\\2022Thesis\\Deep Learning with Python\\Code\\jena_climate_2009_2016.csv'
fname = os.path.join(data_dir, 'jena_climate_2009_2016.csv')
f = open(fname)
data = f.read()
f.close()
lines = data.split('\n')
header = lines[0].split(',')
lines = lines[1:]
print(header)
print(len(lines))
(3) 解析数据
接下来,将 420 551 行数据转换成一个 Numpy 数组。
import numpy as np
float_data = np.zeros((len(lines), len(header) - 1))
for i, line in enumerate(lines):
values = [float(x) for x in line.split(',')[1:]]
float_data[i, :] = values
(4) 绘制温度时间序列
比如,温度随时间的变化如下图所示(单位:摄氏度)
from matplotlib import pyplot as plt
temp = float_data[:, 1] # temperature (in degrees Celsius)(温度(单位:摄氏度))
plt.plot(range(len(temp)), temp)
plt.show()
(5) 绘制前10天的温度时间序列
上图给出了前 10 天温度数据的图像。因为每 10 分钟记录一个数据,所以每天有 144 个 数据点。
plt.plot(range(1440), temp[:1440])
plt.show()
6.3.2 准备数据
(6) 数据标准化
mean = float_data[:200000].mean(axis=0)
float_data -= mean
std = float_data[:200000].std(axis=0)
float_data /= std
(7)生成时间序列样本及其目标的生成器
def generator(data, lookback, delay, min_index, max_index,
shuffle=False, batch_size=128, step=6):
if max_index is None:
max_index = len(data) - delay - 1
i = min_index + lookback
while 1:
if shuffle:
rows = np.random.randint(
min_index + lookback, max_index, size=batch_size)
else:
if i + batch_size >= max_index:
i = min_index + lookback
rows = np.arange(i, min(i + batch_size, max_index))
i += len(rows)
samples = np.zeros((len(rows),
lookback // step,
data.shape[-1]))
targets = np.zeros((len(rows),))
for j, row in enumerate(rows):
indices = range(rows[j] - lookback, rows[j], step)
samples[j] = data[indices]
targets[j] = data[rows[j] + delay][1]
yield samples, targets
(8) 准备训练生成器、验证生成器和测试生成器
lookback = 1440
step = 6
delay = 144
batch_size = 128
train_gen = generator(float_data,
lookback=lookback,
delay=delay,
min_index=0,
max_index=200000,
shuffle=True,
step=step,
batch_size=batch_size)
val_gen = generator(float_data,