Python深度学习读书笔记(七)(温度预测问题Dense,GRU,dropout)

循环神经网络的高级技巧:循环dropout  ,堆叠循环层,  双向循环层。

GRU层工作原理和LSTM相同,做了简化,运行计算代价更低。

#观察数据集中数据
import os
data_dir='D:\\jupyter_code\\jena_climate'
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))
for i, line in enumerate(lines):
    values=[float(x) for x in line.split(',')[1:]]
    float_data[i,:]=values

from matplotlib import pyplot as plt
temp=float_data[:,1]
plt.plot(range(len(temp)),temp)

plt.plot(range(1440),temp[:1440])

#数据标准化(减去平均数,除以标准差)
mean=float_data[:200000].mean(axis=0)
float_data-=mean
std=float_data[:200000].std(axis=0)
float_data/=std


#生成时间序列样本及其目标的生成器
#data:浮点数数据组成的原始数组
#lookback:输入数据应该包括过去多少个时间步
#delay:目标应该在未来多少个时间步后
#min_index,max_index:数组中的索引,界定需要抽取哪些时间步,有助于保存数据用于验证和测试
#shuffle:是否打乱样本
#batch_size:每个批量的样本数
#step:数据采样周期,每个时间步是10min,设置为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.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


#准备训练生成器,验证生成器,测试生成器
#输入数据包括过去10天内的数据,每小时抽取一次数据点
#目标为一天以后的天气,批次样本数为128
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)
train_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
test_steps=(len(float_data)-300001-lookback)//batch_size

Dense

#训练评估一个密集连接模型
from keras.models import Sequential
from keras import layers
from keras.optimizers import RMSprop

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')
history=model.fit_generator(train_gen,steps_per_epoch=500,epochs=20,validation_data=val_gen,validation_steps=val_steps)

全连接方法效果并不好,时间序列展平后从输入数据中删除了时间的概念。

 

GRU

#训练并评估一个基于GRU的模型
from keras.models import Sequential
from keras import layers
from keras.optimizers import RMSprop

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&GRU

#训练并评估一个使用dropout正则化的基于GRU的模型
#不再过拟合,分数更稳定
from keras.models import Sequential
from keras import layers
from keras.optimizers import RMSprop

model=Sequential()
model.add(layers.GRU(32,dropout=0.2,recurrent_dropout=0.2,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=40,validation_data=val_gen,validation_steps=val_steps)


#--------------------------------------------------------------------------
#--------------------------------------------------------------------------



#训练并评估一个使用dropout正则化的堆叠GRU模型
#有所改进但效果并不明显
from keras.models import Sequential
from keras import layers
from keras.optimizers import RMSprop

model=Sequential()
model.add(layers.GRU(32,dropout=0.1,recurrent_dropout=0.5,return_sequences=True,input_shape=(None,float_data.shape[-1])))
model.add(layers.GRU(64,activation='rule',dropout=0.1,recurrent_dropout=0.5))
model.add(layers.Dense(1))

model.compile(optimizer=RMSprop(),loss='mae')
history=model.fit_generator(train_gen,steps_per_epoch=500,epochs=40,validation_data=val_gen,validation_steps=val_steps)

循环网络中使用dropout的正确方法:对每个时间步使用相同的dropout掩码,可以让网络沿着时间正确的传播其学习误差,而不是让dropout掩码随着时间步的增加而随机变化,将dropout应用于层的内部循环激活(循环dropout掩码)

Keras中和dropout相关的参数:dropout是一个浮点数,指定输入单元的dropout比率;recurrent_dropout:指定循环单元的dropout比率。

模型不再过拟合,遇到性能瓶颈时,应该考虑增加网络容量,通常做法:增加每层单元数或者增加层数

你可能感兴趣的:(读书笔记)