bert 的输出格式详解

输出是一个元组类型的数据 ,包含四部分,

last hidden state shape是(batch_size, sequence_length, hidden_size),hidden_size=768,它是模型最后一层的隐藏状态

pooler_output:shape是(batch_size, hidden_size),这是序列的第一个token (cls) 的最后一层的隐藏状态,它是由线性层和Tanh激活函数进一步处理的,这个输出不是对输入的语义内容的一个很好的总结,对于整个输入序列的隐藏状态序列的平均化或池化可以更好的表示一句话。


hidden_states:这是输出的一个可选项,如果输出,需要指定config.output_hidden_states=True,它是一个元组,含有13个元素,第一个元素可以当做是embedding,其余12个元素是各层隐藏状态的输出,每个元素的形状是(batch_size, sequence_length, hidden_size),


attentions:这也是输出的一个可选项,如果输出,需要指定config.output_attentions=True,它也是一个元组,含有12个元素,包含每的层注意力权重,用于计算self-attention heads的加权平均值

import torch
from torch import tensor
from transformers import BertConfig, BertTokenizer, BertModel

model_path = 'model/chinese-roberta-wwm-ext/'#已下载的预训练模型文件路径
config = BertConfig.from_pretrained(model_path, output_hidden_states = True, output_attentions=True)
assert config.output_hidden_states == True
assert config.output_attentions == True
model = BertModel.from_pretrained(model_path, config = config)
tokenizer = BertTokenizer.from_pretrained(model_path)

text = '我热爱这个世界'

# input = tokenizer(text)
# {'input_ids': [101, 2769, 4178, 4263, 6821, 702, 686, 4518, 102], 
#'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0], 
#'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1]}

# input = tokenizer.encode(text)
# [101, 2769, 4178, 4263, 6821, 702, 686, 4518, 102]

# input = tokenizer.encode_plus(text)
# {'input_ids': [101, 2769, 4178, 4263, 6821, 702, 686, 4518, 102], 
#'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0], 
#'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1]}

input_ids = torch.tensor([tokenizer.encode(text)], dtype=torch.long)#一个输入也需要组batch
print(input_ids.shape)
#torch.Size([1, 9])

model.eval()
output = model(input_ids)
print(len(output))
print(output[0].shape) #最后一层的隐藏状态 (batch_size, sequence_length, hidden_size)
print(output[1].shape) #第一个token即(cls)最后一层的隐藏状态 (batch_size, hidden_size)
print(len(output[2])) #需要指定 output_hidden_states = True, 包含所有隐藏状态,第一个元素是embedding, 其余元素是各层的输出 (batch_size, sequence_length, hidden_size)
print(len(output[3])) #需要指定output_attentions=True,包含每一层的注意力权重,用于计算self-attention heads的加权平均值(batch_size, layer_nums, sequence_length, sequence_legth)
# 4
# torch.Size([1, 9, 768])
# torch.Size([1, 768])
# 13
# 12

all_hidden_state = output[2]
print(all_hidden_state[0].shape)
print(all_hidden_state[1].shape)
print(all_hidden_state[2].shape)
# torch.Size([1, 9, 768])
# torch.Size([1, 9, 768])
# torch.Size([1, 9, 768])

attentions = output[3]
print(attentions[0].shape)
print(attentions[1].shape)
print(attentions[2].shape)
# torch.Size([1, 12, 9, 9])
# torch.Size([1, 12, 9, 9])
# torch.Size([1, 12, 9, 9])

后续补充,

text = '我热爱这个世界'

input = tokenizer(text)
#input分词后是一个字典
# {'input_ids': [101, 2769, 4178, 4263, 6821, 702, 686, 4518, 102], 
#'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0], 
#'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1]}


#input_ids = torch.tensor([tokenizer.encode(text)], dtype=torch.long)
#一个输入也需要组batch

input_ids = torch.tensor([input["input_ids"])
token_type_ids = torch.tensor([input["token_type_ids"])
attention_mask = torch.tensor([input["attention_mask"]]

output = model(input_ids, token_type_ids, attention_mask)

# 可以同时输入input_ids token_type_ids 和 attention_mask得到输出

#另一种写法,直接在分词的过程中返回张量
input_tensor = tokenizer(input, return_tensors = "pt")

  • 30
    点赞
  • 100
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
BERT是一种预训练的语言模型,它在自然语言处理领域中表现出色。在这里,我将简要介绍如何使用PyTorch实现BERT模型。 首先,我们需要导入必要的库: ```python import torch import torch.nn as nn from transformers import BertModel ``` 然后,我们定义BERT模型的类: ```python class BERT(nn.Module): def __init__(self, bert_path): super(BERT, self).__init__() self.bert = BertModel.from_pretrained(bert_path) self.dropout = nn.Dropout(0.1) self.fc = nn.Linear(768, 1) def forward(self, input_ids, attention_mask): output = self.bert(input_ids=input_ids, attention_mask=attention_mask) output = output.last_hidden_state output = self.dropout(output) output = self.fc(output) output = torch.sigmoid(output) return output ``` 在这个类中,我们首先使用`BertModel.from_pretrained()`方法加载预训练的BERT模型。然后,我们添加了一个dropout层和一个全连接层。最后,我们使用sigmoid函数将输出值转换为0到1之间的概率。 接下来,我们定义训练和测试函数: ```python def train(model, train_dataloader, optimizer, criterion, device): model.train() running_loss = 0.0 for inputs, labels in train_dataloader: inputs = inputs.to(device) labels = labels.to(device) optimizer.zero_grad() outputs = model(inputs['input_ids'], inputs['attention_mask']) loss = criterion(outputs.squeeze(-1), labels.float()) loss.backward() optimizer.step() running_loss += loss.item() * inputs.size(0) epoch_loss = running_loss / len(train_dataloader.dataset) return epoch_loss def test(model, test_dataloader, criterion, device): model.eval() running_loss = 0.0 with torch.no_grad(): for inputs, labels in test_dataloader: inputs = inputs.to(device) labels = labels.to(device) outputs = model(inputs['input_ids'], inputs['attention_mask']) loss = criterion(outputs.squeeze(-1), labels.float()) running_loss += loss.item() * inputs.size(0) epoch_loss = running_loss / len(test_dataloader.dataset) return epoch_loss ``` 在训练函数中,我们首先将模型设置为训练模式,并迭代数据集中的每个批次,将输入和标签移动到GPU上,然后执行前向传播、计算损失、反向传播和优化器步骤。在测试函数中,我们将模型设置为评估模式,并在数据集上进行迭代,计算测试损失。 最后,我们可以实例化模型并开始训练: ```python if __name__ == '__main__': bert_path = 'bert-base-uncased' train_dataset = ... test_dataset = ... train_dataloader = ... test_dataloader = ... device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') model = BERT(bert_path).to(device) optimizer = torch.optim.Adam(model.parameters(), lr=1e-5) criterion = nn.BCELoss() for epoch in range(num_epochs): train_loss = train(model, train_dataloader, optimizer, criterion, device) test_loss = test(model, test_dataloader, criterion, device) print(f'Epoch {epoch+1}/{num_epochs}, Train loss: {train_loss:.4f}, Test loss: {test_loss:.4f}') ``` 在这里,我们首先定义数据集和数据加载器,然后实例化模型并将其移动到GPU上(如果可用)。然后,我们定义优化器和损失函数,并开始训练模型。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值