Multi_task_learning

多任务学习简述

  • 什么是多任务学习

多任务学习(Multi-Task Learning)顾名思义就是把多个任务放在一起学习,即对多个任务的目标一起联合建模并训练 我们的大脑工作机制也是如此,我们时刻都在进行着多任务学习,而且不同任务之间在相互影响着。比如学习英语和法语,你学习其中的一门语言是有助于另一门语言的学习的。

  • 为什么要多任务学习

多任务学习可以将多个任务联合训练,只需一个流程就可以实现多个任务的学习 多任务学习可以挖掘不同任务间的联系,通过共享特征的方式实现迁移学习 多任务学习一定程度上对其中的任务进行泛化,使得模型不容易过拟合

TensorFlow实现

  • 双任务学习示例图

两个任务除了有各自的TaskLayer参数,还有个共享参数层SharedLayer,那么这样的网络如何来训练呢?下面介绍两种训练方法以及代码实现

交替训练 Alternative Trainning

如图所示,交替训练的意思就是在迭代训练中你来我往地交替进行各自的loss学习

代码

# Import Tensorflow and Numpy
import tensorflow as tf
import numpy as np

# ======================
# Define the Graph
# ======================

# Define the Placeholders
X = tf.placeholder("float", [10, 10], name="X")
Y1 = tf.placeholder("float", [10, 20], name="Y1")
Y2 = tf.placeholder("float", [10, 20], name="Y2")

# Define the weights for the layers
initial_shared_layer_weights = np.random.rand(10,20)
initial_Y1_layer_weights = np.random.rand(20,20)
initial_Y2_layer_weights = np.random.rand(20,20)

shared_layer_weights = tf.Variable(initial_shared_layer_weights, name="share_W", dtype="float32")
Y1_layer_weights = tf.Variable(initial_Y1_layer_weights, name="share_Y1", dtype="float32")
Y2_layer_weights = tf.Variable(initial_Y2_layer_weights, name="share_Y2", dtype="float32")

# Construct the Layers with RELU Activations
shared_layer = tf.nn.relu(tf.matmul(X,shared_layer_weights))
Y1_layer = tf.nn.relu(tf.matmul(shared_layer,Y1_layer_weights))
Y2_layer = tf.nn.relu(tf.matmul(shared_layer,Y2_layer_weights))

# Calculate Loss
Y1_Loss = tf.nn.l2_loss(Y1-Y1_layer)
Y2_Loss = tf.nn.l2_loss(Y2-Y2_layer)
Joint_Loss = Y1_Loss + Y2_Loss

# optimisers
Optimiser = tf.train.AdamOptimizer().minimize(Joint_Loss)
Y1_op = tf.train.AdamOptimizer().minimize(Y1_Loss)
Y2_op = tf.train.AdamOptimizer().minimize(Y2_Loss)

with tf.Session() as session:
    session.run(tf.initialize_all_variables())
    for iters in range(10000):
        if np.random.rand() < 0.5:
            _, Y1_loss = session.run([Y1_op, Y1_Loss],
                            {
                              X: np.random.rand(10,10)*10,
                              Y1: np.random.rand(10,20)*10,
                              Y2: np.random.rand(10,20)*10
                              })
            print("iteration:{}, y1_loss:{}".format(iters, Y1_loss))
        else:
            _, Y2_loss = session.run([Y2_op, Y2_Loss],
                            {
                              X: np.random.rand(10,10)*10,
                              Y1: np.random.rand(10,20)*10,
                              Y2: np.random.rand(10,20)*10
                              })
            print("iteration:{}, y2_loss:{}".format(iters, Y2_loss))
    session.close()

什么时候选择交替训练呢?当不同任务有各自的训练数据时,就可以对不同的任务输入各自的数据,而无需去构造一份专门的数据。如果不同任务的数据集数量差距太大时,此时模型会偏向于数据量大的任务。

联合训练 Joint Training

当你有一份数据带有不同的标签时,就可以对多任务同时进行训练了,怎么做到呢,很简单,只需要把不同任务的loss做一个加权和即可。

代码

# Import Tensorflow and Numpy
import tensorflow as tf
import numpy as np

# ======================
# Define the Graph
# ======================

# Define the Placeholders
X = tf.placeholder("float", [10, 10], name="X")
Y1 = tf.placeholder("float", [10, 20], name="Y1")
Y2 = tf.placeholder("float", [10, 20], name="Y2")

# Define the weights for the layers

initial_shared_layer_weights = np.random.rand(10,20)
initial_Y1_layer_weights = np.random.rand(20,20)
initial_Y2_layer_weights = np.random.rand(20,20)

shared_layer_weights = tf.Variable(initial_shared_layer_weights, name="share_W", dtype="float32")
Y1_layer_weights = tf.Variable(initial_Y1_layer_weights, name="share_Y1", dtype="float32")
Y2_layer_weights = tf.Variable(initial_Y2_layer_weights, name="share_Y2", dtype="float32")

# Construct the Layers with RELU Activations
shared_layer = tf.nn.relu(tf.matmul(X,shared_layer_weights))
Y1_layer = tf.nn.relu(tf.matmul(shared_layer,Y1_layer_weights))
Y2_layer = tf.nn.relu(tf.matmul(shared_layer,Y2_layer_weights))

# Calculate Loss
Y1_Loss = tf.nn.l2_loss(Y1-Y1_layer)
Y2_Loss = tf.nn.l2_loss(Y2-Y2_layer)
Joint_Loss = 0.5*Y1_Loss + 0.5*Y2_Loss

# optimisers
Optimiser = tf.train.AdamOptimizer().minimize(Joint_Loss)
Y1_op = tf.train.AdamOptimizer().minimize(Y1_Loss)
Y2_op = tf.train.AdamOptimizer().minimize(Y2_Loss)

# Joint Training
# Calculation (Session) Code
# ==========================

# open the session
with tf.Session() as session:
    session.run(tf.initialize_all_variables())
    for iters in range(10000):
        _, Joint_loss = session.run([Optimiser, Joint_Loss],
                    {
                      X: np.random.rand(10,10)*10,
                      Y1: np.random.rand(10,20)*10,
                      Y2: np.random.rand(10,20)*10
                      })
        print("iteration:{}, joint_loss:{}".format(iters, Joint_loss))
    session.close()
updatedupdated2020-12-062020-12-06