开始的这部分主要是对DL4NLP的一个简介。
个人理解,DL4NLP中,所有层级都是以向量的形式进行处理,用向量表示单词、用向量表示句子等。向量是最灵活的形式,维度自由,可组成矩阵,可组成高维的tensor等。进行NLP等后续任务,首先需要输入。输入来源主要有两个,一个是来自语音speech,一个是来自文本text。对于NLP中,
有一个概念需要理解:morphology(形态学)。这个所谓的形态学是一个语言学中的概念,涉及到语音特征、句法特征、语义特征等,处于音位学、句法学和语义学的结合部位。
整个的一个NLP的通用处理流程是: 拿到输入(来自语音/文本) -> 形态学分析(morphological analysis) -> 句法分析(syntactic analysis) -> 语义分析(semantic interpretation) -> 对话分析(discourse processing)
最后的那个阶段需要利用上下文语境进行理解。
NLP 的工业界应用:
一般来讲,结合自己的工作经验,有拼写检查、关键词生成、NER、文本分类、情感分析等初中级任务,稍高级的任务有MT、QA、客服系统、chatbot等这些直接利用NLP的产出,还有利用NLP的输出作用于广告投放、推荐等业务的情形。
p.s.对于情感分析,传统方法是用一个情感词袋,在词袋上做分类器;基于DL的方法用RNN等解决,可识别”反话“的情感极性。对于QA,传统方法是手工写大量正则表达式,超蠢,效果也不好;基于DL的方法把事实存储在向量里。对于客服系统,如google的inbox,是基于RNN等DL方法实现的。对于MT,有传统的SMT,也有现在的NMT,NMT是将原文中的各个词映射成向量,由向量来构建译文。
NLP的难点:
1.人类的语言有歧义,需要明确某一代词具体指代的是什么。就是Reference analysis
2.人类的语言较简练,省略了大量的背景知识。省略的原因是由于人类已经储备了大量基于现实世界、常识和上下文的一些知识。
随后进入正题,介绍w2v。词是进行NLP任务的最小单词,需要把词表示明白。
据说过去一直都是用的分类词典,常见是就是像WordNet那样的词库查询上位词和同义词等。这种方法并不能区分同义词之间的细微差别,如expert != good,这专业的程度完全不一样好嘛!!此外,这种方法不需要大量人力去整理,而且不能实时加入新词,由于是人工整理的,就会出现主观化的问题,还无法计算词和词之间的相似度。总而言之,就是不好。
用稍现代化的模式去进行处理的时候,最早是采用one-hot编码的形式进行词语表示。这种就是列一个词典,初始化词典里的各个单词对应的计数都是0,然后一个一个撸单词,句子里出现哪个单词了就把词典相应的位值+1,直到撸完为止。这种方法是有问题的,如果词典特别大,比如达到百万级别的话,那这向量也太长了!而且任意两个向量之间的点积都为0,说人话就是这两个词没有关联,这是不对的,比如说motel和hotel...这两个怎么说是没关联呢?说motel和cat没关联还差不多!
在对词语的理解时,很大程度上需要依赖其对应的上下文,如果能把单词放到正确的上下文中,才说明正确掌握了他的意义。个人认为这就是w2v的语言学基础。通过调整一个单词及其上下文单词的向量,可根据这两个向量推测两个词语的相似度,或者可根据一个单词的向量预测词语的上下文。w2v被称作是分布式表示,称为分布式主要是因为,不像one-hot这种编码形式,把鸡蛋都放在一个篮子里,而是把该单词的含义分散到不同维度,因此称作是分布的表示。
w2v是由两个模型构成的:CBOW和SG,两个模型的作用完全相反,其中CBOW是给定一个中心词,预测其context词,而SG则是给定context词来预测中心词。通过单词和上下文彼此预测。
对于w2v的原始softmax,提出了两种较为高效的训练方法:负采样和层次softmax。
学习神经网络word embedding的基本思路如下:
首先定义一个预测某单词的上下文的模型:
这里的w−t表示wt的上下文(负号通常表示除了某词之外),如果完美预测,损失函数为零。然后在大语料库上不同位置得到训练实例,调整词向量,最小化损失函数
Lecture里主要是针对SG模型进行了详细讲解。计算P(wt-2 | wt)、P(wt-1 | wt)、P(wt+1 | wt )、P(wt+2 | wt)等概率。这里只是拿窗口为2举例,实际上学习出的是一个概率分布。目标函数是对所有中心词其context词的预测结果的乘积,需要最大化这个乘积(理想情况是这个乘积的结果为1,表示对于所有中心词,对其context词的预测都是准的)。
在实际操作时,要对这个最原始的目标函数进行一下改造。乘法显然是不太好处理的,一个通用的trick是将乘法转成求和,利用log操作。而且接触过ML的都知道,处理最小化要比处理最大化更受欢迎,原始目标函数是进行最大化,取个负数就转成了最小化。因此,将原始目标函数进行对数似然的相反数操作即可得到较易处理的损失函数形式。对于目标函数里的p,用softmax函数得到。
softmax函数本质上是将一个向量转换成另一个向量,向量的shape不变,只是将向量中的各个值进行"规范化"处理,将一个任意值转成(0,1)之间的一个浮点数,在NN里这个值可近似认为是概率。softmax的计算函数如下:
这里涉及到的u和v分别对应词o(context词)的向量和词c(中心词)的向量,来自于两个矩阵U和V,二者均为这个模型的参数,是我们要通过损失函数反复迭代更新的。之所以叫做softmax函数是因为,该函数中用的指数函数会将较大的数变得更大,而较小的数变得很小很小,类似于max函数
p.s. 在对应的assignment1里第一部分就是针对softmax做的一些练习。softmax有一个特性,那就是平移不变性(我也不知道专业的说法是这个,勿喷),数学表示就是softmax(x) = softmax(x + c),其中c为一个常数或常向量,x是一个向量。这个很好证。实际利用这个特性时,c普遍取-max x(i),就是x向量中的最大值。为啥要费劲减去这么个值呢?还要从softmax函数本身定义着手。softmax函数用指数来进行”规范化“操作,指数操作会把大数继续放大,如exp(1000)时,直接算是会上溢出的,得到inf,对于exp(-1000),还是不行,会下溢出,得到0,下溢出这个事情是因为,浮点数只有64位,太小的数字也是表示不出来的。减去x(i)的最大值,可以保证指数最大不会超过0,不会发生上溢出,即使下溢出了,也能得到一个相对合理的值。这个softmax函数很重要很重要很重要!!!!!
对于整个SG模型的执行过程,用如下scratch表示很清楚: