深度学习模型: BERT(Bidirectional Encoder Representations from Transformers)详解

server/2024/12/2 14:45:10/

一、引言

自然语言处理(NLP)领域在过去几十年取得了显著的进展。从早期基于规则的方法到统计机器学习方法,再到如今基于深度学习的模型,NLP 不断向着更高的准确性和效率迈进。BERT 的出现为 NLP 带来了新的突破,它能够有效地对自然语言进行编码,从而在多个 NLP 任务中取得优异的表现。

二、BERT 的架构

(一)Transformer 基础

Transformer 架构由 Vaswani 等人提出,它摒弃了传统的循环神经网络(RNN)结构,采用了自注意力机制(Self - Attention Mechanism)。

自注意力机制

自注意力机制的核心公式如下:

import numpy as np
def scaled_dot_product_attention(Q, K, V, mask=None):d_k = Q.shape[-1]scores = np.matmul(Q, K.transpose(-2, -1)) / np.sqrt(d_k)if mask is not None:scores += (mask * -1e9)attention_weights = np.exp(scores) / np.sum(np.exp(scores), axis = -1, keepdims=True)return np.matmul(attention_weights, V)

这里,Q(Query)、K(Key)和V(Value)是输入的向量表示。该机制通过计算QK的点积并进行缩放来得到注意力权重,然后用这些权重对V进行加权求和,得到输出。

多头注意力

  • 多头注意力是对自注意力机制的扩展:
    def multi_head_attention(Q, K, V, num_heads):d_model = Q.shape[-1]d_k = d_model // num_headsQ_heads = np.array([Q[:, :, i * d_k:(i + 1) * d_k] for i in range(num_heads)])K_heads = np.array([K[:, :, i * d_k:(i + 1) * d_k] for i in range(num_heads)])V_heads = np.array([V[:, :, i * d_k:(i + 1) * d_k] for i in range(num_heads)])attention_heads = [scaled_dot_product_attention(Qh, Kh, Vh) for Qh, Kh, Vh in zip(Q_heads, K_heads, V_heads)]concat_attention = np.concatenate(attention_heads, axis=-1)return concat_attention

它将输入分成多个头(heads),每个头独立进行自注意力计算,然后将结果拼接起来。

输入表示

BERT 的输入由三部分组成:词嵌入(Token Embeddings)、段嵌入(Segment Embeddings)和位置嵌入(Position Embeddings)。

(二)BERT 的具体架构

BERT 的架构基于 Transformer 的编码器部分。

import torch
class BERTInputEmbedding(torch.nn.Module):def __init__(self, vocab_size, hidden_size, max_position_embeddings, type_vocab_size):super(BERTInputEmbedding, self).__init__()self.token_embeddings = torch.nn.Embedding(vocab_size, hidden_size)self.segment_embeddings = torch.nn.Embedding(type_vocab_size, hidden_size)self.position_embeddings = torch.nn.Embedding(max_position_embeddings, hidden_size)def forward(self, input_ids, token_type_ids):seq_length = input_ids.size(1)position_ids = torch.arange(seq_length, dtype = torch.long, device = input_ids.device)position_ids = position_ids.unsqueeze(0).expand_as(input_ids)token_embeds = self.token_embeddings(input_ids)segment_embeds = self.segment_embeddings(token_type_ids)position_embeds = self.position_embeddings(position_ids)return token_embeds + segment_embeds + position_embeds

 

词嵌入将输入的单词转换为向量表示,段嵌入用于区分不同的句子(例如在句子对任务中),位置嵌入则对单词的位置进行编码。

多层 Transformer 编码器

BERT 由多层 Transformer 编码器堆叠而成。

class BERTEncoder(torch.nn.Module):def __init__(self, num_layers, hidden_size, num_heads, intermediate_size, dropout):super(BERTEncoder, self).__init__()self.layers = torch.nn.ModuleList([BERTLayer(hidden_size, num_heads, intermediate_size, dropout) for _ in range(num_layers)])def forward(self, hidden_states):for layer in self.layers:hidden_states = layer(hidden_states)return hidden_states
  • 每一层 Transformer 编码器都包括多头注意力机制和前馈神经网络,并且在每层之间有残差连接和层归一化。

三、BERT 的预训练任务

(一)掩码语言模型(Masked Language Modeling,MLM)

  1. 原理
    • 在训练过程中,随机地将输入中的一些单词替换为特殊的[MASK]标记。模型的任务是根据上下文预测被掩码的单词。
    • 例如,对于句子 “The [MASK] is red”,模型需要预测出被掩码的单词 “apple”。
  2. 代码示例
    def mask_tokens(inputs, tokenizer, mlm_probability = 0.15):labels = inputs.clone()probability_matrix = torch.full(labels.shape, mlm_probability)special_tokens_mask = [tokenizer.get_special_tokens_mask(val, already_has_special_tokens=True) for val in labels.tolist()]probability_matrix.masked_fill_(torch.tensor(special_tokens_mask, dtype = torch.bool), value = 0.0)masked_indices = torch.bernoulli(probability_matrix).bool()labels[~masked_indices] = -100indices_replaced = torch.bernoulli(torch.full(labels.shape, 0.8)).bool() & masked_indicesinputs[indices_replaced] = tokenizer.convert_tokens_to_ids(tokenizer.mask_token)return inputs, labels

    (二)下一句预测(Next Sentence Prediction,NSP)

原理

对于给定的两个句子 A 和 B,模型需要判断 B 是否是 A 的下一句。这有助于模型学习句子之间的语义关系。

代码示例

def create_next_sentence_labels(sentence_pairs):next_sentence_labels = []for (sentence_a, sentence_b) in sentence_pairs:if sentence_b is not None:next_sentence_labels.append(1)else:next_sentence_labels.append(0)return torch.tensor(next_sentence_labels, dtype = torch.long)

四、BERT 的微调

(一)文本分类任务

  1. 架构调整
    • 在文本分类任务中,通常在 BERT 的输出上添加一个分类层。
class BERTForTextClassification(torch.nn.Module):def __init__(self, bert_model, num_classes):super(BERTForTextClassification, self).__init__()self.bert = bert_modelself.dropout = torch.nn.Dropout(p = 0.1)self.classifier = torch.nn.Linear(self.bert.config.hidden_size, num_classes)def forward(self, input_ids, token_type_ids, attention_mask):outputs = self.bert(input_ids, token_type_ids, attention_mask)pooled_output = outputs[1]pooled_output = self.dropout(pooled_output)logits = self.classifier(pooled_output)return logits
  • 这里利用 BERT 的输出池化结果,经过一个线性分类器进行分类。
  1. 微调过程
    • 在微调时,使用标记好的文本分类数据集,通过反向传播算法来更新 BERT 模型和分类层的参数。
    • 例如,使用交叉熵损失函数:
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr = 2e - 5)
for epoch in range(num_epochs):for batch_input_ids, batch_token_type_ids, batch_attention_mask, batch_labels in data_loader:optimizer.zero_grad()logits = model(batch_input_ids, batch_token_type_ids, batch_attention_mask)loss = criterion(logits, batch_labels)loss.backward()optimizer.step()

(二)命名实体识别(NER)任务

  • 架构调整
    • 对于 NER 任务,通常在 BERT 的输出上添加一个 CRF(Conditional Random Field)层来进行序列标注。

CRF 层有助于考虑标签之间的依赖关系,提高命名实体识别的准确性。

微调过程

与文本分类类似,使用标记好的 NER 数据集进行微调。

训练过程中,除了更新 BERT 和分类层的参数,还会更新 CRF 层的参数。

五、BERT 的优势

(一)双向编码

  1. 与传统的单向语言模型(如 GPT)不同,BERT 采用双向编码机制。这使得模型能够同时利用上下文信息来对单词进行编码,从而更准确地理解单词的含义。
  2. 在处理诸如文本填空等任务时,双向编码能够更好地根据前后文信息来选择合适的单词。

(二)预训练的通用性

  1. BERT 的预训练任务(MLM 和 NSP)使得模型能够学习到通用的语言知识。
  2. 这种通用性使得 BERT 在微调用于不同的自然语言处理任务时,能够快速适应并取得较好的效果,无论是文本分类、问答系统还是命名实体识别等任务。

(三)性能表现

  1. 在多个自然语言处理基准测试中,BERT 都取得了领先的成绩。
  2. 例如,在 GLUE(General Language Understanding Evaluation)基准测试中,BERT 的表现远远超过了之前的模型。

六、BERT 的局限性

(一)计算资源需求大

  1. BERT 的训练和微调都需要大量的计算资源,包括 GPU 和大量的内存。
  2. 对于一些小型研究机构或企业来说,可能难以承担如此高的计算成本。

(二)长文本处理问题

  1. 虽然 BERT 在处理一般长度的文本时表现良好,但在处理非常长的文本时,由于其架构的限制,可能会出现性能下降的情况。
  2. 这是因为 Transformer 架构中的自注意力机制计算复杂度随着文本长度的增加而急剧增加。

(三)领域适应性

BERT 是在大规模通用语料上进行预训练的,在某些特定领域的自然语言处理任务中,可能需要进一步的领域适应性调整。

例如,在医学领域的文本处理中,BERT 可能需要在医学语料上进行进一步的预训练或微调才能达到较好的效果。

七、BERT 的改进和扩展

(一)RoBERTa

RoBERTa 是对 BERT 的改进,它在预训练过程中进行了一些优化。

例如,取消了下一句预测(NSP)任务,增加了预训练数据的量和多样性,并且采用了动态掩码(Dynamic Masking)的方法来进行掩码语言模型训练。

这些改进使得 RoBERTa 在一些自然语言处理任务中取得了更好的性能。

(二)ALBERT

ALBERT 在 BERT 的基础上进行了架构上的精简和优化。

它提出了跨层参数共享(Cross - Layer Parameter Sharing)的方法,减少了模型的参数数量,同时采用了句子顺序预测(Sentence Order Prediction,SOP)任务来替代 NSP 任务,进一步提高了模型的性能和训练效率。

八、结论

BERT 作为一种基于 Transformer 的预训练模型,在自然语言处理领域取得了巨大的成功。它的双向编码机制、有效的预训练任务和广泛的适用性使其成为自然语言处理研究和应用中的重要工具。尽管存在一些局限性,但通过不断的改进和扩展,如 RoBERTa 和 ALBERT 等变体的出现,BERT 及其相关模型将继续在自然语言处理领域发挥重要作用,推动该领域向着更高的准确性和效率迈进。

在未来的研究中,一方面可以继续探索如何优化 BERT 的架构和训练方法,以减少计算资源需求和提高长文本处理能力;另一方面,可以深入研究如何更好地将 BERT 应用于特定领域,提高其领域适应性,从而在更多的自然语言处理应用场景中取得更好的效果。


http://www.ppmy.cn/server/146743.html

相关文章

一些面试问题的深入与思考

Bug排查 原问题:多个服务的bug你是怎么排查的。如果是内存泄漏这种情况看日志看不了怎么办。 题解:内存泄漏的问题往往不会直接从日志中体现,需要用更多手段来定位解决。如下: 1、使用 Go 自带的性能分析工具 (1) pprof 工具&a…

Spark优化--开发调优、资源调优、数据倾斜调优和shuffle调优等

针对Spark优化,我们可以从多个角度进行,包括开发调优、资源调优、数据倾斜调优和shuffle调优等。以下是一些具体的优化方法: 1. 开发调优 避免创建重复的RDD:对于同一份数据,只应该创建一个RDD,避免创建多…

【MySQL】库和表的基本操作

目录 库 库的增删查改 字符集与校验集 库的备份与恢复 表 表的创建和删除 用不同的存储引擎创建表的区别 查看表 修改表 添加删除属性 修改改变属性 上篇博客我们讲了数据库的基本理解,对数据库有了一个大致的概念,下面我们来介绍一下库和表的…

使用开源GCC编译微软WMI相关函数的示例代码

如下代码是使用国产RedPanda-Cpp的编译工具编译的,该工具使用简单; 该方式是调用微软的WMI接口相关函数 但是使用GCC编译会出现编译不过的问题,很多代码库的函数都不存在; 在编译时,需要添加这些库文件:…

【大数据学习 | Spark调优篇】Spark之JVM调优

1. Java虚拟机垃圾回收调优的背景 如果在持久化RDD的时候,持久化了大量的数据,那么Java虚拟机的垃圾回收就可能成为一个性能瓶颈。因为Java虚拟机会定期进行垃圾回收,此时就会追踪所有的java对象,并且在垃圾回收时,找…

Linux服务器安装Linux宝塔面板部署wordpress网站以及雷池WAF

一、Linux服务器安装Linux宝塔面板 这个步骤参考网上其他教程。 二、Linux宝塔面板部署wordpress网站 这个步骤参考网上其他教程,保证网站能够正常访问,并且使用Linux宝塔面板申请并部署了SSL证书,使用https协议正常访问。 三、Linux宝塔…

MYSQL-查看系统变量信息语法(四十)

13.7.5.40 SHOW WARNINGS 语句 SHOW WARNINGS [LIMIT [offset,] row_count] SHOW COUNT(*) WARNINGSSHOW WARNINGS是一个诊断语句,显示有关在当前会话中执行语句所导致的情况(错误、警告和注释)的信息。DML语句(如INSERT、UPDATE…

Y20030018基于Java+Springboot+mysql+jsp+layui的家政服务系统的设计与实现 源代码 文档

家政服务系统的设计与实现 1.摘要2.开发目的和意义3.系统功能设计4.系统界面截图5.源码获取 1.摘要 随着人们生活水平的提高,老龄化、少子化等多重因素影响,我国对家政服务人群的需求与日俱增。家政服务行业对我国的就业和社会效益贡献也与日俱增&#…