首页 > 技术文章 > RNN汇总

lunge-blog 2019-11-18 12:03 原文

 

RNN(Recurrent Neural Network)循环神经网络。

对于CNN来说,比如图像处理,它逐渐从局部空间抽象到全局空间,有一种空间层次感,通道可以与空间一起卷积,也可以分开卷积。同时由于卷积权重共享,它可以减少参数。

对RNN来说,它擅长处理序列问题,也就是输入中存在依赖的情况,比如预测下一个词语(N对N),情感分类(N对1),encoder-decoder(如seq2seq,N对M)等。

本文力求简洁,仅做概要总结。

1,简单RNN分析

 

如图,这里以N对N为例,X为输入,y为输出,h为隐藏状态。

假设输入X_t对应权重矩阵为U,隐藏状态h_t-1对应的的权重为W,输出y_t对应的权重为V,这里U,W,V一般对各个时刻t来说是共享的。

对于t时刻,有以下公式:

 其中第一个激活函数一般为tanh或relu等,第二个一般为softmax。第一式以矩阵方式运行,提高效率。

TensorFlow调用:

tf.nn.rnn_cell.BasicRNNCell(
    num_units,
    activation=None,# type string
    reuse=None,
    name=None,
    dtype=None,
    **kwargs,
)

BPTT(back-propagation through time):反向传播

t时刻的损失为:

 

 求和,求偏导:

 

 

 

 如果我们以tanh作为激活函数,则中间项

 

 由于tanh函数偏导小于1,多次连乘导致“梯度消失”,如果采用relu激活,导数为1容易导致“梯度爆炸”。

解决梯度爆炸:通过梯度裁剪,容易处理

解决梯度消失:下面将要介绍的LSTM

2,LSTM(长短期记忆)

LSTM通过门的操作来实现信息的选取,遗忘门通过一个sigmoid激活函数对上一个细胞状态c_t-1进行更新,再加上输入门的新信息。

可以看到,上面水平线中,只有与门的2个交换操作,以及一个CEC(常量误差传播子,权值为1的自连接,一个线性激活,保证误差传递而不会发生梯度消失或爆炸)。

 

 

相关公式为:

 

 

 

 

 

 

 TensorFlow实现:

tf.nn.rnn_cell.BasicLSTMCell(
    num_units,
    forget_bias=1.0,#Ger et al等在2000年提出,遗忘门偏置为1使得LSTM更加健壮。
    state_is_tuple=True,
    activation=None,
    reuse=None,
    name=None,
    dtype=None,
    **kwargs,
)

3,LSTM变体

  • 变体1:添加图中深色部分连接。个人理解:输入和遗忘部分加入之前的细胞状态学习可以获得更多context信息,输出门添加基于新的细胞状态信息学习。感觉上比基础LSTM要厉害些,也没增加参数。

 

  •  变体2:输入i_t直接用1-f_t表示。个人认为这样做不太恰当,需要遗忘的细胞状态信息,以及需要增加的输入信息,它们应该分开学习。共同学习存在一种矛盾:比如遗忘的部分想要降低参数,而增加的部分想要提高参数。好处是参数减少了。

 

  •  变体3:GRU。使用2个门(重置门和更新门)代替LSTM的3个门,计算效率高,内存占用少,效果差不多,实际中比较流行。将细胞状态c与隐藏状态h合并,这个变体思想类似变体1,参数减少了不少。

 

 

TensorFlow GRU实现

tf.nn.rnn_cell.GRUCell(
    num_units,
    activation=None,
    reuse=None,
    kernel_initializer=None,
    bias_initializer=None,
    name=None,
    dtype=None,
    **kwargs,
)

 

参考资料

https://blog.csdn.net/zhaojc1995/article/details/80572098

《python深度学习》

 

 

 

推荐阅读