97. BERT微调、自然语言推理数据集以及代码实现

100 篇文章 42 订阅
订阅专栏

1. 微调BERT

在这里插入图片描述

2. 句子分类

在这里插入图片描述

3. 命名实体识别

在这里插入图片描述

4. 问题回答

在这里插入图片描述

5. 总结

  • 即使下游任务各有不同,使用BERT微调时只需要增加输出层
  • 但根据任务的不同,输入的表示,和使用的BERT特征也会不一样

6. 自然语言推理数据集

斯坦福自然语言推断语料库(Stanford Natural Language Inference,SNLI)]是由500000多个带标签的英语句子对组成的集合 。我们在路径../data/snli_1.0中下载并存储提取的SNLI数据集。

import os
import re
import torch
from torch import nn
from d2l import torch as d2l

d2l.DATA_HUB['SNLI'] = (
    'https://nlp.stanford.edu/projects/snli/snli_1.0.zip',
    '9fcde07509c7e87ec61c640c1b2753d9041758e4')

data_dir = d2l.download_extract('SNLI')

6.1 读取数据集

原始的SNLI数据集包含的信息比我们在实验中真正需要的信息丰富得多。因此,我们定义函数read_snli以仅提取数据集的一部分,然后返回前提、假设及其标签的列表。

def read_snli(data_dir, is_train):
def read_snli(data_dir, is_train):
    """将SNLI数据集解析为前提、假设和标签"""
    def extract_text(s):
        # 删除我们不会使用的信息
        s = re.sub('\\(', '', s)
        s = re.sub('\\)', '', s)
        # 用一个空格替换两个或多个连续的空格
        s = re.sub('\\s{2,}', ' ', s)
        return s.strip()
    label_set = {'entailment': 0, 'contradiction': 1, 'neutral': 2}
    file_name = os.path.join(data_dir, 'snli_1.0_train.txt'
                             if is_train else 'snli_1.0_test.txt')
    with open(file_name, 'r') as f:
        # rows是一个list,其中包含多个list,这每个list就是由多个字符串组成,如:
        # rows[i]:['contradiction',
        # '( ( ( A person ) ( on ( a horse ) ) ) ( ( jumps ( over ( a ( broken ( down airplane ) ) ) ) ) . ) )',
        # '( ( A person ) ( ( is ( ( training ( his horse ) ) ( for ( a competition ) ) ) ) . ) )',]
        # 第一个字符串会指示属于哪个标签
        rows = [row.split('\t') for row in f.readlines()[1:]]
    
    # 第2个字符串表示premises(前提)
    premises = [extract_text(row[1]) for row in rows if row[0] in label_set]
    # 第3个字符串表示hypotheses(假设)
    hypotheses = [extract_text(row[2]) for row in rows if row[0] \
                in label_set]
    # 第一个字符串表示label(标签),再通过label_set得到具体的数字
    labels = [label_set[row[0]] for row in rows if row[0] in label_set]
    return premises, hypotheses, labels

现在让我们打印前3对前提和假设,以及它们的标签(“0”“1”和“2”分别对应于“蕴涵”“矛盾”和“中性”)。

train_data = read_snli(data_dir, is_train=True)
# train_data[0]表示premises,[:3]表示premises前三个
for x0, x1, y in zip(train_data[0][:3], train_data[1][:3], train_data[2][:3]):
    print('前提:', x0)
    print('假设:', x1)
    print('标签:', y)

运行结果:

在这里插入图片描述

训练集约有550000对,测试集约有10000对。下面显示了训练集和测试集中的三个标签“蕴涵”“矛盾”和“中性”是平衡的。

test_data = read_snli(data_dir, is_train=False)
for data in [train_data, test_data]:
    # data[2]是label这一数组,row就取到每一个label,一个label也能代表一行
    # 计算训练集和测试集中所有的label的0,1,2的数量
    print([[row for row in data[2]].count(i) for i in range(3)])

运行结果:

在这里插入图片描述

6.2 定义用于加载数据集的类

下面我们来定义一个用于加载SNLI数据集的类。类构造函数中的变量num_steps指定文本序列的长度,使得每个小批量序列将具有相同的形状。换句话说,在较长序列中的前num_steps个标记之后的标记被截断,而特殊标记“< pad>”将被附加到较短的序列后,直到它们的长度变为num_steps。通过实现__getitem__功能,我们可以任意访问带有索引idx的前提、假设和标签。

class SNLIDataset(torch.utils.data.Dataset):
    """用于加载SNLI数据集的自定义数据集"""
    def __init__(self, dataset, num_steps, vocab=None):
        self.num_steps = num_steps
        # dataset[0]是premises数组(由很多字符串组成),每个字符串就是一个句子
        # 每个句子词元化后就是一个列表,premises数组就变成了一个二维数组(包含了很多词元list)
        # 词元化后的列表是如:['person','on','a','horse','jumps','over','a','broken','down','airplane']
        # 所以,all_premise_tokens就是一个二维list
        all_premise_tokens = d2l.tokenize(dataset[0])

        # dataset[1]是hypothesis数组,进行词元化
        # 同理,all_hypothesis_tokens是一个包含了很多个list的大list,
        # 每个小list是每个句子的词元列表
        all_hypothesis_tokens = d2l.tokenize(dataset[1])

        if vocab is None:
            # 如果没有vocab,就对假设和前提进行构建词表
            self.vocab = d2l.Vocab(all_premise_tokens + \
                all_hypothesis_tokens, min_freq=5, reserved_tokens=['<pad>'])
        else:
            # 有的话就用给的词表
            self.vocab = vocab
        
        # 对premises中的所有句子和hypotheses中的进行pad处理
        self.premises = self._pad(all_premise_tokens)
        self.hypotheses = self._pad(all_hypothesis_tokens)
        # labels就是dataset[2]
        self.labels = torch.tensor(dataset[2])
        # len(self.premises) 其实就是全文有多少个这样的'假设、前提、标签'组成的句子对
        print('read ' + str(len(self.premises)) + ' examples')

    # 对句子长度不够的进行pad,长度够的进行截断
    def _pad(self, lines):
        return torch.tensor([d2l.truncate_pad(
            self.vocab[line], self.num_steps, self.vocab['<pad>'])
                         for line in lines])

    def __getitem__(self, idx):
        # 通过id,得到对应的premises、hypotheses、labels
        return (self.premises[idx], self.hypotheses[idx]), self.labels[idx]

    def __len__(self):
        return len(self.premises)

6.3 整合代码

现在,我们可以调用read_snli函数和SNLIDataset类来下载SNLI数据集,并返回训练集和测试集的DataLoader实例,以及训练集的词表。值得注意的是,我们必须使用从训练集构造的词表作为测试集的词表。因此,在训练集中训练的模型将不知道来自测试集的任何新词元。

在pytorch中,提供了一种十分方便的数据读取机制,即,使用torch.utils.data.Dataset与torch.utils.data.DataLoader组合得到数据迭代器。在每次训练时,利用这个迭代器输出每一个batch数据,并能在输出时对数据进行相应的预处理或数据增强等操作。

Pytorch构建数据集——torch.utils.data.Dataset()和torch.utils.data.DataLoader()

def load_data_snli(batch_size, num_steps=50):
    """下载SNLI数据集并返回数据迭代器和词表"""
    # 获取工作线程数量
    num_workers = d2l.get_dataloader_workers()
    data_dir = d2l.download_extract('SNLI')
    # 读取所有的训练数据和测试数据
    train_data = read_snli(data_dir, True)
    test_data = read_snli(data_dir, False)

    # 得到自定义的训练数据集和测试数据集,这是为了之后能得到数据迭代器
    train_set = SNLIDataset(train_data, num_steps)
    test_set = SNLIDataset(test_data, num_steps, train_set.vocab)

    # 得到训练数据迭代器以及测试数据迭代器
    train_iter = torch.utils.data.DataLoader(train_set, batch_size,
                                             shuffle=True,
                                             num_workers=num_workers)
    test_iter = torch.utils.data.DataLoader(test_set, batch_size,
                                            shuffle=False,
                                            num_workers=num_workers)
    
    return train_iter, test_iter, train_set.vocab

在这里,我们将批量大小设置为128时,将序列长度设置为50,并调用load_data_snli函数来获取数据迭代器和词表。然后我们打印词表大小。

train_iter, test_iter, vocab = load_data_snli(128, 50)
len(vocab)

运行结果:

在这里插入图片描述

现在我们打印第一个小批量的形状。与情感分析相反,我们有分别代表前提和假设的两个输入X[0]和X[1]。

for X, Y in train_iter:
    # 打印一下X[0]的前两个批量,也就是训练数据集的前两个premises
    print(X[0][:2])
    print(X[0].shape)
    print(X[1].shape)
    print(Y.shape)
    break

运行结果:

在这里插入图片描述

7. BERT微调代码实现

在本章的前面几节中,我们已经为SNLI数据集上的自然语言推断任务设计了一个基于注意力的结构。现在,我们通过微调BERT来重新审视这项任务。正如在 finetuning-bert中讨论的那样,自然语言推断是一个序列级别的文本对分类问题,而微调BERT只需要一个额外的基于多层感知机的架构,如 图所示。

在这里插入图片描述

本节将下载一个预训练好的小版本的BERT,然后对其进行微调,以便在SNLI数据集上进行自然语言推断。

import json
import multiprocessing
import os
import torch
from torch import nn
from d2l import torch as d2l

7.1 加载预训练的BERT

我们已经在 WikiText-2数据集上预训练BERT(请注意,原始的BERT模型是在更大的语料库上预训练的)。原始的BERT模型有数以亿计的参数。在下面,我们提供了两个版本的预训练的BERT:“bert.base”与原始的BERT基础模型一样大,需要大量的计算资源才能进行微调,而“bert.small”是一个小版本,以便于演示。

d2l.DATA_HUB['bert.base'] = (d2l.DATA_URL + 'bert.base.torch.zip',
                             '225d66f04cae318b841a13d32af3acc165f253ac')
d2l.DATA_HUB['bert.small'] = (d2l.DATA_URL + 'bert.small.torch.zip',
                              'c72329e68a732bef0452e4b96a1c341c8910f81f')

两个预训练好的BERT模型都包含一个定义词表的“vocab.json”文件和一个预训练参数的“pretrained.params”文件。我们实现了以下load_pretrained_model函数来加载预先训练好的BERT参数。

torch.load_state_dict()函数的用法总结

神经网络load_state_dict()进阶使用

def load_pretrained_model(pretrained_model, num_hiddens, ffn_num_hiddens,
                          num_heads, num_layers, dropout, max_len, devices):
    data_dir = d2l.download_extract(pretrained_model)
    # 定义空词表以加载预定义词表
    vocab = d2l.Vocab()
    # type(vocab.idx_to_token) = <class 'list'>
    # 'vocab.json'是预训练好的bert模型包含的
    vocab.idx_to_token = json.load(open(os.path.join(data_dir,
        'vocab.json')))
    # 定义词表的token映射到idx的词典
    vocab.token_to_idx = {token: idx for idx, token in enumerate(
        vocab.idx_to_token)}
    
    bert = d2l.BERTModel(len(vocab), num_hiddens, norm_shape=[256],
                         ffn_num_input=256, ffn_num_hiddens=ffn_num_hiddens,
                         num_heads=4, num_layers=2, dropout=0.2,
                         max_len=max_len, key_size=256, query_size=256,
                         value_size=256, hid_in_features=256,
                         mlm_in_features=256, nsp_in_features=256)
    # 加载预训练BERT参数
    # 'pretrained.params'是预训练好的bert模型包含的
    # 在Pytorch中构建好一个模型后,一般需要进行预训练权重中加载,
    # torch.load_state_dict()函数就是用于将预训练的参数权重加载到新的模型之中
    bert.load_state_dict(torch.load(os.path.join(data_dir,
                                                 'pretrained.params')))
    return bert, vocab

为了便于在大多数机器上演示,我们将在本节中加载和微调经过预训练BERT的小版本(“bert.small”)。在练习中,我们将展示如何微调大得多的“bert.base”以显著提高测试精度。

devices = d2l.try_all_gpus()
bert, vocab = load_pretrained_model(
    'bert.small', num_hiddens=256, ffn_num_hiddens=512, num_heads=4,
    num_layers=2, dropout=0.1, max_len=512, devices=devices)

7.2 微调BERT的数据集

对于SNLI数据集的下游任务自然语言推断,我们定义了一个定制的数据集类SNLIBERTDataset。在每个样本中,前提和假设形成一对文本序列,并被打包成一个BERT输入序列。

片段索引用于区分BERT输入序列中的前提和假设。利用预定义的BERT输入序列的最大长度(max_len),持续移除输入文本对中较长文本的最后一个标记,直到满足max_len。为了加速生成用于微调BERT的SNLI数据集,我们使用4个工作进程并行生成训练或测试样本。

Python进程池pool使用方法以及map函数用法

class SNLIBERTDataset(torch.utils.data.Dataset):
    def __init__(self, dataset, max_len, vocab=None):
        # dataset[:2]取到 premise 数组和 hypothesis数组
        # for sentences in dataset[:2]:取到这两个数组中的每一句话
        # s.lower() for s in sentences:把每一句话的每一个单词全部用小写表示
        # 再把这些单词进行词元化,也就是进行过滤出现次数少的单词等等处理,
        # 最后premise 数组和hypothesis数组中的每一个句子都是用一个字符串列表来表示
        # 再把这两个数组中的句子(两个序列)一一对应,打包放入 all_premise_hypothesis_tokens
        all_premise_hypothesis_tokens = [[
            p_tokens, h_tokens] for p_tokens, h_tokens in zip(
            *[d2l.tokenize([s.lower() for s in sentences])
              for sentences in dataset[:2]])]
        # print(all_premise_hypothesis_tokens[0])的形状如下:
        # [ ['a', 'person', 'on', 'a', 'horse', 'jumps', 'over', 'a', 'broken', 'down', 'airplane', '.'], 
        # ['a', 'person', 'is', 'training', 'his', 'horse', 'for', 'a', 'competition', '.'] ]
        # 可以看出all_premise_hypothesis_tokens[i]是一个大的list,包含两个词元列表,从而可以得知:
        # all_premise_hypothesis_tokens是一个更大的list,包含多个 由两个词元list的大list
        # 第一个词元列表是presmise,第二个词元列表是hypothesis

        # 标签
        self.labels = torch.tensor(dataset[2])
        # 词表
        self.vocab = vocab
        # 输入序列的最大长度
        self.max_len = max_len

        (self.all_token_ids, self.all_segments,
         self.valid_lens) = self._preprocess(all_premise_hypothesis_tokens)

        print('read ' + str(len(self.all_token_ids)) + ' examples')

    def _preprocess(self, all_premise_hypothesis_tokens):
        pool = multiprocessing.Pool(4)  # 使用4个进程
        # pool.map()函数,有两个参数可以传,第一个参数传的是函数,第二个参数传的是数据列表。
        # 用4个进程处理all_premise_hypothesis_tokens,
        # 返回的out是由多个元组组成的list,每个元组的元素是:(token_ids, segments, valid_len)
        out = pool.map(self._mp_worker, all_premise_hypothesis_tokens)
        # print(type(out))  <class 'list'>
        
        # print(out[0]):( [长为maxz_len] , [长为maxz_len], 一个数字),分别举例如下:
        # [3, 12, 844, 17, 12, 1710, 12168, 66, 12,1,1,1,1,1,1],
        # [1, 1, 1, 1, 1, 1, 1, 1, 1,0,0,0,0,0,0],
        # 9

        # 获取到每个句子的token_ids
        all_token_ids = [
            token_ids for token_ids, segments, valid_len in out]
        
        all_segments = [segments for token_ids, segments, valid_len in out]
        valid_lens = [valid_len for token_ids, segments, valid_len in out]

        return (torch.tensor(all_token_ids, dtype=torch.long),
                torch.tensor(all_segments, dtype=torch.long),
                torch.tensor(valid_lens))

    def _mp_worker(self, premise_hypothesis_tokens):
        # 因为用了多进程来处理,all_premise_hypothesis_tokens,
        # 所以每个进程处理一个premise_hypothesis_tokens,

        # premise_hypothesis_tokens的形状如下:
        # [ ['a', 'person', 'on', 'a', 'horse', 'jumps', 'over', 'a', 'broken', 'down', 'airplane', '.'], 
        # ['a', 'person', 'is', 'training', 'his', 'horse', 'for', 'a', 'competition', '.'] ]
        # 所以p_tokens是premises中所有的词元数组,h_tokens是hypothesis中所有的词元数组
        p_tokens, h_tokens = premise_hypothesis_tokens

        # 减小所有的 每两个词元列表 的长度大于 max_len-3的列表长度,使得两个句子拼接后长度为 max_len-3
        # 当然有些 两个词元列表相加长度很小的就不做处理,留到之后的代码语句进行pad
        # 得到新的p_tokens和h_tokens
        self._truncate_pair_of_tokens(p_tokens, h_tokens)
        # tokens[i]:两个词元列表用特殊词元拼接后的字符串列表
        # segments[i]:与tokens[i]对应的长度一样的向量(由连续的0和1组成)
        tokens, segments = d2l.get_tokens_and_segments(p_tokens, h_tokens)

        # 找到每个token对应的id,对于长度小的序列,如果长度不够max_len,用pad去补
        token_ids = self.vocab[tokens] + [self.vocab['<pad>']] \
                             * (self.max_len - len(tokens))
        # 同样,也对segments进行pad
        segments = segments + [0] * (self.max_len - len(segments))
        # 有效长度
        valid_len = len(tokens)

        # 返回的是一个元组,(句子中每个词元对应的id,segments,以及有效长度)
        return token_ids, segments, valid_len

    def _truncate_pair_of_tokens(self, p_tokens, h_tokens):
        # 为BERT输入中的'<CLS>'、'<SEP>'和'<SEP>'词元保留位置
        while len(p_tokens) + len(h_tokens) > self.max_len - 3:
          # 如果两个序列长度加上'<CLS>'、'<SEP>'和'<SEP>' 这3个长度大于max_len,
          # 则对两个序列不断移除最后的字符串,如可以移除'.','competition'等
          # ps:先从长度更大的移除
            if len(p_tokens) > len(h_tokens):
                p_tokens.pop()
            else:
                h_tokens.pop()

    def __getitem__(self, idx):
        return (self.all_token_ids[idx], self.all_segments[idx],
                self.valid_lens[idx]), self.labels[idx]

    def __len__(self):
        return len(self.all_token_ids)

下载完SNLI数据集后,我们通过实例化SNLIBERTDataset类来生成训练和测试样本。这些样本将在自然语言推断的训练和测试期间进行小批量读取。

# 如果出现显存不足错误,请减少“batch_size”。在原始的BERT模型中,max_len=512
batch_size, max_len, num_workers = 512, 128, d2l.get_dataloader_workers()
data_dir = d2l.download_extract('SNLI')
train_set = SNLIBERTDataset(d2l.read_snli(data_dir, True), max_len, vocab)
test_set = SNLIBERTDataset(d2l.read_snli(data_dir, False), max_len, vocab)
train_iter = torch.utils.data.DataLoader(train_set, batch_size, shuffle=True,
                                   num_workers=num_workers)
test_iter = torch.utils.data.DataLoader(test_set, batch_size,
                                  num_workers=num_workers)

运行结果:

在这里插入图片描述

7.3 微调BERT

用于自然语言推断的微调BERT只需要一个额外的多层感知机,该多层感知机由两个全连接层组成(请参见下面BERTClassifier类中的self.hiddenself.output)。这个多层感知机将特殊的“< cls>”词元的BERT表示进行了转换,该词元同时编码前提和假设的信息(为自然语言推断的三个输出):蕴涵、矛盾和中性。

class BERTClassifier(nn.Module):
    def __init__(self, bert):
        super(BERTClassifier, self).__init__()
        self.encoder = bert.encoder
        self.hidden = bert.hidden
        self.output = nn.Linear(256, 3)

    def forward(self, inputs):
        tokens_X, segments_X, valid_lens_x = inputs
        encoded_X = self.encoder(tokens_X, segments_X, valid_lens_x)
        return self.output(self.hidden(encoded_X[:, 0, :]))

在下文中,预训练的BERT模型bert被送到用于下游应用的BERTClassifier实例net中。在BERT微调的常见实现中,只有额外的多层感知机(net.output)的输出层的参数将从零开始学习。预训练BERT编码器(net.encoder)和额外的多层感知机的隐藏层(net.hidden)的所有参数都将进行微调。

net = BERTClassifier(bert)

回想一下,在 sec_bert中,MaskLM类NextSentencePred类在其使用的多层感知机中都有一些参数。这些参数是预训练BERT模型bert中参数的一部分,因此是net中的参数的一部分。然而,这些参数仅用于计算预训练过程中的遮蔽语言模型损失和下一句预测损失。这两个损失函数与微调下游应用无关,因此当BERT微调时,MaskLMNextSentencePred中采用的多层感知机的参数不会更新(陈旧的,staled)。

为了允许具有陈旧梯度的参数,标志ignore_stale_grad=Truestep函数d2l.train_batch_ch13中被设置。我们通过该函数使用SNLI的训练集(train_iter)和测试集(test_iter)对net模型进行训练和评估。由于计算资源有限,训练和测试精度可以进一步提高:我们把对它的讨论留在练习中。

lr, num_epochs = 1e-4, 5
trainer = torch.optim.Adam(net.parameters(), lr=lr)
loss = nn.CrossEntropyLoss(reduction='none')
d2l.train_ch13(net, train_iter, test_iter, loss, trainer, num_epochs,
    devices)

运行结果:

在这里插入图片描述

变形金刚::hugging_face:变形金刚:Pytorch和TensorFlow 2.0的最新自然语言处理
02-03
PyTorch和TensorFlow 2.0的最新自然语言处理 :hugging_face: 变形金刚提供了数千种经过预训练的模型,可以对文本执行多种任务,例如100多种语言的分类,信息提取,问题解答,摘要,翻译,文本生成等。 其目的是使尖端的NLP易于所有人使用。 :hugging_face: Transformers提供了API,可在给定的文本上快速下载和使用那些经过预训练的模型,在您自己的数据集上对其进行微调,然后在我们的上与社区共享。 同时,每个定义架构的python模块都可以独立使用并进行修改,以进行快速的研究实验。 :hugging_face: 变形金刚得到了两个最受欢迎的深度学习库和,它们之间具有无缝集成,允许您训练一个模型,然后加载模型以进行推理。 在线演示 您可以直接从在其页面上测试我们的大多数。 我们还提供了使用这些模型 。 这里有一些例子: 由Hugging Face团队构建的是此存储库文本生成功能的正式演示。 快速导览 为了立即在给定的文本上使用模型,我们提供了pipeline API。 管道将预训练的模型与该模型训练期间使用的预处理组合在一起。 这
59. 微调(fine-tuning)代码实现
weixin_47505105的博客
01-03 1824
笔记
ERNIE:ERNIE的语言理解实现(包括预训练模型和微调工具)
02-04
|简体中文 ERNIE是百度开创性提出的基于知识增强的持续学习语义理解框架,该框架将大数据预训练与多源丰富知识相结合,通过持续学习技术,不断吸收海量文本数据中文字句,结构,语义等方面ERNIE在情感分析,文本匹配,自然语言推理,词法分析,阅读理解,智能问答等16个公开数据集上全面显着超越世界领先技术,在国际权威的通用语言理解上评估基准GLUE上,突破首次突破90分,获得全球第一。在今年3月落下帷幕的全球最大语义评价。SemEval2020上,ERNIE摘得5项世界冠军,该技术也被全球顶级科技商业杂志《麻省理工科技评论》官方网站报道,相关创新成果也被国际顶级学术会议AAAI,IJCAI收录。E
nncf:基于PyTorch *的神经网络压缩框架,用于增强OpenVINO:trade_mark:推理
02-03
神经网络压缩框架(NNCF) 该存储库包含基于PyTorch *的框架和用于神经网络压缩的样本。 该框架以Python *包的形式组织,可以在独立模式下构建和使用。 框架架构是统一的,可以轻松添加不同的压缩方法。 这些样本演示了在公共模型和数据集上三个不同用例中压缩算法的用法:图像分类,对象检测和语义分割。 在本文档末尾的表格中,可以找到使用NNCF驱动的样本可获得的。 主要特点 在模型微调过程中应用的各种压缩算法的支持,以实现最佳压缩参数和精度: 自动,可配置的模型图转换以获得压缩模型。 源模型由自定义类包装,并且在图形中插入了其他特定于压缩的图层。 压缩方法的通用接口 GPU加速层
snli_1.0.zip
05-28
snli_1.0.zip
李沐动手学深度学习V2-BERT微调代码实现
flyingluohaipeng的博客
08-03 4028
load_pretrained_model函数用于加载预先训练好的BERT参数。
(情感倾向分类)2分类文本任务,Bert微调详细教程
zoe9698的博客
05-04 2486
🎀 Dataset:SST-2 Model:bert-base-cased ✨ transformers库的使用【三】对预训练模型进行微调 Transformers实战——使用Trainer类训练和评估自己的数据和模型 HuggingFace 从在线库中载入SST2数据集 from datasets import load_dataset dataset = load_dataset('glue','sst2') Tokenizer:将input转换为模型可以处理的格式。 from
BERT模型微调的基本步骤(demo)
aideshizhe0的博客
05-17 1218
在这个例子中,我们首先加载了预训练的BERT模型和对应的tokenizer。然后,我们准备了一些文本数据和对应的标签,使用tokenizer处理文本数据,然后创建了一个DataLoader。接下来,我们设置了优化器,开始训练模型。最后,我们保存了微调后的模型。请注意,这只是一个非常基础的例子,实际上在进行模型微调时,你可能需要处理更复杂的数据,选择合适的损失函数和优化器,以及进行模型性能的评估等等。对于预训练模型的微调,一个常见的例子是使用BERT模型进行情感分析任务。
动手学习深度学习:[Errno 22] Invalid argument: ‘..\\data\\snli_1.0\\Icon\r‘
打孔员的博客
09-05 2767
最近在B站上看李沐大神的动手学习深度学习V2,在跑他的源码natural-language-inference-and-dataset时,第一个块就出现了如下的报错信息: OSError Traceback (most recent call last) <ipython-input-1-2b8316634310> in <module> 10 '9fcde07509c7e87ec61c640c1b
自然语言推断:微调BERT
yingzi的技术博客
10-11 981
我们以前在WikiText-2数据集上预训练BERT(注意,原始的BERT模型是在更大的语料库上预训练的),原始的BERT模型有数以亿计的参数。在下面,我们提供了两个版本的预训练的BERT:"bert.base"与原始的BERT基础模型一样大,需要大量的计算资源才能进行微调。在下文中,预训练的BERT模型bert被送到用于下游应用的BERTClassifier实例net中,在BERT微调的常见实现中,只有额外的多层感知机(net.output)的输出层的参数将从零开始学习。
bert_extension_tf:TensorFlow中的BERT扩展
03-15
BERT扩展 (来自变压器的双向编码器表示)是Google AI语言小组提出的一种通用的自动编码预训练方法,它在11个NLP任务(包括问题回答,自然,语言推理和情感分析)方面获得了最新的技术成果。 BERT旨在通过在所有层的左,右上下文上共同进行条件调节来预训练来自未标记文本的深层双向表示,这使它可以轻松地针对下游任务进行微调,而无需进行大量针对特定任务的体系结构修改。 该项目旨在提供基于当前BERT的扩展,并将BERT的功能带给NER和NLU等其他NLP任务。 图1:在不同任务上对BERT进行微调的图示 环境 的Python 3.6.7 Tensorflow 1.13.1 NumPy 1.13.3 数据集 是一个多任务数据集,包含3个子任务,POS标记,语法块和NER。 对于NER子任务,它包含4种命名实体:不属于前三组的人员,位置,组织和杂项名称。 (航空公司旅行信息系统)
ABSA-PyTorch:基于方面的情感分析,PyTorch实现。基于方面的情感分析,使用PyTorch实现
02-03
ABSA-PyTorch 基于方面的情感分析,PyTorch实现。 基于方面的情感分析,使用PyTorch实现。 需求 火炬> = 0.4.0 numpy的> = 1.13.3 斯克莱恩 python 3.6 / 3.7 变形金刚 要安装需求,请运行pip install -r requirements.txt 。 对于非基于BERT的模型,需要,请参阅了解更多详细信息。 用法 训练 python train.py --model_name bert_spc --dataset restaurant 所有实现的模型都列在。 有关更多训练参数,请参见 。 请参阅以获取k倍交叉验证支持。 推理 有关基于非BERT的模型和基于BERT的模型,请参考 。 提示 对于非基于BERT的模型,训练过程不是很稳定。 基于BERT的模型对小数据集上的超参数(尤其是学习率)更敏感,请参阅。 为了释放BERT的真正功能,必须对特定任务进行微调。 评论/调查 邱锡鹏等。 “自然语言处理的预训练模型:调查。” arXiv预印本arXiv:2003.08271(2020)。 张磊,王帅和刘
BERT(Transformer Encoder)详解和TensorFlow实现(附源码)
liuqiker的博客
06-07 3054
单向语言模型会限制模型的表征能力,使其只能获取单方向的上下文信息,而BERT利用双向注意力来构建整个神经网络,因此最终生成能融合左右上下文信息的深层双向语言表征,即真正意义上的Bi-Directional Context信息。在实际的训练中,通常另训练集中的50%符合IsNext关系,另外50%的第二句话随机从语料中提取,它们的关系是NotNext,并将这个关系保存在[CLS]中。下图展示了BERT在11种各不同任务中的模型,它们只需要在BERT的基础上再添加一个输出层便可以完成对特定任务的微调
matchzoo的tutorials的data_handing.ipynb的运行学习
qq_19841133的博客
04-22 926
//写在前面 加(雾)的都表示那些命名都是我自己的黑话,标准命名是啥我真的是希腊乃。 因为是.ipynb,我是直接开cmd来运行了. 首先是import mathzoo和pandas,用中文的镜像站来下载,不然下载真的等到死还下不完 pip install -i http://pypi.douban.com/simple/ matchzoo pip install -i http://pypi.d...
94. BERT以及BERT代码实现
weixin_47505105的博客
01-30 1362
笔记
BERT 模型微调实战:使用Transformers微调BERT模型实现问答和文本分类任务
FrenzyTechAI的博客
07-27 7952
BERT(Bidirectional Encoder Representations from Transformers)是一种预训练的自然语言处理模型,由Google于2018年发布。BERT模型的核心是Transformer编码器,它可以在大规模语料库上进行无监督预训练,然后通过微调在各种NLP任务上进行微调BERT模型是一种双向的深度学习模型,它可以同时考虑上下文中的所有单词,从而更好地理解句子的含义。BERT模型已被证明在多项NLP任务上取得了最佳结果,包括问答、文本分类、命名实体识别等。
针对序列级和词元级应用微调BERT(需修改)
liuyingshudian的博客
02-28 641
微调BERT
BERT-多标签文本分类实战】之四——数据集预处理
十一月廿七风雨大作
09-27 7199
可以看到,每个文本平均有1.2个标签,相对其他数据集来说,是极低的。:在使用预训练词向量的时候,首先会构建一个词典,然后把文本里面的每个单词逐个转化成词典里面对应的序号,最后根据序号再去预训练词向量里面找对应单词的d维向量,于是一条文本就变成了。除此之外,我们还应该关心数据集平均一个本文有几个标签、最多有几个标签、最少有几个标签,哪些标签出现的比较频繁,这些有助于我们加深对数据集、任务难点的了解。在处理数据集的文本数据前,有必要了解一下使用预处理词向量的模型,是如何处理文本数据的。的文本有3964个。
大型语言模型的新挑战:AMR语义表示的神秘力量
最新发布
math_bearrr的博客
05-04 1241
1. AMRCOT的概念和设计原理AMRCOT是一种基于抽象意义表示(AMR)的NLP任务提示方法。AMR通过提取文本中的关键语义信息(如实体、关系等),为语言模型提供了一种中间语义表示。这种表示旨在帮助语言模型更有效地理解和处理复杂的语言任务。AMRCOT方法通过将输入文本与其对应的AMR一起呈现给预训练的大型语言模型(LLM),来探索AMR在没有模型训练的情况下,对LLM性能的潜在影响。2. 选择的五个NLP任务和数据集:使用PAWS数据集,测试模型是否能识别两个句子是否为同义重述。
大模型推理和大模型微调的关系是什么
04-29
大模型推理和大模型微调是深度学习中两个相关但不同的概念。 大模型推理是指使用已经训练好的大规模深度学习模型对新的输入数据进行预测或推断的过程。在大模型推理中,我们使用已经具备较高准确性和泛化能力的模型来处理实际应用中的数据,例如图像分类、语音识别、自然语言处理等任务。 而大模型微调是指在已经训练好的大规模深度学习模型的基础上,通过进一步训练模型来适应特定任务或数据集。通常情况下,我们会使用一个在大规模数据集上预训练好的模型(如BERT、GPT等),然后通过在特定任务或数据集上进行微调,使得模型能够更好地适应该任务或数据集。 因此,大模型推理和大模型微调可以说是相互关联的。大模型推理是在已经完成微调或预训练的模型上进行的,而大模型微调则是为了进一步提升模型在特定任务上的性能而进行的训练过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • 关于 __dirname和__filename介绍以及使用场景 11928
  • 补充: 关于new URL() 10149
  • 宏任务和微任务 7797
  • 什么是服务访问点 6219
  • 总结:删除单链表/单循环链表中的最小值节点的两种解法(并延伸至:依次找出链表的最小值,打印并删除,释放空间) 6108

分类专栏

  • 写力扣时自己的笔记 11篇
  • 算法作业 1篇
  • 深度学习 100篇
  • 记录部分写过的题目 6篇
  • Vue实战--电商后台管理系统 29篇
  • 计算机网络复习 6篇
  • 其他杂类 2篇
  • MongoDB 8篇
  • vue2 案例 2篇
  • Express 6篇
  • 原生JavaScript练习题 14篇
  • 前端工程化 1篇
  • art-template 5篇
  • JavaScript 6篇
  • git用法 4篇
  • VSCode用过的插件 1篇
  • Node实战:多人博客管理系统 7篇
  • ES6 10篇
  • Node中用到的第三方模块 5篇
  • Ajax 14篇
  • nodejs 30篇

最新评论

  • Ajax 封装

    2301_80316843: default的type那里是不是写错了 应该写空吧 其他写的都很清除明白~

  • 3.矩阵计算及导数基础

    better_eleven: 同在看李沐的课程,标量对向量求导、向量对标量求导,涉及“求导布局”问题。沐神提到,他这里是使用的分子布局(即求导结果的维度和分子的维度是一致的)。

  • 19. Dropout从零代码实现以及简洁实现

    Wendy_lz: 也就是说先生成一个同shape均匀的数组,[0, 1], 再与0.5作比较,小于的置0, 大于置1,得到mask, 再与X进行乘操作,得到最终需要的dropout后的X,用于后续计算

  • 17. 权重衰退(weight_decay)

    NormalConfidence_Man: 谢谢兄弟了,李沐这一部分讲得太抽象了实在听不懂表情包

  • 3.矩阵计算及导数基础

    Keith J: 请问您现在搞懂为啥是行向量了吗?我也很困惑这个问题,如果您懂了,能给我解释一下吗?李沐的课说是行向量

您愿意向朋友推荐“博客详情页”吗?

  • 强烈不推荐
  • 不推荐
  • 一般般
  • 推荐
  • 强烈推荐
提交

最新文章

  • 二分查找题型总结
  • 归并排序之确定递归层数
  • 位运算相关总结
2024年1篇
2023年58篇
2022年198篇

目录

目录

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值

深圳SEO优化公司新乡关键词按天扣费推荐阿坝企业网站建设厦门品牌网站设计推荐铜仁网站开发价格丽江SEO按天计费价格泰安模板制作价格鹰潭网站优化软件推荐太原网站关键词优化报价福田优化推荐运城网站设计模板价格晋中seo网站优化推荐济源设计公司网站推荐恩施SEO按效果付费观澜设计公司网站哪家好娄底百度竞价包年推广推荐莱芜网站优化按天计费报价怀化网站搜索优化多少钱上饶企业网站设计桂林SEO按效果付费推荐枣庄百搜标王报价朔州企业网站设计价格松岗seo多少钱宿州网络推广哪家好南阳网站建设设计驻马店网站优化排名价格张家界SEO按天计费大庆SEO按天收费哪家好桐城百姓网标王推广深圳seo网站推广价格青岛关键词排名哪家好歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化