动手学深度学习 6.1 语言模型

前言

从零开始学习ai文章系列计划是个人在《动手学深度学习》和《磨菇书》两本书的学习中的个人笔记,文章也会以课本中的章节分开,即每个章节一片笔记。我会尽量的把主要内容以及遇到的难点进行记录与解决,如果哪里有错误的欢迎指正。或者不清晰的可以直接查看原文部分。

《动手学深度学习》原文(课本):https://tangshusen.me/Dive-into-DL-PyTorch/#/

《动手学深度学习》代码:https://github.com/ShusenTang/Dive-into-DL-PyTorch

(由于有时候公式太多,可能会直接贴图片)


语言模型(language model)是自然语言处理的重要技术。自然语言处理中最常见的数据是文本数据

我们可以把一段自然语言文本看作一段离散的时间序列。

假设一段长度为T文本中的词依次为\(w_1,w_2,…,w_T\),那么在离散的时间序列中,\(w_t\)(1≤t≤T)可看作在时间步(time step)t的输出或标签。 \[ P(w_1,w_2,…,w_T) \]

1. 语言模型的计算

既然语言模型很有用,那该如何计算它呢?假设序列 \(w_1,w_2,…,w_T\) 中的每个词是依次生成的,我们有 \[ P(w_1,w_2,…,w_T) = ∏_{t=1}^{T}{P(w_t|w_1,w_2,…,w_{t-1})} \] 例如,一段含有4个词的文本序列的概率,将以上公式展开 \[ P(w_1,w_2,…,w_T) = P(w_1)P(w_2|w_1)P(w_3|w_1,w_2)P(w_4|w_1,w_2,w_3) \] 为了计算语言模型,我们需要计算词的概率,以及一个词在给定前几个词的情况下的条件概率,即语言模型参数。

2. n元语法

当序列长度增加时,计算和存储多个词共同出现的概率的复杂度会呈指数级增加。n元语法通过马尔可夫假设(虽然并不一定成立)简化了语言模型的计算。

这里的马尔可夫假设是指一个词的出现只与前面n个词相关,即n阶马尔可夫链(Markov chain of order n)

如果n=1,那么有 \(P(w_3∣w_1,w_2) = P(w_3∣w_2)\) 。如果基于n−1阶马尔可夫链,我们可以将语言模型改写为 \[ P(w_1,w_2,…,w_T) ≈ ∏_{t=1}^{T}{P(w_t|w_{t-(n-1)},…,w_{t-1})} \] 以上也叫n元语法(n-grams)。它是基于n−1阶马尔可夫链的概率语言模型。当n分别为1、2和3时,我们将其分别称作一元语法(unigram)、二元语法(bigram)和三元语法(trigram)。

例如,长度为4的序列 \(w_1,w_2,w_3,w_4\) 在一元语法、二元语法和三元语法中的概率分别为 \[ \begin{align} P(w_1,w_2,w_3,w_4) &= P(w_1)P(w_2)P(w_3)P(w_4) \\ P(w_1,w_2,w_3,w_4) &= P(w_1)P(w_2|w_1)P(w_3|w_2)P(w_4|w_3) \\ P(w_1,w_2,w_3,w_4) &= P(w_1)P(w_2|w_1)P(w_3|w_1,w_2)P(w_4|w_2,w_3) \end{align} \] 当n较小时,n元语法往往并不准确。例如,在一元语法中,由三个词组成的句子“你走先”和“你先走”的概率是一样的。然而,当n较大时,n元语法需要计算并存储大量的词频和多词相邻频率。

3. 举例说明(个人思考)

假设存在一段对话。(A为输入,可以认为是人类问话。B为输出,可以认为是电脑回答。)

A: 你好吗

B: 我很好

此时存在字符串"你好吗\end"

我们现在要计算字符串 "你好吗\end" 出现的概率 P("你好吗\end我很好\end")

首先输入是 你好吗\end 因此 P("你好吗\end")=1

那么原来的式子变形为(latex中斜杠和双引号) \[ \begin{align*} &P(你好吗\backslash end我很好\backslash end) \\ &= P(我很好\backslash end | 你好吗\backslash end )*P(你好吗\backslash end) \\ &= P(我很好\backslash end | 你好吗\backslash end ) \end{align*} \] 接下来我们分析网络输出"我很好\end"的概率。 \[ \begin{align*} &P(我很好\backslash end | 你好吗\backslash end ) \\ &= P(我 | 你好吗\backslash end )\\ &*P(很 | 你好吗\backslash end我 )\\ &*P(好 | 你好吗\backslash end我很 )\\ &*P(\backslash end | 你好吗\backslash end我很好 )\\ \end{align*} \] 首先在 "你好吗" 的条件下得到 "我" 的概率 P("我" | "你好吗\end" )=0.9 (这里的概率数值都是随便写的)。当然也可能出现其他词,比如 "你" ,但在训练好的模型中其概率很低,大概为 P("你" | "你好吗\end" )=0.01

接着继续在 "你好吗\end我" 的条件下得到 "很" 的概率为 P("很" | "你好吗\end我" )=0.6

同理继续 P("好" | "你好吗\end我很" ) = 0.8P("好" | "你好吗\end我很" )=0.7P("\end" | "你好吗\end我很好" )=0.9

那么我们就算出了网络模型在输入 "你好吗\end" 下输出 "我很好\end" 的概率为 \[ P(我很好\backslash end|你好吗\backslash end) =0.9*0.6*0.8*0.7*0.9=0.27216 \]


拓展到n元语法。举例n=2, 此时我们认为 P("我" | "吗\end") ≈ P("我" | "你好吗\end") ,即下一个词的概率,仅和前n个词有关,不足的时候可以用空格代替。

当然我们也看到从"吗\end" 得到 "我" 是一件匪夷所思的事情,因此n如果太小的话是会出问题的。直接上来理解,n越大说明获取的信息越多,因此输出能表现的更加理性。

最后贴上claude一段回答。