CCF BDCI 剧本角色情感识别:多目标学习开源方案

简介: CCF BDCI 剧本角色情感识别:多目标学习开源方案

1、赛题名称


剧本角色情感识别

比赛链接:https://www.datafountain.cn/competitions/518


2、赛题背景


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


3、赛题任务


本赛题提供一部分电影剧本作为训练集,训练集数据已由人工进行标注,参赛队伍需要对剧本场景中每句对白和动作描述中涉及到的每个角色的情感从多个维度进行分析和识别。该任务的主要难点和挑战包括:1)剧本的行文风格和通常的新闻类语料差别较大,更加口语化;2)剧本中角色情感不仅仅取决于当前的文本,对前文语义可能有深度依赖。


4 数据简介


比赛的数据来源主要是一部分电影剧本,以及爱奇艺标注团队的情感标注结果,主要用于提供给各参赛团队进行模型训练和结果验证使用。


数据说明


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

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


备注:

  1)本赛题的情感定义共6类(按顺序):爱、乐、惊、怒、恐、哀;

  2)情感识别结果:上述6类情感按固定顺序对应的情感值,情感值范围是[0, 1, 2, 3],0-没有,1-弱,2-中,3-强,以英文半角逗号分隔;

  3)本赛题不需要识别剧本中的角色名;

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


5 评估标准


本赛题算法评分采用常用的均方根误差(RMSE)来计算评分,按照“文本内容+角色名”识别出的6类情感对应的情感值来统计。


32.png


score = 1/(1 + RMSE)

其中是yi,j预测的情感值,xi,j是标注的情感值,n是总的测试样本数。

最终按score得分来排名。


6 基于预训练模型的对目标学习


这个题目可操作的地方有很多,一开始见到这个比赛的时候见想到了multi outputs的模型构建,这里给大家分享下这个基线,希望有大佬能够针对这个思路优化上去~


6.1 加载数据


首先读取数据

with open('data/train_dataset_v2.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) != 4:
            print("ERROR:", sp)
            continue
        data.append(sp)
train = pd.DataFrame(data)
train.columns = ['id', 'content', 'character', 'emotions']
test = pd.read_csv('data/test_dataset.tsv', sep='\t')
submit = pd.read_csv('data/submit_example.tsv', sep='\t')
train = train[train['emotions'] != '']


提取情感目标

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()


6.2 构建数据集


数据集的标签一共有六个:

class RoleDataset(Dataset):
    def __init__(self,texts,labels,tokenizer,max_len):
        self.texts=texts
        self.labels=labels
        self.tokenizer=tokenizer
        self.max_len=max_len
    def __len__(self):
        return len(self.texts)
    def __getitem__(self,item):
        """
        item 为数据索引,迭代取第item条数据
        """
        text=str(self.texts[item])
        label=self.labels[item]
        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',
        )
#         print(encoding['input_ids'])
        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], dtype=torch.float)
        return sample


6.3 模型构建


33.png

class EmotionClassifier(nn.Module):
    def __init__(self, n_classes):
        super(EmotionClassifier, self).__init__()
        self.bert = BertModel.from_pretrained(PRE_TRAINED_MODEL_NAME)
        self.out_love = nn.Linear(self.bert.config.hidden_size, n_classes)
        self.out_joy = nn.Linear(self.bert.config.hidden_size, n_classes)
        self.out_fright = nn.Linear(self.bert.config.hidden_size, n_classes)
        self.out_anger = nn.Linear(self.bert.config.hidden_size, n_classes)
        self.out_fear = nn.Linear(self.bert.config.hidden_size, n_classes)
        self.out_sorrow = nn.Linear(self.bert.config.hidden_size, n_classes)
    def forward(self, input_ids, attention_mask):
        _, pooled_output = self.bert(
            input_ids=input_ids,
            attention_mask=attention_mask,
            return_dict = False
        )
        love = self.out_love(pooled_output)
        joy = self.out_joy(pooled_output)
        fright = self.out_fright(pooled_output)
        anger = self.out_anger(pooled_output)
        fear = self.out_fear(pooled_output)
        sorrow = self.out_sorrow(pooled_output)
        return {
            'love': love, 'joy': joy, 'fright': fright,
            'anger': anger, 'fear': fear, 'sorrow': sorrow,
        }


6.4 模型训练


回归损失函数直接选取 nn.MSELoss()

EPOCHS = 1 # 训练轮数
optimizer = AdamW(model.parameters(), lr=3e-5, correct_bias=False)
total_steps = len(train_data_loader) * EPOCHS
scheduler = get_linear_schedule_with_warmup(
  optimizer,
  num_warmup_steps=0,
  num_training_steps=total_steps
)
loss_fn = nn.MSELoss().to(device)


模型总的loss为六个目标值的loss之和

def train_epoch(
  model, 
  data_loader, 
  criterion, 
  optimizer, 
  device, 
  scheduler, 
  n_examples
):
    model = model.train()
    losses = []
    correct_predictions = 0
    for sample in tqdm(data_loader):
        input_ids = sample["input_ids"].to(device)
        attention_mask = sample["attention_mask"].to(device)
        outputs = model(
            input_ids=input_ids,
            attention_mask=attention_mask
        )
        loss_love = criterion(outputs['love'], sample['love'].to(device))
        loss_joy = criterion(outputs['joy'], sample['joy'].to(device))
        loss_fright = criterion(outputs['fright'], sample['fright'].to(device))
        loss_anger = criterion(outputs['anger'], sample['anger'].to(device))
        loss_fear = criterion(outputs['fear'], sample['fear'].to(device))
        loss_sorrow = criterion(outputs['sorrow'], sample['sorrow'].to(device))
        loss = loss_love + loss_joy + loss_fright + loss_anger + loss_fear + loss_sorrow
        losses.append(loss.item())
        loss.backward()
        nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
        optimizer.step()
        scheduler.step()
        optimizer.zero_grad()
#     return correct_predictions.double() / (n_examples*6), np.mean(losses)
    return np.mean(losses)


线上提交0.67+

相关文章
|
16天前
|
机器学习/深度学习 人工智能 智能设计
VisionFM:通用眼科 AI 大模型,具备眼科疾病诊断能力,展现出专家级别的准确性
VisionFM 是一个多模态多任务的视觉基础模型,专为通用眼科人工智能设计。通过预训练大量眼科图像,模型能够处理多种眼科成像模态,并在多种眼科任务中展现出专家级别的智能性和准确性。
63 4
VisionFM:通用眼科 AI 大模型,具备眼科疾病诊断能力,展现出专家级别的准确性
|
10天前
|
人工智能 智能硬件
SPAR:智谱 AI 推出自我博弈训练框架,基于生成者和完善者两个角色的互动,提升了执行准确度和自我完善能力
SPAR 是智谱团队推出的自我博弈训练框架,旨在提升大型语言模型在指令遵循方面的能力,通过生成者和完善者的互动以及树搜索技术优化模型响应。
24 0
SPAR:智谱 AI 推出自我博弈训练框架,基于生成者和完善者两个角色的互动,提升了执行准确度和自我完善能力
|
3月前
|
机器学习/深度学习 测试技术
ACL杰出论文奖:GPT-4V暴露致命缺陷?JHU等发布首个多模态ToM 测试集,全面提升大模型心智能力
【10月更文挑战第6天】约翰斯·霍普金斯大学等机构提出了一项荣获ACL杰出论文奖的研究,旨在解决大模型在心智理论(ToM)上的不足。他们发布了首个MMToM-QA多模态ToM测试集,并提出BIP-ALM方法,从多模态数据中提取统一表示,结合语言模型进行贝叶斯逆规划,显著提升了模型的ToM能力。这一成果为机器与人类自然交互提供了新思路,尽管仍面临一些局限性和技术挑战。论文详情见:https://arxiv.org/abs/2401.08743。
58 6
|
2月前
|
人工智能 自然语言处理 搜索推荐
AI与心理健康:情感支持的新形式
【10月更文挑战第31天】在快节奏的现代生活中,心理健康问题日益突出。AI技术的发展为情感支持提供了新形式,包括心理评估、情感监测、危机干预和个性化咨询。本文探讨了AI在心理健康领域的应用及其对个人和社会的深远影响。
|
5月前
|
人工智能 运维 自然语言处理
从海量信息中脱颖而出:Workflow智能分析解决方案,大语言模型为AI科技文章打造精准摘要评分体系(总篇章)
【8月更文挑战第10天】从海量信息中脱颖而出:Workflow智能分析解决方案,大语言模型为AI科技文章打造精准摘要评分体系(总篇章)
从海量信息中脱颖而出:Workflow智能分析解决方案,大语言模型为AI科技文章打造精准摘要评分体系(总篇章)
|
5月前
|
数据采集 人工智能 数据挖掘
2021 第五届“达观杯” 基于大规模预训练模型的风险事件标签识别】3 Bert和Nezha方案
2021第五届“达观杯”基于大规模预训练模型的风险事件标签识别比赛中使用的NEZHA和Bert方案,包括预训练、微调、模型融合、TTA测试集数据增强以及总结和反思。
50 0
|
机器学习/深度学习 人工智能 自然语言处理
ACL 2022 | 腾讯QQ浏览器实验室提出文本语义匹配训练策略,与PLM结合效率不减
ACL 2022 | 腾讯QQ浏览器实验室提出文本语义匹配训练策略,与PLM结合效率不减
139 0
|
机器学习/深度学习 人工智能 智能设计
基于扩散模型的3D智能创作引擎与内容投放算法最新实践
3D模型在智能设计领域以其可塑性,可编辑性有着属于自己的独特优势,扩展了2D设计的上限。但是其目前存在的局限性也是显而易见的:建模的效率,模型的数量,以及3D设计的成本。
252 0
|
机器学习/深度学习 人工智能 计算机视觉
阿里AI打破视觉对话识别纪录,机器看图说话能力比肩人类
近日, 在第二届视觉对话竞赛Visual Dialogue Challenge中,阿里AI击败了微软、首尔大学等十支参赛队伍,获得冠军。这是阿里巴巴达摩院城市大脑实验室联合阿里巴巴-南洋理工大学联合学院(JRI)等单位取得的又一项世界级技术突破。
1226 0
|
机器学习/深度学习 传感器 人工智能
谷歌 AI 提出双重策略强化学习框架,帮助机器人安全学习动作技能
深度强化学习在自主解决复杂、高维问题方面的前景,引起了机器人、游戏和自动驾驶汽车等领域的极大兴趣。但是,要想有效地进行强化学习策略的训练,需要对大量的机器人状态和行为进行研究。这其中存在一定的安全风险,比如,在训练一个有腿机器人时,由于这类机器人自身不稳定,机器人在学习时很容易发生跌倒,这可能会造成机器人的损害。
332 0
谷歌 AI 提出双重策略强化学习框架,帮助机器人安全学习动作技能

热门文章

最新文章