Pytorch之Bert中文文本分类(二)

本文主要是针对入门级别的Bert使用,包括英文文本分类和中文文本分类。
这部分主要使用Bert进行情感分析,属于中文文本分类,同样使用BertForSequenceClassification
数据集中包括三个情感分类等级[-1,0,1]
在这里插入图片描述
流程和第一部分一致,主要修改地方是在Bert的config文件中将类别设置成3,并将数据集中的[-1,0,1],变化成[0,1,2]的形式,bert的预训练模型使用
bert-base-uncased-cn

这个数据集包括俩列:[‘label’, ‘txt’]
首先读入数据:

df = pd.read_csv(os.path.join(data_path,"train.tsv"), delimiter='\t')
df_dev=pd.read_csv(os.path.join(data_path,"dev.tsv"), delimiter='\t')
print("train:",df.head())
print("dev:",df_dev.head())

在这里插入图片描述
提取句子并进行处理

#提取语句并处理
sentencses=['[CLS] ' + sent + ' [SEP]' for sent in df.txt.values]
labels=df.label.values
#这里中性还是使用0表示1表示积极2表示不积极
labels=list(map(lambda x:0 if x == 0 else 1 if x == 1 else 2,[x for x in labels]))
print("train label:",labels[100:110])
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])

定义Bert的输入格式

  1. 处理后的句子
  2. 同样这里还是一句话[0,0,0,0,…]默认即可不需要传入
  3. mask
MAX_LEN=80
#训练集部分
#将分割后的句子转化成数字  word-->idx
input_ids=[tokenizer.convert_tokens_to_ids(sent) for sent in tokenized_sents]
print("转化后的第一个句子:",input_ids[0])
#做PADDING
#大于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])

#验证集部分
#构建验证集
dev_sentencses=['[CLS] ' + sent + ' [SEP]' for sent in df_dev.txt.values]
dev_labels=df_dev.label.values
print("dev_label:",dev_labels[100:110])
dev_labels=list(map(lambda x:0 if x == 0 else 1 if x == 1 else 2,[x for x in dev_labels]))
# dev_labels=[to_categorical(i, num_classes=3) for i in dev_labels]
dev_tokenized_sents=[tokenizer.tokenize(sent) for sent in dev_sentencses]
dev_input_ids=[tokenizer.convert_tokens_to_ids(sent) for sent in dev_tokenized_sents]
dev_input_ids=pad_sequences(dev_input_ids, maxlen=MAX_LEN, dtype="long", truncating="post", padding="post")
dev_attention_masks = []
for seq in dev_input_ids:
  dev_seq_mask = [float(i>0) for i in seq]
  dev_attention_masks.append(dev_seq_mask)

构建训练集和验证集的dataloader

train_inputs = torch.tensor(input_ids)
validation_inputs = torch.tensor(dev_input_ids)
train_labels = torch.tensor(labels)
validation_labels = torch.tensor(dev_labels)
train_masks = torch.tensor(attention_masks)
validation_masks = torch.tensor(dev_attention_masks)

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的中文模型

#装载预训练bert模型
modelConfig = BertConfig.from_pretrained(bert_config)
model = BertForSequenceClassification.from_pretrained(bert_pre_model, config=modelConfig)
print(model.cuda())

定义优化器

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)

训练部分

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 = []
epochs = 4
for _ in trange(epochs, desc="Epoch"):
    model.train()
    tr_loss = 0
    nb_tr_examples, nb_tr_steps = 0, 0
    for step, batch in enumerate(train_dataloader):
        batch = tuple(t.to(device) for t in batch)#将数据放置在GPU上
        b_input_ids, b_input_mask, b_labels = batch
        optimizer.zero_grad()
        loss = model(b_input_ids, token_type_ids=None, attention_mask=b_input_mask, labels=b_labels)[0]
        # print("loss:",loss)
        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 += 1
    print("Train loss: {}".format(tr_loss / nb_tr_steps))

    #验证集
    model.eval()
    eval_loss, eval_accuracy = 0, 0
    nb_eval_steps, nb_eval_examples = 0, 0
    for batch in validation_dataloader:
        batch = tuple(t.to(device) for t in batch)
        b_input_ids, b_input_mask, b_labels = batch
        with 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_accuracy
        nb_eval_steps += 1
    print("Validation Accuracy: {}".format(eval_accuracy / nb_eval_steps))

测试一下效果

#str
st="真的好吗?"
str='[CLS] ' + st + ' [SEP]'
str_tokenized_sents = tokenizer.tokenize(str)
print(str_tokenized_sents)
# Use the BERT tokenizer to convert the tokens to their index numbers in the BERT vocabulary
str_input_ids = [tokenizer.convert_tokens_to_ids(str_tokenized_sents)]
str_input_ids = pad_sequences(str_input_ids, maxlen=MAX_LEN, dtype="long", truncating="post", padding="post")
print(str_input_ids)
str_mask = [[float(i > 0) for i in str_input_ids[0]]]
str_label=[0]

str_input_ids = torch.tensor(str_input_ids).cuda()
str_mask = torch.tensor(str_mask).cuda()
str_label = torch.tensor(str_label).cuda()
print("size:",str_input_ids.size(),str_mask.size(),str_label.size())
logits_str = model(str_input_ids, token_type_ids=None, attention_mask=str_mask)[0]
print(np.argmax(logits_str.detach().cpu().numpy(), axis=1))

结果是个中性,再看看夸张点的
在这里插入图片描述
这里是负面的

  • 7
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
### 回答1: 要用PyTorch实现BERT中文多分类任务,可以按照以下步骤进行: 1. 准备数据:首先需要将中文多分类数据集准备好,并对其进行处理,使其适合输入BERT模型。可以使用PyTorch提供的Dataset和DataLoader类来加载数据集,并将文本数据转化为BERT模型需要的张量形式。 2. 加载预训练模型:PyTorch提供了许多已经在海量文本数据上预训练好的BERT模型。可以使用HuggingFace提供的transformers库中的预训练模型进行加载。 3. 修改网络结构:加载预训练模型后,需要对其进行微调,以适应中文多分类任务。可以添加一个全连接层,将预训练模型的输出连接到全连接层,从而得到最终的分类结果。 4. 训练模型:将准备好的数据集输入到BERT模型中,使用反向传播算法更新模型参数,直到训练损失收敛。 5. 模型评估:使用测试集对模型进行评估,可以计算准确率、精度、召回率等指标,以评估模型的性能。 以上是使用PyTorch实现BERT中文多分类的大致步骤。具体实现需要参考相关文档和代码。 ### 回答2: PyTorch是一个非常流行的深度学习库,可以用于实现BERT中文多分类任务。下面我将简要介绍如何使用PyTorch实现这个任务。 首先,我们需要安装PyTorch和transformers(一个用于自然语言处理的库,其中包括了预训练的BERT模型)。 接下来,我们需要加载预训练的BERT模型和tokenizer。你可以通过以下代码加载中文BERT模型: ```python from transformers import BertForSequenceClassification, BertTokenizer model_name = 'bert-base-chinese' num_labels = 10 # 根据你的分类任务设定类别数量 tokenizer = BertTokenizer.from_pretrained(model_name) model = BertForSequenceClassification.from_pretrained(model_name, num_labels=num_labels) ``` 然后,我们需要加载和预处理我们的数据。你可以使用PyTorch的Dataset和DataLoader来完成这个任务。你需要将你的文本数据转换为BERT可以理解的格式: ```python # 假设你的数据是一个包含文本和标签的列表 data = [ {'text': '这是文本1', 'label': 0}, {'text': '这是文本2', 'label': 1}, # 更多样本... ] # 将文本转换为BERT可以理解的格式 inputs = tokenizer.batch_encode_plus( [item['text'] for item in data], pad_to_max_length=True, max_length=512, # 根据你的文本长度设定 truncation=True, return_tensors='pt' ) # 创建PyTorch的Dataset dataset = torch.utils.data.TensorDataset( inputs['input_ids'], inputs['attention_mask'], torch.tensor([item['label'] for item in data]) ) # 创建PyTorch的DataLoader dataloader = torch.utils.data.DataLoader( dataset, batch_size=16, # 根据你的显存大小设定 shuffle=True ) ``` 最后,我们可以开始训练模型。下面是一个非常简单的训练循环: ```python device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') model.to(device) optimizer = torch.optim.AdamW(model.parameters(), lr=1e-5) for epoch in range(10): # 根据你的训练需求设定迭代次数 model.train() for input_ids, attention_mask, labels in dataloader: input_ids = input_ids.to(device) attention_mask = attention_mask.to(device) labels = labels.to(device) optimizer.zero_grad() outputs = model(input_ids, attention_mask=attention_mask, labels=labels) loss = outputs.loss loss.backward() optimizer.step() ``` 这是一个简单的PyTorch实现BERT中文多分类的示例。你可以根据你的具体任务需求进行适当的修改和调整。同时,你可能还需要评估模型和保存/加载模型等操作。 ### 回答3: PyTorch是一个开源深度学习框架,可以方便地实现BERT中文多分类任务。下面是一个使用PyTorch实现BERT中文多分类的简单示例: 1. 数据准备:首先,需要准备用于训练和测试的中文文本数据集。数据集应包含已经标注好类别的样本。 2. 数据预处理:使用中文分词工具对文本数据进行分词处理,并根据需要进行数据清洗和处理。可以使用NLTK或jieba等开源中文分词工具。 3. BERT模型加载:从Hugging Face的Transformers库中导入预训练的BERT模型和tokenizer。可以选择不同的中文BERT模型,如BERT-Base、BERT-Large等。 4. 构建模型:使用PyTorch构建BERT分类模型。根据需要,可以添加dropout层、全连接层等。 5. 设置优化器和损失函数:选择一个合适的优化器和损失函数,如Adam优化器和交叉熵损失函数。 6. 训练模型:使用训练数据来训练BERT模型。可以选择合适的epochs、batch size等参数。 7. 模型评估:使用测试数据对训练好的模型进行评估。计算模型在测试集上的准确率、精确率、召回率等指标。 8. 模型应用:使用已经训练好的模型对新的中文文本进行分类预测。 需要注意的是,以上是一个简要的流程,实际应用中还需要对数据进行进一步处理和优化,例如处理不平衡的类别分布、调整模型参数等。此外,还可以使用交叉验证等技术来进一步提高模型的性能。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值