纳勃剌汗-糞皇帝本纪

其实是因为 CS224N 只看了一半捏。剩下一半感觉看不看区别也不是很大捏。

其实也没啥用,放出来给大伙乐呵乐呵。

其之一来自于白山黑水

Denotational Semantics: 一个单词所指代的语义。

如何将单词从描述实存着的一组物体变为可被电脑操纵的一些信息?

  • 法一:使用 WordNet 等网站将单词和术语组成同义集或超同义集等。但是其无法意识到细微的差别,且需要大量人力维护。
  • 在传统 NLP 中,单词会被当作 localist 即“局部化”的表达,此时相当于为每个单词建立一个 one-hot 向量。但是不同向量两两正交无法衡量相似性。
  • 使用 WordNet 手动衡量相似性的手段最终失败了。还是来看看 Attention 罢。

Distributional Semantics: 一个单词的语义不仅由其自身决定,也受到周围单词的影响。

一个单词对应的 context 即为其周边一圈的其它文本。我们认为,context 本身应该即包含了一部分单词的 semantics。

在 NLP 中,一个 'token' 是指一个单词(中文中是单字或词语),而其可能在具体语言中有着 embedding,或称 word vectors 或 (neural) word representations。这是一个 distributional semantics 的概念。

第一个赶到战场的是 Word2Vec 算法 (Mikolov et al., 2013)

有一个大的语料库 corpus。

语料库中出现过的每个词都对应着一个向量。

对于每个位置,其有中心词汇 c 和上下文 o

通过词向量间相似性,可以根据 c 预测 o 或相反,将成功的概率列入最优化的目标。

不断调整词向量以最大化预测概率。

公式:

Likelihood=L(θ)=i=1nmjmPr(wi+jwi,θ)

其中 θ 是模型参数。Loss 被如下设计:

Loss=J(θ)=1nlnL(θ)=1ni=1nmjmlnPr(wi+jwi,θ)

如何计算 Pr?为每个词赋以两向量:vw 为 center 的向量,uw 为 context 的向量,则

Pr(oc)=expuovcwexp(uwvc)

计算法则即为 softmax。

该算法中唯一要调的参数即为全体 u,v。于是把它们直接拼接得到一极长向量即为参数向量 θ,在 θ 空间中跑梯度下降即为算法。

验证词向量优秀性质的方法之一是类比任务(analogy task)。例如,我们或许应该认为,有

kingman+woman=queen

而优秀的词向量集确实能达到如此的类比效果。

  • 使用 u,v 分开的原因之一,是因为全用同一个 embedding 会让算梯度的步骤变得丑陋,例如 center 和 context 中出现同一个单词的场合。

  • 这两个向量会很像但不完全相同,因此实际过程中常常会将它们平均得到唯一的向量作为 embedding。

  • 但是,一词多义的场合又如何呢?

  • “反义词”常常具有相似的 context 地位。我们在一些场合会说这很牛,一些场合会说这很拉,这种相似的地位有可能会导致牛和拉具有相似的向量,但这并非我们想看到的。

  • 例如 'so' 这样的程度词(或称“虚词”,因为它往往没有实际含义)又如何?

  • Word2Vec 没有考虑位置信息?

其之二游走于北海岸畔

Word2Vec 是所谓的“词袋(Bag of Words)”模型:其没有区分 context 中的单词,而是把它们平等对待。

同时,因为选项过多,每个备选项的概率均奇低无比。

  • 梯度下降(Gradient Descent)法非常昂贵,因为参数很多,每次计算成本非常大。因此解法是 SGD(Stochastic Gradient Descent),每次只选择一小批样本,更新其和其周围参数。
  • 但是 SGD 的更新梯度会非常稀疏,只有少量涉及到的参数会被更新。

Aside(旁白):在 Pytorch 中,向量的存储是行向量。

两种 Word2Vec 的变体模型:

  • Skip-Grams(SG) 模型:使用 centre 预测 context。【也即前文所述模型】
  • Continuous Bag of Words(CBOW) 模型:使用 context 预测 center。

同时,以上的概率计算方式是 softmax,但这不牛。更好的方法是 Negative Sampling(NS) 方法,与 SG 结合即得 SGNS。

SGNS:

我们希望 center 与 context 尽量像,同时 context 理应与随机词汇不像。于是有

J(θ)=lnσ(uovc)+i=1k[j(w)]lnσ(ujvc)

即随机采样 j 作为中心词,其与 context 应该不像。σ 即为 sigmoid 函数。其中,采样单词的分布取决于该单词在语料库中出现的频率,但并非直接正比于,而是正比于 0.75 次幂,以遏制那些过于常用的词。实际运用时因为要最小化 J,所以常常取相反数。

定义 co-occurrence 矩阵(共现矩阵)是语料库中每个单词作为 center 时,其它单词在它周围的 context 中出现的次数。想见,该矩阵应是对称矩阵。使用该矩阵的行/列(它们相同)向量作为 embedding 向量,牛吗?

  • 问题:共现矩阵大而稀疏。

如何降维?答曰:SVD。

但是 SVD 不牛,因为有众多出现过多次的常见词与众多出现极少的生僻词。因此可以作如下优化:

  • ln
  • 出现次数对某个上界(例如 100)取 min
  • 忽略 so 等虚词(functional word)。

此类算法的典型例子如 COALS 模型。

GloVe 模型是结合二者优势的模型:线代方法易训练(纯粹统计学),问题在于对不同单词的重视程度的比例不对,且空间开销很大;Word2Vec 方法相当于用时间换空间,易于拓展语料库,但是对统计学的利用不足。

一个思想是:从卡车到司机,从国王到女王,会有一些“有意义的成分meaning component”,这些成分被表示为共现频率的比率。

例如,“从固体到气体”这个过程是一个有意义的成分;ice 与 solid、water 均常出现,与 gas 不常出现;steam 与 gas, water 常出现,与 solid 不常出现;因此考虑一个词与 ice 和与 steam 频率的比值,则:

  • solid 对应的比值很大;gas 对应的比值很小;water 和随机词汇应该接近 1

为应用该观察,我们建立“对数双线性模型”,Log-Bilinear Model。

  • wiwjlogP(ij)(或是 ji,二者应该对称)
  • wx(wiwj)logP(xi)P(xj)。(这一点其实直接由上一条就能推得)

令共现矩阵 X,则误差

J=i,jwordlistf(Xi,j)(wiwj+bi+b~jlnXi,j)2

其中 f 是类似于 min(x,t) 之类的限制过多出现的权重,而 b 是偏置。

好的,上面的东西很不错,那我们应该如何评价它呢?

  • Intrinsic 内部的评估:看看它在特定任务上解决成果如何。往往评估很快,但是不一定能描述现实任务。
  • Extrinsic 外部的评估:看看它在真实问题上成果如何。评估很慢。且只有宏观结果,不清楚优化产生的具体原因(是词向量变牛了还是其与其它组件的交互变牛了)

使用 analogy task 可以检验 embedding 的优秀程度。

同样还有人工给出的单词相似度评分。

使用维基百科训练比使用新闻稿牛!或许是因为维基百科总是客观(存疑)地阐述事实。

增加维度可以提高效果!但 2013-2015 左右,维度提高到 300 效果就几乎不增加了。

  • 最后,我们的词向量能拿来干嘛?

  • 例如,给一段话,找出其中的人名、地名、公司名等“命名实体”。这也是一种好评分的方法。

问题回到一词多义。常见词或历史悠久的词都常常用法众多。

因此常常对于一个词的不同词义构建不同的向量。方法比如说,对于实际例子中的单词,我们将其进行聚类,希望同一个聚类中的单词具有相近的词向量。对于同一个单词在不同聚类中的出现,我们把它当成不同单词看。

这很棒,但是有问题:

  • 训练不是端到端的,要先学词义再学词向量。
  • 切割常常是生硬的,部分含义之间存在的重叠无法处理。
  • 事实上,单一向量已经足够好:它事实上学习的结果被表现为多个向量的比例叠加,比例即为某种词义的出现频率;并且在实际上,因为维数很多,例如 pike 一词同时是长矛和一种鱼,二者关系不大所以单独的语义向量近似垂直,线性组合后,例如和“鱼”点积的结果,则“长矛”分量几乎没有贡献。因此,对于一个词的多个语义(最好差别很大),其实是可以找到与每个语义相近的词,进而还原出其对应的语义分向量。

其之三驰骋于草原戈壁

Named Entity Recognition (NER): 寻找、识别文章中的人名、地名、日期等。

方法:将该词与周围的 context 的 embedding 拼一块跑全连接层分类。

全连接头与词向量部分可以一起训。

数学?谁会想听数学呵!

takeaways:

Hadamard 积 :适用于两个形状相同的矩阵或向量间,得到的结果是对应位置相乘的结果。

其之四忽囿于雠敌之羁轭

the cuddly cat by the door。每个单词都有其词性:determiner(限定词,如 a the my all 等,DET);ADJ;N;P(preposition);DET;N。

单词组成词组 phrase。the cuddly cat 是 NP,the door 是 NP,by the door 是 PP(prepositional phrase),合在一起是一个更大的 NP。

一个 Noun Phrase (NP) 包含一个 DET 和一个 N。更常见的是 DET+ADJ+N+PP,其中 ADJ 和 PP 是 optional 的。形容词可以有多个,因此使用正则表达式的概念,写成

NP->DET+(ADJ)*+N+(PP)。而例如 PP 就是 PP->P+NP。

Dependency Structure 描述文法的方式是一些词汇“修饰”另一些词汇:如果 A 修饰了 B,那么就自 A 连箭头指向 B。

  • Look at the large crate in the kitchen by the door!

箱子修饰 look。the、large 修饰 crate。in the kitchen 修饰 crate。by the door 同样修饰 crate。

因为人读文章时会不自觉地理解文法结构,所以有理由相信波特读文章时想要看懂句子就也要理解文法结构。但是因为歧义的存在,人类自身有纠错机制,波特则需要以概率的方法探索所有可能的方案。

一个例子是介词短语之间互相修饰的方案是树形的,这个树有多种布线方法。

最终,我们有依赖树语法(dependency tree grammar):把全体依赖关系写成一棵树。

treebank 存储了众多人工处理得到的语法树。早期 NLP 处理句子的方式常常是:给定句子,判定其 parse 的结果有多符合 treebank。

dependency parsing 的优势:

  • 双词汇亲和性(bilexical affinity):双向的依赖关系有说服力。
  • dependency distance:dependency 往往发生在临近词句间,很少长距离影响。
  • Intervening material:标点符号/动词两侧成分往往无关。
  • Valency of heads:每个不同词性的元素可能伴随不同修饰“化合价”出现。例如,名词只可能在左侧出现一个 DET,形容词也只可能出现在其左侧。

其有若干限制:

  • 根唯一。
  • 无环。
  • 箭头可以(表现在句子中)交叉(be non projective)吗?【可以的!但是比较少见】出现交叉的场合,CFG 不再适用

建立解释器的若干方法:

  • DP。
  • 因为解释器是树,所以尝试使用 MST。
  • 提出某些不可能满足的限制,不断缩小备选集。
  • Transition based parsing/deterministic dependency parsing(如下)。

Greedy transition based parsing:

有一个栈 σ,初始有 σ=[ROOT]。句子 β=w1,,wnA=。之后,每次可以进行如下三操作之一:

  • Shift(入栈):将句子队首弹入栈。
  • Left-Arc(左依赖):取栈顶两个元素,让栈顶下一个元素依赖栈顶元素,将依赖关系放入 A 然后删除栈顶下一个元素。
  • Right-Arc (右依赖):同上,只不过是让栈顶依赖栈顶下一个元素然后删除栈顶。

最终结束态时,栈中应该仅剩一个元素,这个元素一定是 ROOT

模型很不错,但是如何知道应使用三操作中哪一种?

答曰:机器学习,出列!

算法本身会检测每次操作时,栈、队列、依赖关系中的若干新近信息,然后为其分配对应方案。优化过程可以机器学习找到最牛方案。

问题是如何评估算法牛不牛?指标一是对比波特给出的 dependency 集合和答案的集合。指标二是让波特同时为每个单词打标签:名词性宾语、形容词、补足语等,对比标签的正确程度。

其之五起势于微末孤子

GTBP 的问题之一在于特征是稀疏的,问题之二在于完全无法处理训练数据中未出现的信息(没有迁移能力),问题之三在于训练时间很长。

解决方法是把所谓的“配置”,即对每种情况下要干什么这件事的指令,浓缩为一个向量。

CDQ 神经网络法:

  • 首先,为每个词找到 word embedding。
  • 这个 word embedding 里面还存了其它一些信息这些信息不是存在 word embedding 里面,而是由自己独立的 embedding,例如这个词的词性(part of speech)(具体词性,例如 NNS(复数名词)和 NN(单数名词)、nummod(数词修饰)和 adjmod(形容词修饰);如上述指出的,这些词性之间存在一些相似关系,也可以被特征向量描述;同时还 嵌了 不是内嵌,同样是独立存在的 dependency label(即它们通过当前打标签系统是主语还是补足语等的标签)。
  • 现在开始执行算法!某一时刻,我们能看到的信息包括:
    • s1,s2:倒数第二和栈顶元素。
    • b:队列头元素。
    • lc,rcs1,s2 分别联系着的左右弧们。
    • 注意:目前只有 lc,rc 因为所有 dependency 都已决定所以有 dependency label;其它东西都只能查到词性。
  • 把这所有信息全都拼起来过一个 MLP 分类知道下一步干嘛即可。

Graph Based Dependency Parsers:对于每一个单词对,计算二者存在 dependency 的概率,然后跑 MST。


其它一些神经网络上的细节操作:

  • Regularization:为误差添加一个正则项,例如 λθk2,即所有参数的平方和(此乃 L2 正则化),可以通过让那些无用的数据为零而遏制过拟合。
  • Dropout:避免 co-adaption,即多个神经元必须协同才能有效果,相当于多个只干了一个的活。实际执行时,每次训练随机干掉 η 的神经元,但是记得在真正跑的时候把所有权值都乘以 η 以弥补不再随机干掉神经元的变动。Dropout 往往被看作一种非均匀正则化。

Laguage Modeling:预测下一个词的任务。

前 DL 时代的解法:n-gram。

  • n-gram 是文本中出现的所有“n 个连续单词”的统称。

首先作出 Markov Assumption,即一个单词仅依赖于左侧所有单词,并且丢弃过早期的单词,仅保留当前位置的前 n 个单词。于是,计算条件概率

Pr(xi+1xin+1,,xi)

由条件概率定义,其等于

Pr(xin+1,,xi+1)Pr(xin+1,,xi)

即一个 n+1-gram 与一个 n-gram 的比值。

于是取一个大 corpus,统计里面各种 n-gram 出现的次数,用次数替代概率即可。若分子上采用的是 n-gram(此时分母上采用 n1-gram),则该模型称作 n-gram language model。

  • 问题之一:有很多词汇的影响会隔着很多单词传过来。
  • 问题之二(sparsity problem):语料库中有很多东西从来不出现。若分子未出现但分母出现,可以加一个小 δ 来 smoothing;如果分母都没出现,可以 backoff,取更短的 n-gram 预测。
  • 问题之三:语料库中必须存储所有的 n-gram,以至于必须在云端计算。

用这玩意可以写话!但是写出来的东西常常是 incoherent,不相干的。


最基础的 NLP 生成就是把基于 n-gram 的统计换成神经网络罢了:把前方一个窗口中所有东西一起扔到 classifier 里面生成即可。

这个现在解决了 sparsity 和语料库的问题,但是远距离投射的问题还没解决。同时,它现在为不同位置的向量建立完全不同的系数,这训起来不好训,因此我们希望它有一定的共同性但不完全相同(典型反例如 Word2Vec 即完全未考虑位置关系)。

解决方案是 RNN!我们用 hidden state,每次由前一时刻的 hidden state 和本时刻的 vector 共同得到本时刻的 hidden state,然后用 hidden state 过 MLP 预测即可。

新问题:

  • 没法并行!

其之六展露于风霜磨砺

RNN 如何训?把所有前缀扔进 RNN 得到每一时刻的概率分布 y^t,然后算交叉熵误差

yt(w)logy^t(w)=logy^t(xt+1)

真正训练时应用 SGD 思想,每次仅提供语料库中被切碎的一小坨语料进去。

现在考虑反向传播:可以推式子得到,每次更新时采用的矩阵 Wh 在整个周期内的梯度,等于每一时刻的梯度求和的结果;反向传播时,一个朴素的想法是算出最后时刻的梯度,贡献给 Wh,再推到前一时刻,再贡献……此乃 backpropagation through time。因为正向算时,用的都是统一的 Wh,所以反向的时刻的 Wh 也必须统一,梯度在最后再一起加上去。

但是事实上这很慢!往往会进行一些截断(truncate),例如反向传播二十步即告终。

如何拿来生成句子?输入 [BEG] token 然后一个一个喂进去即可,每次依照生成的分布采样一个单词。以 [EOF] token 告终。

如何衡量你的 Language Model 牛不牛?

定义 Perplexity 困惑度为

perplexity=t=1T(1Pr(xt+1x1,,xt))1/T

ln 就是 CELoss。困惑度越低越好。

n-gram 的困惑度是 100+;但是困惑度有大约 20 的下界,因为有很多场合根本无法预测。

RNN 的其它用处:

  • Part of Speech tagging,named entity tagging……
  • 句子的情感分类。【跑完整个句子后的 hidden state 应该被视作整个句子的 embedding】
  • 问题回答/音频识别/机器翻译……

RNN 的问题:

  • 梯度在时间尺度下消失。【发生于转移矩阵 Wh 的全体特征值均小于 1 的场合】这是因为,RNN 擅长处理周遭事物,而远程对梯度的影响远小于近程。【解决方案:LSTM】
  • 同理,梯度也可能爆炸。【解决方案:gradient clipping 梯度剪裁,如果梯度太大就把它缩放】

LSTM 的思想:如今的算法每一步都会重写整个隐藏状态。因此想让它不完全重写。

  • 两个隐藏状态:hidden state h 和 cell state c。其中,后者更接近常规 RNN 中的 hidden state 的地位。
  • 门向量衡量哪些位置应该被抹去、抹去多少。

首先计算三个门向量 f 遗忘门、i 输入门、o 输出门,都用 σ() 得到。

然后计算新 cell state c~=tanh()。之后,真正的 cell state c=ic~+fc,然后 h=otanc

梯度爆炸、消失等仍会出现。解决方法是建立 shortcut、skip 连接等。


hidden state 可以被看作一个词在上下文中的 embedding。但是也存在一些问题,例如只有左侧的单词会贡献信息。

  • 解决方法之一:双向 RNN,训一个反向的 RNN,将两个 hidden state 直接拼接。【不适用于目标是根据前缀生成下一个的 Language Modelling 任务】

其之七结集众英杰贤达

机器翻译是从源语言(source language)翻译为目标语言(target language)的任务。

早期:纯机械查单词(效果很烂)

1990-2010:Statistical Machine Translation。即,从数据中学习一个概率模型。

思想:对于源语言的句子 x 找到最优的目标语言句子 y,即求得

argmaxPr(yx)

使用 Bayes 公式改写为

argmaxPr(xy)Pr(y)Pr(x)

分母上的 Pr(x) 是常数可以忽略;分母上两部分相对独立。Pr(y) 可以根据语言模型算出,Pr(xy) 呢?

  • 首先,搜集大量的 parallel data,即匹配的源-目标语句对。
  • 然后,引入一个隐变量 a 表示对齐(alignment),即单词级别的对应关系,然后处理 Pr(x,ay)
  • 对齐有一些功能,比如说处理不同语言间的不同语序关系,或者某些语言中没有对应关系的虚词等。因此,对齐可能是一对一、一对多、多对一、多对多(词组对词组的翻译)【这同样也适用于同一种语言中,对同一个意象的不同表达方式】
  • 学习 a 的方式多样,如观察两个单词共同出现的频率等。
posted @   Troverld  阅读(73)  评论(8编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示