文章开头,我们要做一个假设,假设你有个女朋友,好了我们可以了.
这个问题很重要,涉及到我们网络的理解.
一、网络简介
LSTM我们一般称之为递归神经网络或是长短时记忆网络,为什么我们这样称呼这个网络,因为在我们的训练过程中我们要让他像人一样的思考,比如我们举一个例子,你现在有一个女朋友,他突然生气了,我们得想想他为啥生气。
哦,我们都知道,这是一个复杂的问题,按照我们的思路怎么找到问题呢,我们得从开始交流开始回想我们之间得任何话题和话题得延申,我们从第一句聊天开始思考我们怎么让他这样得生气,我们的结果就是计算出我们生气得原因,我们根据我们得一步步推理,前面得话造成得心情反应和语言状态推理后面得反应,这样一步步得来,我们也就能得到我们得问题所在了。
我们得LSTM网络就像这一个流程,就是前面得计算可以影响到我们后面得结果。说了这么多我们来看看我们得网络啥样吧。
二、LSTM思路
LSTM网络可以解决RNN网络长距离无法依赖得问题,因为在我们的网络中我们比RNN网络多了个 记忆门(简称 C )
如下图:
可以来记录下这个时刻的细胞状态,我们的函数一般是一个输入对应一个输出我们在这里定义我们的当前时刻的输出为当前时刻的输出 H ,我们当然还有一个我们数据的输入 X ,我们的定义暂时就这么多.
现在我们看看我们的RNN网络结构:
我们的结构中,我们可以看到的是我们的网络的输入输出了x,输出了H,然后我们上面的输出是将上一次的输出和当次的输入作为模型的输入,在将当次的输出和下一次的输入一起输出,中间经过了tanh激活函数,这就是RNN网络.
下面该看看LSTM网络咯:
我们理解了上面的RNN网络,我们在看我们下面的这个结构,我们首先去除中间的操作,我们发现我们的网络比上面的网络是不是多了一个输出,而这个输出又成了下面模块的输入,我们想想我们最开始是不是说过我们的网络中,LSTM解决了RNN的啥问题?-------长距离依赖.,说的简单点就是看看是不是又没得关联,就像你女朋友生气,肯定不是一下子就来了,这得是问题得积累,对不对啊?
三、LSTM核心思想
首先我们要知道的是在我们网络中间的黑匣子里面我们包含了四个东西**( 细胞状态 , 遗忘门 F ,输入门 Xi ,输出门 Hi)**,这是我们里面最重要的四个东西.
现在我们看看我们得中间得东西是啥:
首先我们看到的这个横线是细胞状态 © ,来记录你的当前得神经细胞状态然后传送到下一个模块.他就像一个流水线,一个接一个的传送.在这里我们的遗忘门就起了作用对我们的细胞状态进行处理,遗忘 0 or 保留 1(数字是介于0,1之间的数),通过添加和删除信息的方式,再由输出门**—由一个sifmoid网络层和一个成对乘法组成.决定信息的流通,是不是要一直保留,还是要适当的删除某一些状态
四、详细讲解
第一步
我们的第一步是决定什么信息可以通过细胞传送带,在这里我们的决策门为遗忘门,使用sigmoid函数来控制,根据上一时刻的输出通过或者一部分通过.
第二步
在我们这里我们定义我们的新信息,我们有两个部分,第一部分是根据我们的输入层经过sigmoid函数来决定那些信息是要更新的,然后就是tanh函数生成一个行的后选值,然后相加得到了新的候选值.
第三步
到了这里我们开始定义我们的输出,先是通过sigmoid函数来得到一个初始的输出,然后在经过tanh经过tanh函数将我们的输出归一到0-1之间,然后在和sigmoid得到的输出逐队的相乘,从而就得到了我们模型的输出.
最终
我们的模型是一个模块一个模块的进行迭代的,所以这是一个模块结构,我们还需要将我们的上一次的输出和当前的输入和上一次的细胞状态进行输入进行计算.
可以理解,首先sigmoid函数的输出是不考虑先前时刻学到的信息的输出,tanh函数是对先前学到信息的压缩处理,起到稳定数值的作用,两者的结合学习就是递归神经网络的学习思想。至于模型是如何学习的,那就是后向传播误差学习权重的一个过程了。
四、人数预测model
######################################################
# step 1 : 导入库文件
######################################################
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from pandas import read_csv
import math
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
######################################################
# step 2 : 导入原始数据
######################################################
dataset = read_csv('D:/lstm_data/true_data.csv', usecols=[1], engine='python', skipfooter=3)
# 提取并转置
dataset = dataset.values.transpose()
dataset = np.asarray(dataset)
print("datafemage shape: ",dataset.shape)
dataset = np.array(dataset).reshape(-1,1)
dataset = dataset.astype('float32')
plt.figure("resart data")
# 绘制原始图像
plt.plot(dataset)
plt.show()
######################################################
# step 3 : 划分数据集
######################################################
def creat_dataset(dataset,look_back=1):
datax, datay = list(), list()
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)
# 归一化数据
scaler = MinMaxScaler(feature_range=(0,1))
dataset = scaler.fit_transform(dataset)
# 划分数据集合,70%是训练集其余是测试集
trian_size = int(len(dataset)*0.7)
train,test = dataset[:trian_size,:], dataset[trian_size:,:]
# 定义超参数
look_back = 1
# 划分数据和标签
train_x,train_y = creat_dataset(train, look_back)
test_x,test_y = creat_dataset(test, look_back)
# 定义输入结构
train_x = np.reshape(train_x, (train_x.shape[0], 1, train_x.shape[1]))
test_x = np.reshape(test_x, (test_x.shape[0], 1, test_x.shape[1]))
######################################################
# step 4 : 定义网络结构
######################################################
model = Sequential()
model.add(LSTM(4,input_shape=(1,look_back)))
model.add(Dense(1))
model.compile(loss='mean_squared_error',optimizer='adam')
model.fit(train_x,train_y,epochs=30,batch_size=1,verbose=2)
######################################################
# step 5 : 进行预测
######################################################
train_predict = model.predict(train_x)
test_predict = model.predict(test_x)
# 计算误差
train_predict = scaler.inverse_transform(train_predict)
train_y = scaler.inverse_transform([train_y])
test_predict = scaler.inverse_transform(test_predict)
test_y = scaler.inverse_transform([test_y])
# 计算均方差
trainScore = math.sqrt(mean_squared_error(train_y[0],train_predict[:,0]))
testScore = math.sqrt((mean_squared_error(test_y[0],test_predict[:,0])))
print("Train Score is {}, Test Score is {}".format(trainScore,testScore))
######################################################
# step 6 : 绘图输出
######################################################
# 绘制输出
train_predict_plot = np.empty_like(dataset)
train_predict_plot[:,:] = np.nan
train_predict_plot[look_back:len(train_predict)+look_back, :] = train_predict
test_predict_plot = np.empty_like(dataset)
test_predict_plot[:,:] = np.nan
test_predict_plot[len(train_predict)+look_back*2+1:len(dataset)-1,:] = test_predict
# 绘图
plt.figure('pre_data')
plt.plot(scaler.inverse_transform(dataset))
plt.plot(train_predict_plot)
plt.plot(test_predict_plot)
plt.show()
致谢
- https://blog.youkuaiyun.com/m0epNwstYk4/article/details/79124800?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param
- https://blog.youkuaiyun.com/zhengxqq27/article/details/90481590