📜  用于深度学习的多任务学习 (MTL) 简介(1)

📅  最后修改于: 2023-12-03 15:11:17.679000             🧑  作者: Mango

用于深度学习的多任务学习 (MTL) 简介

在深度学习领域,单个任务的学习已经非常成熟和有效了。然而,在现实中,许多问题涉及到多个任务,并且这些任务之间具有相关性和依赖性,这就需要用到多任务学习(MTL)。

MTL是什么?

多任务学习是指学习器需要同时处理多个任务的学习问题。在深度学习中,多个任务可以被看做是多个输出层,每个输出层对应一个不同的任务。

为什么需要MTL?

多任务学习与单任务学习相比,具有如下优点:

  • 提高学习效率:多任务学习可以在同一模型中处理多个相关任务,从而在某些情况下可以提高学习效率,比如数据集较小的情况下,可以用多个任务来增加训练数据的样本数量。
  • 提高泛化性能:多任务学习可以共享低级特征,减少冗余学习,提升模型泛化性能。
  • 实现知识迁移:多任务学习可以通过共享参数和层来促进不同任务之间的知识迁移,即当一个任务学习到一些知识时,可以分享这些知识给其它任务。
如何实现MTL?

实现多任务学习的方法有很多,以下列举了几个常用的方法:

Hard parameter sharing

这种方法是在网络的底层共享参数,从而在网络上层构建每个任务的特定部分。这样可以共享低级特征,并且可以确保所有任务都在相同的模型架构下共享。

#示例代码
shared_layer = tf.keras.layers.Dense(32, activation='relu', name='shared_layer')
task1_layer = tf.keras.layers.Dense(16, activation='relu', name='task1_layer')
task2_layer = tf.keras.layers.Dense(8, activation='relu', name='task2_layer')
output1_layer = tf.keras.layers.Dense(1, activation='sigmoid', name='output1_layer')
output2_layer = tf.keras.layers.Dense(1, activation='sigmoid', name='output2_layer')

shared_input = tf.keras.Input(shape=(10,), name='shared_input')
s = shared_layer(shared_input)

task1 = task1_layer(s)
output1 = output1_layer(task1)

task2 = task2_layer(s)
output2 = output2_layer(task2)

model = tf.keras.Model(inputs=shared_input, outputs=[output1, output2])
model.summary()
Soft parameter sharing

这种方法允许网络在不同任务之间共享信息,但是任务之间的参数不同,并且会使用正则化来规定每个任务的差异。通常使用协同型或竞争型的任务来实现这种方法。

#示例代码
shared_layer = tf.keras.layers.Dense(32, activation='relu', name='shared_layer')
task1_layer = tf.keras.layers.Dense(16, activation='relu', name='task1_layer', kernel_regularizer=tf.keras.regularizers.l2())
task2_layer = tf.keras.layers.Dense(8, activation='relu', name='task2_layer', kernel_regularizer=tf.keras.regularizers.l2())
output1_layer = tf.keras.layers.Dense(1, activation='sigmoid', name='output1_layer')
output2_layer = tf.keras.layers.Dense(1, activation='sigmoid', name='output2_layer')

shared_input = tf.keras.Input(shape=(10,), name='shared_input')
s = shared_layer(shared_input)

task1 = task1_layer(s)
output1 = output1_layer(task1)

task2 = task2_layer(s)
output2 = output2_layer(task2)

model = tf.keras.Model(inputs=shared_input, outputs=[output1, output2])
model.summary()
Multi-task Attention Networks

这种方法是通过引入多任务注意力(MTA)机制来实现多任务学习,该机制将每个任务的注意力权重计算为输入与任务特定矩阵之间的点积。

#示例代码
shared_layer = tf.keras.layers.Dense(32, activation='relu', name='shared_layer')
task1_layer = tf.keras.layers.Dense(16, activation='relu', name='task1_layer')
task2_layer = tf.keras.layers.Dense(8, activation='relu', name='task2_layer')
output1_layer = tf.keras.layers.Dense(1, activation='sigmoid', name='output1_layer')
output2_layer = tf.keras.layers.Dense(1, activation='sigmoid', name='output2_layer')

def multi_task_attention(input_shape, num_tasks):
    input = tf.keras.layers.Input(shape=input_shape)
    shared_layer = tf.keras.layers.Dense(32, activation='relu', name='shared_layer')(input)
    att_tasks = []
    for task_i in range(num_tasks):
        task_l = tf.keras.layers.Dense(16, activation='relu', name=f'task_{task_i}_layer')(shared_layer)
        att_w = tf.keras.layers.Dense(1, activation='softmax', name=f'task_{task_i}_attention')(task_l)
        att_m = tf.keras.layers.Dot(axes=(1, 1))([att_w, task_l])
        att_tasks.append(att_m)
    out_layers = [tf.keras.layers.Dense(1, activation='sigmoid', name=f'output_{task_i}_layer')(att_tasks[task_i]) for task_i in range(num_tasks)]
    return tf.keras.Model(inputs=[input], outputs=out_layers)

model = multi_task_attention(input_shape=(10,), num_tasks=2)
model.summary()
总结

多任务学习是深度学习中的一个重要方向,通过共享低级特征、实现知识迁移和提高泛化性能,可以在多任务场景下提高模型的表现。常用的多任务学习方法包括硬共享、软共享和MTA。