CCF-BDCI-2021爱奇艺剧本角色情感识别

摘要:

合集:AI案例-自然语言处理-广告和传媒
赛题:大数据与计算智能大赛CCF-BDCI-2021-剧本角色情感识别
AI问题:文本分类
数据集:爱奇艺标注团队针对部分电影剧本的情感标注数据集,包括42,790条训练数据和21,376条测试数据。
数据集发布方:爱奇艺
数据集价值:挖掘海量电影剧本情感标注数据,采用合适的算法精准预测剧本角色情感。
解决方案:支持BERT模型Transformers开发库、chinese-roberta-wwm-ext等5种模型

一、赛题描述

背景

剧本对影视行业的重要性不言而喻。一部好的剧本,不光是好口碑和大流量的基础,也能带来更高的商业回报。剧本分析是影视内容生产链条的第一环,其中剧本角色的情感识别是一个非常重要的任务,主要是对剧本中每句对白和动作描述中涉及到的每个角色从多个维度进行分析并识别出情感。相对于通常的新闻、评论性文本的情感分析,有其独有的业务特点和挑战。

任务

本赛题提供一部分电影剧本作为训练集,训练集数据已由人工进行标注,参赛队伍需要对剧本场景中每句对白和动作描述中涉及到的每个角色的情感从多个维度进行分析和识别。该任务的主要难点和挑战包括:

1)剧本的行文风格和通常的新闻类语料差别较大,更加口语化;

2)剧本中角色情感不仅仅取决于当前的文本,对前文语义可能有深度依赖。

二、数据集描述

数据说明

训练数据:训练数据(train.tsv)为txt格式,以英文制表符分隔,首行为表头,字段说明如下:

字段名称类型描述说明
idString数据ID
contentString文本内容剧本对白或动作描写
characterString角色名文本中提到的角色
emotionString情感识别结果(按顺序)爱情感值,乐情感值,惊情感值,怒情感值,恐情感值,哀情感值

备注: 1)本赛题的情感定义共6类(按顺序):爱、乐、惊、怒、恐、哀; 2)情感识别结果:上述6类情感按固定顺序对应的情感值,情感值范围是[0, 1, 2, 3],0-没有,1-弱,2-中,3-强,以英文半角逗号分隔; 3)本赛题不需要识别剧本中的角色名; 文件编码:UTF-8 无BOM编码

数据样例如下,格式为:”id, content, character, emotion(love, joy, fright, anger, fear,sorrow)”

1171_0001_A_1   天空下着暴雨,o2正在给c1穿雨衣,他自己却只穿着单薄的军装,完全暴露在大雨之中。   o2  0,0,0,0,0,0
1171_0001_A_3 o2一手拿着一个行李,一路小跑着把c1带到了文工团门口。 o2 0,0,0,0,0,0
1171_0001_A_5 o2停下来接过c1手里的行李:你妈妈交待我了,等领了军装一定要照张相寄回去,让街坊邻居都知道你当兵了。 o2 0,0,0,0,0,0
1171_0001_A_7 c1开心地点了点头。 c1 0,1,0,0,0,0
...

测试数据:测试数据(test.tsv)为txt格式,以英文制表符分隔,首行为表头,字段说明如下:

字段名称类型描述说明
idString数据ID
contentString文本内容剧本对白或动作描写
characterString角色名文本中提到的角色

文件编码:UTF-8 无BOM编码

数据集版权许可协议

BY-NC-SA 4.0
数据集发布方:爱奇艺
https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh-hans

三、解决方案样例

工作原理介绍

源码:

  • data/dataset.py:主要用于对原始剧本数据进行排序和预处理,生成适合情感分析模型训练的格式。
  • baseline.py:这是一个基于BERT架构的情感分析模型,用于预测文本中的多种情感(love, joy, fright, anger, fear, sorrow)。

解决方案采用多种分类模型:

  • chinese-roberta-wwm-ext
  • albert_chinese_base
  • bert-base-chinese
  • chinese-macbert-base
  • ernie-1.0

Chinese-RoBERTa-wwm-ext主要特点

Chinese-RoBERTa-wwm-ext是一种针对中文自然语言处理任务优化的预训练语言模型,由哈工大讯飞联合实验室(HFL)开发。它是目前中文NLP领域最强大的预训练模型之一。

1. 基础架构​​

  • RoBERTa架构​​:基于Facebook RoBERTa模型的改进版
  • 大规模参数​​:”Large”版本有24层Transformer,1024隐藏单元
  • 动态掩码​​:每次训练时动态生成掩码,增强训练效果

2. ​​训练技术​​

  • 全词掩码(Whole Word Masking)​​:将整个汉字词作为一个单元进行掩码
  • 更大规模训练​​:使用额外40GB中文语料进行预训练(相比基础版)
  • 更长的序列长度​​:支持最大512个token的输入序列

3. ​​性能优势​​

  • 在几乎所有中文NLP基准测试中刷新记录
  • 特别擅长处理长文本和复杂语言结构
  • 在少样本学习(few-shot learning)场景表现优异。

运行环境

参考文章:《安装深度学习框架PyTorch》和《安装Huggingface-Transformers》

外部库名称版本号
python3.7.12
pandas1.3.5
numpy1.21.6
transformers4.26.1
torch1.13.1

四、dataset.py工作流程

输入文件

  • train.tsv:原始训练数据文件
  • test.tsv:原始测试数据文件

这些文件包含以下字段(以制表符分隔):

  • 第一列:ID(格式为剧本ID_场景ID_角色ID_句子ID
  • 第二列:文本内容
  • 第三列:角色名称(训练集还有第四列:情感标签)

输出文件

  1. 排序后的中间文件
    • train_sort.tsv:按剧本ID、场景ID、句子ID排序后的训练数据
    • test_sort.tsv:按剧本ID、场景ID、句子ID排序后的测试数据
  2. 最终输出文件
    • train_final.tsv:预处理后的最终训练数据文件。格式:ID\t处理后的文本\t情感标签
    • test_final.tsv:预处理后的最终测试数据文件。格式:ID\t处理后的文本

数据样例:train_final.tsv

1171_0001_A_1   (角色是:o2)天空下着暴雨,o2正在给c1穿雨衣,他自己却只穿着单薄的军装,完全暴露在大雨之中。   0,0,0,0,0,0
1171_0001_A_2 (角色是:c1)天空下着暴雨,o2正在给c1穿雨衣,他自己却只穿着单薄的军装,完全暴露在大雨之中。 0,0,0,0,0,0
1171_0001_A_3 天空下着暴雨,o2正在给c1穿雨衣,他自己却只穿着单薄的军装,完全暴露在大雨之中。(角色是:o2)o2一手拿着一个行李,一路小跑着把c1带到了文工团门口。 0,0,0,0,0,0

五、baseline.py工作流程

这是一个基于BERT架构的情感分析模型,用于预测文本中的多种情感(love, joy, fright, anger, fear, sorrow)。下面我将分析其主要工作原理:

1. 导入开发包

包括Hugging Face Transformers 库中与 BERT 模型相关的几个重要类和函数:

  1. BertPreTrainedModel – BERT 预训练模型基类,所有基于 BERT 的模型都继承自此类
  2. BertTokenizer – BERT 分词器,用于将文本转换为 BERT 模型可以理解的 token ID
  3. BertConfig – BERT 模型配置类,包含模型架构的各种参数
  4. BertModel – 基本的 BERT 模型类
  5. AutoConfig – 自动配置类,可以根据模型名称自动加载对应的配置
from tqdm import tqdm
import pandas as pd
import csv
import os
from functools import partial
import numpy as np
import time

import torch
import torch.nn as nn
import torch.nn.functional as F

from torch.optim import AdamW
from torch.utils.data import DataLoader
from torch.utils.data.dataset import Dataset
from transformers import BertPreTrainedModel, BertTokenizer, BertConfig, BertModel, AutoConfig
from functools import partial
from transformers import get_linear_schedule_with_warmup

2. 参数解析

PRETRAINED_MODEL_LIST = ['./model/chinese-roberta-wwm-ext',
                        './model/albert_chinese_base',
                        './model/bert-base-chinese',
                        './model/chinese-macbert-base',
                        './model/ernie-1.0']

parser = argparse.ArgumentParser()
parser.add_argument('--regenerate_data', action="store_true", default=False)
parser.add_argument('--bert_id', type=int, default=0, help="0 is roberta, 1 is ernie, 2 is base.")
parser.add_argument('--validation', action="store_true", default=False)
parser.add_argument('--no_train', action="store_true", default=False)
args = parser.parse_args()

3. 数据预处理

  • 检查是否需要重新生成数据(args.regenerate_data或文件不存在)
  • 从TSV文件中加载原始数据(train_final.tsv和test_final.tsv)
  • 将情感标签从逗号分隔的字符串转换为数值列表(如”1,0,0,0,0,0″ → [1,0,0,0,0,0])
  • 将处理后的数据保存为CSV格式(train.csv和test.csv)
# 加载数据
if args.regenerate_data or (not os.path.exists('data/train.csv') or not os.path.exists('data/test.csv')):
   print("########################### [ process train and test data and store them in csv format ] ###########################")
   with open('data/train_final.tsv', 'r', encoding='utf-8') as handler:
       lines = handler.read().split('\n')[1:-1]

       data = list()
       for line in tqdm(lines):
           sp = line.split('\t')
           if len(sp) != 3:
               print("Error: ", sp)
               continue
           data.append(sp)

   train = pd.DataFrame(data)
   train.columns = ['id', 'content', 'emotions']

   test = pd.read_csv('data/test_final.tsv', sep='\t')
   test.columns = ['id', 'content']
   submit = pd.read_csv('data/submit_example.tsv', sep='\t')
   train = train[train['emotions'] != '']

   # 数据处理
   train['text'] = train['content'].astype(str)
   test['text'] = test['content'].astype(str)

   train['emotions'] = train['emotions'].apply(lambda x: [int(_i) for _i in x.split(',')])

   train[['love', 'joy', 'fright', 'anger', 'fear', 'sorrow']] = train['emotions'].values.tolist()
   test[['love', 'joy', 'fright', 'anger', 'fear', 'sorrow']] =[0,0,0,0,0,0]

   train.to_csv('data/train.csv',columns=['id','text','love', 'joy', 'fright', 'anger', 'fear', 'sorrow'],
               sep='\t',
               index=False)

   test.to_csv('data/test.csv',columns=['id','text','love', 'joy', 'fright', 'anger', 'fear', 'sorrow'],
               sep='\t',
               index=False)

4. 数据集类定义 (RoleDataset)

RoleDataset 是一个继承自 torch.utils.data.Dataset 的自定义数据集类,用于加载和处理训练数据和测试数据。

  • 读取处理后的CSV数据,分别为 data/train.csv 和 data/test.csv。
  • 使用tokenizer对文本编码
  • 将情感标签归一化(除以3.0)
  • 返回包含”归一化标签”等内容的字典

RoleDataset定义如下:

# 定义dataset
target_cols=['love', 'joy', 'fright', 'anger', 'fear', 'sorrow']

# from torch.utils.data.dataset import Dataset
class RoleDataset(Dataset):
   def __init__(self, tokenizer, max_len, mode='train'):
       super(RoleDataset, self).__init__()
       if mode == 'train':
           self.data = pd.read_csv('data/train.csv',sep='\t', quoting=csv.QUOTE_NONE)
       else:
           self.data = pd.read_csv('data/test.csv',sep='\t', quoting=csv.QUOTE_NONE)

       self.texts=self.data['text'].tolist()
       self.labels=self.data[target_cols].to_dict('records')
       self.tokenizer = tokenizer
       self.max_len = max_len

   def __getitem__(self, index):
       text=str(self.texts[index])
       label=self.labels[index]

       encoding=self.tokenizer.encode_plus(text,
                                           add_special_tokens=True,
                                           max_length=self.max_len,
                                           return_token_type_ids=True,
                                           pad_to_max_length=True,
                                           return_attention_mask=True,
                                           return_tensors='pt',)

       sample = {
           'texts': text,
           'input_ids': encoding['input_ids'].flatten(),
           'attention_mask': encoding['attention_mask'].flatten()
      }

       for label_col in target_cols:
           sample[label_col] = torch.tensor(label[label_col]/3.0, dtype=torch.float)
       return sample

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

获取数据集加载实例train_loader和valid_loader 的调用如下:

trainset = RoleDataset(tokenizer, max_len, mode='train')
print(len(trainset))
train_loader = create_dataloader(trainset, batch_size, mode='train')

valset = RoleDataset(tokenizer, max_len, mode='test')
print(len(valset))
valid_loader = create_dataloader(valset, batch_size, mode='test')

输出的数据集的每个批次(batch_size=配置值)是一个字典,包含以下键:

  • texts:原始文本列表(长度为 batch_size 的字符串列表)。
  • input_ids:编码后的 token IDs(形状为 [batch_size, max_len] 的张量)。
  • attention_mask:注意力掩码(形状为 [batch_size, max_len] 的张量)。
  • 每个标签labels (如 lovejoy 等):为归一化后的标签值(形状为 [batch_size] 的张量)。

其中batch_size为每次前向传播(Forward Pass)和反向传播(Backward Pass)时同时处理的样本数量。取值为8, 16等。

例如,输入数据样例为:

id  text    love    joy fright  anger   fear    sorrow
1171_0001_A_2 (角色是:c1)天空下着暴雨,o2正在给c1穿雨衣,他自己却只穿着单薄的军装,完全暴露在大雨之中。 0 0 0 0 0 0
1171_0001_A_3 天空下着暴雨,o2正在给c1穿雨衣,他自己却只穿着单薄的军装,完全暴露在大雨之中。(角色是:o2)o2一手拿着一个行李,一路小跑着把c1带到了文工团门口。 0 0 0 0 0 0

RoleDataset.getitem() 输出的数据样例:

{
   'texts': '示例文本',
   'input_ids': tensor([101, 1234, 5678, 102, 0, ..., 0]), # 填充到 max_len
   'attention_mask': tensor([1, 1, 1, 1, 0, ..., 0]),       # 注意力掩码(1表示有效token,0表示填充)
   'love': tensor(0.3333),   # 1 / 3.0
   'joy': tensor(0.6667),   # 2 / 3.0
   'fright': tensor(0.0),   # 0 / 3.0
   'anger': tensor(0.3333), # 1 / 3.0
   'fear': tensor(0.0),     # 0 / 3.0
   'sorrow': tensor(0.3333) # 1 / 3.0
}

在 RoleDataset 类中,self.labels 是通过 self.data[target_cols].to_dict(‘records’) 生成的,其数据结构是 一个字典列表,每个字典对应一条样本的标签数据。self.texts 和 self.labels 通过相同的索引一一对应。例如:

texts = ["这部电影很棒", "有点吓人"]
labels = [
  {'love': 1, 'joy': 2, ...},
  {'love': 0, 'joy': 0, ...}
]

5. 模型架构 (IQIYModelLite)

核心模型IQIYModelLite包含以下组件:

BERT基础模型

  • 使用预训练的BERT模型(可从多个中文BERT变体中选择)
  • 配置为输出所有隐藏层状态

注意力机制

  • 一个简单的两层神经网络加softmax,用于计算每个token的重要性权重
  • 通过加权求和得到上下文向量

多任务输出层

  • 建立6个独立的全连接层,分别对应6种情感
  • 每个输出层直接从上下文向量预测对应情感强度

参数初始化函数 init_params 用于对神经网络模块的参数进行 Xavier 均匀分布初始化。函数功能 作用是对给定的神经网络模块列表进行参数初始化。初始化方法为使用 Xavier (Glorot) 均匀分布初始化 (torch.nn.init.xavier_uniform_),适用于全连接层和卷积层等。

# 参数初始化
def init_params(module_lst):
   for module in module_lst:
       for param in module.parameters():
           if param.dim() > 1:
               torch.nn.init.xavier_uniform_(param)
   return

关于模型 IQIYModelLite 的定义:

  • nn.Module 是所有PyTorch神经网络模块的基类,通过继承它来构建自定义模型。通过 import torch.nn as nn 引入。
  • 虽然模型有 6 个头,但 n_classes 是每个头的输出维度。因为每个情感只需预测一个值为二分类代表是否包括该情感,则 n_classes=1
# 模型构建
class IQIYModelLite(nn.Module):
   def __init__(self, n_classes, model_name):
       super(IQIYModelLite, self).__init__()
       config = AutoConfig.from_pretrained(model_name)
       config.update({"output_hidden_states": True,
                      "hidden_dropout_prob": 0.0,
                      "layer_norm_eps": 1e-7})

       self.base = BertModel.from_pretrained(model_name, config=config)

       dim = 1024 if 'large' in model_name else 768

       self.attention = nn.Sequential(
           nn.Linear(dim, 512),
           nn.Tanh(),
           nn.Linear(512, 1),
           nn.Softmax(dim=1)
      )
       # self.attention = AttentionHead(h_size=dim, hidden_dim=512, w_drop=0.0, v_drop=0.0)

       self.out_love = nn.Sequential(
           nn.Linear(dim, n_classes)
      )
       self.out_joy = nn.Sequential(
           nn.Linear(dim, n_classes)
      )
       self.out_fright = nn.Sequential(
           nn.Linear(dim, n_classes)
      )
       self.out_anger = nn.Sequential(
           nn.Linear(dim, n_classes)
      )
       self.out_fear = nn.Sequential(
           nn.Linear(dim, n_classes)
      )
       self.out_sorrow = nn.Sequential(
           nn.Linear(dim, n_classes)
      )

       init_params([self.out_love, self.out_joy, self.out_fright, self.out_anger,
                    self.out_fear,  self.out_sorrow, self.attention])

实例化:

PRE_TRAINED_MODEL_NAME = PRETRAINED_MODEL_LIST[args.bert_id]
model = IQIYModelLite(n_classes=1, model_name=PRE_TRAINED_MODEL_NAME)

6. 训练准备

  • 创建训练集/测试集DataLoader
  • 损失函数:使用BCEWithLogitsLoss(二元交叉熵损失,带sigmoid)
  • 设置优化器和学习率调度器:AdamW,带线性学习率warmup
  • 初始化模型并移至GPU
trainset = RoleDataset(tokenizer, max_len, mode='train')
print(len(trainset))
train_loader = create_dataloader(trainset, batch_size, mode='train')

valset = RoleDataset(tokenizer, max_len, mode='test')
print(len(valset))
valid_loader = create_dataloader(valset, batch_size, mode='test')

model = IQIYModelLite(n_classes=1, model_name=PRE_TRAINED_MODEL_NAME)
model.cuda()

if torch.cuda.device_count()>1:
   model = nn.DataParallel(model)

optimizer = AdamW(model.parameters(), lr=lr, weight_decay=weight_decay) # correct_bias=False,
total_steps = len(train_loader) * EPOCHS

scheduler = get_linear_schedule_with_warmup(
 optimizer,
 num_warmup_steps=warm_up_ratio*total_steps,
 num_training_steps=total_steps
)

criterion = nn.BCEWithLogitsLoss().cuda()

7. 训练循环 (do_train)

训练循环:

  • 计算6种情感各自的损失并求和
  • 反向传播更新参数
  • 定期打印训练状态:每100步打印训练进度
  • 保存模型检查点:每个epoch保存模型
# 模型训练
def do_train(model, date_loader, criterion, optimizer, scheduler, metric=None):
   model.train()
   global_step = 0
   tic_train = time.time()
   log_steps = 100
   for epoch in range(EPOCHS):
       losses = []
       for step, sample in enumerate(date_loader):
           input_ids = sample["input_ids"].cuda()
           attention_mask = sample["attention_mask"].cuda()

           outputs = model(input_ids=input_ids, attention_mask=attention_mask)

           loss_love = criterion(outputs['love'], sample['love'].view(-1, 1).cuda())
           loss_joy = criterion(outputs['joy'], sample['joy'].view(-1, 1).cuda())
           loss_fright = criterion(outputs['fright'], sample['fright'].view(-1, 1).cuda())
           loss_anger = criterion(outputs['anger'], sample['anger'].view(-1, 1).cuda())
           loss_fear = criterion(outputs['fear'], sample['fear'].view(-1, 1).cuda())
           loss_sorrow = criterion(outputs['sorrow'], sample['sorrow'].view(-1, 1).cuda())
           loss = loss_love + loss_joy + loss_fright + loss_anger + loss_fear + loss_sorrow

           losses.append(loss.item())
           loss.backward()

           optimizer.step()
           scheduler.step()
           optimizer.zero_grad()
           global_step += 1

           if global_step % log_steps == 0:
               print("global step %d, epoch: %d, batch: %d, loss: %.5f, speed: %.2f step/s, lr: %.10f"
                     % (global_step, epoch, step, np.mean(losses), global_step / (time.time() - tic_train),
                        float(scheduler.get_last_lr()[0])))
       state = {
           'state': model.state_dict(),
           'epoch': epoch
      }
       torch.save(state, 'iqiyi_model_{}.ckpt'.format(str(epoch)))

调用模型训练函数。其中训练数据集为 train_loader。

if args.no_train:
   checkpoint = torch.load('iqiyi_model_0.ckpt')
   model.load_state_dict(checkpoint['state'])
else:
   do_train(model, train_loader, criterion, optimizer, scheduler)

8. 预测流程

代码:model.eval(),将模型切换到评估模式(关闭 Dropout 和 BatchNorm 的随机性)。确保预测结果稳定,不受训练阶段随机操作的影响。

函数 predict()

  • 加载训练好的模型
  • 对测试集进行预测
  • 将预测结果通过sigmoid并乘以3.0还原到原始评分范围
  • 生成符合提交格式的TSV文件

关键点:

  1. 评估模式:必须调用 model.eval()torch.no_grad()
  2. 数据移动:输入数据需通过 .cuda() 移到 GPU。
  3. 预测结果 logists 的数据类型为 Dict[str, torch.Tensor],为一个字典,键是标签名(如 ‘love’, ‘joy’ 等,对应 target_cols),值是对应标签的原始情感值。
  4. 输出处理:
    • sigmoid() 将 预测结果值 logists 转为概率值。
    • * 3.0 还原到原始标签范围。
  5. 结果存储:字典按标签名组织预测值,方便后续拼接。
model.eval()

def predict(model, test_loader):
   val_loss = 0
   test_pred = defaultdict(list)
   model.eval()
   model.cuda()
   for  batch in tqdm(test_loader):
       b_input_ids = batch['input_ids'].cuda()
       attention_mask = batch["attention_mask"].cuda()
       with torch.no_grad():
           logists = model(input_ids=b_input_ids, attention_mask=attention_mask)
           for col in target_cols:
               out2 = logists[col].sigmoid().squeeze(1)*3.0
               test_pred[col].extend(out2.cpu().numpy().tolist())

   return test_pred

# 加载submit
submit = pd.read_csv('data/submit_example.tsv', sep='\t')
test_pred = predict(model, valid_loader)

假设 target_cols = ['love', 'joy', 'fright']test_pred 的结构如下:

{
  'love': [1.2, 0.8, 2.3, ...], # 每条样本的预测值(还原情感取值范围为0-3)
  'joy': [0.5, 2.7, 1.1, ...],
  'fright': [2.8, 0.2, 1.5, ...],
  ...
}

9. 关键特点

  1. 多模型支持:通过--bert_id参数可以选择不同的预训练模型
  2. 多任务学习:同时预测6种情感,共享BERT编码层但使用独立输出层
  3. 注意力机制:在BERT最后一层隐藏状态上应用注意力,增强关键信息
  4. 命令行参数:
    • --regenerate_data:强制重新生成CSV数据
    • --validation:启用验证模式
    • --no_train:跳过训练直接预测

样例运行展示

1、原始数据集预处理

将 dataset.py 放在 ./data 目录下,并执行如下命令: python dataset.py

2、运行基线代码

执行如下命令:python baseline.py –bert_id 0

36781
21375

global step 100, epoch: 0, batch: 99, loss: 1.29497, speed: 0.22 step/s, lr: 0.0000099728
global step 200, epoch: 0, batch: 199, loss: 1.23105, speed: 0.21 step/s, lr: 0.0000099456
global step 300, epoch: 0, batch: 299, loss: 1.27569, speed: 0.21 step/s, lr: 0.0000099184
global step 400, epoch: 0, batch: 399, loss: 1.22632, speed: 0.21 step/s, lr: 0.0000098912
...
global step 19500, epoch: 0, batch: 19499, loss: 0.90920, speed: 0.19 step/s, lr: 0.0000046983
global step 19600, epoch: 0, batch: 19599, loss: 0.90861, speed: 0.19 step/s, lr: 0.0000046712
global step 19700, epoch: 0, batch: 19699, loss: 0.90739, speed: 0.19 step/s, lr: 0.0000046440
global step 19800, epoch: 0, batch: 19799, loss: 0.90712, speed: 0.19 step/s, lr: 0.0000046168

输出信息解析:

字段含义详细说明
global step 100全局训练步数从训练开始累计每100条训练数据打印一次。
epoch: 0当前轮次模型正在训练第0轮。代码中设置EPOCHS=1,表示模型完整遍历整个训练数据集的次数。
batch: 99当前批次当前轮次中第99条数据(注意:batch编号从0开始,实际是第100条数据)。
loss: 1.29497当前损失值最近一个batch的多标签分类损失(6个标签的BCEWithLogitsLoss总和)。
speed: 0.22 step/s训练速度每秒完成0.22个训练步骤(即约4.5秒/step),受GPU性能、数据加载等影响。
lr: 0.0000099728当前学习率优化器当前的学习率(初始lr=1e-5,因使用warmup调度器略有变化)。

源码开源协议

GPL-v3

六、获取案例套装

需要登录后才允许下载文件包。登录

发表评论