词向量与分布式语义
文档概述
本文档系统阐述词向量的理论基础、实现原理及认知科学联系。重点介绍Word2Vec、GloVe、FastText等经典模型,以及ELMo、BERT等上下文词向量技术,并探讨Embedding空间的几何性质及其认知意义。
关键词速览
| 术语 | 英文 | 核心定义 |
|---|---|---|
| 分布式假说 | Distributional Hypothesis | 词语由其上下文定义 |
| 词向量 | Word Vector/Embedding | 词语的稠密向量表示 |
| Word2Vec | Word2Vec | 经典的词嵌入训练模型 |
| GloVe | Global Vectors | 全局共现统计词嵌入 |
| FastText | FastText | 子词嵌入模型 |
| 上下文词向量 | Contextualized Embedding | 随上下文变化的词表示 |
| ELMo | Embeddings from Language Models | 双向LSTM词向量 |
| BERT | Bidirectional Encoder Representations | Transformer编码器 |
| 语义空间 | Semantic Space | 词向量张成的空间 |
| 认知科学 | Cognitive Science | 研究人类认知的学科 |
一、分布式假说(Distributional Hypothesis)
1.1 理论起源与核心思想
分布式假说是现代计算语言学和词向量研究的理论基石,由英国语言学家John Rupert Firth于1957年首次系统性地提出。Firth的经典论述至今仍是NLP领域最重要的指导思想之一:
“You shall know a word by the company it keeps” (观其伴,知其义)
这一假说的核心洞见在于:语义相似的词语倾向于出现在相似的上下文中。因此,我们可以通过分析一个词的上下文分布来推断其语义。
1.2 形式化定义
从数学角度,分布式假说可以形式化为:
其中上下文相似度可以通过以下方式度量:
这里 表示词语 的上下文向量。
1.3 上下文的定义
窗口上下文(Window-based) 最常用的上下文定义是基于词语周围的窗口:
原始句子: "The quick brown fox jumps over the lazy dog"
窗口大小=2时的上下文:
- "quick" 的上下文: [The, brown, fox]
- "fox" 的上下文: [quick, brown, jumps, over]
更广义的上下文定义
| 上下文类型 | 定义 | 应用场景 |
|---|---|---|
| 词汇窗口 | 固定窗口内的词 | 句法/语义分析 |
| 文档级 | 同一文档中的词 | 主题建模 |
| 依赖结构 | 依存语法关系中的词 | 句法语义 |
| 语义框架 | 同一框架中的词 | 框架语义学 |
二、经典词向量模型
2.1 Word2Vec系列模型
Word2Vec由Tomas Mikolov等人于2013年提出,是词向量研究的里程碑式工作。该模型通过浅层神经网络学习词的高维稠密表示。
2.1.1 Skip-gram模型
Skip-gram模型的核心思想是:用中心词预测上下文词。
模型架构
输入层: 中心词 one-hot 向量 [V × 1]
↓ W [V × d]
隐藏层: 词嵌入 [d × 1]
↓ W' [d × V]
输出层: Softmax → 上下文词概率分布 [V × 1]
目标函数
给定训练语料中的词序列 ,Skip-gram的目标是最大化:
其中 是上下文窗口大小,条件概率定义为:
这里 是输入词嵌入, 是输出词嵌入。
高效训练技术:负采样(Negative Sampling)
由于完整softmax需要遍历整个词表,计算代价极高。负采样通过二分类近似解决这个问题:
其中 是sigmoid函数, 是负样本数量, 是负采样分布。
2.1.2 CBOW模型
CBOW(Continuous Bag-of-Words)与Skip-gram互补,用上下文预测中心词:
class CBOW(nn.Module):
def __init__(self, vocab_size, embedding_dim):
super().__init__()
self.embeddings = nn.Embedding(vocab_size, embedding_dim)
self.linear = nn.Linear(embedding_dim, vocab_size)
def forward(self, context_words):
# context_words: [batch_size, window_size * 2]
# 形状: [batch_size, 2c]
# 获取上下文词的嵌入并求平均
embedded = self.embeddings(context_words) # [batch, 2c, embed_dim]
averaged = torch.mean(embedded, dim=1) # [batch, embed_dim]
# 预测中心词
output = self.linear(averaged) # [batch, vocab_size]
return output2.1.3 Skip-gram完整实现
import torch
import torch.nn as nn
import torch.optim as optim
from collections import Counter
import numpy as np
class SkipGramModel(nn.Module):
"""
Skip-gram词向量模型
核心思想:用中心词预测上下文词
训练目标:最大化真实上下文词的概率,最小化负采样词的概率
"""
def __init__(self, vocab_size, embedding_dim):
super().__init__()
self.vocab_size = vocab_size
self.embedding_dim = embedding_dim
# 词嵌入层
self.target_embeddings = nn.Embedding(vocab_size, embedding_dim)
self.context_embeddings = nn.Embedding(vocab_size, embedding_dim)
# 初始化
nn.init.uniform_(self.target_embeddings.weight, -0.5/embedding_dim, 0.5/embedding_dim)
nn.init.zeros_(self.context_embeddings.weight)
def forward(self, target, context, negative):
"""
Args:
target: 中心词ID [batch_size]
context: 上下文词ID [batch_size]
negative: 负采样词ID [batch_size, num_negative]
Returns:
正样本损失 + 负样本损失
"""
# 正样本得分
target_emb = self.target_embeddings(target) # [batch, dim]
context_emb = self.context_embeddings(context) # [batch, dim]
pos_score = torch.sum(target_emb * context_emb, dim=1) # [batch]
pos_loss = torch.nn.functional.binary_cross_entropy_with_logits(
pos_score, torch.ones_like(pos_score)
)
# 负样本损失
neg_emb = self.context_embeddings(negative) # [batch, k, dim]
neg_score = torch.bmm(neg_emb, target_emb.unsqueeze(2)).squeeze() # [batch, k]
neg_loss = torch.nn.functional.binary_cross_entropy_with_logits(
neg_score, torch.zeros_like(neg_score)
)
return pos_loss + neg_loss
def train_word2vec(corpus, embedding_dim=100, window_size=5,
min_count=5, negative_samples=5, epochs=5):
"""
Word2Vec训练流程
"""
# 1. 构建词表
word_counts = Counter(corpus)
vocab = [word for word, count in word_counts.items() if count >= min_count]
word_to_idx = {word: idx for idx, word in enumerate(vocab)}
idx_to_word = {idx: word for word, idx in word_to_idx.items()}
# 2. 生成训练样本
def generate_training_data(corpus, word_to_idx, window_size):
pairs = []
for i, word in enumerate(corpus):
if word not in word_to_idx:
continue
center_idx = word_to_idx[word]
# 窗口内上下文
start = max(0, i - window_size)
end = min(len(corpus), i + window_size + 1)
for j in range(start, end):
if i != j and corpus[j] in word_to_idx:
pairs.append((center_idx, word_to_idx[corpus[j]]))
return pairs
# 3. 训练模型
model = SkipGramModel(len(vocab), embedding_dim)
optimizer = optim.Adam(model.parameters(), lr=0.01)
training_pairs = generate_training_data(corpus, word_to_idx, window_size)
for epoch in range(epochs):
total_loss = 0
for target, context in training_pairs:
# 负采样
neg_samples = np.random.choice(
len(vocab), size=negative_samples, replace=False
)
target_t = torch.tensor([target])
context_t = torch.tensor([context])
neg_t = torch.tensor(neg_samples)
optimizer.zero_grad()
loss = model(target_t, context_t, neg_t)
loss.backward()
optimizer.step()
total_loss += loss.item()
print(f"Epoch {epoch+1}, Loss: {total_loss/len(training_pairs):.4f}")
return model, word_to_idx2.2 GloVe模型
GloVe(Global Vectors)由Pennington等人于2014年提出,融合了全局矩阵分解和局部上下文窗口两种方法的优点。
2.2.1 核心思想
GloVe基于全局词共现矩阵进行训练,其损失函数设计结合了:
- 全局统计信息:利用词共现矩阵 ,其中 表示词 在词 的上下文中出现的次数
- 局部上下文:保持Skip-gram的窗口概念
2.2.2 损失函数
其中权重函数 用于处理稀有和常见词:
通常取 ,。
2.2.3 GloVe与Word2Vec的对比
| 特性 | Word2Vec | GloVe |
|---|---|---|
| 训练目标 | 预测概率(条件) | 重构共现概率 |
| 语料利用 | 局部上下文 | 全局共现矩阵 |
| 训练速度 | 快(在线) | 慢(需要矩阵分解) |
| 语义任务表现 | 相似词效果好 | 类比推理更优 |
2.3 FastText模型
FastText由Mikolov等人于2016年提出,核心创新是引入子词(subword)信息。
2.3.1 子词嵌入原理
FastText将每个词表示为其字符n-gram的集合:
词 "where" 的n-gram表示 (n=3):
- <wh, whe, her, ere, re>
- 特殊边界符号: <where>
词表大小 = 所有字符n-gram的集合
词嵌入计算
2.3.2 FastText的优势
- 处理未登录词(OOV):可以通过组合子词表示未知词
- 处理形态丰富语言:如德语、土耳其语等
- 捕捉词缀信息:自动学习词根、词缀的语义关联
class FastTextModel(nn.Module):
"""
FastText模型 - 使用子词嵌入
"""
def __init__(self, vocab_size, embedding_dim, ngram_min=3, ngram_max=6):
super().__init__()
self.ngram_min = ngram_min
self.ngram_max = ngram_max
# 子词嵌入
self.subword_embeddings = nn.Embedding(vocab_size, embedding_dim)
# 词级别嵌入(用于完整词)
self.word_embeddings = nn.Embedding(vocab_size, embedding_dim)
def forward(self, word_ids, subword_ids):
"""
Args:
word_ids: 完整词ID [batch_size]
subword_ids: 子词ID列表 [batch_size, num_subwords]
"""
# 完整词嵌入
word_emb = self.word_embeddings(word_ids) # [batch, dim]
# 子词嵌入平均
subword_emb = self.subword_embeddings(subword_ids) # [batch, num_sub, dim]
subword_avg = torch.mean(subword_emb, dim=1) # [batch, dim]
# 组合
combined = (word_emb + subword_avg) / 2
return combined三、上下文词向量(Contextualized Embeddings)
3.1 传统词向量的局限性
传统词向量(如Word2Vec、GloVe)的主要问题是词义消歧能力不足:
传统词向量的问题示例:
"bank" 只有一个向量表示,无法区分:
- "bank account" (银行账户)
- "river bank" (河岸)
3.2 ELMo:双向LSTM词向量
ELMo(Embeddings from Language Models)由Peters等人于2018年提出,首次实现了上下文相关的词表示。
3.2.1 架构设计
输入: The mouse ate the cheese
↓
字符卷积层 + Highway网络
↓
前向LSTM: [The] → [mouse] → [ate] → [the] → [cheese]
后向LSTM: [cheese] ← [the] ← [ate] ← [mouse] ← [The]
↓
双向LSTM各层输出
↓
加权组合(学习得到)→ 最终表示
3.2.2 预训练目标
ELMo通过预测下一个词来预训练:
3.2.3 上下文表示的获取
对于每个词 ,其ELMo表示为:
其中 是可学习的层权重, 是任务特定的缩放因子。
3.3 BERT:Transformer编码器
BERT(Bidirectional Encoder Representations from Transformers)由Devlin等人于2018年提出,是NLP领域的里程碑式模型。
3.3.1 核心创新
- 双向Transformer编码器:同时利用左右上下文
- 掩码语言模型(MLM):随机mask输入词进行预测
- 下一句预测(NSP):学习句子间关系
3.3.2 BERT架构
class BERTModel(nn.Module):
"""
BERT模型核心结构
关键特性:
1. Transformer编码器(双向注意力)
2. 子词tokenization(WordPiece)
3. 位置嵌入(可学习)
4. 层归一化 + 残差连接
"""
def __init__(self, config):
super().__init__()
self.config = config
# 嵌入层
self.embeddings = nn.ModuleDict({
'token': nn.Embedding(config.vocab_size, config.hidden_size),
'position': nn.Embedding(config.max_position_embeddings, config.hidden_size),
'segment': nn.Embedding(config.type_vocab_size, config.hidden_size)
})
self.embed_layer_norm = nn.LayerNorm(config.hidden_size)
# Transformer编码器层
self.encoder_layers = nn.ModuleList([
TransformerEncoderLayer(config) for _ in range(config.num_hidden_layers)
])
# 输出层
self.pooler = nn.Linear(config.hidden_size, config.hidden_size)
self.pooler_activation = nn.Tanh()
def forward(self, input_ids, attention_mask=None, token_type_ids=None):
# 1. 嵌入
seq_len = input_ids.size(1)
position_ids = torch.arange(seq_len, device=input_ids.device)
position_ids = position_ids.unsqueeze(0).expand_as(input_ids)
token_emb = self.embeddings.token(input_ids)
position_emb = self.embeddings.position(position_ids)
segment_emb = self.embeddings.segment(token_type_ids or torch.zeros_like(input_ids))
embeddings = token_emb + position_emb + segment_emb
embeddings = self.embed_layer_norm(embeddings)
# 2. Transformer编码
hidden_states = embeddings
for layer in self.encoder_layers:
hidden_states = layer(hidden_states, attention_mask)
# 3. 池化
pooled = self.pooler(hidden_states[:, 0]) # [CLS] token
pooled = self.pooler_activation(pooled)
return {
'last_hidden_state': hidden_states,
'pooled_output': pooled
}
class TransformerEncoderLayer(nn.Module):
"""Transformer编码器层"""
def __init__(self, config):
super().__init__()
self.attention = nn.MultiheadAttention(
config.hidden_size, config.num_attention_heads,
dropout=config.attention_dropout
)
self.attention_norm = nn.LayerNorm(config.hidden_size)
self.ffn = nn.Sequential(
nn.Linear(config.hidden_size, config.intermediate_size),
nn.GELU(),
nn.Linear(config.intermediate_size, config.hidden_size),
nn.Dropout(config.hidden_dropout)
)
self.ffn_norm = nn.LayerNorm(config.hidden_size)
def forward(self, x, attention_mask):
# 自注意力 + 残差
attn_out, _ = self.attention(x, x, x, key_padding_mask=attention_mask)
x = self.attention_norm(x + attn_out)
# 前馈网络 + 残差
ffn_out = self.ffn(x)
x = self.ffn_norm(x + ffn_out)
return x3.3.3 BERT的预训练任务
掩码语言模型(MLM)
随机选择15%的token进行mask:
- 80%替换为[MASK]
- 10%替换为随机词
- 10%保持不变
def mask_tokens(inputs, tokenizer, mlm_probability=0.15):
"""
BERT式掩码处理
"""
labels = inputs.clone()
# 特殊token不mask
probability_matrix = torch.full(labels.shape, mlm_probability)
special_tokens_mask = torch.tensor(
[tokenizer.get_special_tokens_mask(val) for val in labels.tolist()]
)
probability_matrix.masked_fill_(special_tokens_mask.bool(), value=0.0)
# 随机mask
masked_indices = torch.bernoulli(probability_matrix).bool()
labels[~masked_indices] = -100 # 不计算损失的标记
# 实际替换操作(80/10/10策略)
indices_replaced = torch.bernoulli(torch.full(labels.shape, 0.8)).bool() & masked_indices
inputs[indices_replaced] = tokenizer.mask_token_id
# 随机替换
indices_random = torch.bernoulli(torch.full(labels.shape, 0.5)).bool() & masked_indices & ~indices_replaced
random_words = torch.randint(len(tokenizer), labels.shape, dtype=torch.long)
inputs[indices_random] = random_words[indices_random]
return inputs, labels下一句预测(NSP)
def create_nsp_data(sentences, tokenizer, seq_length):
"""
创建NSP训练数据
"""
for i in range(len(sentences) - 1):
# 正样本:连续句子对
tokens_a = tokenizer.encode(sentences[i])
tokens_b = tokenizer.encode(sentences[i + 1])
is_next = 1
# 负样本:随机句子对
if random.random() < 0.5:
tokens_b = tokenizer.encode(random.choice(sentences))
is_next = 0
# 截断并组合
...四、Embedding空间的几何性质
4.1 语义空间的数学结构
词向量空间具有丰富的几何结构,这些结构编码了语言学规律。
4.1.1 线性关系
词向量空间中存在系统性的线性关系:
Mikolov等人发现这种关系广泛存在:
- 城市-国家关系:Paris - France + Italy ≈ Rome
- 动词时态关系:walk - walked + think ≈ thought
- 复数关系:apple - apples + car ≈ cars
这种线性可加性的数学解释
词的语义可以分解为多个语义特征的线性组合:
其中 表示语义特征向量, 是权重。
4.1.2 语义距离与相似度
词向量空间中的距离度量:
| 度量方法 | 公式 | 适用场景 |
|---|---|---|
| 余弦相似度 | 方向相似性 | |
| 欧氏距离 | 绝对距离 | |
| 曼哈顿距离 | 稀疏向量 | |
| 内积 | 非归一化相似度 |
def compute_similarity(vecs1, vecs2, method='cosine'):
"""
词向量相似度计算
"""
if method == 'cosine':
# 余弦相似度
norm1 = vecs1 / np.linalg.norm(vecs1, axis=1, keepdims=True)
norm2 = vecs2 / np.linalg.norm(vecs2, axis=1, keepdims=True)
return np.dot(norm1, norm2.T)
elif method == 'euclidean':
# 欧氏距离(转相似度)
distances = np.linalg.norm(vecs1[:, np.newaxis] - vecs2[np.newaxis, :], axis=2)
return 1 / (1 + distances)4.2 语义类别的空间分布
4.2.1 聚类结构
词向量空间中的语义类别呈现聚类分布:
Embedding空间示意图(2D降维可视化)
[水果类]
🍎 🍊 🍋
[动物类]
🐕 🐈 🐇 🐁
[颜色类]
🔴 🔵 🟢 🟡
[数字类] [动作类]
1 2 3 4 5 跑 跳 飞 游
4.2.2 类别边界的模糊性
语义类别之间的边界往往是模糊的,这反映了语义原型理论:
# 使用GMM建模语义类别的概率分布
from sklearn.mixture import GaussianMixture
def model_semantic_categories(word_embeddings, category_labels, n_components=3):
"""
使用高斯混合模型建模语义类别
假设每个语义类别不是严格的聚类,
而是服从高斯分布的概率分布
"""
categories = set(category_labels)
category_models = {}
for cat in categories:
mask = np.array(category_labels) == cat
cat_embeddings = word_embeddings[mask]
# 每个类别用多个高斯建模(捕捉子类变体)
gmm = GaussianMixture(n_components=min(n_components, len(cat_embeddings)))
gmm.fit(cat_embeddings)
category_models[cat] = gmm
return category_models4.3 语义空间的异常现象
4.3.1 性别偏差
词向量中系统性存在的性别偏见:
职业词的性别向量投影:
男性方向
↑
医生 ──────┼────── 护士
│
工程师 ──────┼────── 保育员
│
女性方向
偏见校正方法
def debias_embeddings(embeddings, definitional_pairs, equalize_pairs):
"""
Hard Debias算法
步骤:
1. 计算性别方向向量
2. 对中性词去偏
3. 均衡化性别词
"""
# 1. 计算性别方向
gender_direction = compute_gender_direction(embeddings, definitional_pairs)
# 2. 中性词去偏
for word in neutral_words:
v = embeddings[word]
v_bias = (v @ gender_direction) * gender_direction
embeddings[word] = v - v_bias
# 3. 均衡化性别对
for (word1, word2) in equalize_pairs:
v1, v2 = embeddings[word1], embeddings[word2]
v_mean = (v1 + v2) / 2
v1_new = v_mean + (v1 - v_mean).dot(gender_direction) * gender_direction
v2_new = v_mean - (v1 - v_mean).dot(gender_direction) * gender_direction
embeddings[word1] = v1_new
embeddings[word2] = v2_new
def compute_gender_direction(embeddings, definitional_pairs):
"""
从定义性词对计算性别方向向量
"""
directions = []
for word1, word2 in definitional_pairs:
if word1 in embeddings and word2 in embeddings:
directions.append(embeddings[word1] - embeddings[word2])
return np.mean(directions, axis=0)五、与认知科学的联系
5.1 分布式表征与人类语义记忆
词向量的分布式表征假说与认知科学中的分布式记忆理论高度一致。
5.1.1 特征理论 vs. 分布式表征
经典特征理论
- 词义由一组二元或数值特征定义
- 特征如:[+ANIMATE, +HUMAN, +MALE]等
- 问题:无法解释语义模糊性和语境依赖
分布式表征理论
- 词义由整个向量空间的模式定义
- 每个维度可能对应多个相关特征的加权组合
- 更好地解释语义泛化和原型效应
5.1.2 语义网络的神经基础
人类语义记忆的神经表征
前颞叶
┌──────────┐
│ 语义 │
│ 知识 │
└──────────┘
梭状回 角回
↓ ↓
┌──────┴────────────┴──────┐
│ 分布式语义表征 │
│ (词向量空间类比) │
└─────────────────────────┘
研究表明,语义知识在前颞叶(ATL)区域以分布式方式存储,这与词向量的分布式表征相符。
5.2 语义启动效应
语义启动效应(Semantic Priming)现象与词向量的语义相似度计算密切相关:
实验范式
- 启动词:“医生”
- 目标词:“医院” vs “面包”
- 结果:识别”医院”更快
向量空间解释
def simulate_priming(prime_embedding, target_embedding, distractor_embedding):
"""
模拟语义启动效应
假设:语义相关词对的处理更快
因为它们在语义空间中距离更近
"""
prime_target_distance = cosine_distance(prime_embedding, target_embedding)
prime_distractor_distance = cosine_distance(prime_embedding, distractor_embedding)
# 相关词对距离更近 → 处理更快
return prime_target_distance < prime_distractor_distance5.3 原型效应与最佳示例
人类在分类时表现出原型效应(Prototype Effect):某些成员比其他人更能代表类别。
词向量空间中也存在类似现象:
def compute_prototypicality(word_embeddings, category_members):
"""
计算词的原型性
原型词 = 距离类别中心最近的词
"""
category_center = np.mean(word_embeddings[category_members], axis=0)
distances = [cosine_distance(w, category_center) for w in word_embeddings[category_members]]
prototypicality = 1 / (1 + np.array(distances))
return dict(zip(category_members, prototypicality))
# 示例:水果类的原型性
# 原型词可能是"苹果"或"橙子"(更典型)
# 而非常见水果如"牛油果"原型性较低5.4 概念组合与语义合成
人类能够灵活组合概念生成新意义。词向量的组合性研究探索这一能力:
简单组合(向量加法)
属性组合(向量乘法/ Hadamard积)
乘法操作可以更好地捕捉属性修饰关系。
复杂组合(神经网络组合器)
class NeuralComposition(nn.Module):
"""
神经网络语义组合器
比简单线性组合更能处理复杂语义组合
"""
def __init__(self, embed_dim, hidden_dim):
super().__init__()
self.f = nn.Sequential(
nn.Linear(embed_dim * 2, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, embed_dim)
)
def forward(self, head, modifier):
"""
组合两个词的语义表示
Args:
head: 被修饰词 [batch, embed_dim]
modifier: 修饰词 [batch, embed_dim]
"""
combined = torch.cat([head, modifier], dim=-1)
result = self.f(combined)
return result六、实践应用与工具
6.1 主流词向量工具
| 工具 | 语言 | 特点 | 预训练模型 |
|---|---|---|---|
| gensim | Python | Word2Vec/FastText实现 | 多语言 |
| spaCy | Python | 集成词向量 | en_core_web_md |
| TensorFlow Hub | 多语言 | Universal Sentence Encoder | 17种语言 |
| HuggingFace | Python | BERT系列模型 | 100+模型 |
| fastText | C++/Python | 快速子词嵌入 | 157种语言 |
6.2 词向量可视化
# 使用t-SNE/UMAP可视化词向量
from sklearn.manifold import TSNE
import plotly.express as px
def visualize_embeddings(word_embeddings, words, labels=None):
"""
词向量可视化
"""
# 降维
tsne = TSNE(n_components=2, random_state=42)
coords = tsne.fit_transform(word_embeddings)
# 绘制
df = pd.DataFrame({
'x': coords[:, 0],
'y': coords[:, 1],
'word': words,
'label': labels or ['unknown'] * len(words)
})
fig = px.scatter(df, x='x', y='y', text='word', color='label')
fig.update_traces(textposition='top center')
fig.show()参考文献与推荐阅读
- Mikolov, T., et al. (2013). Distributed representations of words and phrases and their compositionality. NeurIPS.
- Pennington, J., Socher, R., & Manning, C. D. (2014). GloVe: Global vectors for word representation. EMNLP.
- Bojanowski, P., et al. (2017). Enriching word vectors with subword information. TACL, 5, 135-146.
- Peters, M. E., et al. (2018). Deep contextualized word representations. NAACL-HLT.
- Devlin, J., et al. (2019). BERT: Pre-training of deep bidirectional transformers for language understanding. NAACL-HLT.
- Rogers, A., et al. (2020). A primer in BERTology: What we know about how BERT works. TACL, 8, 842-866.
关联文档