推荐系统系列:新浪搜索团队FiBiNET理论和代码实现

一、前言

(1)代码参考了阿里巴巴浅梦大神的实现,非常牛逼的一位大佬,非常值得大家学习;

(2)微博提出的fibinet点击预估模型,论文地址为:https://arxiv.org/pdf/1905.09433.pdf

二、算法原理

(1)整体框架如图所示:

(2)SENET Layer部分的主要作用是学习不同特征的一个重要程度,对重要特征加权,对蕴含信息量不多的特征进行削弱;参考浅梦大神的文章https://www.zhihu.com/people/shenweichen/posts

(3)SENET的主要处理流程:E为特征的embedding表示;

通过平均池化表示为Z,来获取特征的全局信息;

然后对Z进行加权学习得到需要的重要性权重表示;

(4)Bilinear_Interaction部分:左边上半部分为内积,下半部分为哈达玛积;原论文提出了一种添加一个参数w矩阵来学习交叉特征提高效果,公式如下:

几种实现方式的直观图像表示:

(5)最后将bi部分的p和senet部分的q进行拼接,然后输入给全连接层DNN部分和sigmoid部分得到点击的概率值;

(6)损失函数部分的设计如下公式所示:

三、实验效果

四、代码实现

from tensorflow.python.keras.layers import Layer
from tensorflow.python.keras.initializers import glorot_normal
import itertools
import tensorflow as tf

class senet(Layer):
    def __init__(self, reduction_ratio=3, seed=1024, **kwargs):
        self.reduction_ratio = reduction_ratio
        self.seed = seed
        super(senet, self).__init__(**kwargs)
    
    def build(self, input_shape, **kwargs):
        self.filed_size = len(input_shape)
        self.embedding_size = input_shape[0][-1]
        reduction_size = max(1, self.filed_size // self.reduction_ratio)
        self.w1 = self.add_weight(name='w1', shape=(self.field_size, reduction_size), 
                                  initializer=glorot_normal(self.seed))
        self.w2 = self.add_weight(name='w2', shape=(reduction_size, self.field_size), 
                                  initializer=glorot_normal(self.seed))
        self.tensordot = tf.keras.layers.Lambda(lambda x : tf.tensordot(x[0], x[1], axes=(-1, 0)))
        super(senet, self).build(input_shape)
    
    def call(self, inputs):
        Z = tf.keras.layers.concatenate(inputs, axis=1)#(batch, field_size, embed_size)
        Z = tf.reduce_mean(Z, axis=-1)#(batch, field_size)
        A_1 = tf.nn.relu(self.tensordot([Z, self.w1]))#(batch, reduction_size)
        A_2 = tf.nn.relu(self.tensordot([A_1, self.w2]))#(batch, field_size)
        V = tf.multiply(inputs, tf.expand_dims(A_2, axis=2))#(batch, field_size, embed_size)
        return tf.split(V, self.filed_size, axis=1)
        
class bilinear_interaction(Layer):
    def __init__(self, seed=1024, **kwargs):
        self.seed = seed
        super(bilinear_interaction, self).__init__(**kwargs)
    
    def buid(self, input_shape):
        emdedding_size = input_shape[0][-1]
        self.w = [self.add_weight(shape=(emdedding_size, emdedding_size), 
                                  initializer=glorot_normal(self.seed), 
        name='w' + str(i) + str(j)) for i, j in itertools.combinations(range(len(input_shape)), 2)]
    
    def call(self, inputs):
        p = [tf.multiply(tf.tensordot(v[0], w, axes=(-1, 0)), v[1]) for v, w in zip(itertools.combinations(inputs, 2), self.w)]
        return tf.keras.layers.concatenate(p, axis=-1)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值