1 数学符号(Notation)

$ x^{<1>}, x^{<2>}, ..., x^{<t>}, ..., x^{<q>} $ 表示一段输入序列x,比如一句文字

$ y^{<1>}, y^{<2>}, ..., y^{<t>}, ..., y^{<q>} $ 表示输出序列y

$ T_{x} = T_{y} = q, $ 表示长度,x和y在长度可以不相等

$ x^{(i)<t>}, y^{(i)<t>}$ 表示第i个样本的第t个元素

$ T_{x}^{(i)}, T_{y}^{(i)} $ 表示第i个样本的x长度和y长度

构建一个表示单词的词典,对一般规模的商业应用来说3万到5万的大小比较常见,也有10万的,而大型互联网公司会用百万级甚至更大的词典。

例子中词典以1万词为例,统计常用的1万个词,使用one-hot来表示每个单词,由此来表示整段文字。对于不存在于词典的单词可以构建一个unknown词来表示。

2 循环神经网络模型(Recurrent Neural Network Model)

为什么不使用标准的神经网络呢?主要有两个问题。

首先时序问题中输入和输出都可以是不同长度的,你当然可以用填充来使输入输出单元数最大,但仍然不是很好的表示方式。

其次,单纯的神经网络并不能共享从文本的不同位置学到的特征,具体表现为,如果能学到了位置1出现的harry为人名的概率,当harry出现在其它位置时,也能自动识别为人名,这样就很棒了。

如下图所示,循环神经网络做的就是,在第一个时间步用$ x^{<1>} $ 来预测 $ y^{<1>} $

但是在第二个时间步的不仅接收$ x^{<1>} $ ,还接收来自第一个时间步的信息,以此类推。

要开始整个步骤,需要在第一个时间步接收一个默认的$ a^{<0>} $ 表示“来自第0个时间步的信息”,0向量是常见的选择,也可以随机初始化。

每个时间步的参数是共享的,记为$ W_{ax} $,下标ax中的x表示和x相乘,a表示计算a

水平激活值的参数记为 $ W_{aa} $,下标aa中的a表示和a相乘,计算a

输出激活值的参数记为 $ W_{ya} $,下表ya中的a表示和a相乘,y表示计算y

这个例子中,对序列的扫描是从左到右的,只使用了之前的信息来做出预测。使用BRNN则可以使用之前和之后的信息来预测。

输出a的激活函数g通常使用tanh,然后可以使用另外的方法来避免梯度消失。

输出y的激活函数决定于你的问题,如果是二分类则可能使用sigmoid

为了简化符号,$ W_{ya} = W_{y} $

为了简化符号,可以将两个W合并: $ [ W_{aa} | W_{ax} ] = W_{a} $

3 不同类型的循环神经网络(Different types of RNNs )

$ T_{x}, T_{y} $ 不一定相同,比如下图的几个例子中,音乐生成的输入可以为长度为1或空集而输出是一段序列;感情分类的输出可以是1到5的整数而输入是一个序列;命名实体识别中,输入和输出长度相同;机器翻译中输入和输出的序列长度不同。

基于此,可以分为几种不同的结构:

One-to-one(标准的神经网络,不需要RNN)

One-to-many (比如音乐生成)

Many-to-one(比如评论的情感分类)

Many-to-many(又分为输入和输出长度相同的和不同的,比如命名实体识别和机器翻译)

4 语言模型和序列生成(Language model and sequence generation)

如何用RNN来构建一个语言模型呢?

首先需要一个很大的文本语料库作为训练集,语料库由数量众多的句子组成。

假如你在语料库中得到一句话,你需要将它们切分标记(tokenize)为一个个one-hot向量,在这个过程可以自行决定要不要忽略标点

在某些应用中需要用额外的标记<EOS> 来定义句子的结尾

对于在字典中未出现的单词可以标记为<UNK>来统一处理

$ \hat{y}^{<1>} $ 是表示第一个位置出现的词的概率,根据softmax输出整个词典上的10002个词的概率,包括结束词和未知词,最后得到Cats的概率最大

预测 $ \hat{y}^{<2>} $ 的时候输入为y<1>,这个情况预测的是在第一个词为cats的情况下,为其它词的概率:P(词 | cats)

后面的时间步以此类推,最后得到P(EOS | ...)的概率。

定义每个时间步的softmax损失函数,求和得到最终的损失函数,然后优化。

5 RNN的梯度消失(Vanishing gradients with RNNs)

RNN和标准NN一样,随着网络层数的增加,导数有可能呈指数型减小或增加,容易发生梯度消失和梯度爆炸的问题。

对于梯度爆炸的问题很容易发现,你会发现很多NaN和非数字的情况,意味着神经计算出现了数值溢出,可以使用梯度裁剪(gradient clipping),观察某个梯度,当它大于某个阈值的时候,缩放梯度向量保证它不会太大。

然而梯度消失更难解决,接下来几节将介绍解决方法。

6 GRU单元(Gated Recurrent Unit)

标准的RNN利用上一时间步的激活值a和这一时间步的输入x计算出这一时间步的激活a $ a^{<t>} = g( W_a [a^{<t-1>}, x^{t}] + b_a) $

然后用激活a计算这一时间步的输出y: $ \hat{y}^{<t>} = g( W_y  a^{t} + b_y ) $

GRU,为了句子能在猫吃了很多东西之后,仍然能对be动词形式做出正确判断(was还是were),用了细胞单元来记忆信息。

在GRU这里,记忆单元c会输出激活值a,二者是一样的,在LSTM中这两者代表的是不同值。

在每个时间步计算一个候选值 $ \tilde{c}^{<t>} = tanh( W_c [ c^{<t-1>}, x^{<t>} ] + b_c ) $

GRU重要的思想是使用一个更新门 $ \Gamma_u = \sigma ( W_u [ c^{<t-1>}, x^{<t>} ] + b_u ) $ ,它的输出在0到1之间,大部分的输出是在非常接近0或非常接近1。

由更新门来决定是否更新记忆单元的值,这样在扫描整句话的时间,在每个时间步就会决定是要更新还是不更新记忆信息,比如例子中的cat的相关信息就会被一直保存,直到遇到要选择was/were的时候,就根据记忆单元里的cat信息来做出判断,随后就可以不再保存记忆单元中的cat信息

$ c^{<t>} = \Gamma_u * \tilde{c}^{<t>} + (1 - \Gamma_u) *  c^{<t-1>}$

更新/保存的c会传到下一时间步,另外可以根据更新/保存的c计算出这一时间步的输出y

更新门的作用就是保存记忆信息,然后一直不更新,直到需要使用的时候。

由于更新门很容易取到一个很接近0的数,那么c的值被保留下来了,这样就可以缓解梯度消失的问题了,因为即使经过很多很多时间步,历史信息依然被保存下来了,因此允许神经网络训练有着非常庞大依赖范围的序列,比如例子中的cat和was被很多句子分割开。

更新门不只能保存cat和was的关系信息,比如它们维度是100,那么就可以保存100种类型的记忆信息,决定是否更新,你可以决定一些比特更新而另一些比特不更新。

现实中的更新门比特不是确切的0/1,只是接近的值。

上述说的是一个简化后的GRU,完整的GRU会增加一个相关门,如下图所示。

有很多设计使得网络的类型多种多样,多年来科研人员做了很多实验来设计这些单元,尝试让深度网络产生更大范围的影响,还有解决梯度消失的问题,GRU就是研究者们常用的一个版本,也被发现在很多不同问题上也是非常健壮和实用的。研究者们也尝试了很多其它版本,类似的但是不完全一样(similar but exactly not the same)

7 LSTM(long short term memory )unit

LSTM中细胞单元c不再等于激活值a,计算候选值使用的是激活值a,$ \tilde{c}^{<t>} = tanh( W_c [ a^{<t-1>}, x^{<t>} ] + b_c ) $

LSTM中使用三个门,更新门,遗忘门和输出门。

$ \Gamma_u = \sigma ( W_u [ a^{<t-1>}, x^{<t>} ] + b_u ) $

$ \Gamma_f = \sigma ( W_f [ a^{<t-1>}, x^{<t>} ] + b_f ) $

$ \Gamma_o = \sigma ( W_o [ a^{<t-1>}, x^{<t>} ] + b_o ) $

细胞的更新不再像GRU一样用单独的更新门控制,而是用更新门和遗忘门来控制

$ c^{<t>} = \Gamma_u * \tilde{c}^{<t>} + \Gamma_f *  c^{<t-1>}$

最后的激活值由输出门来控制 $ a^{<t>} = \Gamma_o *  c^{<t>}$

如下图所示,再c更新的那条连着的横线中可以看出,只要合理地设置三个门,c的值是可以一直往下一个时间步传递下去的。

此外还有另外的版本,在计算三个门的时候不只用到a和x,还加入了上一个细胞的信息$ c^{<t-1>} $ ,这叫作窥视孔连接(peephole connection)

对于使用GRU还是LSTM,没有统一的准则,LSTM通常是默认的选择,但是GRU也获得了很多的支持因为它简单而且效果还不错。

GRU是在LSTM的基础上进行的简化,他的优点是更加简单,更容易创建一个更大的网络,而且它只有两个门,运行得更快。

但LSTM更加强大和灵活,因为它有三个门而不是两个。

8 双向RNN(Bidirectional RNN)

双向RNN可以让你在序列的某点既能获取之前的信息,也能获取未来的信息。

如图所示,就是反向连接一下,这样就有两个输出a,接在一起来决定最后的输出y。

每个模块可以是传统RNN也可以是LSTM也可以是GRU。

事实,上对于很多包含大量文本的NLP问题,带LSTM的双向RNN模型是最常用的。

双向RNN的一个缺点就是你需要完整的数据序列,你才能预测任意位置。

9 深层循环神经网络(Deep RNNs)

通常会把多个RNN叠起来构建更深的模型,如下图所示,是一个三隐层的RNN。

ng-深度学习-课程笔记-15: 循环序列模型(Week1)的更多相关文章

  1. 深度学习课程笔记(八)GAN 公式推导

    深度学习课程笔记(八)GAN 公式推导 2018-07-10  16:15:07

  2. 深度学习课程笔记(十一)初探 Capsule Network

    深度学习课程笔记(十一)初探 Capsule Network  2018-02-01  15:58:52 一.先列出几个不错的 reference: 1. https://medium.com/ai% ...

  3. 深度学习课程笔记(十八)Deep Reinforcement Learning - Part 1 (17/11/27) Lectured by Yun-Nung Chen @ NTU CSIE

    深度学习课程笔记(十八)Deep Reinforcement Learning - Part 1 (17/11/27) Lectured by Yun-Nung Chen @ NTU CSIE 201 ...

  4. 深度学习课程笔记(十七)Meta-learning (Model Agnostic Meta Learning)

    深度学习课程笔记(十七)Meta-learning (Model Agnostic Meta Learning) 2018-08-09 12:21:33 The video tutorial can ...

  5. 深度学习课程笔记(十六)Recursive Neural Network

    深度学习课程笔记(十六)Recursive Neural Network  2018-08-07 22:47:14 This video tutorial is adopted from: Youtu ...

  6. 深度学习课程笔记(十五)Recurrent Neural Network

    深度学习课程笔记(十五)Recurrent Neural Network 2018-08-07 18:55:12 This video tutorial can be found from: Yout ...

  7. 深度学习课程笔记(十四)深度强化学习 --- Proximal Policy Optimization (PPO)

    深度学习课程笔记(十四)深度强化学习 ---  Proximal Policy Optimization (PPO) 2018-07-17 16:54:51  Reference: https://b ...

  8. 深度学习课程笔记(十三)深度强化学习 --- 策略梯度方法(Policy Gradient Methods)

    深度学习课程笔记(十三)深度强化学习 --- 策略梯度方法(Policy Gradient Methods) 2018-07-17 16:50:12 Reference:https://www.you ...

  9. 深度学习课程笔记(十)Q-learning (Continuous Action)

    深度学习课程笔记(十)Q-learning (Continuous Action) 2018-07-10 22:40:28 reference:https://www.youtube.com/watc ...

随机推荐

  1. angularjs基础——变量绑定

    1)弄一个ng-app(angularjs 应用) 2)在里面用ng-model(angularjs 模型)就可以定义一个模型变量 3)使用模版方法就可以输出变量了(例如:{{name}}) 示例: ...

  2. 查看系统负载:uptime

    uptime命令用于查看系统负载,跟 w 命令的输出内容一致 [root@localhost ~]$ uptime :: up days, :, users, load average: 0.03, ...

  3. MFC-TCP连接代码片段(支援大富的)

    BOOL CClientSocketTestDlg::OnInitDialog() { CDialogEx::OnInitDialog(); ........................ // T ...

  4. IntersectRect、wcsrchr、CComPtr、GetFileAttributes

    IntersectRect    两矩形相交形成的新矩形 The IntersectRect function calculates the intersection of two source re ...

  5. 谷歌Volley网络框架讲解——Network及其实现类

    我们看到Network接口只有一个实现类BasicNetwork,而HttpStack有两个实现类. BasicNetwork这个类是toolbox工具箱包里的,实现了Network接口. 先来看下N ...

  6. MyBatis——Mapper XML 文件

    Mapper XML 文件 MyBatis 的真正强大在于它的映射语句,也是它的魔力所在.由于它的异常强大,映射器的 XML 文件就显得相对简单.如果拿它跟具有相同功能的 JDBC 代码进行对比,你会 ...

  7. CentOS下安装cvechecker并进行主机基线安全检查

    一.cvechecker的安装 1.首先下载cvechecker并解压该文件: cd /home/username mkdir cve wget https://raw.githubuserconte ...

  8. 《FPGA那些事儿》原创教程总结

    经过我们黑金工程师多年的不断努力,黑金原创教程已经达到了14部,包括: 第一部:[黑金原创教程]NIOSII那些事儿 http://www.heijin.org/forum.php?mod=viewt ...

  9. Android中textView自动识别电话号码,电子邮件,网址(自动加连接)

    extends:http://blog.csdn.net/wx_962464/article/details/8471195 其实这个是很简单的,在android中已经为我们实现了,但是我估计很多人都 ...

  10. Javaweb程序打包或exe执行文件

    java程序的打包与发布 这里主要是讲解一下怎样将 Java程序打包成独立运行的exe程序包,以下这种方法应该是最佳的解决方案了.NetDuke的EXE程序包了是使用这种方案制作的.在操作步骤上还是比 ...