当前位置:   article > 正文

Pytorch-使用Bert预训练模型微调中文文本分类

bert pytorch 文本情感分析

笔记摘抄

语料链接:https://pan.baidu.com/s/1YxGGYmeByuAlRdAVov_ZLg
提取码:tzao

neg.txt和pos.txt各5000条酒店评论,每条评论一行。

1. 导包和设定超参数

  1. import numpy as np
  2. import random
  3. import torch
  4. import matplotlib.pylab as plt
  5. from torch.nn.utils import clip_grad_norm_
  6. from torch.utils.data import TensorDataset, DataLoader, RandomSampler, SequentialSampler
  7. from transformers import BertTokenizer, BertForSequenceClassification, AdamW
  8. from transformers import get_linear_schedule_with_warmup
  9. SEED = 123
  10. BATCH_SIZE = 16
  11. learning_rate = 2e-5
  12. weight_decay = 1e-2
  13. epsilon = 1e-8
  14. random.seed(SEED)
  15. np.random.seed(SEED)
  16. torch.manual_seed(SEED)

2. 数据预处理

2.1 读取文件

  1. def readFile(filename):
  2. with open(filename, encoding='utf-8') as f:
  3. content = f.readlines()
  4. return content
  5. pos_text, neg_text = readFile('./hotel/pos.txt'), readFile('./hotel/neg.txt')
  6. sentences = pos_text + neg_text
  7. # 设定标签
  8. pos_targets = np.ones([len(pos_text)]) # (5000, )
  9. neg_targets = np.zeros([len(neg_text)]) # (5000, )
  10. targets = np.concatenate((pos_targets, neg_targets), axis=0).reshape(-1, 1) # (10000, 1)
  11. total_targets = torch.tensor(targets)

2.2 BertTokenizer进行编码,将每一句转成数字

  1. model_name = 'bert-base-chinese'
  2. cache_dir = './sample_data/'
  3. tokenizer = BertTokenizer.from_pretrained(model_name, cache_dir=cache_dir)
  4. print(pos_text[2])
  5. print(tokenizer.tokenize(pos_text[2]))
  6. print(tokenizer.encode(pos_text[2]))
  7. print(tokenizer.convert_ids_to_tokens(tokenizer.encode(pos_text[2])))
  1. 不错,下次还考虑入住。交通也方便,在餐厅吃的也不错。
  2. ['不', '错', ',', '下', '次', '还', '考', '虑', '入', '住', '。', '交', '通', '也', '方', '便', ',', '在', '餐', '厅', '吃', '的', '也', '不', '错', '。']
  3. [101, 679, 7231, 8024, 678, 3613, 6820, 5440, 5991, 1057, 857, 511, 769, 6858, 738, 3175, 912, 8024, 1762, 7623, 1324, 1391, 4638, 738, 679, 7231, 511, 102]
  4. ['[CLS]', '不', '错', ',', '下', '次', '还', '考', '虑', '入', '住', '。', '交', '通', '也', '方', '便', ',', '在', '餐', '厅', '吃', '的', '也', '不', '错', '。', '[SEP]']

为了使每一句的长度相等,稍作处理;

  1. # 将每一句转成数字 (大于126做截断,小于126做 Padding,加上首位两个标识,长度总共等于128)
  2. def convert_text_to_token(tokenizer, sentence, limit_size = 126):
  3. tokens = tokenizer.encode(sentence[:limit_size]) # 直接截断
  4. if len(tokens) < limit_size + 2: # 补齐(pad的索引号就是0)
  5. tokens.extend([0] * (limit_size + 2 - len(tokens)))
  6. return tokens
  7. input_ids = [convert_text_to_token(tokenizer, sen) for sen in sentences]
  8. input_tokens = torch.tensor(input_ids)
  9. print(input_tokens.shape) # torch.Size([10000, 128])

2.3 attention_masks, 在一个文本中,如果是PAD符号则是0,否则就是1

  1. # 建立mask
  2. def attention_masks(input_ids):
  3. atten_masks = []
  4. for seq in input_ids: # [10000, 128]
  5. seq_mask = [float(i > 0) for i in seq] # PAD: 0; 否则: 1
  6. atten_masks.append(seq_mask)
  7. return atten_masks
  8. atten_masks = attention_masks(input_ids)
  9. attention_tokens = torch.tensor(atten_masks)
  10. print(attention_tokens.shape) # torch.Size([10000, 128])
  • 构造input_ids 和 atten_masks 的目的 和 前面一节中提到的 .encode_plus函数返回的 input_ids 和 attention_mask 一样

  • input_type_ids 和 本次任务无关,它是针对每个训练集有两个句子的任务(如问答任务)。

2.4 划分训练集和测试集

  • 两个划分函数的参数 random_state 和 test_size 值要一致,才能使得 train_inputs 和 train_masks一一对应。
  1. from sklearn.model_selection import train_test_split
  2. train_inputs, test_inputs, train_labels, test_labels = train_test_split(input_tokens, total_targets,
  3. random_state=666, test_size=0.2)
  4. train_masks, test_masks, _, _ = train_test_split(attention_token
声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号