【李宏毅机器学习笔记】5、Logistic Regression
【李宏毅机器学习笔记】6、简短介绍Deep Learning
【李宏毅机器学习笔记】7、反向传播(Backpropagation)
【李宏毅机器学习笔记】8、Tips for Training DNN
【李宏毅机器学习笔记】9、Convolutional Neural Network(CNN)
【李宏毅机器学习笔记】10、Why deep?(待填坑)
【李宏毅机器学习笔记】11、 Semi-supervised
【李宏毅机器学习笔记】 12、Unsupervised Learning - Linear Methods
【李宏毅机器学习笔记】 13、Unsupervised Learning - Word Embedding(待填坑)
【李宏毅机器学习笔记】 14、Unsupervised Learning - Neighbor Embedding(待填坑)
【李宏毅机器学习笔记】 15、Unsupervised Learning - Auto-encoder(待填坑)
【李宏毅机器学习笔记】 16、Unsupervised Learning - Deep Generative Model(待填坑)
【李宏毅机器学习笔记】 17、迁移学习(Transfer Learning)
【李宏毅机器学习笔记】 18、支持向量机(Support Vector Machine,SVM)
【李宏毅机器学习笔记】 19、Structured Learning - Introduction(待填坑)
【李宏毅机器学习笔记】 20、Structured Learning - Linear Model(待填坑)
【李宏毅机器学习笔记】 21、Structured Learning - Structured SVM(待填坑)
【李宏毅机器学习笔记】 22、Structured Learning - Sequence Labeling(待填坑)
【李宏毅机器学习笔记】 23、循环神经网络(Recurrent Neural Network,RNN)
------------------------------------------------------------------------------------------------------
【李宏毅深度强化学习】视频地址:https://www.bilibili.com/video/av10590361?p=36
课件地址:http://speech.ee.ntu.edu.tw/~tlkagk/courses_ML16.html
-------------------------------------------------------------------------------------------------------
Example Application
先以一个智能机器人的例子开始。
理解一段文字的一种方法是标记那些对句子有意义的单词或记号。在自然语言处理领域,这个问题被称为槽填充(Slot Filling)。
所以此时机器人要找出input句子的有用的信息(destination,time of arrival),然后输出要回答的答案。
这件事情可以先尝试用一个普通的network做一下,看看会遇到什么问题。
把词语转成vector作为input,其它步骤和普通的network一样。
但,怎么把词语转成vector呢?如下。
1-of-N encoding
这个方法很简单,将物品在对应的列上置1 。
缺点:如果出现lexicon没有记录的物品,没办法在所属的列上置1 。
所以,可以用以下方法改进。
Beyond 1-of-N encoding
- Dimension for “Other” : 把没记录过的物品归到 other 类里。
- Word hashing : 用词汇的字母的n-gram来表示这个vector 。
刚才讲了几种把word转成vector的方法,现在能进行输入以后,就能获得输出。
这个输出是一个分布,这个分布是输入的词汇(比如Taipei)属于哪个slot(destination,time of arrival)的几率。
这样做看起来好像很合理,但其实是有问题的,如下。
如果network的input是一样的,那output应该也是一样的,但现在面临个问题:
现在有两个句子:
- 11月2号到达台北(台北是目的地)
- 11月2号离开台北(台北是出发地)
对于刚才的network来说,input只有台北,它要么就一直认定台北是目的地,要么就一直认定台北市出发地。
所以,我们就希望这个network是有记忆力的,能记住联系台北之前的词汇,来判断台北市目的地还是出发地。
这种有记忆力的network就是循环神经网络(Recurrent Neural Network,RNN)。
Recurrent Neural Network (RNN)
- 输入 x1,x2后,神经元的输出结果会存储到内存中
- 此时再输入 x1, x2 ,神经元不仅会此时的x1 ,x2,还会考虑之前 x1,x2的结果,综合后才得到输出。
下面以一个例子来看下。
为了计算方便,假设weight都是1,没有bias,**函数也是线性函数。
- 先给memory那边初始值,假设都设置为0
- 现在输入[1,1]
- 绿色的神经元输出[2,2],并把[2,2]存到memory中
- 红色的神经元输出[4,4]
- 此时输入[1,1]
- 绿色的神经元会加上memory的值[2,2],输出[6,6],并把[6,6]存到memory中
- 红色的神经元输出[12,12]
- 此时输入[2,2]
- 绿色的神经元会加上memory的值[6,6],输出[16,16,],并把[16,16]存到memory中
- 红色的神经元输出[32,32]
另外,在RNN中,input的顺序对结果是有影响的。如果第一次就输入[2,2],最后的结果是不一样的。
下面回到刚才的例子。
把network改为RNN。
- 输入Taipei
- 网络就会考虑上前面的词语是arrive还是leave。
- 此时就能输出Taipei是目的地还是出发地的几率。
上图不是指有三个network,而是一个network被用了3次。
之前举的RNN的例子,都只有一层hidden layer。但其实你也可以如上图一样,DIY你的network,要加几层随便你。
Elman Network & Jordan Network
- Elman Network:(就是刚才举例的RNN)把某一个hidden layer的output存起来,在下一次使用network的时候,这个hidden layer会考虑现在的input和之前存的值,综合后再得出output。
- Jordan Network:它是把output的值存起来,下次用到再读出来。传说它的性能会好点,因为它存的是output的值,这个值和target比较有关系,所以此时我们知道存在memory的值大概会是怎样的。
Bidirectional RNN
假设一个句子的词语从前往后是、、。
Bidirectional RNN的做法:训练两个network,一个正向,一个逆向。把所处的两个hidden layer都接给output layer 。
Bidirectional RNN的好处:network产生output的时候,它考虑的范围比较广。比如输入句子中间的词语进去,之前RNN只考虑了这个词语前面句子的部分。而Bidirectional RNN是考虑了句子前面和句子后面的部分,所以它的准确率会更高。
前面讲的各种RNN是比较simple的,现在的话有些更好的结构,比如Long Short-term Memory (LSTM)。下面具体看下。
Long Short-term Memory (LSTM)
- Memory Cell:保存神经元的output
- Input Gate:决定神经元的output要不要被保存到Memory Cell(由network自己学习并决定是否打开阀门)
- Output Gate:决定神经元能不能从Memory Cell读取之前保存的东西(由network自己学习并决定是否打开阀门)
- Forget Gate:决定Memory Cell里面的东西要不要删掉(由network自己学习并自己决定是否Forget)
这里有4个input和1个output:
- input的值
- 操控Input Gate的信号
- 操控Output Gate的信号
- 操控Forget Gate的信号
- 一个output是LSTM的输出值
接下来看看LSTM在具体公式中如何体现。
、、 经过的**函数均为Sigmoid Function。代表这个gate开启的程度。
- 输入是 z,经过**函数后变成 g(z) 。
- 代表 是否开启 Input Gate 的信号,经过**函数后变成 。数值为1代表完全让数据输入。
- 代表 是否开启 Output Gate 的信号,经过**函数后变成 。数值为1代表完全让数据输出。
- 代表 是否开启 Forget Gate 的信号,经过**函数后变成 。数值为0代表完全忘掉数据。
假设memory初始值是 c ,这个式子可以看出这几个信号如何操控gate:
- 如果为1,代表输入值 g(z) 能输入进memory。
- 如果为1,代表保留memory原来的值 c ,并和输入的 g(z) 加起来,综合得到memory里新的值 c' 。
- 蓝色格子代表memory里的值。
- 代表input
- 当 时代表,input能被写进memory
- 当 时代表,清空memory
- 当 时代表,memory的值能被输出
- 红色格子代表输出的值。
知道这些规则,就可以知道上图的LSTM的运行的大概过程。其中的每一个更具体的过程如下:
以[3,1,0]为输入。
- 代表input值。input值为3,乘上weight值1,所以实际的input值为1 。
- 接下来看Input Gate那边,对应的weight是100。如果的值为1,此时bias为-10,此时通过sigmoid后,Input Gate就会打开;如果的值为0,此时bias为-10,通过sigmoid后,Input Gate就会关闭。
- 接下来看Forget Gate那边,对应的weight是100。如果的值为-1,此时bias为10,此时通过sigmoid后,Forget Gate就会关闭(即清空memory);如果的值为0,此时bias为10,通过sigmoid后,Forget Gate就会打开(即保留memory)。
- 接下来看Output Gate那边,对应的weight是100。如果的值为1,此时bias为-10,此时通过sigmoid后,Output Gate就会打开;如果的值为0,此时bias为-10,通过sigmoid后,Output Gate就会关闭。
普通的network和LSTM的对比
- 左边就是普通的network,有两个神经元,每个神经元有两个input。
- 右边则是2个LSTM的单元。
其实它们是差不多的,整个LSTM可以看做一个神经元,只是它的需要的input是左边神经元的4倍。
所以,在同样神经元的状况下,使用LSTM的参数会是原来的4倍。
LSTM的过程也可以写成以下这样:
如上图,把LSTM排成一排,c 这个vector就是指这一整排LSTM的memory cell 的值,每个memory cell 里的值代表 c 的一个维度。
- 在时间点 t 输入一个
- 分别乘上4个matrix,把转换成四个vector,分别是(操控forget gate的)、(操控input gate的)、(LSTM的input)、(操控output gate的)。其中,z的第一维就是第一个LSTM的输入,第二维就是第二个LSTM的输入。、、 同理。
此时,一个LSTM的运算过程就可以用上图左边的样子来描述。
进一步,把多个LSTM连起来,就形成上图左边的样子。
但这还只是一个简化版的LSTM 。
LSTM的最终形态如上图右边的样子。它在input 的时候,会考虑之前的memory cell的值(peephole),还会考虑之前的output的值,考虑这三个vector,再做transform去操控LSTM 。
所以,叠多几个LSTM之后,整个network就变得很吓人。
不过不用慌,Keras已经帮我们搞定这些东西了 ,到时敲上图几个命令就完事了。
施工ing。。。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:【李宏毅机器学习笔记】 23、循环神经网络(Recurrent Neural Network,RNN) - Python技术站