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

一、引言

自然语言处理(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.mzph.cn/news/888097.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ESP8266 (ESP-01S)烧录固件 和 了解与单片机通信必需的AT指令

ESP8266(ESP-01s)烧录固件 工具: 需要安装的原装出厂固件库: ESP8266 --接线-- VCC 3.3(外接开发板) GND GND(外接开发板) IO0 GND(外接…

<三>51单片机PWM开发SG90和超声测距

目录 1,PWM开发SG90 1.1简介 1.2控制舵机 1.3编程实现 2,超声测距 2.1简介 2.2,超声波测距代码实现 1,PWM开发SG90 1.1简介 PWM,英文名Pulse Width Modulation,是脉冲宽度调制缩写,它是通过对一系列脉冲的宽度进 行调制,等…

【Python爬虫五十个小案例】爬取猫眼电影Top100

博客主页:小馒头学python 本文专栏: Python爬虫五十个小案例 专栏简介:分享五十个Python爬虫小案例 🐍引言 猫眼电影是国内知名的电影票务与资讯平台,其中Top100榜单是影迷和电影产业观察者关注的重点。通过爬取猫眼电影Top10…

springboot信息化在线教学平台的设计与实现(代码+数据库+LW)

摘要 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了信息化在线教学平台的开发全过程。通过分析信息化在线教学平台管理的不足,创建了一个计算机管理信息化在线教学平台的方案。文章介绍了信息化在线教…

Hadoop批量计算实验

参考: Hadoop(一)之实验一CentOS7配置Hadoop系统:配置CentOS和下载安装包_基于虚拟机cents7搭建hadoop实验目的-CSDN博客 --------------------------------------------------------- 一、安装Vmware 二、创建虚拟机 1.安装centos7 ①打开VMware,点击新建虚拟机。 …

Flink四大基石之Time (时间语义) 的使用详解

目录 一、引言 二、Time 的分类及 EventTime 的重要性 Time 分类详述 EventTime 重要性凸显 三、Watermark 机制详解 核心原理 Watermark能解决什么问题,如何解决的? Watermark图解原理 举例 总结 多并行度的水印触发 Watermark代码演示 需求 代码演示&#xff…

Ubuntu 操作系统

一、简介 Ubuntu 是一个基于 Linux 的开源操作系统,它由 Canonical Ltd. 公司维护和资助。Ubuntu 以其易用性、强大的社区支持和定期的安全更新而闻名,一个一桌面应用为主的操作系统。 二、用户使用 1、常规用户的登陆方式 在登录时一般使用普通用户&…

Apifox Echo - 简单而强大的API测试服务

什么是Apifox Echo? Apifox Echo 是由 Apifox 官方推出的一个专业的接口请求和返回数据服务平台。它的主要目的是帮助开发人员和测试人员更好地学习和测试API接口。 核心特点 简单易用 提供简洁的HTTP请求和响应服务操作界面直观,上手容易服务地址统一: https://echo.api…

Linux笔记---进程:进程等待

1. 进程等待的概念 进程等待是指父进程通过系统调用wait或waitpid来对子进程进行状态检测与回收的功能。 当子进程退出时,如果父进程不读取子进程的退出状态,子进程就会成为僵尸进程,造成内存泄漏的问题。因此,父进程需要调用wa…

常见靶场的搭建

漏洞靶场 渗透测试(漏洞挖掘)切忌纸上谈兵,学习渗透测试(漏洞挖掘)知识的过程中,我们通常需要一个包含漏洞的测试环境来进行训练。而在非授权情况下,对于网站进行渗透测试攻击,是触及…

AtomicIntegerFieldUpdater能否降低内存

1. 代码如下: import java.util.LinkedList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger;public class AtomicIntegerTest {final AtomicInteger startPosition new AtomicInteger(0);final AtomicInteger wrotePosition new Atom…

从零开始:使用Vite和pnpm搭建Vue3项目实战指南

目录 一、Node.js的下载和安装 1、打开Node.js官网(Node.js — Run JavaScript Everywhere) 2、点击下载按钮,下载完成后,打开文件,一直按Next按钮,直到 3、下载完成后,找到文件所在位置,然…

立创庐山派 K230 RTSP 推流

立创庐山派使用的是K230芯片,按照教程刷了canmv固件,下载canmv ide,使用嘉楠社区的rtsp和wlan例程,修改成连接wifi以及RTSP推流例程 # Description: This example demonstrates how to stream video and audio to the network us…

数据湖的概念(包含数据中台、数据湖、数据仓库、数据集市的区别)--了解数据湖,这一篇就够了

文章目录 一、数据湖概念1、企业对数据的困扰2、什么是数据湖3、数据中台、数据湖、数据仓库、数据集市的区别 网上看了好多有关数据湖的帖子,还有数据中台、数据湖、数据仓库、数据集市的区别的帖子,发现帖子写的都很多,而且专业名词很多&am…

springboot kafka在kafka server AUTH变动后consumer自动销毁

前言 笔者使用了kafka用来传输数据,笔者在今年10月写了文章,怎么使用配置化实现kafka的装载:springboot kafka多数据源,通过配置动态加载发送者和消费者-CSDN博客 不过在实际运行中,kafka broker是加密的&#xff0c…

在Windows下编译支持https的wsdl2h

下载源码 在官网下载源码 安装Openssl 下载OpenSSL并安装,安装完成后需要将OpenSSL的路径添加到环境变量中 配置VS 1、打开工程 2、因为前面安装的OpenSLL是64位的,因此需要创建一个X64的配置 打开配置管理器,然后选择新建&#xff0…

【Webgl_glslThreejs】制作流水效果/毛玻璃效果材质

效果预览 shadertory源码 source: https://www.shadertoy.com/view/lldyDs 材质代码 import { DoubleSide, ShaderChunk, ShaderMaterial, TextureLoader } from "three"; /** * * source https://www.shadertoy.com/view/lldyDs */export default fu…

vue3+ts+uniapp微信小程序顶部导航栏

这是colorui改的&#xff0c;不用就不用看啦 color-ui(https://docs.xzeu.com/#/) 新建component文件夹创建topNavigation.vue <template><view><view class"cu-custom" :style"height: CustomBar px"><view class"cu-bar…

openssl使用哈希算法生成随机密钥

文章目录 一、openssl中随机数函数**OpenSSL 随机数函数概览**1. **核心随机数函数** **常用函数详解**1. RAND_bytes2. RAND_priv_bytes3. RAND_seed 和 RAND_add4. RAND_status **随机数生成器的熵池****常见用例****注意事项** 二、使用哈希算法生成随机的密钥 一、openssl中…

刷题日常(找到字符串中所有字母异位词,​ 和为 K 的子数组​,​ 滑动窗口最大值​,全排列)

找到字符串中所有字母异位词 给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 题目分析&#xff1a; 1.将p里面的字符先丢进一个hash1中&#xff0c;只需要在S字符里面找到多少个和他相同的has…