pytorch 针对多个(分类)任务训练wav2vec2

1cklez4t  于 2023-01-17  发布在  其他
关注(0)|答案(1)|浏览(216)

我用pytorch和huggingface transformer训练了一个wav2vec2模型,代码如下:https://github.com/padmalcom/wav2vec2-nonverbalvocalization
我现在想要在第二任务上训练模型,例如年龄分类或语音识别(ASR)。
我的问题是,我真的不明白如何配置我的模型来接受一个秒输入和训练另一个输出。谁能给予我一个简短的解释吗?
我知道我必须在我的模型中使用多个头脑,我想达到的目标叫做“多任务学习”,但我的问题是,我不知道如何为此编写模型。

fnx2tebb

fnx2tebb1#

如果您可以为了简单而放弃一些性能,那么这将更容易实现。
这个答案是基于这样一个假设:你是多任务/联合学习策略的新手,正在寻找一些简单的开始。

方法1

由于Wav2Vec2的被设计为CTC模型,因此您可以轻松地初始化具有与此处完全相同架构的第二个分类头,并在同一数据加载器中同时为两个任务采样 * 输入 * 和 * 标签 。如果您希望将 * ASR * 作为第二个任务执行,则会变得有点复杂。但是如果您选择在这两种情况下都只关注序列分类,则会足够容易。
现在,假设您有两个合并的数据集,其中列为:
1.音频路径:应力
1.标签:整数
1.任务:整数
在DataCollator中,您通常会使用相对Tensor连接所有内容,如此处所述,但有一个小的更改:返回批处理的
任务索引
Tensor以及
输入
标签*。
之后,您可以重用该信息来拆分***隐藏状态***,以便将它们路由到此行之后的不同分类头。例如,如果您的***任务Tensor***如下所示:torch.tensor([[0, 0, 1, 1]]),您可以使用hidden_states[:2, :, :]作为第一分类头输入,hidden_states[2:, :, :]作为第二分类头输入。
但是它们可能是均匀分布的([0, 1, 0, 0, 1, ...])-在这种情况下,您可以将每个批添加到相对列表中,然后将它们连接起来。

  • 这是为了避免多任务学习的复杂性,并将此任务转换为更多的联合学习方法以实现简单性。*

您向分类负责人发送的转发请求如下所示:

hidden_states = self.merged_strategy(hidden_states, mode=self.pooling_mode)
hidden_states_1 = ... # As described above
hidden_states_2 = ... # As described above
labels_1 = ... # As described above
labels_2 = ... # As described above
task_1_logits = self.classifier_1(hidden_states_1)
task_2_logits = self.classifier_2(hidden_states_2)

当你得到两项任务的对数时,你需要分别计算它们的损失,然后对它们进行summean运算,或者预先将它们乘以某个权重。
它看起来像这样:

loss_1 = loss_fct(logits_1.view(-1, self.num_labels_1), labels_1.view(-1))
  loss_2 = loss_fct(logits_2.view(-1, self.num_labels_2), labels_2.view(-1))
  total_loss = (loss_1 * 0.5) + (loss_2 * 0.5)

请注意,无论如何都有一些事情需要考虑,例如-如果您不打算编写自定义数据加载器,则可能无法在某些批处理中同时获得两个任务的数据。
这种方法不会产生您可以投入生产的SOTA结果(至少没有大量进一步优化),但是对于实验和私人使用来说可能是不错的。

方法2

更简单的方法如下:
1.冻结波形2矢量2模型
1.培训***分类负责人***完成第一项任务并减轻重量
1.培训***分类负责人***执行第二项任务并减轻重量。
1.在推理期间初始化两个分类头,并相应地加载训练权重
1.根据你想用你的输入做什么,通过两个头中的任何一个做正向传递。
这种方法将产生更差的结果,因为***Wav2Vec2***的变压器层将不会被微调。

相关问题