本文主要是针对入门级别的Bert使用,先让模型能够实现文本分类,后续会讲解huggingface的Bert流程化的使用,包括英文文本分类和中文文本分类。

英文部分使用
BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding中的Cola数据集,任务如下图

这个数据集包括四列:[‘sentence_source’, ‘label’, ‘label_notes’, ‘sentence’]
第一列是句子来源,第三列大部分缺失,我们的目的是做文本分类,这俩列可以不用。

第二列lable:[0,1]
第四列sentence:英文

下面就开始:

这里我们使用自己的方法快速处理数据集进行模型训练,后续文章将会进一步使用huggingface的方法来处理数据集
https://github.com/huggingface/transformers

首先定义路径:

data_path='cola_public/raw/'#数据集路径
bert_pre_model='bert-base-uncased/pytorch_model.bin'#预训练模型文件
bert_config='bert-base-uncased/bert_config.json'#配置文件
bert_pre_tokenizer='bert-base-uncased/bert-base-uncased-vocab.txt'#词表

首先将数据使用pandas读取,并处理成bert的输入格式

  1. 处理后的句子
  2. [0,0,0…,1,1,1…]编号如果是一句话,不输入也可以,默认会自动生成[0,0,0…0]
  3. attietion mask 数据集中有效的长度,模型能attention到的所有位置
#读取训练数据 os.path.join(data_dir, "train.txt")
df = pd.read_csv(os.path.join(data_path,"in_domain_train.tsv"), delimiter='\t', header=None,\names=['sentence_source', 'label', 'label_notes', 'sentence'])#提取语句并处理
sentencses=['[CLS] ' + sent + ' [SEP]' for sent in df.sentence.values]
labels=df.label.values
print("第一句话:",sentencses[0])
tokenizer=BertTokenizer.from_pretrained(bert_pre_tokenizer,do_lower_case=True)
tokenized_sents=[tokenizer.tokenize(sent) for sent in sentencses]
print("tokenized的第一句话:",tokenized_sents[0])#定义句子最大长度(512)
MAX_LEN=128#将分割后的句子转化成数字  word-->idx
input_ids=[tokenizer.convert_tokens_to_ids(sent) for sent in tokenized_sents]
print("转化后的第一个句子:",input_ids[0])#做PADDING,这里使用keras的包做pad,也可以自己手动做pad,truncating表示大于最大长度截断
#大于128做截断,小于128做PADDING
input_ids=pad_sequences(input_ids, maxlen=MAX_LEN, dtype="long", truncating="post", padding="post")
print("Padding 第一个句子:",input_ids[0])#建立mask
attention_masks = []
for seq in input_ids:seq_mask = [float(i>0) for i in seq]attention_masks.append(seq_mask)
print("第一个attention mask:",attention_masks[0])


划分训练集,这里使用sklearn的方法,当然自己可以手动改切分。

#划分训练集、验证集
train_inputs, validation_inputs, train_labels, validation_labels = train_test_split(input_ids, labels,random_state=2018, test_size=0.1)
train_masks, validation_masks, _, _ = train_test_split(attention_masks, input_ids,random_state=2018, test_size=0.1)
print("训练集的一个inputs",train_inputs[0])
print("训练集的一个mask",train_masks[0])


到这里我们就可以生成dataloader放入到模型中进行训练了

#将训练集、验证集转化成tensor
train_inputs = torch.tensor(train_inputs)
validation_inputs = torch.tensor(validation_inputs)
train_labels = torch.tensor(train_labels)
validation_labels = torch.tensor(validation_labels)
train_masks = torch.tensor(train_masks)
validation_masks = torch.tensor(validation_masks)#生成dataloader
batch_size = 32
train_data = TensorDataset(train_inputs, train_masks, train_labels)
train_sampler = RandomSampler(train_data)
train_dataloader = DataLoader(train_data, sampler=train_sampler, batch_size=batch_size)
validation_data = TensorDataset(validation_inputs, validation_masks, validation_labels)
validation_sampler = SequentialSampler(validation_data)
validation_dataloader = DataLoader(validation_data, sampler=validation_sampler, batch_size=batch_size)

加载预训练模型,首先加载bert的配置文件,然后使用BertForSequenceClassification这个类来进行文本分类

modelConfig = BertConfig.from_pretrained('bert-base-uncased/bert_config.json')
model = BertForSequenceClassification.from_pretrained('bert-base-uncased/pytorch_model.bin', config=modelConfig)
print(model.cuda())

定义优化器,注意BertAdam、AdamW是不同版本的adam优化方法,版本更新太快,知道使用就行,定义需要weight decay的参数
‘gamma’, ‘beta’ 是值LayerNormal层的,不要decay,直接训练即可。其他参数除去bias,均使用weight decay的方法进行训练
weight decay可以简单理解在Adam上的一个优化的基础上成使用L2正则(AdamW)。

param_optimizer = list(model.named_parameters())
no_decay = ['bias', 'gamma', 'beta']
optimizer_grouped_parameters = [{'params': [p for n, p in param_optimizer if not any(nd in n for nd in no_decay)],'weight_decay_rate': 0.01},{'params': [p for n, p in param_optimizer if any(nd in n for nd in no_decay)],'weight_decay_rate': 0.0}
]optimizer = BertAdam(optimizer_grouped_parameters,lr=2e-5,warmup=.1)

接下来就是训练部分了,注意在训练是传入label,模型可以直接得到loss,如果不传入label,便只有一个logits

  1. (loss,logits) train
  2. (logits) dev 或者 test
#定义一个计算准确率的函数
def flat_accuracy(preds, labels):pred_flat = np.argmax(preds, axis=1).flatten()labels_flat = labels.flatten()return np.sum(pred_flat == labels_flat) / len(labels_flat)#训练开始
train_loss_set = []#可以将loss加入到列表中,后期画图使用
epochs = 10
for _ in trange(epochs, desc="Epoch"):#训练开始model.train()tr_loss = 0nb_tr_examples, nb_tr_steps = 0, 0for step, batch in enumerate(train_dataloader):batch = tuple(t.to(device) for t in batch)b_input_ids, b_input_mask, b_labels = batchoptimizer.zero_grad()#取第一个位置,BertForSequenceClassification第一个位置是Loss,第二个位置是[CLS]的logitsloss = model(b_input_ids, token_type_ids=None, attention_mask=b_input_mask, labels=b_labels)[0]train_loss_set.append(loss.item())loss.backward()optimizer.step()tr_loss += loss.item()nb_tr_examples += b_input_ids.size(0)nb_tr_steps += 1print("Train loss: {}".format(tr_loss / nb_tr_steps))#模型评估model.eval()eval_loss, eval_accuracy = 0, 0nb_eval_steps, nb_eval_examples = 0, 0for batch in validation_dataloader:batch = tuple(t.to(device) for t in batch)b_input_ids, b_input_mask, b_labels = batchwith torch.no_grad():logits = model(b_input_ids, token_type_ids=None, attention_mask=b_input_mask)[0]logits = logits.detach().cpu().numpy()label_ids = b_labels.to('cpu').numpy()tmp_eval_accuracy = flat_accuracy(logits, label_ids)eval_accuracy += tmp_eval_accuracynb_eval_steps += 1print("Validation Accuracy: {}".format(eval_accuracy / nb_eval_steps))

结果如下:

[1] BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding
[2] https://github.com/huggingface/transformers

Pytorch之Bert文本分类(一)相关推荐

  1. pytorch bert文本分类_一起读Bert文本分类代码 (pytorch篇 四)

    Bert是去年google发布的新模型,打破了11项纪录,关于模型基础部分就不在这篇文章里多说了.这次想和大家一起读的是huggingface的pytorch-pretrained-BERT代码exa ...

  2. Transformer课程 第7课Gavin大咖 BERT文本分类-BERT Fine-Tuning

    Transformer课程 第7课Gavin大咖 BERT文本分类-BERT Fine-Tuning Part III - BERT Fine-Tuning 4. Train Our Classifi ...

  3. 基于Bert文本分类进行行业识别

    NLP学习之Bert文本分类 行业识别--基于Bert 项目介绍 数据集: 数据迭代器: 项目结构: 总入口: 模型搭建和配置 配置类: config 模型搭建:model 数据预处理: 数据预处理 ...

  4. 6.自然语言处理学习笔记:Multi-head-self-attention 和Transformer基础知识 和BERT文本分类原理

    Multi-head-self-attention: 可以更细致的去发现局部信息. Transformer:   BERT文本分类原理:  

  5. 【代码实战】基于pytorch实现中文文本分类任务

    点击上方,选择星标或置顶,不定期资源大放送! 阅读大概需要15分钟 Follow小博主,每天更新前沿干货 来自 | 知乎 地址 | https://zhuanlan.zhihu.com/p/73176 ...

  6. 【PyTorch】7 文本分类TorchText实战——AG_NEWS四类别新闻分类

    使用 TorchText 进行文本分类 1.访问原始数据集迭代器 2. 准备数据处理管道 3. 生成数据批次和迭代器 4. 定义模型 5. 初始化一个实例 6. 定义训练模型和评估结果的函数 7. 拆 ...

  7. BERT文本分类,代码超基础、超详细解析

    声明: 关于文章: 内容:使用bert进行新闻文本分类, 目的:熟悉预训练模型的使用过程以及数据处理,和模型的各个接口,输入输出,做到对bert的简单使用 环境:windows,pytorch,tra ...

  8. 自然语言处理(NLP): 12 BERT文本分类

    文章目录 BERT介绍 BERT 论文阅读 BERT用做特征提取 BERT 源码分析 BERT升级版 RoBERTa:更强大的BERT ALBERT:参数更少的BERT DistilBERT:轻量版B ...

  9. BERT文本分类实战

    一.简介 在开始使用之前,我们先简单介绍一下到底什么是BERT,大家也可以去BERT的github上进行详细的了解.在CV问题中,目前已经有了很多成熟的预训练模型供大家使用,我们只需要修改结尾的FC层 ...

最新文章

  1. mysql docker 制作_docker 制作自己的mysql镜像
  2. 区域医疗卫生信息化建设将成投资重点
  3. 知识图谱(四)——实体识别和扩展
  4. Log4net 在framework Client中编译失败
  5. 安装Docker的三种方式
  6. mysql optimize 作用_mysql optimize table
  7. 用C# (.NET Core) 实现抽象工厂设计模式
  8. SQLyog中文乱码的解决方法
  9. Bit.com BCH期权上线以来日交易量持续翻倍
  10. androidpn的学习研究(四)androidpn-client客户端几个类说明
  11. 【狂神说Redis】2Redis入门 2-2Redis部署在Linux(Ubuntu)
  12. Python requests库大全
  13. matlab中与或非、等逻辑符号
  14. ADW_Launcher
  15. autojs 悬浮框演示代码
  16. 侍魂微信新服务器2019,侍魂胧月传说手游2019年5月17日微信问答试炼答案
  17. y5_运五飞机最新改进型号——Y5BG
  18. 版本管理软件--Git的安装、配置并使用
  19. Wordpress 所有 hook 钩子
  20. 百度搜索技巧,精确搜索,搜索指定标题、内容、网址,黑语法搜索入门

热门文章

  1. 山东大学计算机学院李庆忠,研究生导师李庆忠:山东大学
  2. 搭建 Apache Http Server 服务器
  3. 《匠人精神》读书笔记要点记录及自我剖析
  4. YMIR2.0 部署教程
  5. 公交卡信息是在服务器还是卡片,北京“市政交通一卡通”卡号的相关说明
  6. DLL搜索路径和DLL劫持
  7. Mybatis新增数据后,报ERROR: Field * doesn‘t have a default value
  8. 从零开始学习CANoe(十)—— 信号发生器(Signal Generator)
  9. ESD器件的主要性能参数
  10. 让你不再害怕指针——C指针详解(经典,非常详细)