【李宏毅机器学习笔记】1、回归问题(Regression)
【李宏毅机器学习笔记】2、error产生自哪里?
【李宏毅机器学习笔记】3、gradient descent
【李宏毅机器学习笔记】4、Classification
【李宏毅机器学习笔记】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)
【李宏毅机器学习笔记】 24、集成学习(Ensemble)
------------------------------------------------------------------------------------------------------
【李宏毅深度强化学习】视频地址:https://www.bilibili.com/video/av10590361?p=36
课件地址:http://speech.ee.ntu.edu.tw/~tlkagk/courses_ML16.html
-------------------------------------------------------------------------------------------------------
先以一个智能机器人的例子开始。
理解一段文字的一种方法是标记那些对句子有意义的单词或记号。在自然语言处理领域,这个问题被称为槽填充(Slot Filling)。
所以此时机器人要找出input句子的有用的信息(destination,time of arrival),然后输出要回答的答案。
这件事情可以先尝试用一个普通的network做一下,看看会遇到什么问题。
把词语转成vector作为input,其它步骤和普通的network一样。
但,怎么把词语转成vector呢?如下。
这个方法很简单,将物品在对应的列上置1 。
缺点:如果出现lexicon没有记录的物品,没办法在所属的列上置1 。
所以,可以用以下方法改进。
刚才讲了几种把word转成vector的方法,现在能进行输入以后,就能获得输出。
这个输出是一个分布,这个分布是输入的词汇(比如Taipei)属于哪个slot(destination,time of arrival)的几率。
这样做看起来好像很合理,但其实是有问题的,如下。
如果network的input是一样的,那output应该也是一样的,但现在面临个问题:
现在有两个句子:
对于刚才的network来说,input只有台北,它要么就一直认定台北是目的地,要么就一直认定台北市出发地。
所以,我们就希望这个network是有记忆力的,能记住联系台北之前的词汇,来判断台北市目的地还是出发地。
这种有记忆力的network就是循环神经网络(Recurrent Neural Network,RNN)。
下面以一个例子来看下。
为了计算方便,假设weight都是1,没有bias,激活函数也是线性函数。
另外,在RNN中,input的顺序对结果是有影响的。如果第一次就输入[2,2],最后的结果是不一样的。
下面回到刚才的例子。
把network改为RNN。
上图不是指有三个network,而是一个network被用了3次。
之前举的RNN的例子,都只有一层hidden layer。但其实你也可以如上图一样,DIY你的network,要加几层随便你。
假设一个句子的词语从前往后是、、。
Bidirectional RNN的做法:训练两个network,一个正向,一个逆向。把所处的两个hidden layer都接给output layer 。
Bidirectional RNN的好处:network产生output的时候,它考虑的范围比较广。比如输入句子中间的词语进去,之前RNN只考虑了这个词语前面句子的部分。而Bidirectional RNN是考虑了句子前面和句子后面的部分,所以它的准确率会更高。
前面讲的各种RNN是比较simple的,现在的话有些更好的结构,比如Long Short-term Memory (LSTM)。下面具体看下。
这里有4个input和1个output:
接下来看看LSTM在具体公式中如何体现。
、、 经过的激活函数均为Sigmoid Function。代表这个gate开启的程度。
假设memory初始值是 c ,这个式子可以看出这几个信号如何操控gate:
知道这些规则,就可以知道上图的LSTM的运行的大概过程。其中的每一个更具体的过程如下:
以[3,1,0]为输入。
其实它们是差不多的,整个LSTM可以看做一个神经元,只是它的需要的input是左边神经元的4倍。
所以,在同样神经元的状况下,使用LSTM的参数会是原来的4倍。
如上图,把LSTM排成一排,c 这个vector就是指这一整排LSTM的memory cell 的值,每个memory cell 里的值代表 c 的一个维度。
此时,一个LSTM的运算过程就可以用上图左边的样子来描述。
进一步,把多个LSTM连起来,就形成上图左边的样子。
但这还只是一个简化版的LSTM 。
LSTM的最终形态如上图右边的样子。它在input 的时候,会考虑之前的memory cell的值(peephole),还会考虑之前的output的值,考虑这三个vector,再做transform去操控LSTM 。
所以,叠多几个LSTM之后,整个network就变得很吓人。
不过不用慌,Keras已经帮我们搞定这些东西了 ,到时敲上图几个命令就完事了。
经过上面的介绍,已经知道RNN的大概样子了,接下来就要看下它是如何训练的。
想要训练模型就要:
先看第一点。
在这里,:
这样就得到一个loss function。
接下来要更新参数,使loss最小化。
这边还是使用gradient descent来更新参数。
之前为了让gradient descent更有效率的进行,有使用了反向传播(Backpropagation) 。
不过这里需要考虑一个句子的顺序,所以需要改用Backpropagation的进阶版,Backpropagation through time (BPTT)。
虽然上面有了loss function,也有了做gradient的方法。但是RNN没那么容易train。
上图绿线就是实际train RNN的loss值,可以看到很不稳定。
这是因为RNN 的error surface是很崎岖的,如下。
如上图,可以看到,RNN 的error surface是很崎岖的。
在平坦的surface上,由于gradient比较小,所以用比较大的learning rate。但是一旦突然遇到一个悬崖,此时gradient突然变大,而learning rate还没来得及变小,此时参数就会直接跑飞了。就像前面图的绿线,最后直接往上顶上去了。
以上图的network为例子。上面一排network是代表不同时间点使用的,不是指有这么多个network。
这个network很简单。
现在input是[1,……,0],除了第一个是1,其他都是0 。
那么时间点为1000的output就是 。
在这整个过程中,神经元的那个weight被使用了999次。所以,w的变化有两种影响:
由于这里有两种变化情况,所以不能很死板地说,用大的learning rate或者小的learning rate就是好的。
所以RNN不好train的原因是:它有时间顺序,同样的weight在不同的时间点会被反复使用多次。
使用LSTM可以解决gradient vanishing的问题(即error surface平坦那部分的问题),原因:
另外,如果使用LSTM发生过拟合(由于LSTM有3个gate,参数比较多)。可以改用一个比LSTM简单的版本 ,Gated Recurrent Unit (GRU),它只有2个gate(它把input gate和forget gate联动起来):
上图是更多改进RNN的方法。也是能解决gradient vanishing的问题。具体可以看上图所示的论文了解。
因为本文主要讲的是RNN原理相关的内容。而下面的内容偏向于RNN的应用,所以下面的内容都是粗略讲而已。
RNN也可以做到,输入是vector sequence,而输出只有一个vector。如上图,是一个情感分析的例子。
输入一个句子到RNN中,最后输出这个句子包含的情感。
输入是一个sequence(比较长),输出也是一个sequence(比较短)。以语音辨识为例子:
但是这样做还是有问题,如果经过Trimming操作会去除重复的东西,那如果实际结果是“好棒棒”的话,就会出错。要知道“好棒”和“好棒棒”(yygq)是完全相反的两种意思。
怎么办呢?用Connectionist Temporal Classification (CTC)。
Connectionist Temporal Classification (CTC)
这里简单看下过程 。
这个方法会输出一个 代表 “null” 的意思。
如上图,如果input一串语音,它的output是{ 好,,,棒,,,, },把其中的 拿掉就变成“好棒”。
如上图,如果input一串语音,它的output是{ 好,,,棒,,棒,, },把其中的 拿掉就变成“好棒棒”。
因为老师这块没细讲,本人水平有限,不想说错误导人,所以更多具体过程建议参考论文。
现在的情况是:输入的sequence和输出的sequence的长短不确定。
上图是做翻译的例子。输入machine learning,输出机器学习。
但是有一个问题,输出正确结果后它不会停下来。怎么做呢?
给它加一个“===”的符号,代表任务结束。
上图是Google的一片论文,它实现了输入声音讯号(比如英语),不经过语音辨识,然后直接输出翻译后的句子(比如翻译成中文)。具体看图中的论文地址。
Sequence-to-Sequence的技术还可以用于生成 Syntactic parsing tree 。
它可以做到让机器看一段句子,然后机器就会输出这个句子的语法的结构树。
具体可以看上图中的论文。
使用bag-of-word方法把一段文字转成word vector的话,是没有考虑顺序的。
上图两个单词相同但不同意思句子,在bag-of-word看来就是一样的。
Sequence-to-sequence Auto-encoder - Text就能在考虑顺序的情况下,把一段文字转成word vector。
接下去挺多在NLP的应用,而我对NLP了解不多,视频里也没细讲。所以为了防止误导人,下面内容建议直接看视频吧,等以后我把NLP熟悉一下,再回来填坑。。。