统计语言模型:把语言(词的序列)看做一个随机事件,并赋予相应的概率来描述其属于某种语言集合的可能性。
1.自编码(Auto Encoding,AE)
自编码语言模型:使用自编码神经网络进行训练的模型,即该模型的任务是使输出的句子尽量靠近输入的句子。
在BERT模型中,自编码语言模型的用法是:在输入句子随机找一个或几个子词,用掩码标识将该子词替换掉,再将句子输入模型,让模型输出原始输入句子。除BERT外,训练词向量的Word2Vec模型也属于自编码语言模型。
优点:能够很好地编码上下文语义信息(考虑句子的双向信息)。
缺点:在BERT模型的自编码神经网络中,使用带有[MASK]标识的数据进行预训练,在预训练完成之后,还要使用不带[MASK]标识的数据进行微调。这会导致预训练数据与微调阶段数据不一致的问题。这种问题又叫“BERT的独立性假设”,即如果被[MASK]替换的子词只与句子中的上下文语义相关,与其他被[MASK]替换的子词语义无关,则BERT模型的预训练方式是合理的。但实际上,被[MASK]替换的子词之间也会有语义相关。很显然BERT模型的预训练方式没有学习到被[MASK]替换的子词间的语义关系,这会导致模型在微调阶段无法表现出太好的效果。此外,对于生成式问题,自编码模型表现不好。
2.自回归(Auto Regressive,AR)
自回归语言模型:依据前/后出现的子词来预测当前时刻的子词,代表有ELMo模型、GPT模型等。另外,带有RNN特性的一系列模型都可以被归类为自回归语言模型。
优点:善于输出完整的句子或文章,天然适合生成式任务的处理。
缺点:只能利用单向语义,不能同时利用上下文信息。
3.Word2Vec
将单词映射/嵌入(Embedding)到一个新的空间,形成词向量,以此来表示词的语义信息,在这个新的空间中,语义相同的单词距离很近。
一篇文章有3000个单词,就会有3000个1x3000的one-hot向量,每个one-hot向量表示一个单词。我们需要将其降维到300,就将隐藏层的神经元个数设定为300个,最后在链接3000个output,代表全文3000个单词,通过softmax输出该输入的单词是这3000个单词每一个的概率值,加总为1。通过输入和输出向量间的误差值来优化网络参数。经过不断的优化,损失值最小化后,输入层和隐藏层之间3000x300的权重矩阵,对应输入层中3000单词的向量,每个单词被表示为一个1x300的向量。
3.1 CBOW(Continous Bags Of Words,CBOW)
CBOW根据某个词前面的n个词、或者前后各n个连续的词,来计算某个词出现的概率,即给定上下文,来预测input word。相比Skip-Gram,CBOW更快一些。
举例:“小明”,“喜欢”,“吃”,“草莓”。
小明:[1,0,0,0]
喜欢:[0,1,0,0]
吃:[0,0,1,0]
草莓:[0,0,0,1]
预测“吃”,则input为[1,1,0,1],上下文的加总。
3.2 Skip-Gram
以某个词为中心,分别计算该中心词前后可能出现其他词的各个概率,即给定input word来预测上下文。
举例:“小明”,“喜欢”,“吃”,“草莓”。
小明:[1,0,0,0]
喜欢:[0,1,0,0]
吃:[0,0,1,0]
草莓:[0,0,0,1]
input为[0,0,1,0],输出为:[1,0,0,0],[0,1,0,0],[0,0,0,1]
学习简单实现:(代码出处在注释中)
# -*- coding: utf-8 -*-
# @Time : 2022/1/2 14:31
# @Author : hp
'''
代码出处:https://wmathor.com/index.php/archives/1443/
https://github.com/graykode/nlp-tutorial
'''
import torch
import numpy as np
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt
import torch.utils.data as Data
dtype = torch.FloatTensor
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
sentences = ["jack like dog", "jack like cat", &