An Overview of Multi-Task Learning in Deep Neural Networks∗

An Overview of Multi-Task Learning in Deep Neural Networks (Paper, Blog)

1. 서론

보통 우리가 머신러닝으로 무언가를 할때 통상적으로 하나의 모델을 훈련하거나 복수의 모델을 훈련하여 Ensemble 하는 형태로 우리가 추구하고자 하는 목표를 잘 해석할 수 있는 모델을 만들고자 노력한다. 그 이후에는 Fine 튜닝 등의 방법으로 성능을 끌어올리고자 노력하다가 더 이상 모델의 성능의 개선되지 않으면 모델 개발을 완료하는 형태로 진행한다. 이러한 방법으로도 어지간한 경우에는 원하는 성능을 달성할 수 있다. 하지만 이렇게만 모델 개발을 종료하게 되면 어쩌면 우리의 모델의 도움이 되었을 수도 있는 연관된 데이터들을 활용할 수가 없다. 이러한 문제를 해결하고자 Multi Tasking 이라는 방법이 연구되었으며, 이 논문에서는 몇 가지 대표적인 Multi Tasking 방법과 응용 방법을 소개하고자 한다.

2. 대표적인 두 가지 방법

(1) Hard Parameter Sharing 

Hard Parameter Sharing 은 가장 흔히 사용되는 방법으로 Hidden Layer 를 공유하고 Task 별로 일부 개별적인 Layer 를 가지고 가는 형태로 활용된다. 이러한 방법의 활용은 당연히 Over Fitting 을 방지하는데 효과가 있다. (N 개의 Task 에 전부 Over Fit 되기는 어려움으로.. )

(2) Soft Parameter Sharing 

Soft Parameter Sharing 는 조금 다르게 각각의 Task 별로 별도의 Layer 를 가지고 있다. 다만, 각각의 Layer 가 비슷해 질 수 있도록 L2 Distance 를 사용한다. (아마도 LOSS 함수 구성시 Classification Loss 와 각각의 Layer 간의 거리를 최소화 하는 Loss 를 조합하는 형태일 것이라고 예상함)

3. Multi Task Learning 이 동작하는 이유 

(1) Implicit Data Augmentation  

어짜피 딥러닝은 High Dimension Data 를 Deep Learning 을 통해 Low Dimension 에서 Representation 하는 것에 목적이 있는데 , 특정한 데이터 셋에 종속적으로 모델을 훈련하는 것보다 다양한 데이터를 활용하여 더욱더 범용적인 Representation 을 만들어 낼 수 있다면, Over fitting 을 회피할 수 있다.

(2) Attention Focusing   

Task 가 만약 매우 지저분하거나 데이터가 제한적인 경우 모델이 관련이 있는 것과 관련이 없는 것을 구분하는 것이 쉽지 않을 것이다. 이러한 경우에 MTL 기법은 모델에 관련있는 것과 관련 없는 것을 구분하기 위한 추가적인 정보를 제공하여 줄 것이다.

(3) Eavesdropping  

어떤 Feature G 가 있다고 하자, Task A 에서는 이러한 Feature 를 학습하게 어려운데 Task B 에서는 학습하기가 용이하다고 하자, 이러한 문제를 해결하기에 가장 쉬운 방법은 Task B 를 통해서 Feature G 를 학습하기에 중요한 포인트를 전달 받아서 Task A 를 훈련하는 것일 것이다.

(4) Representation Bias   

하나의 Task 뿐만 아니라 다른 Task 에서도 선호되는 Representation 을 만들 수 있도록 Bias 를 줄 수 있다. 이를 통해서 모델의 Generalization 을 달성하는데 도움을 줄 수 있다.

(5) Regularization    

MTL 은 Regularizer 의 역할도 수행을 하는데, 귀납적인 Bias 를 제공하여 준다. 결론적으로 Over fitting 의 위험등을 감소 시킬 수 있다.

4. 최근 MTL 에 관한 연구  

(1) “Learning Multiple Tasks with Deep Relationship Networks” NIPS 2017 (링크)

Pretrained 된 CNN(Alex Net) 을 활용하여 Fine Tune 개념으로 CNN Layer 를 활용하며, Multi Tasking 까지 적용하는 형태로 뒤의 FCC 레이어는 각각의 Task 별로 존재하는 형태로 자세한 사항은 직접 논문을 참조하기를 바란다.

(2) Fully-adaptive Feature Sharing in Multi-Task Networks with Applications in
Person Attribute Classification (링크)

Bottom up 방식으로  Thin 아키택쳐로 시작해서 복잡한 아키택쳐로 확대해 가는 형태로 훈련을 진행하면서 Dynamic 하게 Branch 를 추가해 가는 형태를 제안하고 있는다.

(3) Cross-stitch Networks for Multi-task Learning (링크)

일반적인 Soft Parameter Sharing 과 비슷한 형태로 구성되어 Shared CNN Layer 에 대해서 각 Task 별 별도의 Hidden Layer 를 구성하고 각 Layer 간의 거리를 최소화하는 방향으로 훈련하는 개념으로 구성되어 있다. 다만, Cross-Stitch 라는 개념이 추가되어 있는데, Task A 와 Task B 가 있다고 했을 때,  각 Task 에서 다음 Layer 의 Input 을 계산할 때, 아래와 같이 서로간에 Linear 한 관계로 값을 Combine 하는 구조가 추가되어 있다.

(4) A Joint Many-Task Model: Growing a NN for Multiple NLP Tasks (링크)

NLP 에는 POS, Chunking, Dependency Parsing, entailment 등 다양한 Task 들이 존재하는데,  보통은 각각의 목적별로 별도의 아키택쳐를 구성하지만, 여기에서는 모든 Task 를 하나의 아키택쳐로 구성하고, 훈련하고자 하는 대상별로 다른 LOSS Function 을 구성하여 하나의 아키택쳐에서 같이 훈련시키고 있다.

 

 

(5) Multi-Task Learning Using Uncertainty to Weigh Losses for Scene Geometry and Semantics (링크)

Share 하는 Layer 을 훈련하는 형태가 아닌 복수의 목적을 갖는 Loss Function 을 설계하고 이를 Sum 하여 한번에 훈련하는 형태를 제시하고 있다.

(3) Learning what to share between loosely related tasks (링크)

지금까지 나온 Hard Parameter Sharing, Cross-Stitch , NLP의 Task Hierarchy 등 다양한 기법들을 복합적으로 적용한, MTL 아키택쳐이다.

5. Examples with Tensorflow   

(1) Linear Transformation 

간단한 Linear Regression 을 Tensorflow 로 구현한 모습이다. MTL 을 설명하기 전에 가장 간단한 구조를 한번 설명하고 있다.

<code class="language-python" data-lang="python"># Import Tensorflow and Numpy
import Tensorflow as tf
import numpy as np

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

# Create Placeholders For X And Y (for feeding in data)
X = tf.placeholder("float",[10, 10],name="X") # Our input is 10x10
Y = tf.placeholder("float", [10, 1],name="Y") # Our output is 10x1

# Create a Trainable Variable, "W", our weights for the linear transformation
initial_W = np.zeros((10,1))
W = tf.Variable(initial_W, name="W", dtype="float32")

# Define Your Loss Function
Loss = tf.pow(tf.add(Y,-tf.matmul(X,W)),2,name="Loss")

with tf.Session() as sess: # set up the session
    sess.run(tf.initialize_all_variables())
    Model_Loss = sess.run(
                Loss, # the first argument is the name of the Tensorflow variabl you want to return
                { # the second argument is the data for the placeholders
                  X: np.random.rand(10,10),
                  Y: np.random.rand(10).reshape(-1,1)
                })
    print(Model_Loss)</code class="language-python" data-lang="python">

(2) Simple Hard Parameter Sharing 

Hard Parameter Sharing 의 간단한 예가 되겠다. 공유되는 Shared Layer 를 가지고 있는 상태에서 각각의 Task 가 별도의 Layer 를 가지고 있으며, 두개의 Task 는 각각 다른 X,Y Set 으로 Loss 구해서 BackPropagation 을 진행하고 있다.

#  GRAPH CODE
# ============

# 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)

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

(3) Joint Loss 

각각 따로 따로 모델을 훈련하는 것이 아닌 Joint Loss 를 활용하여 훈련하는 예제이다

#  GRAPH CODE
# ============

# 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)

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

# open the session

with tf.Session() as session:
    session.run(tf.initialize_all_variables())
    _, 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(Joint_Loss)

6. Real Examples    

(1) VoC Example  

고객의 STT 데이터를 가지고 현업에서 실제 사용할 모델을 만들 때 응용했던 결과를 보여주고 있다. 현업에서의 문제는 Inbound Call 이 들어올 때, 고객이 선택한 카테고리 정보 외에 우리가 분류하고 싶은 형태의 정답지(Labeled Data)가 없거나 매우 적다는 것이 문제다. 이러한 문제를 해결하기 위해서 Transfer Learning, Multi Tasking, Learning by Association 3가지 기법을 적용한 결과이다. 전체적으로 데이터가 적어서 발생하는 Over Fitting 을 회피하기 위한 기법들이 위주로 적용되었으며, 아래와 같이 Walker Loss, Classification Loss 와 더불어 우리가 목적하였던 고객의 감정 분석 모델의 Loss 와 Accuracy 도 향상됨을 볼 수 있다. 실제 테스트 결과 완전 별도로 작업한 Test Set 1,000건 기준으로 79.5 F1 Score 를 달성 하였다.

Leave a Reply

Your email address will not be published. Required fields are marked *