tensorflow2实现deepfm

1.deepfm的概述

deepfm是wide&deep的衍生模型,将wide&deep模型中的wide侧替换成FM模型,从而实现二阶的特征组合,增强模型的“记忆性”,deep侧依旧使用传统的DNN模型,增强模型的泛化能力

2.FM侧的二阶组合tensorflow实现
class FM(Layer):
    """Factorization Machine models pairwise (order-2) feature interactions
     without linear term and bias.

      Input shape
        - 3D tensor with shape: ``(batch_size,field_size,embedding_size)``.

      Output shape
        - 2D tensor with shape: ``(batch_size, 1)``.
    """

    def __init__(self,):

        super(FM, self).__init__()

    def build(self, input_shape):
        if len(input_shape) != 3:
            raise ValueError("Unexpected inputs dimensions % d,\
                             expect to be 3 dimensions" % (len(input_shape)))

    def call(self, inputs):

        if K.ndim(inputs) != 3:
            raise ValueError(
                "Unexpected inputs dimensions %d, expect to be 3 dimensions"
                % (K.ndim(inputs)))

        concated_embeds_value = inputs

        square_of_sum = tf.square(tf.math.reduce_sum(
            concated_embeds_value, axis=1, keepdims=True)) # (None,1,k)
        sum_of_square = tf.math.reduce_sum(
            concated_embeds_value * concated_embeds_value, axis=1, keepdims=True) # (None,1,k)
        cross_term = square_of_sum - sum_of_square
        cross_term = 0.5 * tf.math.reduce_sum(cross_term, axis=2, keepdims=False) # (None,1)


        return cross_term

    def compute_output_shape(self, input_shape):
        return (None, 1)

FM的模块输入的一个3维的embedding向量,输出是个2维的向量,同时基于矩阵的维度对计算进行了优化,减缓了不必要的计算消耗。

3.deepfm的实现
# -*- coding:utf-8 -*-
"""
deepfm
"""

from itertools import chain

import tensorflow as tf
from utils import build_input_features,get_linear_logit,get_sparse_emb_dict
from Layers.core import DNN
from Layers.interaction import FM
from tensorflow.keras.layers import Add,Activation,Flatten,Concatenate,Dense
from utils import get_dense_input


def DeepFM(linear_feature_columns, dnn_feature_columns, dnn_hidden_units=(128,64,16),
           l2_reg_linear=0.00001, l2_reg_embedding=0.00001, l2_reg_dnn=0, seed=1024, dnn_dropout=0,
           dnn_activation='relu', dnn_use_bn=True, task='binary'):
    """Instantiates the DeepFM Network architecture.

    :param linear_feature_columns: An iterable containing all the features used by linear part of the model.
    :param dnn_feature_columns: An iterable containing all the features used by deep part of the model.
    :param fm_group: list, group_name of features that will be used to do feature interactions.
    :param dnn_hidden_units: list,list of positive integer or empty list, the layer number and units in each layer of DNN
    :param l2_reg_linear: float. L2 regularizer strength applied to linear part
    :param l2_reg_embedding: float. L2 regularizer strength applied to embedding vector
    :param l2_reg_dnn: float. L2 regularizer strength applied to DNN
    :param seed: integer ,to use as random seed.
    :param dnn_dropout: float in [0,1), the probability we will drop out a given DNN coordinate.
    :param dnn_activation: Activation function to use in DNN
    :param dnn_use_bn: bool. Whether use BatchNormalization before activation or not in DNN
    :param task: str, ``"binary"`` for  binary logloss or  ``"regression"`` for regression loss
    :return: A Keras model instance.
    """

    features_inputs = build_input_features(linear_feature_columns + dnn_feature_columns)

    inputs_list = list(features_inputs.values())

    # LR
    linear_logit = get_linear_logit(features_inputs, linear_feature_columns, seed=seed, prefix='linear',
                                    l2_reg=l2_reg_linear)
    # FM
    sparse_emb_dict = get_sparse_emb_dict(features_inputs,dnn_feature_columns,l2_reg_embedding,prefix='sparse_')
    fm = FM()
    fm_logit = fm(tf.keras.layers.Concatenate(axis=1)(sparse_emb_dict.values()))
    # print(sparse_emb_dict)

    # DNN
    dense_input = get_dense_input(features_inputs, dnn_feature_columns)
    dense_input = Concatenate(axis=1)(dense_input)
    dnn_input = tf.concat([Flatten()(Concatenate(axis=1)(sparse_emb_dict.values())),dense_input],axis=1)
    dnn_output = DNN(dnn_hidden_units, dnn_activation, l2_reg_dnn, dnn_dropout,
                     dnn_use_bn, seed)(dnn_input)
    dnn_logit = Dense(1,use_bias=True, activation='NOne',
                      name='dnn_output',
                      kernel_regularizer=tf.keras.regularizers.l2(l2_reg_dnn),
                      bias_regularizer=tf.keras.regularizers.l2(l2_reg_dnn),
                      )(dnn_output)

    # concat and activation
    out_put =Add()([linear_logit,fm_logit,dnn_logit])
    out_put = Activation('sigmoid')(out_put)
    model = tf.keras.models.Model(inputs=inputs_list, outputs=out_put)
    return model

可以看出:deepfm = FM + DNN = LR + 二阶组合 + DNN

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值