CS224N
NLP与深度学习的结合简介
文章目录
- CS224N
- NLP与深度学习的结合简介
-
- 简介
- 为什么NLP会这么困难?
- Deep NLP:
- What is word2vector?
-
- word2vector的常见方法(word embedding):
-
- skip-grams(最基础,效率不高):
- 摘录一篇csdn大佬的总结:
- skip-grams的优化
- 负采样(negative sampling)
- CBOW模型
-
- CBOW网络计算的步骤:
- 一种基于这种直接查看共现(co-occurence)矩阵的方法:
-
- **怎么解决呢?答案是奇异值分解:SVD**
- 所以,SVD到底存在什么问题呢?
- 两种模型的对比:
- 结合后的模型-全局向量模型-Glove
-
- Glove和skip-gram、CBOW模型对比
- 总结:
- 如何评估:
-
- 一个有效的内在评估方法:
- 经过试验后的经验结果:
- 单词分类:
- 补充小知识:参数稀疏
- 论文补充:如何解决多义词的词向量转化?《Linear algebraic structure of word senses,with Applications to polysemy》
简介

Amazon-Alexa (牛逼!)专用家庭领域人机交互做的非常好!
结构分析
->
句法分析
->
语义解释
语音信号分析-处理
一些典型应用:
NLP已经有了很多的产业落地应用-如搜索引擎-商业广告推送,情感倾向和舆情分析,还有很多时候,其往往是和语音结合在一起使用的。先听到,再理解。语音信号处理!
人类语言:
我们在做自然语言处理的时候,想着从一堆数据中提取出有意义和有价值的信息,但实际上人类的语言系统并不是这样的,人类的语言系统是抽象的/符号化的/明确的信号系统,人类是通过构建语言来传递信息,这与我们做的其实本质上有很多区别。
人类语言就是一套符号体系!
传输的媒介是连续的!
深度学习的核心是可以去自动、黑箱型的去学习中介表征(intermediate representation)
深度学习的第一个重大突破是语音识别 CS224D?
为什么NLP会这么困难?
语言作为人类的一种高效的沟通工具,常常伴随着很多省略!
语言是一种华丽的混沌(glorious chaos),其和很多因素有关,语境,不同的人有不同的理解。
一些有趣的例子:
Deep NLP:
把深度学习应用于自然语言处理的一个重点是使用一个向量去表示一个词 (word 2 vector)
将单词放到高维向量空间中,这些空间就构成了非常棒的语义空间
具有相似含义的词汇将在矢量空间中形成聚集块
向量空间中存在方向会透露关于成分和意义的信息
而人类不是非常擅长解读高维向量空间,一般会使用降维到2、3维(PCA主成分降维)-但容易造成误导-遗漏了很多高维向量空间的信息
t-SNE (非线性降维)
大佬陈丹琦做的用神经网络进行依存句法分析
传统的方法是做一个lambda计算,给每个词定义一个语义函数,然后找出一种算法来计算不同词之间的语义关系,相似度之类的。
深度学习方法将词表示成高维向量,然后句子也是由高维向量组合而成,而这些语义之间的关系则是由深度学习的模型训练来完成。(不同模型考虑了不同的特征 CNN GNN-文章 RNN LSTM Bert GRU-之类的)
传统的方法的经典分析是这句话的关键词里面有很多积极词汇,所以是一个postive的评论,但实际上,因为前面还有一个don‘t,神经网络就会注意到这一点从而判断其整个情绪的负面性。
flawlessly-无瑕的 完美的
一些其他应用:
所有的一切都是用向量(有真实值)的去表达语言
实际上,向量是一种非常强大的数据结构。可以变形成张量,可以变形,可以改变方向。
计算机语言学中常用的并不是大名鼎鼎的韦式词典,而是wordNet。
其可以做很好的分类。
对于词汇的离散表征的问题:
主观的-相似度的定义模糊不清
深度学习的忍者和深度学习的专家到底是否相似?
一种常见的做法是用one-hot decoding去表示原子词汇
其是一种存储在某地的本地表示,我们在一个大的向量空间中模糊化词汇的含义。
但是这种表示肯定是存在问题的,因为它没有给出各种单词的意义相似性(这个问题可以加一个self-attention层,大家可以看看我的另外一篇博客)-word-embbing
解决这个问题的关键就是,我们需要从两个词的向量表示来看出来两个向量的相似性,例如计算两个向量的点积来查看其相似度。
一个方法是通过上下文来理解单词的意思,分布式相似度计算
其实一种关于词汇语义的理论
distributed representation(分布式表示)-distributional(分布式的)
What is word2vector?
简介:。Word2vec是一类神经网络模型——在给定无标签的语料库的情况下,为语料库中的单词产生一个能表达语义的向量。
应用:
- 通过词向量来计算两个单词的词义相似性
- 对某些监督型NLP任务如文本分类、语义分析构造特征
Word-embedding:
我们的目标是使得词汇的向量表示能够使损失最小化。所以词汇的意义就应该有深度学习的魔法来实现和实现
w-t代表除它外所有的上下文
w代表中心词汇 f3-search
word2vector的常见方法(word embedding):
skip-grams(最基础,效率不高):
给定一个中心词汇,某个单词在它上下文中出现的概率,我们会选取词汇的向量表示,从而让概率分布值最大化,这个模型只有一个概率分布,对于一个中心词汇周围的上下文我们只有一个输出。
θ 是 模 型 的 参 数 , 也 是 每 个 词 汇 的 向 量 表 示 的 唯 一 参 数 ( 系 数 ) \theta是模型的参数,也是每个词汇的向量表示的唯一参数(系数) θ是模型的参数,也是每个词汇的向量表示的唯一参数(系数)
一个目标函数就这样被构造出来了,我们使用对数化让最大值从求积变为求和,加负号使得最大化问题变为了最小化问题。
这个模型当然有很多个超参数-比如窗口的大小2m,还有一些容差系数,限制先忽略它们,作为常数。 i buy that one-我很喜欢这一点
负数的对数似然分布-意味着我们需要使用交叉熵损失函数-目标函数。
c和0分布代表单词在词汇表空间中的索引,以及它们的类型(中心,输出单词(outside)):
t和t+j代表的是单词在文本中的位置
每种单词类型都有一个对应的向量
Uo是索引为o的单词所对应的向量
Vc是中心单词所对应的向量
这种表示相互独立,在做优化时不会相互耦合。-两个向量
这里使用softmax函数(类似于放大一个最大化函数,但仍然是一个较软的放大-logistic回归)来表征
求点积具体(点积也是一种模糊求相似度的方法,值越大,相似度越高):
softmax(数值-变为-概率):
指数函数可以很容易将一个数值变到正区间。
这里的方法并不考虑单词的位置和中心单词的距离,我们主要从句义来理解而不是从句法构造。
Skip-grams模型的一个手写表达:
学习参数(所有向量都是参数,都需要进行计算):
SGD
摘录一篇csdn大佬的总结:
这里第二个应该是笔误,每个单词实际上是与矩阵的每一行相对应的。,不过这取决于你怎么定义。
v u向量分别是隐藏层和输出层权重矩阵的一部分
中心词向量指的是经过第一个权重矩阵得到的隐藏层向量,背景层向量指的是第二组权重矩阵中的某一列
需要学习的两个矩阵w和w‘ (一个是单词降维的,一个是背景向量矩阵计算相似度的)
将词汇变到高维向量这个想法很重要!,让神经网络能够有更多机会去创造魔法
每个词都有两个向量表示,一个是作中心词,一个是作为背景词。随着窗口的移动,每个词都会成为中心词,这个神经网络的输入是one-hot-vector,输出是各个词经过计算后的含有语义的数值表示
输入是one-hot vector编码后,独立解耦的问题得到解决。
在输入层后做一个softmax层分类,注意,是词汇表中的所有词。
两个权重矩阵
输入乘以第一个权重矩阵得到隐藏层
隐藏层乘以第二个权重矩阵得到输出层
输出层经过softmax层得到V个结果,也就是各词汇的背景层向量表示,当然甚至有自己的背景层向量表示。!
求和的时候词汇表所有的单词都会被遍历到
两个假设:
- 假设给定中心词的情况下,背景词之前是相互独立的
- 假设在对中心词权重更新时,背景词的权重是固定的,然后在以同样的方式来更新背景词的权重。
skip-grams的优化
1.负采样(negative sampling)
负采样(negative sampling)解决了这个问题,它是用来提高训练速度并且改善所得到词向量的质量的一种方法。不同于原本每个训练样本更新所有的权重,负采样每次让一个训练样本仅仅更新一小部分的权重,这样就会降低梯度下降过程中的计算量。至于具体的细节我在这里就不在介绍了
2.层序softmax也是解决这个问题的一种方法。这里也不做详细介绍。
cost function都是非凹的,为了避免陷入局部最小值,初始化很重要,实际上,一般初始化为一个很小的数都可以避免这样的问题。
σ ( − x ) = 1 − σ ( x ) \sigma(-x)=1-\sigma(x) σ(−x)=1−σ(x)
负采样(negative sampling)
训练一个神经网络意味着要输入训练样本并且不断调整神经元的权重,从而不断提高对目标的准确预测。每当神经网络经过一个训练样本的训练,它的权重就会进行一次调整。
vocabulary的大小决定了我们的Skip-Gram神经网络将会拥有大规模的权重矩阵,所有的这些权重需要通过我们数以亿计的训练样本来进行调整,这是非常消耗计算资源的,并且实际中训练起来会非常慢。
负采样(negative sampling)解决了这个问题,它是用来提高训练速度并且改善所得到词向量的质量的一种方法。不同于原本每个训练样本更新所有的权重,负采样每次让一个训练样本仅仅更新一小部分的权重,这样就会降低梯度下降过程中的计算量。
当我们用训练样本 ( input word: “fox”,output word: “quick”) 来训练我们的神经网络时,“ fox”和“quick”都是经过one-hot编码的。如果我们的vocabulary大小为10000时,在输出层,我们期望对应“quick”单词的那个神经元结点输出1,其余9999个都应该输出0。在这里,这9999个我们期望输出为0的神经元结点所对应的单词我们称为“negative” word。
当使用负采样时,我们将**随机选择一小部分的negative words(比如选5个negative words)来更新对应的权重。**我们也会对我们的“positive” word进行权重更新(在我们上面的例子中,这个单词指的是”quick“),目标是最小化这些可能出现在中心词单词的概率,取几个negtive words可以被当作超参数。
在论文中,作者指出指出对于小规模数据集,选择5-20个negative words会比较好,对于大规模数据集可以仅选择2-5个negative words。
回忆一下我们的隐层-输出层拥有300 x 10000的权重矩阵。如果使用了负采样的方法我们仅仅去更新我们的positive word-“quick”的和我们选择的其他5个negative words的结点对应的权重,共计6个输出神经元,相当于每次只更新300*6=1800个权重。对于3百万的权重来说,相当于只计算了0.06%的权重,这样计算效率就大幅度提高。
随机取是基于频率进行采样的,当然也不能只采样经常出现的词。上面的3/4使频率不高的单词更容易被采样。这只是一种方法,上面是测试出来的不错的结果。大型语料库采样很少可能把下面两个中采样相同,独立同分布相乘变相加。
右边部分的数量级是10(底数)
θ作为模型所有的参数,(U,V),j损失函数,T是遍历语料库的第T个时间步或者说第T个窗口。
J t ( θ ) = log s i g m a ( u 0 T u c ) + ∑ j p ( w ) [ log s i g m a ( − u j T v c ) ] J_t(\theta)=\log^{sigma(u_0^Tu_c)}+\sum_{j~p(w)}[\log^{sigma(-u_j^Tv_c)]} Jt(θ)=logsigma(u0Tuc)+j p(w)∑[logsigma(−ujTvc)]
CBOW模型
CBOW(Continuous Bag-of-Word Model)又称连续词袋模型,是一个三层神经网络。如下图所示,该模型的特点是输入已知上下文,输出对当前单词的预测。
其学习目标是最大化对数似然函数:
其中,w表示语料库C中任意一个词。
下面上一个更细节的一个图:
CBOW网络计算的步骤:
- 输入层:上下文单词的onehot。(假设单词向量空间dim为V,上下文单词个数为C)
- 所有onehot分别乘以共享的输入权重矩阵W(VN矩阵,N为自己设定的数,初始化权重矩阵W)
- 所得的向量 (注意onehot向量乘以矩阵的结果) 相加求平均作为隐层向量, size为1*N.
- 乘以输出权重矩阵W’ {N*V}
- 得到向量 {1*V} 激活函数处理得到V-dim概率分布 {PS: 因为是onehot嘛,其中的每一维斗代表着一个单词},概率最大的index所指示的单词为预测出的中间词(target word)
- 与true label的onehot做比较,误差越小越好。loss function(一般为交叉熵代价函数)
- 我们并不关心输出的内容,预测的结果不重要,重要的是训练完成后第一个全连接层的参数就是我们要的word embedding矩阵。
使用word2vectors后,在高维向量空间中,单词开始聚在一起,当然,我们也可以使用PCA主成分分析法降维供我们观察。在skip-gram中,我们使用了向量内积来衡量相似性,实际上,使用欧式距离也是可以的,效果大差不差。
一些关于这个方法模型的问题:
一种基于这种直接查看共现(co-occurence)矩阵的方法:
实际上,以这种矩阵作为wordt2vector的显著缺点是,很容易出现很多高维向量,这会造成学习出的矩阵非常稀疏,从而导致整个模型不是那么robust。
怎么解决呢?答案是奇异值分解:SVD
选中目标段落shift+tab可以实现自动对齐
既然这种奇异值分解的方法如此有效,当然我们就想要去进一步改进它。
一个有效的方法是对于句子中经常也总会出现的词,例如the,he,has等做一个计数最大限制处理。
因为实际上根据zipf‘s law,最高频率出现的词会比其他词出现的越来越频繁,其他词会出现的越来越少。但实际上,那些不常出现的词,或者说稀有的词往往含有非常多的语义内容。
另一个技巧是不平等计数法,当然优化的方法还有很多。
可以看到,经过可视化,SVD这种方法也能捕捉到很多有用的信息。
但是经过观察,会发现其实相近的词语的欧式距离都差不多,都是以相同的模式在一起的,并且经常出现在相似的上下文中。
基于字符的自然语言处理也很重要,对于一些较为复杂的语言,因为越复杂的词出现的越少,这对于计数模型来说是非常不利的。
所以,SVD到底存在什么问题呢?
large svd的计算效率不高
两种模型的对比:
结合后的模型-全局向量模型-Glove
模型的结果,可以看到是非常棒的!
内在评价通常是针对特定的或中间环节的子任务进行的
总结:
1. 代 价 函 数 : J ( θ ) = 1 2 ∑ i , j = 1 N f ( X i , j ) ( v i T v j + b i + b j − l o g ( X i , j ) 2 ) 1.代价函数:J(\theta)=\frac{1}{2}\sum_{i,j=1}^{N}f(X_{i,j})({v_i}^Tv_j+b_i+b_j-log(X_{i,j})^2) 1.代价函数:J(θ)=21i,j=1∑Nf(Xi,j)(viTvj+bi+bj−log(Xi,j)2)
可以明显的看到,这个模型是考虑了全局语料库的。
这里并没有使用神经网络的方法
具体推导:理解GLOVE+总结
Glove和skip-gram、CBOW模型对比
Cbow/Skip-Gram 是一个local context window的方法,比如使用NS来训练,缺乏了整体的词和词的关系,负样本采用sample的方式会缺失词的关系信息。
另外,直接训练Skip-Gram类型的算法,很容易使得高曝光词汇得到过多的权重
Global Vector融合了矩阵分解Latent Semantic Analysis (LSA)的全局统计信息和local context window优势。融入全局的先验统计信息,可以加快模型的训练速度,又可以控制词的相对权重。
总结:
1.通过统计实验,发现共现矩阵与词向量之间的联系(即与第三个向量共现频率相近的两个向量,含义也相近) ; 2.定义词向量与共现矩阵的差方代价,用来优化词向量 ; 3.猜想得到g函数,去除第三个向量,并同时简化代价 ;4.进行数学上的优化(解决Pij的不对称性、平衡不同词频的权重
如何评估:
内在评价的实用性和普适性有待考证!
外在评价一次都耗费时间太长,是否有效效率太低!
一个有效的内在评估方法:
直觉性的结果。
基于这个直觉,出现了这样一个数据集:
不同语料库对于项目的落地至关重要,不同语料库的结果是不同的。
三百维向量好于千维向量。
数据越多越牛逼!
数据集质量同样重要。
经过试验后的经验结果:
爬取的维基百科语料库往往好于正常的新闻的语料库
人工评测
余弦相似度评测
与人类评价的相关性评估
实体命名模型
目前我们做的都是无监督学习,实际上,我们还可以通过标注做成监督学习,给予地点之类的信息。使得测试集能够做的和训练集一样好
单词分类:
补充小知识:参数稀疏
dense:稠密的
论文补充:如何解决多义词的词向量转化?《Linear algebraic structure of word senses,with Applications to polysemy》
解决这个问题可以使用稀疏编码:
V = ∑ i = 0 D a i A i + η V=\sum_{i=0}^{D}a_iA_i+\eta V=i=0∑DaiAi+η
每一个word vector都是被一个称之为语境向量的少量选定数的总和组成的,一般整个语料库中只找到2000个语境向量,但在每个单词中都很常见。每一个单词,都只由语境向量中很少的一部分组成。
word sense:词义
评估结果,结果此种方法后,模型可以达到和非英语母语者的水平。
summary: