1.定义
自然语言处理(Natural Language Processing, NLP),是人工智能领域的一个重要分支。自然语言,指人类日常使用的语言(如中文、英文),NLP的目标是让计算机“理解”或“使用”这些语言。
文本表示
分词
子词级分词是一种介于词级分词与字符级分词之间的分词方法,它将词语切分为更小的单元——子词(subword),例如词根、前缀、后缀或常见词片段。与词级分词相比,子词分词可以显著缓解OOV问题;与字符级分词相比,它能更好地保留一定的语义结构。子词分词的基本思想是:即使一个完整的词没有出现在词表中,只要它可以被拆分为词表中存在的子词单元,就可以被模型识别和表示,从而避免整体被替换为。
常 见 的 子 词 分 词 算 法 包 括BPE(Byte Pair Encoding) 、WordPiece 和 Unigram Language Model。
其中,BPE是最早被广泛应用的方法,其需要先从语料中学习一个子词词表,基本原理是:首先将所有词语拆分为单个字符,然后迭代地统计语料中出现频率最高的字符对,将其合并为一个新的子词,并加入词表。该过程持续进行,直到达到设定的词表大小。
然后再根据词表对新输入的文本进行分词,其基本原理是:从输入文本的第一个字符开始,优先选择词表中能够匹配的最长子词单元,然后继续处理剩余部分,直到完成整个序列的切分。
子词级分词已经成为现代英文NLP模型中的主流方法,如BERT、GPT等模型均采用了基于子词的分词机制。
分词工具
基于词典或模型的传统方法,主要以“词”为单位进行切分;代表工具包括jieba、HanLP等,这些工具广泛应用于传统NLP任务中。
基于子词建模算法(如BPE)的方式,从数据中自动学习高频字组合,构建子词词表。代表工具包括Hugging Face Tokenizer、SentencePiece、tiktoken等,常用于大规模预训练语言模型中。
GitHub - huggingface/tokenizers: 💥 Fast State-of-the-Art Tokenizers optimized for Research and Production
GitHub - google/sentencepiece: Unsupervised text tokenizer for Neural Network-based text generation.
GitHub - openai/tiktoken: tiktoken is a fast BPE tokeniser for use with OpenAI’s models.
GitHub - fxsjy/jieba: 结巴中文分词
GitHub - hankcs/HanLP: 中文分词 词性标注 命名实体识别 依存句法分析 成分句法分析 语义依存分析 语义角色标注 指代消解 风格转换 语义相似度 新词发现 关键词短语提取 自动摘要 文本分类聚类 拼音简繁转换 自然语言处理
词表示
语义化词向量
传统的one-hot表示虽然结构简单,但它无法反映词语之间的语义关系,也无法衡量词与词之间的相似度。为了解决这个问题,研究者提出了Word2Vec模型,它通过对大规模语料的学习,为每个词生成一个具有语义意义的稠密向量表示。这些向量能够在连续空间中表达词与词之间的关系,使得“意思相近”的词在空间中距离更近。
Word2Vec的设计理念源自“分布假设”——即一个词的含义由它周围的词决定。
Word2Vec原理
Word2Vec不依赖人工标注,而是直接利用大规模原始文本(如书籍、新闻、网页等)作为数据源,从中自动构造训练样本。
由于两种模型的输入和输出都是词语,因此首先需要对原始文本进行分词,将连续文本转换为token序列。
此外,模型无法直接处理文本符号,训练时仍需将词语转换为one-hot编码,以便作为模型的输入和输出进行计算。
:::info
CBOW(Continuous Bag-of-Words)模型:输入是一个词的上下文(即前后若干个词),模型的目标是预测中间的目标词。
:::
CBOW模型的前向传播过程如下:
1.输入上下文词(乘坐、上班)
每个词用one-hot向量表示。
2.查找词向量(W𝑖𝑛)
每个one-hot向量与参数矩阵W𝑖𝑛相乘,查出对应的词向量。
(W𝑖𝑛实际上就是词向量矩阵,每一行表示一个词的向量)
3.平均上下文向量
将多个上下文词向量取平均,得到一个整体的上下文表示。
4.预测中心词
将平均后的上下文向量与参数矩阵Wout相乘,得到对整个词表的预测得分。
5.Softmax输出
将得分输入Softmax,得到每个词作为中心词的概率分布。
6.计算损失
将预测结果与真实中心词“地铁”的one-hot向量进行比对,计算交叉熵损失。
之后在进行反向传播时,参数矩阵Win中“乘坐”和“上班”对应的词向量就会被更新。模型通过不断训练,逐步优化这些向量,最终便能得到具有语义的词向量。
:::info
Skip-gram模型:输入是一个中心词,模型的目标是预测其上下文中的所有词(即前后若干个词)。
:::
前向传播过程如下:
1.输入中心词(地铁)
“地铁”用one-hot向量表示
2.查找词向量(W𝑖𝑛)
与参数矩阵W𝑖𝑛相乘,取出“地铁”对应的词向量。(W𝑖𝑛实际上就是词向量矩阵,每一行表示一个词的向量)
3.预测上下文
将中心词向量与参数矩阵Wout相乘,得到对整个词表的预测得分。
4.Softmax输出
得分通过Softmax转为概率分布,表示各词作为上下文的可能性。
5.计算损失
与真实上下文词“乘坐”、“上班”进行比对,计算交叉熵损失并求和,得到总损失。
之后在进行反向传播时,参数矩阵W𝑖𝑛中的“地铁”对应的词向量就会被更新,模型通过这个过程不断的进行学习,最终便能得到具有语义的词向量。
2.传统序列模型
RNN
RNN(循环神经网络)的核心结构是一个具有循环连接的隐藏层,它以时间步(time step)为单位,依次处理输入序列中的每个token。
在每个时间步,RNN接收当前token的向量和上一个时间步的隐藏状态(即隐藏层的输出),计算并生成新的隐藏状态,并将其传递到下一时间步。
其中隐藏层的计算公式为 ℎ𝑡=𝑡𝑎𝑛ℎ(𝑥𝑡𝑊𝑥+ℎ𝑡―1𝑊ℎ+𝑏)
torch.nn.RNN(input_size,hidden_size,num_layers=1,nonlinearity="tanh",bias=True,batch_first=False,dropout=0.0,bidirectional=False,device=None,dtype=None,)| 参数名 | 类型 | 说明 |
|---|---|---|
| input_size | int | 每个时间步输入特征的维度(词向量维度) |
| hidden_size | int | 隐藏状态的维度 |
| num_layers | int | RNN层数,默认为1 |
| nonlinearity | str | 激活函数,‘tanh’(默认)或’relu’ |
| bias | bool | 是否使用偏置项,默认True |
| batch_first | bool | 输入张量是否是(batch, seq, feature),默认False表示 (seq, batch, feature) |
| dropout | float | 除最后一层外,其余层之间的dropout概率 |
| bidirectional | bool | 是否为双向RNN,默认False |
| device | torch.device or str | 模块的初始化设备,如’cuda’, ‘cpu’ |
| dtype | torch.dtype | 模块初始化时的默认数据类型,如torch.float32 |
rnn=torch.nn.RNN()output,h_n=rnn(input,h_0)| input | 输入序列,形状为(seq_len, batch_size, input_size),如batch_first=True,则为(batch_size, seq_len, input_size) |
|---|---|
| h_0 | 可 选 , 初 始 隐 藏 状 态 , 形 状 为(num_layers × num_directions, batch_size, hidden_size) |
| output | RNN层的输出,包含最后一层每个时间步的隐藏状态,形状为(seq_len, batch_size, num_directions × hidden_size ),如果batch_first=True,则为 (batch_size, seq_len, num_directions × hidden_size ) |
| h_n | 最后一个时间步的隐藏状态,包含每一层的每个方向,形状为(num_layers × num_directions, batch_size, hidden_size) |
文本分类、序列标注、文本生成、信息抽取、文本转换
英文分词有哪些分词粒度?词级分词、字符级分词、子词分词
双向RNN的意义是什么?多层RNN的意义是什么?使每个时间步都可以获取上下文的信息
每层提取不同的语义,例如底层提取局部信息(词组,短语),高层提取更抽象的语义信息(句子含义)