
一、模型和数据集介绍1.1 预训练模型chinese-roberta-wwm-ext是基于RoBERTa架构下开发其中wwm代表Whole Word Masking即对整个词进行掩码处理通过这种方式模型能够更好地理解上下文和语义关联提高中文文本处理的准确性和效果。与原始的BERT模型相比chinese-roberta-wwm-ext在训练数据规模和训练步数上做了一些调整以进一步提升模型的性能和鲁棒性。并且在大规模无监督语料库上进行了预训练使其具备强大的语言理解和生成能力。它能够广泛应用于各种自然语言处理任务如文本分类、命名实体识别、情感分析等。我们可以使用这个模型作为基础在不同的任务上进行微调和迁移学习以实现更准确、高效的中文文本处理。huggingface地址https://huggingface.co/hfl/chinese-roberta-wwm-ext进到huggingface中下载预训练模型1.2 数据集数据集采用SMP2020微博情绪分类评测进入下面链接下载数据集https://smp2020ewect.github.io/下载后数据分了三种类型训练集、测试集、验证集数据的格式为JSON格式结构如下其中label为当前content的分类一共分了6种类别如下所示label说明fear恐惧neutral无情绪sad悲伤surprise惊奇angry愤怒happy积极二、模型微调训练2.1、处理数据集构建DataLoaderfromtransformersimportBertTokenizerfromtorch.utils.dataimportDataLoader,RandomSampler,TensorDatasetimportnumpyasnpimporttorchimportjsonimportosclassGenDateSet():def__init__(self,tokenizer,train_file,val_file,label_dict,max_length128,batch_size10):self.train_filetrain_file self.val_fileval_file self.max_lengthmax_length self.batch_sizebatch_size self.label_dictlabel_dict self.tokenizertokenizerdefgen_data(self,file):ifnotos.path.exists(file):raiseException(数据集不存在)input_ids[]input_types[]input_masks[]labels[]withopen(file,encodingutf8)asf:datajson.load(f)ifnotdata:raiseException(数据集不存在)# 处理数据forindex,iteminenumerate(data):textitem[content]labelitem[label]tokensself.tokenizer(text,paddingmax_length,truncationTrue,max_lengthself.max_length)input_id,types,maskstokens[input_ids],tokens[token_type_ids],tokens[attention_mask]input_ids.append(input_id)input_types.append(types)input_masks.append(masks)y_self.label_dict[label]labels.append([y_])ifindex%10000:print(处理,index,条数据)# 构建 TensorDatasetdata_genTensorDataset(torch.LongTensor(np.array(input_ids)),torch.LongTensor(np.array(input_types)),torch.LongTensor(np.array(input_masks)),torch.LongTensor(np.array(labels)))# 打乱samplerRandomSampler(data_gen)# 构建 DataLoaderreturnDataLoader(data_gen,samplersampler,batch_sizeself.batch_size)defgen_train_data(self):# 生成训练集returnself.gen_data(self.train_file)defgen_val_data(self):# 生成验证集returnself.gen_data(self.val_file)2.2 构建模型迭代训练importtorchfromtransformersimportAutoTokenizer,AutoModelForSequenceClassificationimporttorch.nnasnnfromtqdmimporttqdmfromgen_datasetsimportGenDateSet# 标签结构label_dict{fear:0,neutral:1,sad:2,surprise:3,angry:4,happy:5}# 预训练模型位置model_dirD:\\AIGC\\model\\chinese-roberta-wwm-ext# 这里暂时使用测试集训练数据较少train_filedata/usual_train.txt# train_file data/usual_test_labeled.txt# 验证集val_filedata/virus_eval_labeled.txt# 训练模型存储位置save_model_path./model/# 最大长度max_length128# 分类数num_classes6batch_size10epoch10defval(model,device,data):model.eval()test_loss0.0acc0for(input_id,types,masks,y)intqdm(data):input_id,types,masks,yinput_id.to(device),types.to(device),masks.to(device),y.to(device)withtorch.no_grad():y_model(input_id,token_type_idstypes,attention_maskmasks)logitsy_[logits]test_lossnn.functional.cross_entropy(logits,y.squeeze())predlogits.max(-1,keepdimTrue)[1]accpred.eq(y.view_as(pred)).sum().item()test_loss/len(data)returnacc/len(data.dataset)defmain():# 加载 tokenizer 和 modeltokenizerAutoTokenizer.from_pretrained(model_dir)modelAutoModelForSequenceClassification.from_pretrained(model_dir,num_labelsnum_classes)# 加载数据集datesetGenDateSet(tokenizer,train_file,val_file,label_dict,max_length,batch_size)# 训练集train_datadateset.gen_train_data()# 验证集val_datadateset.gen_val_data()devicetorch.device(cudaiftorch.cuda.is_available()elsecpu)model.train()modelmodel.to(device)# 优化器optimizertorch.optim.Adam(model.parameters(),lr1e-5)best_acc0.0forepoch_indexinrange(epoch):batch_epoch0for(input_id,types,masks,y)intqdm(train_data):input_id,types,masks,yinput_id.to(device),types.to(device),masks.to(device),y.to(device)# 前向传播outputsmodel(input_id,token_type_idstypes,attention_maskmasks,labelsy)# 梯度清零optimizer.zero_grad()# 计算 losslossoutputs.loss# 反向传播loss.backward()optimizer.step()batch_epoch1ifbatch_epoch%100:print(Train Epoch:,epoch_index, , batch_epoch: ,batch_epoch, , loss ,loss.item())# 评估准确度accval(model,device,val_data)print(Train Epoch:,epoch_index, val acc ,acc)# 存储 best modelifbest_accacc:# torch.save(model.state_dict(), save_model_path)model.save_pretrained(./model)tokenizer.save_pretrained(./model)best_accaccif__name____main__:main()运行之后可以看到训练进度训练中可以看到验证集的准确率等待训练结束后可以在model下看到保存的模型和tokenizer文件三、模型测试importtorchfromtransformersimportAutoTokenizer,AutoModelForSequenceClassification label_dict{0:恐惧,1:无情绪,2:悲伤,3:惊奇,4:愤怒,5:积极}model_dir./modelnum_classes6max_length128defmain():# 加载预训练模型和分词器tokenizerAutoTokenizer.from_pretrained(model_dir)modelAutoModelForSequenceClassification.from_pretrained(model_dir,num_labelsnum_classes)whileTrue:textinput(请输入内容: \n )ifnottextortext:continueiftextq:breakencoded_inputtokenizer(text,paddingmax_length,truncationTrue,max_lengthmax_length)input_idstorch.tensor([encoded_input[input_ids]])token_type_idstorch.tensor([encoded_input[token_type_ids]])attention_masktorch.tensor([encoded_input[attention_mask]])# 前向传播y_model(input_ids,token_type_idstoken_type_ids,attention_maskattention_mask)outputy_[logits][0]predoutput.max(-1,keepdimTrue)[1][0].item()print(预测结果,label_dict[pred])if__name____main__:main()