吴恩达深度学习课程五:自然语言处理 第一周:循环神经网络 (三)语言模型
<p>此分类用于记录吴恩达深度学习课程的学习笔记,目前已完结,点击进入全集目录<br>课程相关信息链接如下:</p>
<ol>
<li>原课程视频链接:[双语字幕]吴恩达深度学习deeplearning.ai</li>
<li>github课程资料,含课件与笔记:吴恩达深度学习教学资料</li>
<li>课程配套练习(中英)与答案:吴恩达深度学习课后习题与答案</li>
</ol>
<p>本篇为第五课的第一周内容,1.5到1.7的内容。</p>
<hr>
<p>本周为第五课的第一周内容,与 CV 相对应的,这一课所有内容的中心只有一个:<strong>自然语言处理(Natural Language Processing,NLP)</strong>。<br>
应用在深度学习里,它是专门用来进行<strong>文本与序列信息建模</strong>的模型和技术,本质上是在全连接网络与统计语言模型基础上的一次“结构化特化”,也是人工智能中<strong>最贴近人类思维表达方式</strong>的重要研究方向之一。<br>
<strong>这一整节课同样涉及大量需要反复消化的内容,横跨机器学习、概率统计、线性代数以及语言学直觉。</strong><br>
语言不像图像那样“直观可见”,更多是抽象符号与上下文关系的组合,因此<strong>理解门槛反而更高</strong>。<br>
因此,我同样会尽量补足必要的背景知识,尽可能用比喻和实例降低理解难度。<br>
本篇的内容关于<strong>语言模型</strong>,是在了解 RNN 原理上的进一步应用。</p>
<h1 id="1-不同类型的-rnn">1. 不同类型的 RNN</h1>
<p>我们在上一篇中用命名实体识别作为示例来演示 RNN 的基本原理,但我们也提到了:<br>
<strong>模型输入序列的长度 <span class="math inline">\(T_x\)</span> 和输出序列的长度 <span class="math inline">\(T_y\)</span> 并不都是相等的。而二者的对应关系不同,往往就代表了不同的任务类型。</strong><br>
因此,我们以 <span class="math inline">\(T_x\)</span> 和 <span class="math inline">\(T_y\)</span> 的不同对应关系,划分了不同类型的 RNN,常见情况可以概括为以下几类:</p>
<ol>
<li><strong>一对一(One-to-One)</strong></li>
<li><strong>多对一(Many-to-One)</strong></li>
<li><strong>一对多(One-to-Many)</strong></li>
<li><strong>多对多(Many-to-Many,等长)</strong></li>
<li><strong>多对多(Many-to-Many,非等长)</strong></li>
</ol>
<p><img src="https://img2024.cnblogs.com/blog/3708248/202601/3708248-20260107215709176-1109618344.png" alt="image.png" loading="lazy"><br>
现在,来<strong>逐个简单展开</strong>一下:<br>
<img src="https://img2024.cnblogs.com/blog/3708248/202601/3708248-20260107220014271-1535817236.png" alt="image.png" loading="lazy"><br>
<img src="https://img2024.cnblogs.com/blog/3708248/202601/3708248-20260107220011950-1342522143.png" alt="image.png" loading="lazy"><br>
<img src="https://img2024.cnblogs.com/blog/3708248/202601/3708248-20260107220010979-2118108004.png" alt="image.png" loading="lazy"><br>
现在,我们就知道了:如果我们要完成之前用来演示的命名实体识别任务,那一般需要构建等长的多对多 RNN 模型。<br>
而语言模型,同样也是一种等长的多对多 RNN 模型,由此,我们正式开始引入语言模型。</p>
<h1 id="2语言模型language-model-lm">2.语言模型(Language Model, LM)</h1>
<p>先摆一下语言模型较为官方的定义:</p>
<blockquote>
<p><strong>语言模型</strong>是一种用于刻画自然语言中<strong>词(或字符)序列概率分布</strong>的模型。其核心目标是:<strong>对一个序列中下一个符号出现的可能性进行建模</strong>,即在已知前文的条件下,预测当前或下一时刻的词。</p>
</blockquote>
<p>而通俗点来说,语言模型所实现的功能是:<strong>猜你输入的下一个字更可能是什么</strong>。<br>
比如输入“我爱”时,它可以预测到下一个字更可能是“你”,而在输入“我爱你”时,模型会预测<strong>一个表示句子结束的特殊符号</strong>的概率较高。</p>
<p>显然,问题来了:<strong>什么样的训练逻辑可以得到拥有这种预测功能的语言模型呢?</strong><br>
先给出一个较简洁的结论,然后我们来进行演示:<strong>在每一个时间步 <span class="math inline">\(t\)</span>,把前 <span class="math inline">\(t-1\)</span> 个词作为输入,让模型去预测第 <span class="math inline">\(t\)</span> 个词,计算损失,不断优化参数,实现学习。</strong><br>
来看看它的具体运行过程:</p>
<h2 id="21-语言模型的数据准备">2.1 语言模型的数据准备</h2>
<p><img src="https://img2024.cnblogs.com/blog/3708248/202601/3708248-20260107215708710-1370975958.png" alt="image.png" loading="lazy"><br>
在这里,你可能会有这样一个问题:我们定义了一个控制信号 <code><EOS></code> 来表示序列的终止,但是<strong>在语言直觉上,句号本身不就是终止的意思吗?能不能直接用句号来代表终止信号?</strong></p>
<p>答案当然是不能的,使用<code><EOS></code>并非是多此一举,不能使用句号本身直接代替的<code><EOS></code>的原因可以简单概括为一句话:<strong>语言结束并不代表序列结束。</strong><br>
来看这样几个例子:</p>
<table>
<thead>
<tr>
<th>语言</th>
<th>句子示例</th>
<th>说明</th>
<th>为什么句号不能直接代表 <code><EOS></code></th>
</tr>
</thead>
<tbody>
<tr>
<td>中文</td>
<td>我真的爱你。我真的饿了。</td>
<td>句子中包含多个子句。</td>
<td>第一个句号是子句结束,句号是语法结束,但整个序列可能还没结束,无法作为统一序列终止信号。</td>
</tr>
<tr>
<td>中文</td>
<td>他爱你吗?</td>
<td>句子中没有句号。</td>
<td>不使用句号也可以代表结束。</td>
</tr>
<tr>
<td>英文</td>
<td>“Dr. Smith works at St. Mary’s Hospital.”</td>
<td>英文中缩写、专有名词中包含句点。</td>
<td>句点不一定表示句子或序列结束,例如缩写中的“Dr.”,如果直接用句号作为 <code><EOS></code>,会误判序列结束。</td>
</tr>
</tbody>
</table>
<p>从这些例子来看,<code><EOS></code> 并不是语言符号,而是模型训练与生成过程中必不可少的<strong>控制信号</strong>。<br>
因此,你会发现:<strong>我们需要一个明确不歧义,在各语言中统一且唯一的控制信号来代表序列的结束,这就是 <code><EOS></code> 。</strong></p>
<p>在完成了数据准备之后,我们就正式来看看语言模型的传播逻辑。</p>
<h2 id="22-语言模型的传播过程">2.2 语言模型的传播过程</h2>
<p>回忆我们最开始简述的正向传播逻辑:<strong>在每一个时间步 <span class="math inline">\(t\)</span>,把前 <span class="math inline">\(t-1\)</span> 个词作为输入,让模型去预测第 <span class="math inline">\(t\)</span> 个词。</strong><br>
现在就来先展开看看语言模型的正向传播过程:<br>
<img src="https://img2024.cnblogs.com/blog/3708248/202601/3708248-20260107220012733-870010096.png" alt="image.png" loading="lazy"><br>
语言模型的正向传播过程并不复杂,但要真正明白它的学习逻辑,自然还离不开它的反向传播,而一个需要再次强调的就是:<strong>模型每一步的输出是一个概率分布,也就是“可能性”。</strong><br>
带着这一点,我们来看看反向传播的过程:<br>
<img src="https://img2024.cnblogs.com/blog/3708248/202601/3708248-20260107220013578-590433542.png" alt="image.png" loading="lazy"><br>
仍然是反向传播不变的基本逻辑:<strong>计算损失,计算梯度,更新参数,实现学习。</strong><br>
我们在上一篇中也展开了 RNN 具体的反向传播逻辑,这里就不再多提了。</p>
<p>至此,我们已经从训练视角理解了语言模型是如何学习到序列建模能力的。<br>
在模型训练完成之后,如何利用这个语言模型真正生成新的文本序列,就成为接下来需要回答的问题,其中相关的一门技术叫做<strong>新序列采样</strong>。</p>
<h1 id="3新序列采样">3.新序列采样</h1>
<p>当我们拥有一个训练好的语言模型时,有时我们会想具体地看看这个模型都学到了什么,它的“文风”是什么样的,其中一种方法就是新序列采样。<br>
这个概念同样不难理解:</p>
<blockquote>
<p><strong>新序列采样</strong>,指的是:在语言模型生成文本时,<strong>不再固定选择概率最大的 token</strong>,而是根据模型给出的概率分布,从中 <strong>“抽样”生成下一个 token</strong>,从而逐步生成一整段新序列的过程。</p>
</blockquote>
<p>再通俗一点:<strong>新序列采样不是“选最可能的那个”,而是“按可能性来抽一个”,让模型生成更自然、多样的文本。</strong><br>
它的具体过程是这样的:<br>
<img src="https://img2024.cnblogs.com/blog/3708248/202601/3708248-20260107220012413-1576332189.png" alt="image.png" loading="lazy"><br>
再复述一下这个过程:<br>
给定一个已训练好的语言模型,在生成阶段,模型以起始符号作为输入,<strong>在每个时间步根据当前上下文输出一个 token 的概率分布,并通过采样策略选取下一个 token</strong>,将其作为下一步输入,直到生成 <code><EOS></code> 或达到设定长度为止。</p>
<p>而在实际应用中,常见的新序列采样策略包括:</p>
<ul>
<li><strong>随机采样(Sampling)</strong></li>
<li><strong>Top-k 采样</strong>:只在概率最高的 <span class="math inline">\(k\)</span> 个 token 中采样。</li>
<li><strong>Top-p(Nucleus)采样</strong>:在累计概率达到 <span class="math inline">\(p\)</span> 的最小 token 集合中采样。</li>
</ul>
<p>这样,我们便可以较直观地观察模型<strong>在语言层面所学习到的统计规律与生成偏好</strong>。<br>
在具体部署中合理使用新序列采样策略,也可以在保证基本语言合理性的前提下,提高生成文本的多样性。</p>
<p>最后,吴恩达老师还提及了<strong>基于字符的语言模型</strong>。这类模型<strong>不再以词或子词作为基本单位</strong>,而是直接以<strong>字符序列</strong>作为输入与预测对象,如<strong>字母、空格及标点符号</strong>等。<br>
字符级建模的优势在于不依赖分词规则、天然不存在未登录词问题,但代价也十分明显:单个字符所携带的语义信息极弱,序列长度显著变长,模型需要先“学会拼词”,再学习句法与语义结构,训练难度和计算成本都更高。<br>
因此,这种模型在实际部署中的价值并不高,实际上也并不流行,我们就不再展开了。</p>
<h1 id="4-总结">4. 总结</h1>
<table>
<thead>
<tr>
<th>概念</th>
<th>原理</th>
<th>比喻</th>
</tr>
</thead>
<tbody>
<tr>
<td>不同类型的 RNN</td>
<td>根据输入序列长度 <span class="math inline">\(T_x\)</span> 与输出序列长度 <span class="math inline">\(T_y\)</span> 的对应关系,RNN 可适配不同任务结构,如分类、序列标注、生成等</td>
<td>不同规格的传送带:有的只收一件吐一件,有的收一排给一个结果</td>
</tr>
<tr>
<td>语言模型(LM)</td>
<td>建模序列的条件概率分布 <span class="math inline">\(P(w_t \mid w_{<t})\)</span>,在已知前文的情况下预测下一个 token</td>
<td>根据已经写下的内容,猜作者下一笔会写什么</td>
</tr>
<tr>
<td>语言模型的训练逻辑</td>
<td>在时间步 <span class="math inline">\(t\)</span>,用前 <span class="math inline">\(t-1\)</span> 个 token 作为输入,预测第 <span class="math inline">\(t\)</span> 个 token,通过损失函数和反向传播更新参数</td>
<td>做完一句话的“完形填空”,错了就记住,下次改正</td>
</tr>
<tr>
<td><code><EOS></code> 结束符</td>
<td>使用一个不歧义的特殊符号明确标记序列结束,而不是依赖语言中的标点</td>
<td>像文件里的“结束标志”,而不是文章里的句号</td>
</tr>
<tr>
<td>语言模型输出</td>
<td>每一步输出的是对整个词表的概率分布,而不是一个确定结果</td>
<td>给出一张“可能性排行榜”,而不是直接拍板</td>
</tr>
<tr>
<td>新序列采样</td>
<td>在生成阶段,不固定选择概率最大的 token,而是根据概率分布进行抽样生成</td>
<td>不是每次都选第一名,而是按权重抽签</td>
</tr>
<tr>
<td>字符级语言模型</td>
<td>以字符而非词或子词为建模单位,逐字符预测</td>
<td>先学拼字母,再学组词、造句</td>
</tr>
<tr>
<td>字符级模型不流行原因</td>
<td>序列过长、语义单位过弱,训练和推理成本高,工程性价比低</td>
<td>用积木一粒一粒搭摩天楼,理论可行但太慢</td>
</tr>
</tbody>
</table><br><br>
来源:https://www.cnblogs.com/Goblinscholar/p/19454021
頁:
[1]