datafountain剧本角色情感分析赛后总结
比赛链接
源码地址
本次我与抖音大佬共同组队参加了剧本角色情感识别的比赛,成绩为二十多名的水平,这个成绩距离前排大佬还有一定的差距,因此我们需要进行一定的反思总结。
模型的搭建
第一个遇到的问题是模型的搭建问题,起初我们的想法是采用常规的分类做法,搭6个网络层,对于每一个网络层使用交叉熵损失函数进行模型训练,但是在这个比赛上这种方式指标并不佳。原因在于本次比赛采用了均方根误差的方式来计算评分,所以使用mse作为损失函数效果较好。
这里也提醒我们,在打比赛的过程之中一定要采用更加贴合评测指标的损失函数进行训练。
修改了模型结构之后,我们选用nezha后面接上一个(768,6)的线性层进行回归计算,效果有明显的提升。
在比赛的过程中,我们还实验过其他结构,比如多个线性层加上dropout
class ClassificationModel(nn.Module):
def __init__(self,model,config,n_labels):
super(ClassificationModel,self).__init__()
#self.embedding = nn.Embedding(30522,768)
self.model = model
self.fc1 = nn.Linear(config.embedding_size,128)
self.activation = F.relu
self.dropout = nn.Dropout(0.2)
#self.activation = F.tanh
self.fc2 = nn.Linear(128,n_labels)
def forward(self,input_ids,segment_ids,input_mask):
#outputs = self.embedding(input_ids)
output = self.model(input_ids)
#[64,128,768]
output = self.dropout(output)
output = output[:,0]
output = self.fc1(output)
output = self.activation(output)
output = self.dropout(output)
output = self.fc2(output)
return output
整体效果与(768,6)线性层效果差不多,另外使用这种结构训练之后进行融合模型结果也没有明显的上升。
整数与浮点数提交之争
对于mse损失函数,有一个必要的特性,就是当你的值越远离增加标签的时候,每远离一步就会放大误差,这里举一个例子来说明
如果真实标签为1的时候,假设标签距离都为0.1
1.本身预测为0.9,放缩为1
减小误差 ( 1 − 0.9 ) 2 − ( 1 − 1 ) 2 = 0.01 (1-0.9)^2 - (1-1)^2 = 0.01 (1−0.9)2−(1−1)2=0.01
2.本身预测为1.9,放缩为2
增大误差 ( 2 − 1 ) 2 − ( 1.9 − 1 ) 2 = 1 − 0.81 = 0.19 (2-1)^2-(1.9-1)^2 =1-0.81 = 0.19 (2−1)2−(1.9−1)2=1−0.81=0.19
可以看出来情形2比情形1放大了19倍
这也就是我们为什么选择浮点数提交的原因
有些标签计算的可能有向正确标签的趋势,但是由于模型学习能力所限未能够达到正确的标签,此时如果选择整数提交的话,可能这一部分数据过大会拉大误差,因此这里我们选择浮点数进行提交
上下文的选择以及主语的加入
如果想要模型学习充分,必须加入所有的特征。
首先我们必须加入主语部分,因为同一句可能包含不同的主语。
其次我们需要加入上下文部分,因为上下文的情感同样也可能影响当前的情感。
对于上文加入,我们有以下几种策略:
1.加入上文不同角色的5句话(可以是n句话,大致4~6句最佳)
2.加入上文同一角色的多句话(可以是n句话,也可以全加)
实验的过程中发现策略1效果更好,猜测可能是由于方案2中的加入多句话有的时候距离较远,可能影响模型对于情感的判断。
同时跨幕在实验中发现结果会下降,说明上一幕的情感并不会影响到本幕的情感。
验证集和测试集的划分问题
验证集和测试集的划分有两种方式:一种是按照不同的情感来进行划分,另外一种是不同的剧本来进行划分。官方的baseline推荐的是按照剧本进行划分,这里我们尝试了两种方案,发现两种方案线上线下都有较大的差距,相对来讲按照剧本划分可能更好一些,因为按照标签划分前面有一些句子可能在模型中训练过了。
多折模型训练及模型融合的方法
通过实验,我们选择按照剧本划分多折,每一折选择3个剧本,总共为10折的过程,模型融合采用平均融合的方式,单折多模可以提升到0.707x的水平。
模型融合的时候应该选择分数相近的模型进行融合,才能有效的提升分数。针对mse一般采用平均融合的方法
之所以可以采用平均的模型融合方法,这里通过举例说明一下:
由于两个模型预测结果分数相近,假设第一个模型对于标签1的距离为0.75,对于标签2的距离为0.25,第二个模型对于标签1的距离为0.25,对于标签2的距离为0.75,则这两个模型的mse均为 1 2 ∗ ( 0.7 5 2 + 0.2 5 2 ) \frac{1}{2}*(0.75^2+0.25^2) 21∗(0.752+0.252),而融合之后两个标签的距离均为0.5, m s e = 1 2 ∗ ( 0. 5 2 + 0. 5 2 ) < 1 2 ∗ ( 0.7 5 2 + 0.2 5 2 ) mse = \frac{1}{2}*(0.5^2+0.5^2) < \frac{1}{2}*(0.75^2+0.25^2) mse=2