Long Short-Term Memory(LSTM)

版权声明:本文为博主自我学习整合内容,欢迎转载,转载请注明出处。 https://blog.csdn.net/qq_39388410/article/details/78674558

循环神经网络(Recurrent Neural Network,RNN)可以通过许多不同的方式建立,但就像几乎所有函数都可以被认为是前馈网络,基本上任何涉及循环的函数可以被认为是一个循环神经网络。它的基本结构以及其展开的理解如下图所示:

这里写图片描述
同一网络被视为展开的计算图,其中每个节点现在与一个特定的时间实例相关联。
h ( t ) = f ( U x t + W h ( t 1 ) ) \mathrm h^{(t)}=f(U\mathrm{x}_t+W\mathrm h^{(t-1)})
之前在神经网络中证明过如果加深网络的话可能会造成梯度消失或者梯度爆炸,在RNN中也是,这就导致了RNN不能处理长期依赖数据的问题,即随着时间的推移,以前的数据会影响非常小,且时间间隔非常小,很难处理超过10的序列。不过只要有需求就会有技术!其中一个RNN的变体–Long Short-Term Memory(LSTM)的表现在处理这个问题上非常好。它主要是采用了模块记忆体,将数据给记录下来,从而可以保存比较长时间的信息,具体的结构如下:

这里写图片描述

比照人脑的记忆运行,LSTM相比RNN它的结构特意的添加了:
遗忘机制(forgetting mechanism),即遗忘门,当新输入来时,它专注于需要记住哪些信息,以及需要丢弃哪些信息。
保存机制(saving mechanism),即输入门,用于保存信息。
所谓“门”用以控制输入的向量,即可以看成是一个普通的全连接层: g ( x ) = σ ( W x + b ) g(\mathbf{x})=\sigma(W\mathbf{x}+\mathbf{b})
回忆人类在面对事件时,总是依据现有事实再从以往经验中那些对当前境况有用的经验中提取有利的信息用以综合判断,解决事件。所以当新输入来时,往往需要先决定新输入中的哪部分信息是有用的,并将它们保存在自己的长期记忆体中,再搜索判断存于长期记忆体中的记忆哪些是对当前状态有用的,最后综合得出结果。于是可以看到整个结构图:

这里写图片描述

在上图中,可以看到这些细胞之间彼此循环相连用以代替一般循环网络中普通的隐藏单元,所有门控单元都具有Sigmoid非线性,而输入单元可具有任意的压缩非线性。其中黑色方块表示单个时间步的延迟。
它不仅有外部RNN的循环,还有内部状态单元的线性自环,因此它不仅仅是简单的向输入和循环单元的仿射变换之后施加一个逐元素的非线性。自环权重由循环门控制
f i ( t ) = σ ( b i f + U f x ( t ) + W f h ( t 1 ) ) f_i^{(t)}=\sigma(b_i^f+\sum U^fx^{(t)}+\sum W^fh^{(t-1)})
g i ( t ) = σ ( b i g + U g x ( t ) + W g h ( t 1 ) ) g_i^{(t)}=\sigma(b_i^g+\sum U^gx^{(t)}+\sum W^gh^{(t-1)})
q i ( t ) = σ ( b i q + U q x ( t ) + W q h ( t 1 ) ) q_i^{(t)}=\sigma(b_i^q+\sum U^qx^{(t)}+\sum W^qh^{(t-1)})
b,U,W分别是偏置,输入权重和遗忘门的循环权重。f,g,q分别是遗忘门和输入门,输出门。记忆体细胞的更新为:
c t = f t c t 1 + i t c ~ t \mathbf{c}_t=f_t\circ{\mathbf{c}_{t-1}}+i_t\circ{\mathbf{\tilde{c}}_t}
输出为 h t = σ ( W [ h t 1 , x t ] + b ) tanh ( c t ) \mathbf{h}_t=\sigma(W\cdot[\mathbf{h}_{t-1},\mathbf{x}_t]+\mathbf{b})\circ \tanh(\mathbf{c}_t)
然后通过反向传播调整参数训练网络即可。

论加法与乘法。
为什么结构图中有些地方用了 \circ ,有些地方用了 + + 呢?
乘法直观来讲是作为一种对信息某种控制的操作(比如乘0就消失,1不变,其他的数作放大缩小反向等),而加法可以看作是新信息叠加旧信息。当然了,lstm的设置肯定不会仅仅从直观来判断,如果把两者进行比较会发现如果不这样做将没办法解决梯度问题。

为什么记忆要分长期记忆和有利记忆,而不是直接用同一种记忆呢?
门控递归单元(Gated Recurrent Units,GRU)本质上就是一个没有输出门的LSTM,因此它在每个时间步都会将记忆单元中的所有内容写入整体网络,即直接使用了同一种记忆。具体的实现区别在于GRU单个门控同时控制遗忘因子和更新状态单元的决定。

这里写图片描述
输出更新的方式变为:
h i ( t ) = u i ( t 1 ) h i ( t 1 ) + ( 1 u i ( t 1 ) ) σ ( b i + U x ( t ) + W r ( t 1 ) h ( t 1 ) ) h_i^{(t)}=u_i^{(t-1)}h_i^{(t-1)}+(1-u_i^{(t-1)})\sigma(b_i+\sum Ux^{(t)}+\sum Wr^{(t-1)}h^{(t-1)}) 其中u是更新门(Update Gate),r是复位门(Reset Gate)。
u i ( t ) = σ ( b i u + U u x ( t ) + W u h ( t ) ) u_i^{(t)}=\sigma(b_i^u+\sum U^ux^{(t)}+\sum W^uh^{(t)})
r i ( t ) = σ ( b i r + U r x ( t ) + W r h ( t ) ) r_i^{(t)}=\sigma(b_i^r+\sum U^rx^{(t)}+\sum W^rh^{(t)})

LSTM应用:
基于keras的时间序列预测

from keras.layers.core import Dense, Activation, Dropout
from keras.layers.recurrent import LSTM
from keras.models import Sequential

#载入自己数据,并进行基本的数据切分和归一化预处理
X_train, y_train, X_test, y_test = load_data('text.csv')

model = Sequential()
model.add(LSTM(input_shape=(None, 1), return_sequences=True, units=50))
model.add(Dropout(0.2))
model.add(LSTM(100,return_sequences=False))
model.add(Dropout(0.2))
model.add(Dense(units=1))
model.add(Activation("linear"))

model.compile(loss="mse", optimizer="rmsprop")
print ("Compilation Time : ", time.time() - start)

model.fit(X_train,y_train,batch_size=50,epochs=20,validation_split=0.05)

#重载数据用以画图
f=open('text.csv')
df=pd.read_csv(f)
data=np.array(df[kdata])
data=data[::-1]

#预测数据并画图
predicted = model.predict(X_test)
print(predicted)
predicted = np.reshape(predicted, (predicted.size,))
plt.plot(data,'y')
plt.plot(list(range(len(data),len(data)+len(X_test))),predicted,'b')
plt.show()

在这里插入图片描述
主要参考:
bengio deep learning

猜你喜欢

转载自blog.csdn.net/qq_39388410/article/details/78674558