当前位置:   article > 正文

RNN——循环神经网络(tensorflow)_tensorflow rnn

tensorflow rnn

1、RNN的基本设定

在语言模型任务中,给定特定的单词序列(句子片段),任务目标是预测该片段的下一个单词(或者符号)。传统的n-gram模型可以应用于该任务,但是它存在着许多难以解决的问题:假设预测序列为 Tom open his ___

①强假设问题:n-gram模型的构建依赖于过强的假设,即假设待预测的第n各单词只依赖于它之前的n-1个单词,即:

P(x^{(t+1)}|x^{(t)},...,x^{(1)})=p(x^{(t+1)}|x^{(t)},...,x^{(t-n+2)})

②稀疏问题:由于n-gram模型的预测靠的是第对条件概率:

P(x^{(t+1)}|x^{(t)},...,x^{(t-n+2)})=\frac{P(x^{(t+1)},x^{(t)},...,x^{(t-n+2)})}{P(x^{(t)},...,x^{(t-n+2)})}=\frac{count(x^{(t+1)},x^{(t)},...,x^{(t-n+2)})}{count(x^{(t)},...,x^{(t-n+2)})}

如果分子统计量为0,则预测概率会被模型直接置为0;如果分母的统计量为0,则无法正确地计算预测概率。当我们试图通过增大n-gram模型中的参数n来扩展待预测单词的语境以达到更好的效果是,稀疏问题会变得愈发严重。

③存储问题:为了更好得到n-gram模型,我们需要对训练语料中的所有n元组进行计算并存储相关数据;当n或者语料增大时,模型大小也会随之增大。

面对传统n-gram模型的种种问题,我们希望得到一个不依赖于过强假设、不会出现稀疏问题、可以更好利用语境与句中的长距离依赖关系、且模型的大小不会随着输入的变化而变化的模型。由此引入RNN模型。

2、RNN是什么?

Recurrent Neural Networks(RNN)是一类神经网络结构,最基础的RNN结构如下:

最基础的RNN模型分为上中下三层。中间的红色部分称为隐藏层,每个红色方框表示一个隐藏状态。RNN的特点:每个隐藏状态h^{(t)}的值都依赖于它前一个隐藏状态h^{(t-1)}和当前状态的输入值x^{(t)},并且模型中很多参数都是共享的。所谓共享是指,虽然模型中不同的隐藏状态处于不同的位置,但是他们的输入、输出、以及状态转移时所使用的参数矩阵(E,W_{t},U)(E,W_{t},U)是相同的。并且由于RNN结构中隐藏状态的处理在时间上是有先后顺序,只有处理完前一个隐藏状态才能处理当前的状态,因此隐藏状态又被称为时间步。

3、RNN在语言模型任务中的应用

①首先,给定一个输入句子S=x_{1}x_{2}...x_{n},可以通过查词库得到每个单词x_{t}的one-hot向量表示(x^{t}\in R^{|V|});之后,利用词向量矩阵E得到每个单词对应的词向量e^{t}=Ex^{t},e^{t}\in R ^{d},d表示词向量的维度;

②然后,有了输入的词向量之后,按照顺序对每个隐藏状态进行计算:

 

h(t)=σ(Whh(t1)+Wee(t)+b1),h(t)RDh

其中,D_{h}表示隐藏状态的维度,W_{h}表示隐藏状态间的转换矩阵,W_{e}表示输入与隐藏层间的转换矩阵;

③最后,通过softmax层给出模型对单词概率的预测\hat{y}^{(t)}=softmax(Uh^{(t)} + b_{2})\in R^{|V|},其中,U表示从隐藏层到输出之间的权重矩阵。

以任务预测句子 the student opened their ___ 的下一个单词为例,其过程如下图所示:

 

4、RNN的优缺点

优点:

①可以处理任意长度的输入,且模型大小不会随着输入的增长而变化;模型中的参数量是固定的,与输入大小无关。

②理论上,对隐藏状态h^{(t)}进行计算时,可以利用多步之前的信息。

缺点:

①计算缓慢:必须计算完迁移状态才能计算当前状态,我们只能序列化的计算所有状态而无法利用并行算法加速计算。

②虽然理论上RNN可以利用多步以前的信息,然而实践当中很难做到这一点。

5、RNN模型的训练过程与反向传播(https://zhuanlan.zhihu.com/p/101928642

6、梯度消失与梯度爆炸(https://zhuanlan.zhihu.com/p/101928642

梯度消失:随着反向传播的前进,梯度越来越小,小到几乎为0。这样远小于来自附近的梯度信息的来自远处的梯度信息就会丢失,模型的权重参数也就只受附近信息的影响,而不受远处信息的影响。

梯度爆炸:反向传播时梯度的数值迅速变得非常巨大。

对于梯度爆炸的解决方法:

假设对于代价函数J(W, b)的梯度图如图所示: 

 

对于含有陡峭悬崖的梯度模型,需要进行梯度阶段(Gradient Clipping)。其中红色的点为最优值的位置,如果使用梯度截断法(如右图),则可以使梯度在接近悬崖时降低步伐(学习率衰减),如果不使用梯度截断法(如左图),则可能由于过大的学习率使当前的参数被”抛出“曲面。

7、LSTM(Long Short-Term Memory) 

LSTM是一种时间循环神经网络,是为了解决一般的RNN存在的梯度消失问题而专门设计出来的。

输入门:对输入的信息进行选择性的输入;遗忘门:对前一状态的信息进行选择性的记忆;输出门:对当前状态的信息进行选择性的输出;记忆单元:存储历史信息。

 

LSTM向前传递的更新公式:

整体的LSTM序列:

一个LSTM单元的内部详细结构图: 

 

8、GRU(Gated Recurrent Unit)

门控循环单元(GRU)旨在解决标准RNN中出现的梯度消失问题。CRU背后的原理很LSTM非常相似,可以看作LSTM的变体。

CRU有两个门:重置门(reset gate)和更新门(update gate)。重置门决定了如何将新的输入信息与前面的记忆结合,更新门定义了前面记忆保存到当前时间步的量。

 

9、Bidirectional RNN

在电影点评的情感分类任务中,有评论:the movie was terribly exciting!当RNN只有一个方向,从左往右读取时,terribly则会被理解成负面评论,然后真实情况是 terribly exciting = very exciting。由此,我们不仅仅需要考虑过去的信息,也需要考虑未来的信息。由此,双向RNN被提出。对于双向的RNN,需要输出的是完整的句子,而语言模型任务只有左边的信息不是完整的句子,故而不适用双向RNN。

10、Multi-layer RNN

11、RNN小例子:

  1. import tensorflow as tf
  2. from tensorflow.examples.tutorials.mnist import input_data
  3. #载入数据集
  4. mnist = input_data.read_data_sets("MNIST_data/",one_hot=True)
  5. #输入图片是28*28
  6. n_inputs = 28 #输入一行,一行有28个数据
  7. max_time = 28 #一共28行
  8. lstm_size = 100#隐层单元
  9. n_classes = 10 #10个分类
  10. batch_size = 50#每个批次50个样本
  11. n_batch = mnist.train.num_examples //batch_size #计算一共有多少批次
  12. #这里的none表示第一个维度可以是任意长度
  13. x = tf.placeholder(tf.float32,[None,784])
  14. #正确的标签
  15. y = tf.placeholder(tf.float32,[None,10])
  16. #初始化权值
  17. weights = tf.Variable(tf.truncated_normal([lstm_size,n_classes],stddev=0.1))
  18. #初始化偏置值
  19. biases = tf.Variable(tf.constant(0.1,shape=[n_classes]))
  20. #定义RNN网络
  21. def RNN(X, weights, biases):
  22. #inputs=[batch_size, max_time, n_inputs]
  23. inputs = tf.reshape(X,[-1,max_time,n_inputs])
  24. #定义LSTM基本CELL
  25. lstm_cell = tf.contrib.rnn.core_rnn_cell.BasicLSTMCell(lstm_size)
  26. #final_state[state,batch_size,cell.state_size]
  27. #final_state[0]是cell state
  28. #final_state[1]是hidden_state
  29. #outputs:The RNN output 'Tensor'
  30. # If time_major == False(default), this will be a 'Tensor' shaped:
  31. # [batch_size,max_time,cell.output_size]
  32. # If time_major == Ture, this will be a 'Tensor' shaped:
  33. # [max_time,batch_size,cell.output_size]
  34. outputs,final_state= tf.nn.dynamic_rnn(lstm_cell,inputs,dtype=tf.float32)
  35. results = tf.nn.softmax(tf.matmul(final_state[1],weights)+biases)
  36. return results
  37. #计算RNN的返回结果
  38. prediction = RNN(x,weights,biases)
  39. #损失函数
  40. cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=prediction,labels=y))
  41. #使用AdamOpimizer进行优化
  42. train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
  43. #结果存放在一个布尔型列表中
  44. correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(prediction,1))#argmax返回一维张量中最大值的位置
  45. #求准确率
  46. accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))#把correct_prediction变为float32类型
  47. with tf.Session() as sess:
  48. sess.run(tf.global_variables_initializer())
  49. for epoch in range(6):
  50. for batch in range(n_batch):
  51. batch_xs,batch_ys = mnist.train.next_batch(batch_size)
  52. sess.run(train_step,feed_dict={x:batch_xs,y:batch_ys})
  53. acc = sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels})
  54. print("Iter"+str(epoch)+",Testing Accuracy="+str(acc))

参考资料:

https://zhuanlan.zhihu.com/p/101928642

https://www.bilibili.com/video/av46216519?p=7

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号