最近在做意见解释挖掘项目中解释性意见分类任务,尝试将解释性意见分类和意见解释抽取任务联合训练,在这里对最近的工作做一下整理。因为是实验室的自然科学基金项目中的子任务,项目数据暂时还未公开,在这里就不展开介绍具体任务了。
一、思路
解释性意见句的类别是依据意见句中的意见解释的内容进行定义的,那么在对句子进行分类之前,如果模型获取到了意见句中的意见解释信息,是否有助于模型进行分类呢?
同样的,意见解释抽取任务是在意见句中识别句中的意见解释片段,那么在识别片段之前,如果模型获取到了句子的类别特征,是否有助于模型进行片段识别呢?
基于上述的思考,我提出将这两个任务放在一起训练,建立联合模型获取更多的特征用于训练,希望能同时提高这两个模型的效果。
二、设计模型
首先,我需要得到这两个任务的pipeline模型的性能,作为接下来进行联合模型训练时的参照。这里就选用单层的BILSTM模型作为pipeline模型。
然后,联合训练的话大体上有这么两个思路:
1. 先训练分类模型,然后将分类的结果作为新的特征加入片段识别模型中;
2. 先训练片段识别模型,然后将识别出的片段的模型隐层信息作为新的特征加入分类模型中。
其中,分类模型和片段识别模型可以共用一个BILSTM,模型之间可以共享参数,也可以使用不同的BILSTM,两个模型分别训练参数。
三、实验情况
针对前面提到的几点思路,设计了以下几个实验:
3.1 提取分类特征用于片段识别
实验尝试一:
joint-model-5-sgd-200:分类和片段识别使用的是不同的LSTM,用的是SGD优化器,将分类的预测结果embedding之后加入片段识别中。在训练了500轮之后,片段识别再加入分类提取的特征;
joint-model-3-adam:分类和片段识别使用的是不同的LSTM,用的是Adam优化器;
joint-model-4-adam-20:分类和片段识别使用的是不同的LSTM,用的是Adam优化器,分类的特征映射为20维的向量,作为新特征加入片段识别中;
joint-model-4-adam-50:将分类的特征映射改为50维,其他设置与上个模型相同;
joint-model-5-adam-20:分类和片段识别使用的是不同的LSTM,用的是Adam优化器,分类的预测标签embedding之后,作为新特征加入片段识别中,embed_size设为20;
joint-model-5-adam-50:将embed_size设为50,其他设置与上个模型相同;
结果分析:
(1)joint-model-3-adam模型的片段抽取距离pipeline还有2个点,造成这种情况的原因可能是种子还未固定,因为原数据是按类别排序的,太整齐,所以只是在每个程序训练之前打乱了1000次,之后每次运行再打乱1次,若种子未固定,则随机的情况会差别比较大。但是鉴于分类的性能和pipeline一摸一样,这个原因可能并不成立。还需要再排查一下原因。
(2)受到AAAI分词论文的影响,调了一下加入特征的维度,对比joint-model-4-adam-50和joint-model-4-adam-20模型,都运行到180+轮时,50维的性能是比20维的好的,所以可以继续调试维度,加大维度可能能提高性能;
(3)对比joint-model-5-adam-20和joint-model-5-adam-50模型,发现都运行到170+轮时,50维的性能就很差了,20维的性能还算正常范围,结合joint-model-5-sgd-200模型的运行情况,发现若加入的是embedding特征,可能维度小一些较好;
(4)对比(2)和(3)分析的情况,发现针对不同的特征融合方法,调参还是不太一样的,可能是因为模型5中加入的是全新的embedding向量,这种随机初始的可能会造成很大的噪声影响,所以维度要小一些,而模型4中加入的是lstm之后的结果,两者不太一样。这是我的一些猜测。
实验尝试二:
根据之前的实验情况,对模型进行了一下调整,保存pipeline的最好模型,作为pretrain的参数导入模型,而且在分类上不再backward,提取分类特征用于片段识别。
joint-model-4-adam-20:分类和片段识别使用的是不同的LSTM,用的是Adam优化器,分类的特征映射为20维的向量,作为新特征加入片段识别中;
joint-model-4-adam-100:将分类的特征映射改为100维,其他设置与上个模型相同;
joint-model-5-adam-16:分类和片段识别使用的是不同的LSTM,用的是Adam优化器,分类的预测标签embedding之后,作为新特征加入片段识别中,embed_size设为16;
实验尝试三:
保存了pipeline的最好模型,作为pretrain的参数导入模型,在分类上继续backward,提取分类特征用于片段识别:
joint-model-4-adam-10:分类和片段识别使用的是不同的LSTM,用的是Adam优化器,分类的特征映射为10维的向量,作为新特征加入片段识别中;
joint-model-5-adam-8:分类和片段识别使用的是不同的LSTM,用的是Adam优化器,分类的预测标签embedding之后,作为新特征加入片段识别中,embed_size设为8;
实验尝试四:
分别运行了pipeline模型,保存了pipeline的最好模型,在联合模型中,保存的最好模型作为pretrain的参数导入模型,在分类上继续backward,提取分类特征用于片段识别:
joint-model-4-adam-20:分类和片段识别使用的是不同的LSTM,用的是Adam优化器,分类的特征映射为20维的向量,作为新特征加入片段识别中;
joint-model-4-adam-50:分类的特征映射为50维的向量;
joint-model-4-adam-80:分类的特征映射为80维的向量;
joint-model-4-adam-100:分类的特征映射为100维的向量;
joint-model-5-adam-16:分类和片段识别使用的是不同的LSTM,用的是Adam优化器,分类的预测标签embedding之后,作为新特征加入片段识别中,embed_size设为16;
joint-model-5-adam-50:embed_size设为50;
joint-model-5-adam-80:embed_size设为80;
joint-model-5-adam-100:embed_size设为100;
3.2 提取片段特征用于分类模型
将pipeline保存的最好模型作为pretrain的参数导入模型,在片段抽取任务上继续backward,提取片段特征用于分类:
joint-model-7-adam:分类和片段识别使用的是不同的LSTM,用的是Adam优化器,将预测的片段的lstm输出,经过max pooling之后和分类的lstm输出cat到一起,最后预测分类结果;
joint-model-8-adam:分类和片段识别使用的是不同的LSTM,用的是Adam优化器,将预测的片段的lstm输出做lstm的相减操作,结果和分类的lstm输出cat到一起,最后预测分类结果;
模型实现过程中的注意点:
对这两个任务进行联合训练时,需要对这两个任务分别backward,同时又需要任务之间共享特征,所以backward的时候不能清空计算图,想要不清空计算图可以这么做:
pytorch实现:loss.backward(retain_graph=True)
这样就可以保留计算图上的节点了。