NLP这是一个非常自然的延伸——你已经掌握了处理图像CV的核心工具CNN、PyTorch现在想了解另一个同样重要甚至更为火爆的领域自然语言处理。NLP的全称是Natural Language Processing中文叫自然语言处理。简单来说它就是让计算机能够理解、处理和生成人类语言如中文、英文的技术。为了让刚学完图像处理的你更好地理解我会一直和CNN处理图像的方式进行对比。这样你会发现虽然数据变了但很多核心思想是相通的。1. NLP 的核心难点教会计算机“识字”计算机不认识字它只认识数字。所以NLP 的第一步永远是把文字转换成计算机能处理的数字形式。这和你把一张图片像素值转换成数字矩阵是一样的道理。2. NLP 的数据结构 vs. 图像的数据结构这是两者最直观的区别也是导致模型结构差异的根本原因。维度图像 (CV)语言 (NLP)数据结构网格结构(Grid)序列结构(Sequence)依赖关系空间依赖一个像素跟它周围的像素有关。时序依赖一个词的意思依赖于它前面的词上下文。数据形状(H, W, C)例如(224, 224, 3)(序列长度, 特征维度)例如(20, 768)你的代码x.view(x.size()[0], -1)把图片拉直在 NLP 中不能拉直顺序一旦打乱句子意思就变了“我打你”≠“你打我”。3. 核心概念对比从“像素”到“词向量”在 CV 里你通过torchvision.transforms把图片变成了 Tensor。在 NLP 里这个过程的专业术语叫Embedding嵌入。词向量 (Word Embedding)作用把一个个的单词如 “猫”映射到一个高维空间中的向量。特点语义相近的词如 “猫” 和 “狗”在向量空间里的距离也很近。类比就像你myAlexNet里的卷积层把图片像素变成了抽象的特征图词向量层把离散的文字变成了稠密的语义向量。python# 伪代码示例 import torch.nn as nn embedding nn.Embedding(num_embeddings10000, embedding_dim300) # 10000个词每个词用300维向量表示 sentence torch.tensor([1, 25, 6, 100]) # 一句话的词索引 vectorized embedding(sentence) # 变成 (4, 300) 的张量4. 核心模型对比从“卷积”到“循环/注意力”由于数据从“空间网格”变成了“时间序列”提取特征的工具也变了。RNN/LSTM你之前了解过的它像一个有记忆的阅读器逐词阅读并传递“隐藏状态”记忆。CV 类比有点像你myModel里的conv1-pool1-conv2这种流水线只不过在 NLP 里这一步处理的是一个时间序列。Transformer目前 NLP 的绝对霸主GPT、BERT 的基础。它不再逐词阅读而是一眼看全句通过一种叫自注意力 (Self-Attention)的机制计算出句子中每个词和其他所有词的相关度。CV 类比很像你在ResNet里用全局信息去理解图片Transformer 就是让每个词都能“看到”句子里的所有词从而更好地理解上下文。5. 典型任务对比任务类型计算机视觉 (CV)自然语言处理 (NLP)分类图片分类是不是猫文本分类情感分析好评/差评、垃圾邮件检测检测/分割目标检测框出猫的位置信息抽取命名实体识别找出句子中的人名、地名生成图像生成GAN 画图文本生成机器翻译、摘要生成、对话机器人ChatGPT6. 总结从你的视角看 NLP如果你擅长 CV你懂的是“空间上的特征提取”。如果你学 NLP你要学的是“时序上的特征提取”。它们本质上都是在做同一件事把原始数据像素/文字映射到特征空间然后基于这些特征完成分类、生成等任务。常见的输入输出如何用数据表示文字 这里可以使用one-hot编码 但是普通的one-hot编码 就汉字而言有两万多种。维度太长且不能体现关系。Word Embedding将相同类型的文字划分为一类 通过全连接来改变编码维度让模型自己学习。NLP任务的输入输出常见的输入一个字对应一个编号 把编号传给模型就可以判断每一个字是什么词性 分类任务只输出一个值 1/0输入输出不对应长度 下一节学习问题假如在词性识别任务中 出现相同的字 如何分辨词性RNN有一个传家宝 导致它一直传宗接代就可以一直考虑这段文字前面的信息他就可以做到序列问题日RNN了解即可RNNRecurrent Neural Network循环神经网络是一类专门用于处理序列数据的神经网络。它的核心特点是网络内部存在循环连接使得信息可以在时间步之间传递从而让网络具有“记忆”能力。1. RNN 的核心思想为什么需要记忆在处理图像时一张图片的所有像素是同时输入的像素之间的空间关系由卷积来捕捉。但在处理序列如文本、语音、时间序列时数据是依次到达的当前时刻的理解往往依赖于之前的信息。例如在句子“我今天吃了苹果它很甜”中要理解“它”指代什么必须记住前面的“苹果”。在预测股票价格时明天的价格往往与过去几天的走势有关。RNN 正是为了解决这类时序依赖问题而设计的。它通过一个循环结构将上一时刻的隐藏状态传递到当前时刻使得网络在每一步都能“记住”过去的信息。2. RNN 的基本结构一个标准的 RNN 单元在时刻 tt 接收两个输入当前时刻的输入 xtxt​例如一个词的词向量上一时刻的隐藏状态 ht−1ht−1​记忆然后通过一个带有激活函数通常是 tanh⁡tanh 或 ReLU的全连接层计算出当前时刻的隐藏状态 htht​ 和输出 ytyt​可选。数学公式简化版httanh⁡(WihxtWhhht−1bh)ht​tanh(Wih​xt​Whh​ht−1​bh​)ytWhyhtbyyt​Why​ht​by​其中WihWih​输入到隐藏层的权重矩阵。WhhWhh​隐藏层到自身的权重矩阵循环部分。WhyWhy​隐藏层到输出的权重矩阵。关键点所有时间步共享同一套权重Wih,Whh,WhyWih​,Whh​,Why​这大大减少了参数量并使模型能够处理任意长度的序列。3. RNN 的工作流程展开计算图RNN 的循环结构在时间维度上展开后可以看作是一个深度前馈网络其中每一层对应一个时间步且各层权重共享。例如处理一个长度为 TT 的序列时RNN 会依次执行 TT 次计算每次传递隐藏状态。展开图texty1 y2 y3 ↑ ↑ ↑ h1 ← h2 ← h3 ← ... ↑ ↑ ↑ x1 x2 x3隐藏状态 htht​ 包含了从序列开始到当前步的所有信息理论上。输出 ytyt​ 可以根据任务需求在每一步都产生如词性标注也可以只在最后一步产生如情感分类。4. RNN 的变体LSTM 和 GRU虽然标准 RNN 理论上可以记住长期信息但在实践中由于梯度消失/爆炸问题它很难学习到长距离的依赖关系例如句子开头的词对结尾的影响。为了解决这个问题研究者提出了两个著名变体LSTM长短期记忆网络引入门控机制输入门、遗忘门、输出门和记忆单元让网络可以自主选择记住或遗忘信息。能够有效捕捉长距离依赖是目前最常用的 RNN 变体之一。GRU门控循环单元是 LSTM 的简化版本将遗忘门和输入门合并为更新门参数量更少训练更快效果与 LSTM 相当。这些变体在语音识别、机器翻译、文本生成等任务中取得了巨大成功。5. RNN 的优缺点优点缺点能够处理任意长度序列难以并行计算必须按时间步依次计算参数共享模型简洁梯度消失/爆炸问题尤其在长序列中符合时序数据特性具有记忆能力长期记忆能力有限即使 LSTM 也有限由于 Transformer 架构的兴起并行计算、全局注意力RNN 在 NLP 领域的地位已被大幅削弱但在处理某些特定序列数据如传感器信号、短文本时仍有应用。Self-attention自注意力机制RNN LSTM处理序列类似串行 self-attention则解决了这个问题 可以并行。输入 输出 维度不变计算注意力aa在计算a1注意力时 首先a1×Wq q1 其余a234 × Wk 得到各自的k 并且求a1×Wv v1a1’ × v1 a2‘ × v2 ... 四项相乘的结果相加得到b1的值b1就是 a1这个字看过整体之后得到的结果 从而统揽全局。总结Q K V 计算注意力计算注意力A矩阵 经过softmax 得到A’从而相加得到 b1234总结整体的过程 计算维度位置信息TransformerBertBERT确实是“先看到整个文本然后再遮住一部分”来训练的。这个过程就像我们做英语完形填空给你一整篇文章先看整个文本然后随机挖掉一些单词Mask让你根据上下文填出正确的词。BERT的预训练就是这个原理。1. 为什么叫“无监督训练”它真的“无监督”吗这是一个很好的问题也常常让人困惑。严格来说BERT的预训练不是完全无监督而是“自监督”Self-supervised。区别在哪在真正的无监督学习中数据是没有标签的我们需要算法自己去发现隐藏的结构。而BERT的“标签”是从数据本身自动生成的。怎么生成的就是通过你提到的Mask操作。我们把文本中的词遮住这些被遮住的词本身就变成了我们要预测的“标签”。模型的任务就是去预测这些由我们“制造”出来的标签。所以整个过程是给你大量无标签的原始文本比如维基百科 → 我算法自动在文本上挖空并把这些空位当作“伪标签” → 让模型去学习预测这些空位。这样模型就在海量数据上学会了语言规律 。2. BERT是怎么“先看整个文本再Mask”的MLM流程BERT的核心预训练任务叫做掩码语言模型Masked Language ModelMLM它完美体现了你所说的“先看再遮” 。具体操作如下输入整个文本BERT首先会完整地“读”一遍输入的句子。随机Mask挖空它会在句子中随机选中15%的词严格来说是WordPiece token来进行处理 。但处理方式不是简单粗暴地全部换成[MASK]标记而是有一套精妙的设计80%的概率用特殊的[MASK]标记替换这个词。例如句子“我爱吃苹果”变成“我爱[MASK]苹果”。10%的概率用一个随机词替换它。例如“我爱吃苹果”变成“我爱唱苹果”。这是为了让模型学会纠错因为它需要知道当前词可能不对要去结合上下文猜正确的。10%的概率保持不变。例如句子仍然是“我爱吃苹果”。这是为了让模型也关注当前词本身的信息因为在下游任务如命名实体识别中[MASK]标记是不会出现的。进行预测最后BERT模型需要根据其他未被遮住的词即上下文来预测这些被选中的15%位置上原本是什么词。3. 为什么说BERT是“双向”的这和你之前学的RNN很不一样。RNN是从左到右单向读取的这就导致它在预测第t个词时只能看到前t-1个词 。而BERT基于Transformer编码器它在预训练时通过MLM任务能够同时利用一个词左侧和右侧的所有上下文信息来预测被遮住的词 。这就是它被称为“双向”的原因。正因为能结合左右信息BERT对语言的理解才那么深刻。4. 预训练的数据是什么BERT最初是在海量的纯文本上进行预训练的例如维基百科和BooksCorpus一个包含约8亿词的书籍语料库。这些数据都没有任何人工标注这就是它被称为“无监督预训练”的由来。总结一下流程第一步准备原材料收集海量、无标注的纯文本如所有维基百科文章。第二步制造“伪标签”在输入文本上随机选择15%的词按照80%、10%、10%的策略进行Mask、随机替换或保持不变 。第三步模型学习让BERT模型去预测这些被处理过的位置原本是什么词即MLM任务同时它还要学习一个额外的辅助任务下一句预测NSP来理解句子间的关系 。第四步得到通才经过这样在海量数据上的反复训练BERT就成为了一个掌握了丰富语言知识的“通才”模型。bert的输入cls 分类头 sep逗号或者句号bert的输出回顾