会飞的鱼

2020
Godam
首页 » 人工智能 » Python深度学习--循环神经网络的高级用法

Python深度学习--循环神经网络的高级用法

同样拿这本书做总结的一个博客

温度预测问题

基本就是数据的分析

# 观察数据集中的数据
import os

data_dir = r'G:\pycharm\tensorflow\Python深度学习'
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))
# 解析数据
import numpy as np

float_data = np.zeros((len(lines), len(header) - 1))
print(lines[1])
for i, line in enumerate(lines):
    values = [float(x) for x in line.split(',')[1:]]
    float_data[i,:] = values

print(float_data)
# 绘制温度时间序列
from matplotlib import pyplot as plt

temp = float_data[:, 1]  #温度(单位:摄氏度)
plt.plot(range(len(temp)), temp)
# 绘制前10天的温度时间序列
plt.plot(range(1440), temp[:1440])

准备数据

一个时间步是10分钟,每steps个时间步采样一次数据,给定过去lookback个时间步以内的数据,能否预测delay个时间步之后的温度?用到的参数值如下:

  • lookback = 720:给定过去5天内的观测数据。
  • steps = 6:观测数据的采样频率是每小时一个数据点
  • delay = 144:目标是未来24小时之后的数据
  1. 将数据预处理为神经网络可以处理的格式,需要对每个时间序列分别做标准化,让它们在相似的范围内都取较小的值。
  2. 编写一个Python生成器,以当前的浮点数据数组作为输入,并从中最近的数据中生成数据批量,同时生成未来的目标温度。
    预处理数据的方法是,将每个时间序列减去其平均值,然后除以其标准差。我们将使用前200 000个时间步作为训练数据,所以只对这部分数据计算平均值和标准差。
    # 数据标准化
    mean = float_data[:200000].mean(axis=0)
    float_data -= mean #平均值
    std = float_data[:200000].std(axis=0) #标准差
    float_data /= std
    
    下面的代码给出了要用到的生成器。它生成了一个元组(samples, targets),其中samples是输入数据的一个批量,targets是对应的目标温度数组。生成器参数如下:
  • data:浮点数数据组成的原始数组
  • lookback:输入数据应该包括过去多少个时间步
  • delay:目标应该在未来多少个时间步之后
  • min_index和max_index:data数组中的索引,用于界定需要抽取哪些时间步。这有助于保存一部分数据用于验证、另一部分用于测试。
  • shuffle:是打乱样本,还是按顺序抽取样本
  • batch_size:每个批量的样本数
  • step:数据采样的周期,我们设置为6,为的是每小时抽取一个数据点

    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.arrange(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)
              sample[j] = data[indices]
              targets[j] = data[rows[j] + delay][2]
          yield sample, target
    

    np.arange用于生成带起点和终点的特定步长的排列。
    yield

    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, lookback=lookback, delay=delay, min_index=200001, max_index=300000, shuffle=True, step=step, batch_size=batch_size)
    test_gen = generator(float_data, lookback=lookback, delay=delay, min_index=300001, max_index=None, shuffle=True, step=step, batch_size=batch_size)
    
    val_steps = (300000 - 200001 -lookback) // batch_size #为了查看整个验证集需要从val_gen中抽取多少次
    test_steps = (len(float_data) - 300001 -lookback) // batch_size #为了查看整个测试集需要从test_gen中抽取多少次
    

    一种基于常识的、非机器学习的基准方法

    面对一个尚没有已知解决方案的新问题时,这种基于常识的基准方法很有用。一个经典的例子就是不平衡的分类任务,其中某些类别比其他类别更常见。如果数据集中包含90%的A和10%的类别B,那么分类任务的一种基于常识的方法是对新样本始终预测类别“A”。这种分类器的总体精度为90%,因此任何基于学习的方法在精度高于90%时才能证明其有效性。有时候,这种基本的基准方法可能很难打败。
    在本例中,我们可以放心假设,温度时间序列是连续的(明天的温度很可能接近今天的温度),并且具有每天的周期性变化。因此,一种基于常识的方法就是始终预测24小时后的温度等于现在的温度。我们使用平均绝对误差(MAE)指标来评估这种方法。
    下面是评估的循环代码

    计算符合常识的基准方法的MAE

    def evaluate_native_method():
    batch_maes = []

      samples, targets = next(val_gen)
      preds = samples[:, -1, 1]
      mae = np.mean(np.abs(preds - targets))
      batch_maes.append(mae)
    

    print(np.mean(batch_maes))

evaluate_native_method()

将MAE转换为摄氏温度误差

celsius_mae = 0.29 * std1

# 一种基本的机器学习方法
尝试机器学习方法之前,建立一个基于常识的基准方法是很有用的,同样,在开始研究复杂且计算代价很高的模型(比如RNN)之前,尝试使用简单且计算代价低的机器学习模型也是很有用的,比如小型的密集连接网络。这可以保证进一步增加问题的复杂度是合理的,并且会带来真正的好处。
下面的代码给出了一个密集连接模型,首先将数据展平,然后通过两个Dense层并运行。注意,最后一个Dense层没有使用激活函数,这对于回归问题是很常见的。我们使用MAE作为损失。

训练并评估一个密集连接模型

from keras.models import Sequential
from keras import layers

model = Sequential()
model.add(layers.Flatten(input_shape=(lookback // step, float_data.shape[-1])))
model.add(layers.Dense(32, activation=’relu’))
model.add(layers.Dense(1))
model.compile(optimizer=RMSprop(), loss=’mae’)

绘制结果

import matplotlib.pyplot as plt

loss = history.history[‘loss’]

epochs = range(1, len(loss) + 1)

plt.figure()

plt.plot(epochs, loss, ‘bo’, label=’Training loss’)
plt.plot(epochs, val_loss, ‘b’, label=’validation loss’)

plt.legend()

# 第一个循环网络基准
将数据展平,从数据中删除了时间的概念。我们将使用**GRU**循环网络层来再次进行训练,GRU同LSTM相似但做了一些简化,运算代价更低(虽然表示能力可能不如LSTM)。

model = Sequential()
model.add(layers.GRU(32, input_shape=(None, float_data.shape[-1])))
model.add(layers.Dense(1))
model.compile(optimizer=RMSprop(), loss=’mae’)
history = model.fit_generator(train_gen, steps_per_epoch=500, epochs=20, validation_data=val_gen, validation_steps=val_steps)

使用循环dropout来降低过拟合

使用循环层堆叠

文章如无特别注明均为原创! 作者: 果果, 转载或复制请以 超链接形式 并注明出处 GODAM|博客|godam
原文地址《 Python深度学习--循环神经网络的高级用法》发布于2021-1-19

分享到:
打赏

评论

游客

切换注册

登录

您也可以使用第三方帐号快捷登录

切换登录

注册

sitemap