一、相似度计算:从基础到进阶
相似度计算是NLP任务的核心基础,广泛应用于文本匹配、信息检索、推荐系统等场景。其核心目标是通过量化文本间的语义关联程度,为后续任务提供决策依据。
1.1 传统相似度方法
-
词重叠相似度:基于词袋模型(Bag-of-Words)的Jaccard系数和余弦相似度,通过统计词共现频率衡量相似性。例如,计算两句话的词集合交集与并集的比例:
def jaccard_similarity(text1, text2):set1 = set(text1.split())set2 = set(text2.split())intersection = len(set1 & set2)union = len(set1 | set2)return intersection / union if union > 0 else 0
局限性:无法捕捉语义顺序和上下文关联,例如“苹果公司”与“公司苹果”会被误判为完全相似。
-
TF-IDF加权余弦相似度:通过词频-逆文档频率(TF-IDF)加权,降低高频无意义词(如“的”“是”)的权重。实现时需构建语料库的IDF字典:
from sklearn.feature_extraction.text import TfidfVectorizercorpus = ["文本1内容", "文本2内容"]vectorizer = TfidfVectorizer()tfidf_matrix = vectorizer.fit_transform(corpus)similarity = (tfidf_matrix[0] * tfidf_matrix[1].T).toarray()[0][0]
适用场景:短文本匹配、文档去重,但对长文本的语义理解能力有限。
1.2 深度语义相似度(DSSM)
基于深度学习的DSSM模型通过多层神经网络将文本映射到低维语义空间,直接计算向量间的余弦相似度。其典型结构包括:
- 输入层:将文本转换为词向量或字符级向量。
- 隐藏层:使用全连接或卷积网络提取特征。
- 输出层:生成语义向量并计算相似度。
优势:可捕捉上下文语义,适用于长文本匹配。例如在问答系统中,通过DSSM计算问题与候选答案的相似度,筛选最优回答。
1.3 预训练模型下的相似度计算
BERT等预训练模型通过[CLS]标记的输出向量表示整句语义,结合余弦相似度或曼哈顿距离计算相似度:
from transformers import BertModel, BertTokenizerimport torchtokenizer = BertTokenizer.from_pretrained("bert-base-chinese")model = BertModel.from_pretrained("bert-base-chinese")text1 = "自然语言处理"text2 = "NLP技术"inputs1 = tokenizer(text1, return_tensors="pt", padding=True, truncation=True)inputs2 = tokenizer(text2, return_tensors="pt", padding=True, truncation=True)with torch.no_grad():outputs1 = model(**inputs1)outputs2 = model(**inputs2)cls_vector1 = outputs1.last_hidden_state[:, 0, :]cls_vector2 = outputs2.last_hidden_state[:, 0, :]similarity = torch.cosine_similarity(cls_vector1, cls_vector2, dim=1).item()
最佳实践:需结合任务微调模型,避免直接使用通用预训练参数导致语义偏差。
二、Attention机制:从基础到变体
Attention机制通过动态分配权重,使模型聚焦于关键信息,已成为NLP模型的标配组件。
2.1 基础Attention机制
-
加性Attention:通过前馈神经网络计算查询(Query)与键(Key)的相似度,再经Softmax归一化得到权重:
score(Q, K) = W^T * tanh(W_q Q + W_k K)attention_weight = Softmax(score)context_vector = attention_weight * V
适用场景:需要非线性变换捕捉复杂关系的任务,如机器翻译中的长句对齐。
-
点积Attention:直接计算Q与K的点积,再通过缩放因子(√d_k)避免梯度消失:
score(Q, K) = Q^T K / √d_kattention_weight = Softmax(score)
优势:计算效率高,适合大规模并行化,是Transformer的核心组件。
2.2 自注意力(Self-Attention)
自注意力机制中,Q、K、V均来自同一输入序列,通过捕捉序列内元素间的关系生成上下文感知的表示。例如在句子“The cat sat on the mat”中,自注意力可发现“cat”与“mat”的空间关联。
实现步骤:
- 线性变换生成Q、K、V矩阵。
- 计算缩放点积注意力。
- 多头注意力并行处理不同子空间信息。
- 拼接多头输出并通过线性层融合。
2.3 多头注意力(Multi-Head Attention)
通过将Q、K、V拆分为多个子空间(如8个头),每个头独立计算注意力后拼接,增强模型对不同位置和特征的捕捉能力。例如在文本分类中,不同头可分别关注语法结构、情感词汇等特征。
代码示例:
import torch.nn as nnclass MultiHeadAttention(nn.Module):def __init__(self, embed_dim, num_heads):super().__init__()self.embed_dim = embed_dimself.num_heads = num_headsself.head_dim = embed_dim // num_headsself.q_linear = nn.Linear(embed_dim, embed_dim)self.k_linear = nn.Linear(embed_dim, embed_dim)self.v_linear = nn.Linear(embed_dim, embed_dim)self.out_linear = nn.Linear(embed_dim, embed_dim)def forward(self, query, key, value):batch_size = query.size(0)# 线性变换Q = self.q_linear(query).view(batch_size, -1, self.num_heads, self.head_dim).transpose(1, 2)K = self.k_linear(key).view(batch_size, -1, self.num_heads, self.head_dim).transpose(1, 2)V = self.v_linear(value).view(batch_size, -1, self.num_heads, self.head_dim).transpose(1, 2)# 缩放点积注意力scores = torch.matmul(Q, K.transpose(-2, -1)) / torch.sqrt(torch.tensor(self.head_dim, dtype=torch.float32))attention = torch.softmax(scores, dim=-1)out = torch.matmul(attention, V)# 拼接多头输出out = out.transpose(1, 2).contiguous().view(batch_size, -1, self.embed_dim)return self.out_linear(out)
2.4 层级注意力(Hierarchical Attention)
针对长文档或层次化结构(如段落-句子-词),层级注意力通过两阶段注意力机制分别捕捉局部和全局信息。例如在文档分类中,先对句子内词分配权重,再对文档内句子分配权重。
架构设计:
- 词级注意力:对句子内词向量加权求和,生成句子表示。
- 句子级注意力:对文档内句子表示加权求和,生成文档表示。
三、性能优化与最佳实践
-
相似度计算的效率优化:
- 使用近似最近邻(ANN)库(如Faiss)加速大规模文本检索。
- 对长文本采用分段计算或关键句抽取,减少计算量。
-
Attention机制的稀疏化:
- 局部注意力:限制注意力范围(如仅关注前后k个词),降低计算复杂度。
- 块状注意力:将序列划分为块,仅计算块内或块间注意力。
-
多模态注意力融合:
- 在图文匹配任务中,设计跨模态注意力机制,使图像区域与文本词动态交互。例如,通过共注意力(Co-Attention)同时更新图像和文本的表示。
-
可解释性增强:
- 可视化注意力权重图,分析模型对关键信息的聚焦程度。例如在医疗文本分类中,验证模型是否关注到疾病名称等核心词汇。
四、总结与展望
相似度计算与Attention机制是NLP模型理解语义和捕捉关键信息的核心工具。从传统的词重叠方法到深度语义匹配,从基础Attention到多头、层级变体,技术的演进不断推动着任务精度的提升。未来,随着模型规模的扩大和多模态数据的融合,如何设计更高效、可解释的注意力机制将成为研究重点。开发者可结合具体场景,灵活选择或组合上述方法,构建高性能的NLP系统。