推荐系统(十八)推荐系统中的MMOE

契机

多任务学习一开始比较流行的模型是share-bottom模型,即不同的任务共享一份底层特征(如下图所示),这样做能够令不同任务之间共享信息,但如果任务之间相关度不高,不同塔相似度较低,这样做的效果就会大打折扣。MMOE模型能通过gates和experts的配合来解决上述问题。

模型结构

MMOE结构是由MOE衍化而来的,因而下文会先讲解MOE,然后再具体解释MMOE的工作原理。

MOE

MOE的全称为Mixture of Experts,其底层由一个长度为N的gate向量 G ( x ) G(x) G(x)和N个expert向量 E i ( x ) E_i(x) Ei(x)组成,运行流程如下:

  1. 每个expert共享底层输入 x x x,其中第 i i i个expert经过若干全连接层后得到对应的 E i ( x ) E_i(x) Ei(x)
  2. E i ( x ) E_i(x) Ei(x)与gate向量的第 i i i维向量相乘得到加权输出 G ( x ) i ∗ E i ( x ) G(x)_i * E_i(x) G(x)iEi(x)
  3. 将所有的加权输出相加得到最终的输出, y = ∑ i N G ( x ) i ∗ E i ( x ) y=\sum_i^N G(x)_i * E_i(x) y=iNG(x)iEi(x)
  4. y y y输入到指定塔,经过若干全连接层后得到塔的最终输出。

这里需要注意的是,某一个 x x x计算的结果只会输出到某一个塔上(例如towerA),且不同的 x x x会对应不同的 G ( x ) G(x) G(x) E ( x ) E(x) E(x)

MOE模型中,由gate来控制experts的输出,从而动态地决定哪些experts对某一个塔比较重要,这样即使不同塔的相似较低,experts也能够学习地较好,因为每个expert的学习是相互独立的,这一点很重要。

MMOE

MMOE的全称为Multi-gate Mixture-of-Experts,从名字上可以看出,MMOE是MOE的升级版。它的改进手段相对直观,具体来说,把原先单一gate向量变为M个gate向量,M为塔的个数,示意图如下所示。
在这里插入图片描述

这里需要注意的是,上图中towerA和towerB所用到的experts是同一套experts。可以看出,相比于MOE,MMOE对gates和experts做了进一步的解耦,模型对于不同相似度塔的协同学习处理的更好,而且更重要的一点在于MMOE能够得到 x x x相对于每一个塔的得分,这是一个很大的进步。

模型代码

具体应用时,MMOE的自由度会比较大,最一开始gates和experts的输入都是全部底层特征,有时gates底层输入为item侧特征,experts底层输入为全量特征,这种组合下模型的指标会有进一步提升,不过这些都是视业务场景而定的,我们的代码实现如下所示。

# coding=utf-8
import tensorflow as tf


class MMOE(object):
    def __call__(self, expert_input, gate_input):
        self.target_num = 2
        self.expert_num = 4  # expert个数
        self.es = 32  # embedding_size

        # experts
        expert_list = []
        for i in range(self.expert_num):
            expert = expert_input
            for n in [128, 64]:
                expert = tf.layers.dense(expert, units=n,
                                         kernel_initializer=tf.truncated_normal_initializer(stddev=0.1),
                                         bias_initializer=tf.constant_initializer(0.1), activation=tf.nn.relu)
            expert = tf.layers.dense(expert, units=self.es,
                                     kernel_initializer=tf.truncated_normal_initializer(stddev=0.1),
                                     bias_initializer=tf.constant_initializer(0.1))
            expert_list.append(expert)
        experts = tf.reshape(tf.stack(expert_list, axis=1), [-1, self.es, self.expert_num])
        print("experts: %s" % experts)

        # gates
        gate_list = []
        for i in range(self.target_num):
            gate_net = gate_input
            for n in [128, 32]:
                gate_net = tf.layers.dense(gate_net, units=n,
                                           kernel_initializer=tf.truncated_normal_initializer(stddev=0.1),
                                           bias_initializer=tf.constant_initializer(0.1), activation=tf.nn.relu)
            gate_net = tf.nn.softmax(tf.layers.dense(gate_net, self.expert_num,
                                                     kernel_initializer=tf.truncated_normal_initializer(stddev=0.1),
                                                     bias_initializer=tf.constant_initializer(0.1)))
            gate_list.append(gate_net)
        gates = tf.reshape(tf.stack(gate_list, axis=1), [-1, self.expert_num, len(gate_list)])

        # merge
        merge = tf.reshape(tf.matmul(experts, gates), [-1, self.target_num, self.es])

        # towers
        towers = merge
        for n in [32, 16]:
            towers = tf.layers.dense(towers, units=n,
                                     kernel_initializer=tf.truncated_normal_initializer(stddev=0.1),
                                     bias_initializer=tf.constant_initializer(0.1), activation=tf.nn.relu)
        towers = tf.nn.softmax(tf.layers.dense(towers, units=1,
                                               kernel_initializer=tf.truncated_normal_initializer(stddev=0.1),
                                               bias_initializer=tf.constant_initializer(0.1)))

        return tf.squeeze(towers, axis=2)

参考

  1. mmoe paper
  2. moe paper
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值