GRU网络的实现

GRU网络的实现

      • 一、简介
      • 二、网络实现
          • 1.带入包库
          • 2.导入数据
          • 3.定义我们训练的数据和标签函数
          • 4.数据正则化和划分数据测试集和训练集
          • 5.生成训练集和测试集
          • 6.定义输入维度
          • 7.构建模型
          • 8.预测数据和计算误差
          • 9.画出我们的数据
      • 三、完整网络实现
      • 四、结尾

本博客是数据预测的GRU网络的实现,在阅读这篇文章是,我认为读者是知道GRU网络的实现过程,如果对GRU网络不是很了解建议阅读 深度学习之GRU网络通过阅读这篇文章你将对网络实现的基本数学和过程有一定的了解。



一、简介


在带入代码的开始我们想了解哈什么是GRU网络,做个铺垫,在学习过LSTM网络的小伙伴应该不会陌生GRU网络,这是因为这是前者衍生出来的变体,他们之间的变化就是GRU的更新门取代了原始LSTM网络的遗忘门和输入门,他还在这个基础上去掉了原来的细胞状态,使用影藏状态来进行信息的传递,这就是我们说的GRU网络(Gated Recurrent Unit,门控循环单元网络)。



二、网络实现


1.带入包库
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error

在这里我们导入了我们的numpy库和画图库matplotlib、mean_squared_error,这是我们在我们的训练中常使用的库。


2.导入数据
from pandas import read_csv
data = read_csv(file_path,header=None, usecols=[1])  # 导入真实的数据
data = data.values
data = np.array(data).reshape(-1,1)
data = data.astype('float32')

在这里呢,我们导入了我们要使用的数据,他是二维的浮点数构成的,通过导入他的csv文件的路径和列标我们来读取我们要使用的数据,转换成一列的数据,方便我们后面的输入


3.定义我们训练的数据和标签函数
np.random.seed(7)
def create_dataset(dataset, look_back=1):
    dataX, dataY = [], []
    for i in range(len(dataset)-look_back-1):
        a = dataset[i:(i+look_back), 0]
        dataX.append(a)
        dataY.append(dataset[i + look_back, 0])
    return np.array(dataX), np.array(dataY)

在这里我们的数据和标签的输入是一个一个的他将前一个定义为数据后一个是标签这就意味着我们的训练过程是输入一个数字然后预测一个数字,这样的输入方式是可以更改的,他的改进位置在lookback,这里通过切片定义了你的输入数据。


4.数据正则化和划分数据测试集和训练集
from sklearn.preprocessing import MinMaxScaler
scalar = MinMaxScaler(feature_range=(0,1))
dataset = scalar.fit_transform(data)

train_size = int(len(dataset)*0.7)
test_size = len(dataset)-train_size
train, test = dataset[0:train_size,:],dataset[train_size:len(dataset),:]

在这里我们定义了我们的正则化函数MinMaxScaler,数据范围定义在0-1之间,我们在将这个正则化的数据填充到我们的原始数据,这里正则化就完成了,我们下面定义我们的训练集和测试集,我们这里用过使用数据的长度来定义我们的划分范围,通过切片的方式进行划分


5.生成训练集和测试集
look_back = 1
trainX, trainY = create_dataset(train, look_back)
testX, testY = create_dataset(test, look_back)

这里没有什么需要讲的,就是带入我们的函数


6.定义输入维度
trainX = np.reshape(trainX, (trainX.shape[0], 1, trainX.shape[1]))
testX = np.reshape(testX, (testX.shape[0], 1, testX.shape[1]))

我们现在定义的GRU网络,他的输入维度是:[samples, time_steps, features], 所以我们续要做一点变换,将他的维度变为适应我们网络的三维数据。


7.构建模型
from keras.models import Sequential
from keras.layers import GRU
from keras.layers import Dense
model = Sequential()
model.add(GRU(4,input_shape=(1,look_back)))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
model.fit(trainX,trainY,epochs=5,batch_size=1,verbose=2)

这里就是导入了我们的GRU封装函数,定义了一个全连接成,这里我们的训练函数是adam(不了解的同学可以看看这里adam梯度下降法),这里我们定义loss是我们的均方函数,放入训练集,定义次数,和输入batch_size,后面是说我们查看网络训练的状态定义。


8.预测数据和计算误差
trainPredict = model.predict(trainX)
testPredict = model.predict(testX)

trainPredict = scalar.inverse_transform(trainPredict)
trainY = scalar.inverse_transform([trainY])
testPredict = scalar.inverse_transform(testPredict)
testY = scalar.inverse_transform([testY])

import math
trainScore = math.sqrt(mean_squared_error(trainY[0], trainPredict[:, 0]))
print("Train Sore :%.2f RMSE" % (trainScore))
testScore = math.sqrt(mean_squared_error(testY[0], testPredict[:, 0]))
print("Test Sore :%.2f RMSE" % (testScore))

上面就是直接导入我们的测试数据,下面我们定义我们的误差,我们需要转换我们的数据是一个单位的,然后下面我们直接用方差来进行计算就完事了。


9.画出我们的数据
# shift train predictions for plotting
trainPredictPlot = np.empty_like(dataset)  # 给定数组(a)的形状和类型返回一个新的空数组
trainPredictPlot[:, :] = np.nan   # 全部填充为nan
trainPredictPlot[look_back:len(trainPredict)+look_back, :] = trainPredict
# 画出结果:蓝色为原数据,绿色为训练集的预测值,红色为测试集的预测值
# shift test predictions for plotting
testPredictPlot = np.empty_like(dataset)
testPredictPlot[:, :] = np.nan
testPredictPlot[len(trainPredict)+(look_back*2)+1:len(dataset)-1, :] = testPredict

# plot baseline and predictions
plt.figure('flow')
plt.plot(scalar.inverse_transform(dataset))  # 将降维后的数据转换成原始数据
# X=scaler.inverse_transform(X[, copy])
# 将标准化后的数据转换为原始数据。
plt.plot(trainPredictPlot)
plt.plot(testPredictPlot)
plt.show()

这里就是让让我们的数据填充进去划分不同的输入在我们的画图函数。



三、完整网络实现

import tensorflow as tf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error

# -----------------导入数据集合-------------------
# 导入数据
from pandas import read_csv
data = read_csv(data_file_path,header=None, usecols=[1])  # 导入真实的数据
data = data.values
data = np.array(data).reshape(-1,1)
data = data.astype('float32')
# 绘制原始数据的样本图像
# plt.plot(data)
# plt.show()

# -----------------data group------------------
# convert an array of values into a dataset matrix
def create_dataset(dataset, look_back=1):
    dataX, dataY = [], []
    for i in range(len(dataset)-look_back-1):
        a = dataset[i:(i+look_back), 0]
        dataX.append(a)
        dataY.append(dataset[i + look_back, 0])
    return np.array(dataX), np.array(dataY)


# 数据归一化
np.random.seed(7)

# 因为达到当前的激活函数是sigmoid和tanh,所以要将数据进行正则化
from sklearn.preprocessing import MinMaxScaler
scalar = MinMaxScaler(feature_range=(0,1))
dataset = scalar.fit_transform(data)

# 划分数据集和测试集合
train_size = int(len(dataset)*0.7)
test_size = len(dataset)-train_size
train, test = dataset[0:train_size,:],dataset[train_size:len(dataset),:]

# 现在我们得到了训练的数据和测试的数据,挡墙的维度是:[sanples,fearture]
# use this function to prepare the train and test datasets for modeling
look_back = 1
trainX, trainY = create_dataset(train, look_back)
testX, testY = create_dataset(test, look_back)

# 我们现在定义的GRU网络,他的输入维度是:[samples, time_steps, features], 所以我们续要做一点变换
# reshape input to be [samples, time_steps, features]
trainX = np.reshape(trainX, (trainX.shape[0], 1, trainX.shape[1]))
testX = np.reshape(testX, (testX.shape[0], 1, testX.shape[1]))

# 构建模型
# 建立GRU模型
# input: 输入的是一个input,定义四个神经元,输出的值是一个数据,激活函数使用sigmoid函数,迭代100次
# creat a GRU network
from keras.models import Sequential
from keras.layers import GRU
from keras.layers import Dense
model = Sequential()
model.add(GRU(4,input_shape=(1,look_back)))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
model.fit(trainX,trainY,epochs=5,batch_size=1,verbose=2)

# 预测数据
# make predictions
trainPredict = model.predict(trainX)
testPredict = model.predict(testX)

# 计算误差的时候我们要将我们的预测的数据转换为一个相同的单位
# 改变我们的数据的单位
trainPredict = scalar.inverse_transform(trainPredict)
trainY = scalar.inverse_transform([trainY])
testPredict = scalar.inverse_transform(testPredict)
testY = scalar.inverse_transform([testY])

# 计算 mean square error
import math
trainScore = math.sqrt(mean_squared_error(trainY[0], trainPredict[:, 0]))
print("Train Sore :%.2f RMSE" % (trainScore))
testScore = math.sqrt(mean_squared_error(testY[0], testPredict[:, 0]))
print("Test Sore :%.2f RMSE" % (testScore))

# shift train predictions for plotting
trainPredictPlot = np.empty_like(dataset)  # 给定数组(a)的形状和类型返回一个新的空数组
trainPredictPlot[:, :] = np.nan   # 全部填充为nan
trainPredictPlot[look_back:len(trainPredict)+look_back, :] = trainPredict
# 画出结果:蓝色为原数据,绿色为训练集的预测值,红色为测试集的预测值
# shift test predictions for plotting
testPredictPlot = np.empty_like(dataset)
testPredictPlot[:, :] = np.nan
testPredictPlot[len(trainPredict)+(look_back*2)+1:len(dataset)-1, :] = testPredict

# plot baseline and predictions
plt.figure('flow')
plt.plot(scalar.inverse_transform(dataset))  # 将降维后的数据转换成原始数据
# X=scaler.inverse_transform(X[, copy])
# 将标准化后的数据转换为原始数据。
plt.plot(trainPredictPlot)
plt.plot(testPredictPlot)
plt.show()


四、结尾

这是一篇自我学习笔记,有什么问题请联系读者。谢谢

你可能感兴趣的:(GRU网络的实现)