循环神经网络的简单实现:
import tensorflow as tf x=[1,2] state=[0.0,0.0] w_cell_state=np.array([[0.1,0.2],[0.3,0.4]]) w_cell_input=np.array([0.5,0.6]) b_cell=np.array([0.1,-0.1]) w_output=np.array([1.0,2.0]) b_output=0.1 for i in range(len(x)): before_a=np.dot(state,w_cell_state)+x[i]*w_cell_input+b_cell state=np.tanh(before_a) final_out=np.dot(state,w_output)+b_output print(before_a) print(‘state:‘, state) print(‘final_out:‘, final_out)
与单一tanh循环体结构不同,LSTM是一个拥有三个门结构的特殊网络结构。
LSTM靠一些门结构让信息有选择性的影响循环神经网络中每个时刻的状态,所谓的门结构就是一个使用sigmoid神经网络和一个按位做乘法的操作,这两个操作合在一起就是一个门结构。之所以该结构叫门是因为使用sigmoid作为激活函数的全连接神经网络层会
输出一个0到1之间的数值,描述当前输入有多少信息量可以通过这个结构。LSTM单元结构示意图如下所示:
为了使循环神经网络更有效的保存长期记忆,遗忘门和输入门是LSTM核心,遗忘门的作用是让神经网络忘记之前没有用的信息,遗忘门会根据当前的输入xt、上一时刻状态ct-1和上一时刻输出ht-1共同决定哪一部分记忆需要被遗忘。
在循环神经网络忘记了部分之前的状态后,它还需要从当前的输入补充最新的记忆。这个过程就是输入门完成的,输入门会根据xt、ct-1和ht-1决定哪些部分进入当前时刻的状态ct。比如当看到文章中提到环境被污染之后,模型需要将这个信息写入
新的状态,通过遗忘门和输入门,LSTM可以更有效的决定哪些信息应该被遗忘,哪些信息应该得到保留。
LSTM结构在计算得到新的状态ct后需要产生当前时刻的输出,该过程通过输出门完成,输出门会根据最新的状态ct、上一时刻的输出ht-1和当前的输入xt来决定该时刻的输出ht。如下代码展示了tensorflow中实现LSTM结构的循环神经网络的前向传播过程:
#定义一个LSTM结构,通过一个简单的命令实现一个完整的LSTM结构,LSTM中使用的变量也会在该函数中自动被声明 lstm=tf.nn.rnn_cell.BasicLSTMCell(lstm_hidden_size) #将LSTM中的状态初始化为全0数组,在优化循环神经网络时,每次也会使用一个batch的训练样本。 state=lstm.zero_state(batch_size,tf.float32) loss=0.0 for i in range(num_steps): #在第一个时刻声明LSTM结构中使用的变量,在之后的时刻都需要复用之前定义好的变量 if i>0: tf.get_variable_scope().reuse_variables() #每一步处理时间序列中的一个时刻,将当前输入(current_input)和前一时刻状态(state)传入定义的LSTM结构可以得到当前LSTM结构的输出lstm_output和更新后的状态state lstm_output,state=lstm(current_input,state) #将当前时刻LSTM结构的输出传入一个全连接层得到最后的输出 final_output=fully_connected(lstm_output) #计算当前时刻输出的损失 loss+=calc_loss(final_output,expected_output)