LSTM的学习
学习目标:
1·理解什么是人工神经网络。
2·深入理解LSTM(长短期记忆网络)
3·Code
浅析人工神经网络:
在谈人工神经网络模型之前我们先来了解一下生理上的神经网络。
下面是一张对比图:
Neural Science
Computer Science
人工神经网络实际上是模仿人类的神经元网络的搭建,就像最初图灵模型也是基于人类运算行为而提出的一个模型。
在人体中,当感受器受到刺激的时候会产生神经冲动,产生信号。神经元之间通过突起相互连结,实现信息的传递。但是医学上发现,信息传入细胞核之后并不是直接传给下一个神经元,而是需要达到某一特定”值“,被激活之后才能传给其他神经元。所以我们在模仿的时候会引入激活函数(高度非线性的)。另外,对于相同的信息,经过不同的”路线“传递,会出现不同程度的信息损失。因此,我们还会引入权重这一概念。所以人工神经元的工作流程就如下所示:
外界的输入乘上相应的权重就是该细胞核所获取的信息,信息累加之后由激活函数判断是否输出。
激活函数是信息传递比较重要的一环,但是我们不知道这个高度非线性的函数到底是什么,我们只能去猜这个函数,我们流行的“猜法”有如下四种形式:
当我们用sigmoid去构建网络的时候就可以发现,其实LogisticRegression是最简单的人工神经网络。在使用过程中,我们搭建复杂的人工神经网络,是基于每一个简单的人工神经元,通过排列、组合、连接完成的,本源其实是一样的,本质的东西是不会改变的。
我们在后面的代码coding部分会详细讲解如何使用。
下面是简单的全连接神经网络模型,每一列我们称之为一个神经网络层。由此我们可以具象地看到信息传递的路线的差别和信息的丢失。
理解了什么是人工神经网络,我们接下来进行学习一个基础模型解决有关 时间序列问题——
先上概览图:
LSTM模型在时间轴上是连续的,每一个A都表示某个时间点,信息是有继承的。该模型的处理数据的方式也是模拟人在处理时间序列的方式。
我们可以看到这其中,总共有两条时间序列:
下面这一条时间序列代表的输入=观测数据的输入+前一时刻的输出。
上面这一时间序列是知识、信息的继承,我们来看一看他是怎么运行的:
Ct-1是该模型在t-1时刻的知识状态,C~t是在输入新的观测之后新获得的信息,分别乘上相应的权重参数之后相加即可得到t时刻的知识状态。这个权重参数就决定了你在这些时刻所保留的知识。打个比方,如果是一个经验主义者,那么他的Ft就会偏大,不太相信新的观测,如果是一个现实主义者那么他的It就会偏大。实际上我们只要把这个等式理解明白了,我们就差不多弄清楚LSTM的原理了。
我们接下来讲讲上述等式的各个变量:)
首先是Ft的计算,因为此值是一个百分比数值,所以我们偏向于使用sigmoid激活函数。
Ft的输入= (对应权重) * [(t-1时刻的输出) concat (t时刻的新输入)] 最后套上激活函数。我们还可以看到该等式后面还有一项bf,其实这一项对于帮助我们理解LSTM并没有太大的帮助,只是担心模型太过复杂或者数据过于简单导致的模型过拟合,所加上的随机扰动(白噪音)。
其次是Ct和It:
我们可以看到其实这些变量在计算上的方法都是类似的,这里值的一提的是我们为什么要选用tanh为激活函数。因为我们的模型在学习的时候,每一次新的输入不一定给机器带来正面的影响,也有可能是负面的影响。所以我们需要的激活函数的返回值有正负。
最后是计算在t时刻的输出ht:
我们会发现一个很奇怪的现象,为什么在输出的时候还要乘上一个权重参数Ot?
Ot代表你打算用多少Ct激活后的数值做输出的百分比。
举一个生活中的例子,比如你明天要去参加考试了,已经准备的十分充分了,但是你十分低调,有100分的实力但就是不想考100分。虽然不是每个人都这么想,但是我们得给他们这个权力,这个“权力”就是这里的Ot。
得出Ct和ht之后便会传给下一时刻,那么LSTM这一模型就在时间轴上“跑”起来了。
如何评价一个分类模型的好坏?
我们通常会建立一个Confusion Matrix:
这里预测正确的概率是:(TP + TN) / (TP + FP + FN + TN)
延申说一下:
FP:Type I error(本来是错的,被预测成对的)
FN:Type II error (本来是对的,被预测成错的)。
Coding(实战——气候科学中的EHI)
首先,什么是EHI?
EHI(热浪系数)>0说明热浪对身体有影响,反之则无影响。公式如下图所示:
先读入数据:
import numpy as np
import matplotlib.pyplot as plt
from netCDF4 import Dataset
file1 = 'pr_Amon_CESM1-CAM5_rcp85_r1i1p1_200601-210012.nc'
file2 = 'tas_Amon_CESM1-CAM5_rcp85_r1i1p1_200601-210012.nc'
ds1 = Dataset(file1,'r')
ds2 = Dataset(file2,'r')
pr = ds1.variables['pr'][:]
tas = ds2.variables['tas'][:]
lon = ds1.variables['lon'][:]
lat = ds1.variables['lat'][:]
我们这边以New York为例:
lon_NY_index = int((360 - 74)/(360/288))
lat_NY_index = int(40.7 / (180/192)) + 96
tas_NY = tas[:,lat_NY_index,lon_NY_index]
pr_NY = pr[:,lat_NY_index,lon_NY_index]
下面准备数据集:
Tips:LSTM是依赖于时间序列的,所以在进行数据集拆分的时候要注意不能打乱时间!
# prepare data
X = np.hstack((pr_NY[90:-2].reshape(-1,1), tas_NY[90:-2].reshape(-1,1)))
y = np.full([len(tas_NY)-92],np.nan)
for i in range(len(y)):
y[i] = ( np.mean(tas_NY[90+i:90+i+3]) - np.mean(tas_NY[i:i+90])) > 0
X_train = []
y_train = []
for i in range(10,int(len(X)*0.8)):
X_train.append(X[i-10:i,:])
y_train.append(y[i])
X_train, y_train = np.array(X_train), np.array(y_train)
X_test = []
y_test = []
for i in range(int(len(X)*0.8), len(X)):
X_test.append(X[i-10:i,:])
y_test.append(y[i])
X_test, y_test = np.array(X_test), np.array(y_test)
LSTM模型的建立(此处为方便起见我们只建立一层神经网络):
# build model
from keras.models import Sequential
from keras.layers import LSTM
from keras.layers import Dense
mymodel = Sequential()
mymodel.add(LSTM(10, input_shape=(X_train.shape[1], X_train.shape[2])))
mymodel.add(Dense(units=1, activation = 'sigmoid'))
神经网络建立起来之后我们进行训练及预测:
# compile
mymodel.compile(optimizer='adam', loss='mse')
mymodel.fit(X_train, y_train, epochs = 50, batch_size=50)
# prediction
y_pred = mymodel.predict(X_test)
y_pred = y_pred > 0.5
最后评价此模型:
from sklearn.metrics import confusion_matrix
c = confusion_matrix(y_pred, y_test)
accuracy = (c[0,0]+c[1,1])/(np.sum(c))*100
OK到这里我们基本了解LSTM模型,并且进行了实战。希望对你有帮助 :)