谷歌双塔模型原理及Estimator实现

背景介绍

  • 文章核心?
    目前在大数据推荐系统环境下, 基于模型的建模方式有很多,利用双塔模型对User和Item建模是最经典的模型之一.双塔模型通过独立训练用户特征和文章特征,通过Embedding的方式去表达用户和物品的属性,在线上通过向量计算得到用户对物品的Label信息.

  • 应用场景
    推荐系统的两个场景包括召回和推荐.
    召回
    召回的作用是从千万级别的海量数据中找出千百级别左右的用户可能喜欢的物品,主要目的是解决海量数据处理;
    对于召回来说: 双塔可以根据用户和物品的Embedding表示,去做向量计算,这样有利于海量数据的计算.
    排序
    排序的作用是从召回的千百级别的物品对用户做个性化精准排序,主要目的是考虑更多用户特征,比如点击序列特征,通过更复杂的模型学习用户属性.
    对于排序来说: 双塔可以考虑用户和物品更多的特征,以端到端的方式计算用户对物品的Label结果

模型结构

在这里插入图片描述
这里简单说几点:

  • 用户和物品的网络可以根据自己需求来改相应的结构;
  • DSSM模型结构跟双塔类似,塔的数量可能不一样;
  • 线上可以用faiss向量索引工具计算向量之间的相似性,提升计算效率

Estimator实现

这块是通过tensorflow的高阶api去构建用户侧和物品侧的网络,一个简单的DNN网络demo,大家可以根据需求更改自己的网络结构.

#!/usr/bin/env python3

#############################################
# FileName: model.py
# Descreption: 双塔召回模型
#############################################

import tensorflow as tf
import config
# 配置参数文件
FLAGS = config.FLAGS

def build_user_model(features, mode, params):
    """
    User Tower Feature Embedding
    :param features:
    :param mode:
    :param params:
    :return:
    """
    # 特征输入
    user_vector_net = []
    for key, value in params["feature_configs"].user_columns.items():
        user_vector_net.append(tf.feature_column.input_layer(features, value))
    # 特征拼接
    net = tf.concat(user_vector_net, axis=1)
    # 全连接
    for idx, units in enumerate(params["hidden_units"]):
        net = tf.layers.dense(net, units=units, activation=tf.nn.leaky_relu, name="user_fc_layer_%s"%idx)
        net = tf.layers.dropout(net, 0.4, training=(mode == tf.estimator.ModeKeys.TRAIN))
    # 最后输出
    net = tf.layers.dense(net, units=64, name="user_output_layer")
    return net


def build_item_model(features, mode, params):
    """
    Item Tower Feature Embedding
    :param features:
    :param model:
    :param params:
    :return:
    """
    # 特征输入
    item_vector_net = []
    for key, value in params["feature_configs"].items_columns.items():
        item_vector_net.append(tf.feature_column.input_layer(features, value))
    # 特征拼接
    net = tf.concat(item_vector_net, axis=1)
    # 全连接
    for idx, units in enumerate(params["hidden_units"]):
        net = tf.layers.dense(net, units=units, activation=tf.nn.leaky_relu, name="user_fc_layer_%s"%idx)
        net = tf.layers.dropout(net, 0.4, training=(mode == tf.estimator.ModeKeys.TRAIN))
    # 最后输出
    net = tf.layers.dense(net, units=64, name="item_output_layer")
    return net


def model_fn(features, labels, mode, params):
    # predict
    if mode == tf.estimator.ModeKeys.PREDICT:
        predictions = dict()
        if FLAGS.export_user_model:
            user_net = build_user_model(features, mode, params)
            predictions = {"user_vector": user_net}
        elif FLAGS.export_item_model:
            item_net = build_item_model(features, mode, params)
            predictions = {"item_vector": item_net}
        export_outputs = {"prediction": tf.estimator.export.PredictOutput(outputs=predictions)}
        return tf.estimator.EstimatorSpec(mode, predictions=predictions, export_outputs=export_outputs)

    # 构建user侧模型
    user_net = build_user_model(features, mode, params)
    # 构建item侧模型
    item_net = build_item_model(features, mode, params)

    # 向量计算
    dot = tf.reduce_sum(tf.multiply(user_net, item_net), axis=1, keep_dims=True)
    pred = tf.sigmoid(dot)

    if mode == tf.estimator.ModeKeys.EVAL:
        labels = tf.cast(labels, tf.float32)
        loss = tf.losses.log_loss(labels, pred)
        metrics = {"auc": tf.metrics.auc(labels=labels, predictions=pred)}
        return tf.estimator.EstimatorSpec(mode, loss=loss, eval_metric_ops=metrics)

    if mode == tf.estimator.ModeKeys.TRAIN:
        labels = tf.cast(labels, tf.float32)
        loss = tf.losses.log_loss(labels, pred)
        global_step = tf.train.get_global_step()
        train_op = tf.train.AdagradOptimizer(FLAGS.learning_rate).minimize(loss, global_step=global_step)
        return tf.estimator.EstimatorSpec(mode, loss=loss, train_op=train_op)

其他的模块都是estimator的公共模块,根据自己的需求来改就可以了.
总的来说: 双塔模型算是深度学习中比较简单的,容易实现的模型了!

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值