前言
这篇主要讲述LSTM的基本过程以及实现代码,LSTM是一种RNN模型,是对Simple RNN的改进 如下图,LSTM有四个参数矩阵 LSTM避免梯度消失问题,可以有更长的记忆
LSTM基础知识
传输带记为向量c,解决梯度消失问题,过去的信息通过传输带直接送到下一个时刻,不会发生太多的变化 LSTM中有很多Gate,可以有选择的让信息通过 sigmoid函数 sigmoid作用到向量a的每一个元素上,将每一个元素都压到0-1之间 算出f向量之后,计算传输带向量c和遗忘门向量f的Elementwise multiplication
遗忘门f 有选择的让传输带c的值通过,假如f的一个元素是0,那么c对应的元素就不能通过对应的输出是0,如果是1,那么c对应的元素全部通过,对应输出是c的本身 遗忘门
f
t
f_t
ft?是上一个状态
h
t
?
1
h_{t-1}
ht?1?与当前输入x的函数,状态
h
t
?
1
h_{t-1}
ht?1?与输入
x
t
x_t
xt?做串联操作得到更高维的向量,然后算矩阵Wf与这个向量的乘积,得到一个向量,再用sigmoid的函数得到向量
f
t
f_t
ft?。`
f
t
f_t
ft?的每一个元素都介于0和1之间。 遗忘门有一个参数矩阵$w_f$,需要通过反向传播从训练数据学习
输入门 把旧的状态
h
t
?
1
h_{t-1}
ht?1?与新的输入
x
t
x_t
xt?做串联,得到更高维的向量 然后算矩阵
W
i
W_i
Wi?与这个向量的乘积得到一个向量,最后再用sigmoid函数得到向量
i
t
i_t
it?,
i
t
i_t
it?的每一个元素都介于0和1之间。 这里的激活函数是双曲正切函数 把旧状态
h
t
?
1
h_{t-1}
ht?1?,与新输入xt做串联操作,再乘以参数矩阵。区别在于激活函数不是Sigmoid,而是双曲正切函数
t
a
n
h
tan_h
tanh?,所以算出的向量的元素都介于[-1,1]之间,同时如图可知计算该向量
c
t
’
c_t’
ct?’也需要单独的一个参数矩阵,记作
w
c
w_c
wc?
更新
c
t
c_t
ct?的值 用遗忘门
f
t
f_t
ft?和传送带旧的值
c
t
?
1
c_{t-1}
ct?1?算Elementwise multiplication 计算输入门
i
t
i_t
it?和新的值
c
t
’
c_t’
ct?’的Elementwise multiplication 计算输出门向量
O
t
O_t
Ot? 旧的状态
h
t
?
1
h_{t-1}
ht?1?与新的输入
x
t
x_t
xt?做串联,得到更高维的向量,然后算矩阵
w
o
w_o
wo?与这个向量的乘积得到一个向量,最后再用sigmoid函数得到向量
O
t
O_t
Ot? 输出门也有自己的参数矩阵
w
0
w_0
w0?
计算状态向量
h
t
h_t
ht? 对传输带
c
t
c_t
ct?的每一个元素求双曲正切函数,把元素全都压到[-1,1]的区间,然后求这两个向量的Elementwise multiplication Lstm参数 LSTM有遗忘门,输入门,new value以及输出门,这四个模块都有各自的参数矩阵w,所以一共有四个参数矩阵 using keras 总结
代码实现 只需将上篇的simple RNN改成LSTM 即可 from keras.layers import LSTM, Dense, Embedding
'数据集读取与预处理'
from keras.datasets import imdb
from keras import preprocessing
max_feature = 10000
maxlen = 500
(input_train, y_train), (input_test, y_test) = imdb.load_data(num_words=max_feature)
print(len(input_train), 'train sequences')
print(len(input_test), 'test sequences')
print('sequence 格式:(samples*time)')
input_train = preprocessing.sequence.pad_sequences(input_train, maxlen=maxlen)
input_test = preprocessing.sequence.pad_sequences(input_test, maxlen=maxlen)
print('input_train shape:', input_train.shape)
print('input_test shape:', input_test.shape)
'定于模型:Simple RNN'
from keras.models import Sequential
from keras.layers import LSTM, Dense, Embedding
'词嵌入操作:降低输入向量维度'
embedding_dim = 32
model = Sequential()
model.add(Embedding(max_feature, embedding_dim, input_length=maxlen))
'Simple RNN Layer'
state_dim = 32
model.add(LSTM(state_dim, return_state=False))
model.add(Dense(1, activation='sigmoid'))
'设定优化算法以及模型评价标准'
model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])
'设置训练模型'
history = model.fit(
input_train, y_train,
epochs=10,
batch_size=128,
validation_split=0.2
)
model.summary()
'查看模型最终性能'
loss_and_acc = model.evaluate(input_test, y_test)
print('loss=' + str(loss_and_acc[0]))
print('acc=' + str(loss_and_acc[1]))
|