多任务学习(Multi-Task Learning,MTL):SB,MMOE,SNR

文章目录

  • 多任务学习
    • 最简单直接的MTL想法(效果往往最差)
    • SB(Shared-Bottom)
    • MMOE(Multi-gate Mixture-of-Experts)
    • SNR(Sub-Network Routing)

  多任务学习(Multi-Task Learning,MTL)也是研究的热点,尤其是在推荐领域。以推荐视频为例,我们可能需要提升很多label,例如提升用户的点赞率、分享率等,在单任务学习中,预测用户点赞动作的模型和预测用户点击分享的模型是两个模型;而在多任务学习中,一个模型一次性就输出了这两个label的预测结果。

  所以多任务模型的一个重要的优点就是节省了计算开销,一个模型干了之前多个模型的事情,这在实时任务中是至关重要的,你给用户推荐,用户不可能刷新一下网页,等个10分钟(夸张一下)才看到你推荐的结果;同时,多任务模型由于联合学习了多个label,附带的也学习了label之间的相关性,这其实是提升了模型的鲁棒性和准确性的,因为单任务模型是无法学习label间的相关性的。

  多任务学习通常通过 Hard 或 Soft 参数共享来完成。以下内容摘自其它blog(最近有点懒),我看总结的不错,我自己是主用hard共享的。

  共享 Hard 参数是神经网络 MTL 最常用的方法,可以追溯1993年Caruana所发表的论文。在实际应用中,通常通过在所有任务之间共享隐藏层,同时保留几个特定任务的输出层来实现。共享Hard 参数大大降低了过拟合的风险。1997年Jonathan Baxter在他的论文中证明过拟合共享参数的风险为 O(N)——其中 N 是任务数——小于过拟合特定任务参数,即输出层。这很直观:我们同时学习的工作越多,我们的模型找到一个含有所有任务的表征就越困难,而过拟合我们原始任务的可能性就越小。

  另一方面,在共享 Soft 参数时,每个任务都有自己的参数和模型。模型参数之间的距离是正则化的,以便鼓励参数相似化。1998年Caruana对早期的MTL的研究进行了总结,并演示了三个领域中的多任务学习。他们解释了多任务学习的工作原理,提出了一个基于案例的方法(如k-最近邻和核回归)的多任务学习算法和结果,并为决策树中的多任务学习绘制了一个算法。目前大部分MTL学习所基于的机制仍然来源于此篇文章。

  下面的讨论都是基于深度模型(神经网络)的,如果没有神经网络的知识,可以参考blog。

多任务学习

最简单直接的MTL想法(效果往往最差)

  假设我们已经有一个单任务模型,它预测 l a b e l   1 label~1 label 1,我们又提前知道 l a b e l   1 label~1 label 1 l a b e l   2 label~2 label 2有相关性(这个相关性认识很重要,MTL学习的多任务最好是有一定的潜在相关性的),我们想把这个单任务模型改成一个多任务模型,最简单的方法就是我们把最后一层的输出层的数量扩展,由原来的 n n n个神经元扩展成 2 n 2n 2n个,多出的神经元用于预测 l a b e l   2 label~2 label 2,损失函数是计算所有输出label与真实label的差别,重新或基于已经训练好的 l a b e l   1 label~1 label 1模型,来训练多任务模型。

  这种很直观的改进方法我试过,效果果然不好。。。。,其实也是可以想象的,我们仅在最后输出层分割任务的输出,就算 l a b e l   2 label~2 label 2在怎么和 l a b e l   1 label~1 label 1相关,还是有不相干性在里面的,仅仅在最后输出层分隔开,彼此之间的不相关性学习的还是不够充分(我 l a b e l   2 label~2 label 2不要面子的啊)。所以一个直观的改进想法就出现在我们脑子里,我们为2个label添加各自的分支任务神经网络(我下文也会这么叫),也就是把任务分割的位置提前到某一个隐藏层执行,而不是在最后的输出层分割任务,这就引出了下面的SB(Shared-Bottom)算法。

SB(Shared-Bottom)

  SB模型看名字就是“共享底部结构的模型”,其结构如下所示:

多任务学习(Multi-Task Learning,MTL):SB,MMOE,SNR_第1张图片

  可以直观的看到,这是一个双塔模型(或者多塔模型),在共享底部结构中,学习相似性,每个独立的塔在学习一下每个label的自己独立的特性,这样设计很有意思。但是之前我们说过,SB模型一个很重要的前提就是任务相关性,如果多个label的相关性比较差,那共享的底部结构就是一种相互负面影响,会对每个label的预测带来一定的负面影响。但是相似性问题本身就没有一个明确的度量,在全世界范围内都是一个开放问题,那么多相似性度量指标咱们怎么选,为何这样能衡量相似性,这就陷入了另一个问题之中。

  因此,一些研究就尝试利用神经网络学习的方法,自动解决这个相似性的问题,其中一种方法是引入门结构(gating structures),这就有一些很有名的改进型,例如MMOE(Multi-gate Mixture-of-Experts)和SNR(Sub-Network Routing)。

MMOE(Multi-gate Mixture-of-Experts)

  MMOE论文地址:https://dl.acm.org/doi/10.1145/3219819.3220007

  MOE模型和MMOE模型的结构如下图所示

多任务学习(Multi-Task Learning,MTL):SB,MMOE,SNR_第2张图片

  MOE(Mixture-of-Experts MoE)模型,听名字,就感觉到是多个Expert的融合,对应上图中的b图,多个Expert(一般是多个神经网络)共享输入,输出经过加权叠加后,输入到各自的分支任务神经网络中。用公式表示如下:

y = Σ i n g ( x ) i f i ( x ) y=\Sigma_{i}^{n}g(x)_if_i(x) y=Σing(x)ifi(x)

Σ i n g ( x ) i = 1 \Sigma_{i}^{n}g(x)_i=1 Σing(x)i=1

x x x是输入, f i ( ⋅ ) f_i(·) fi()对应第i个expert网络, g ( ⋅ ) g(·) g()对应gate网络, g ( ⋅ ) i g(·)_i g()i对应gate网络第i个输出神经元输出值, y y y是分支任务神经网络的输入,分支任务网络共用同一个 y y y

  MMOE(Multi-gate Mixture-of-Experts)更进一步,针对每个分支任务,也会有不同的gate网络。用公式表示如下:

y k = Σ i n g k ( x ) i f i ( x ) y^k=\Sigma_{i}^{n}g^k(x)_if_i(x) yk=Σingk(x)ifi(x)

g k ( x ) = s o f t m a x ( W k x ) g^k(x)=softmax(W^kx) gk(x)=softmax(Wkx)

同样, x x x是输入, f i ( ⋅ ) f_i(·) fi()对应第i个expert网络, g k ( ⋅ ) i g^k(·)_i gk()i对应第k个任务的gate网络的第i个输出神经元输出值, y k y^k yk是第k个分支任务神经网络的输入。

  论文对相关性不同的任务进行实验,结果如下,可以看到,MMOE对相关性不那么高的任务,仍具有较好的收敛性。当然,具体任务还要具体实验分析。

多任务学习(Multi-Task Learning,MTL):SB,MMOE,SNR_第3张图片

SNR(Sub-Network Routing)

  SNR论文地址:https://aaai.org/ojs/index.php/AAAI/article/view/3788

  SNR模型的结构如下图所示

多任务学习(Multi-Task Learning,MTL):SB,MMOE,SNR_第4张图片

  MMOE仅仅利用门结构,产生的一个权重参数,控制shared bottom的expert的输出,到分支任务神经网络的输入的转换,这样的设定不够灵活,假设一个expert输出10个值,你一个权重参数就想白嫖 控制我10个值,这么想确实是不灵活。SNR模型实现了更加灵活的参数共享。

We aim to improve multi-task learning models by flexible parameter sharing, where we want to make more related tasks share more model parameters and less related tasks share fewer model parameters.

  SNR任务,和NAS(neural architecture search)任务有一定的相似性,论文中提出了两种SNR结构,如上图中的b和c, 被称为SNR-Trans和SNR-Aver。首先,SNR会把shared bottom部分分割中上下两个子网络(sub-networks),两个子网络之间通过二进制编码变量(binary coding variable,取值非0即1)连接,SNR-Trans和SNR-Aver的不同,就体现在连接方式的不同。假设第一层子网络有三个,输出是 u 1 , u 2 , u 3 u_1,u_2,u_3 u1,u2,u3,第二层子网络有两个,输入是 v 1 , v 2 v_1,v_2 v1,v2,SNR-Trans通过神经网络的矩阵运算转换(matrix transformations)连接两个子网络,SNR-Trans公式表达如下:
[ v 1 v 2 ] = [ z 11 W 11 z 12 W 12 z 13 W 13 z 21 W 21 z 22 W 22 z 13 W 13 ] [ u 1 u 2 u 3 ] \left[ \begin{matrix} v_1\\ v_2 \end{matrix} \right]=\left[ \begin{matrix} z_{11}W_{11} & z_{12}W_{12} & z_{13}W_{13}\\ z_{21}W_{21} & z_{22}W_{22} & z_{13}W_{13} \end{matrix} \right]\left[ \begin{matrix} u_1\\ u_2\\ u_3 \end{matrix} \right] [v1v2]=[z11W11z21W21z12W12z22W22z13W13z13W13]u1u2u3

其中, W i j W_{ij} Wij表示从 u j u_j uj v i v_i vi的转换矩阵, z i j z_{ij} zij是二进制编码变量。SNR-Aver通过加权平均(weighted average),公式表达如下:
[ v 1 v 2 ] = [ z 11 I 11 z 12 I 12 z 13 I 13 z 21 I 21 z 22 I 22 z 13 I 13 ] [ u 1 u 2 u 3 ] \left[ \begin{matrix} v_1\\ v_2 \end{matrix} \right]=\left[ \begin{matrix} z_{11}I_{11} & z_{12}I_{12} & z_{13}I_{13}\\ z_{21}I_{21} & z_{22}I_{22} & z_{13}I_{13} \end{matrix} \right]\left[ \begin{matrix} u_1\\ u_2\\ u_3 \end{matrix} \right] [v1v2]=[z11I11z21I21z12I12z22I22z13I13z13I13]u1u2u3

其中, I i j I_{ij} Iij表示从 u j u_j uj v i v_i vi的单位矩阵,看这部分需要一点点矩阵分块运算的知识。如果所有二进制编码变量都为1,那么SNR退化为SB模型,如果 z 11 = z 22 = 1 z_{11}=z_{22}=1 z11=z22=1,其余为0,SNR就变为若干独立神经网络,每个独立神经网络对应学习一个任务。

  在学习中,最大的问题是如何学习更新二进制编码变量。一种解决方法是手动去调这个二进制编码变量,每次训练时,二进制编码变量都是固定的,这样手动调不一定效果差,但是需要有足够的算力资源。如果想要依靠神经网络自动去学习,最大的问题就是二进制编码变量是离散的,无法执行正常的梯度反向传播。SNR论文采用了另一个论文提出的方法,Learning sparse neural networks through L0 regularization,简单来说,就是把离散变量松弛(松弛法就是迭代逼近最优解的解法)为连续变量,假设输入数据是 D = ( x i , y i ) , i = 1 … N D={(x_i,y_i)},i=1\dots N D=(xi,yi),i=1N,注意这里 x i x_i xi y i y_i yi都是向量,我们优化的目标是

min ⁡ W , z E 1 N Σ i = 1 N L ( f ( x i ; W , z ) , y i ) \min_{W,z}E\frac{1}{N} \Sigma_{i=1}^{N} L(f(x_i;W,z),y_i) W,zminEN1Σi=1NL(f(xi;W,z),yi)

其中, f ( ⋅ ) f(·) f()表示多目标网络,E表示期望,W是待学习的神经网络参数,z是待学习的二进制编码变量,我们把z松弛为一个关于变量s的变量,使用hard softmax

z = g ( s ) = m i n ( 1 , m a x ( 0 , s ‾ ) ) z = g(s) = min(1, max(0, \overline{s})) z=g(s)=min(1,max(0,s))

随机变量s用下式计算:

s ‾ = s ( ζ − γ ) + γ \overline{s}=s(\zeta-\gamma)+\gamma s=s(ζγ)+γ

s = s i g m o i d ( ( l o g ( u ) − l o g ( 1 − u ) + l o g ( α ) / β ) s = sigmoid((log(u)-log(1- u) + log(\alpha)/\beta) s=sigmoid((log(u)log(1u)+log(α)/β)

u是01区间的随机变量, ζ \zeta ζ γ \gamma γ β \beta β都是超参数, l o g ( α ) log(\alpha) log(α)是真正需要优化的和z有关的参数。关于z,也有对应的L0正则化表示:

E ∣ ∣ z ∣ ∣ 0 = Σ j = 1 ∣ z ∣ ( 1 − Q ( s j < 0 ) ) E||z||_0=\Sigma_{j=1}^{|z|}\big(1-Q(s_j<0)\big) Ez0=Σj=1z(1Q(sj<0))

其中Q是s的概率密度函数,这样我们优化的目标就变成了

E 1 N Σ i = 1 N L ( f ( x i ; W , g ( s ) ) , y i ) + λ Σ j = 1 ∣ z ∣ ( 1 − Q ( s j < 0 ) ) E\frac{1}{N} \Sigma_{i=1}^{N} L(f(x_i;W,g(s)),y_i)+\lambda \Sigma_{j=1}^{|z|}\big(1-Q(s_j<0)\big) EN1Σi=1NL(f(xi;W,g(s)),yi)+λΣj=1z(1Q(sj<0))

λ \lambda λ是超参数。

  需要学习的参数只有神经网络参数W和 l o g ( α ) log(\alpha) log(α),在确定了超参数并初始化待学习参数W和 l o g ( α ) log(\alpha) log(α)后,每次前向传播,都要确定一组01均匀分布变量u,这样z就确定了,进而shared bottom中两个子网络的连接也就确定了。

Multiple samples of u can be drawn to reduce the variance of the gradient estimates but one sample of u per mini-batch works well in practice.

在推断时,求z直接使用下面的公式就行了:

z = m i n ( 1 , m a x ( 0 , s i g m o i d ( l o g ( α ) ) ( ζ − γ ) + γ ) ) ) z = min(1, max(0, sigmoid(log(\alpha))(\zeta-\gamma) + \gamma))) z=min(1,max(0,sigmoid(log(α))(ζγ)+γ)))

具体数学原理可以看我上面列出的论文。


参考文献:
多任务学习 Multi-task learning:https://blog.csdn.net/chanbo8205/article/details/84142075

详解谷歌之多任务学习模型MMoE(KDD 2018):https://zhuanlan.zhihu.com/p/87288876

你可能感兴趣的:(深度学习)