ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

推荐系统-DeepCrossing

2021-03-16 23:59:15  阅读:205  来源: 互联网

标签:inputs dense list DeepCrossing dnn 系统 sparse input 推荐


这是一个把深度学习架构应用于推荐系统中的模型, 2016年由微软提出, 完整的解决了特征工程、稀疏向量稠密化, 多层神经网络进行优化目标拟合等一系列深度学习再推荐系统的应用问题。 这个模型涉及到的技术比较基础,在传统神经网络的基础上加入了embedding,残差连接等思想,且结构比较简单.

DeepCrossing模型应用场景是微软搜索引擎Bing中的搜索广告推荐, 用户在输入搜索词之后, 搜索引擎除了返回相关结果, 还返回与搜索词相关的广告,Deep Crossing的优化目标就是预测对于某一广告, 用户是否会点击,依然是点击率预测的一个问题。

DeepCrossing模型要在内部网络结构中解决如下问题:

  1. 离散类特征编码后过于稀疏, 不利于直接输入神经网络训练, 需要解决稀疏特征向量稠密化的问题
  2. 如何解决特征自动交叉组合的问题
  3. 如何在输出层中达成问题设定的优化目标

Embedding Layer
Stacking Layer
#将所有的dense特征拼接到一起
dense_dnn_list = list(dense_input_dict.values())
dense_dnn_inputs = Concatenate(axis=1)(dense_dnn_list) # B x n (n表示数值特征的数量)

因为需要将其与dense特征拼接到一起所以需要Flatten,不进行Flatten的Embedding层输出的维度为:Bx1xdim

sparse_dnn_list = concat_embedding_list(dnn_feature_columns, sparse_input_dict, embedding_layer_dict, flatten=True)

sparse_dnn_inputs = Concatenate(axis=1)(sparse_dnn_list) # B x m*dim (n表示类别特征的数量,dim表示embedding的维度)

将dense特征和Sparse特征拼接到一起

dnn_inputs = Concatenate(axis=1)([dense_dnn_inputs, sparse_dnn_inputs]) # B x (n + m*dim)

该层的主要结构是MLP, 但DeepCrossing采用了残差网络进行的连接。

DNN残差块的定义

class ResidualBlock(Layer):
def init(self, units): # units表示的是DNN隐藏层神经元数量
super(ResidualBlock, self).init()
self.units = units

def build(self, input_shape):
    out_dim = input_shape[-1]
    self.dnn1 = Dense(self.units, activation='relu')
    self.dnn2 = Dense(out_dim, activation='relu') # 保证输入的维度和输出的维度一致才能进行残差连接
def call(self, inputs):
    x = inputs
    x = self.dnn1(x)
    x = self.dnn2(x)
    x = Activation('relu')(x + inputs) # 残差操作
    return x

Scoring Layer

block_nums表示DNN残差块的数量

def get_dnn_logits(dnn_inputs, block_nums=3):
dnn_out = dnn_inputs
for i in range(block_nums):
dnn_out = ResidualBlock(64)(dnn_out)

# 将dnn的输出转化成logits
dnn_logits = Dense(1, activation='sigmoid')(dnn_out)

return dnn_logits

如果是用于点击率预估模型的损失函数就是对数损失函数:

l o g l o s s = − 1 N ∑ 1 N ( y i l o g ( p i ) + ( 1 − y i ) l o g ( 1 − p i ) logloss=-\frac 1N\sum_1^N(y_ilog(p_i)+(1-y_i)log(1-p_i) logloss=−N1​1∑N​(yi​log(pi​)+(1−yi​)log(1−pi​)
其中 y i y_i yi​表示真实的标签(点击或未点击), p i p_i pi​表示Scoring Layer输出的结果。但是在实际应用中,根据不同的需求可以灵活替换为其他目标函数。

def DeepCrossing(dnn_feature_columns):
# 构建输入层,即所有特征对应的Input()层,这里使用字典的形式返回,方便后续构建模型
dense_input_dict, sparse_input_dict = build_input_layers(dnn_feature_columns)

# 构建模型的输入层,模型的输入层不能是字典的形式,应该将字典的形式转换成列表的形式
# 注意:这里实际的输入与Input()层的对应,是通过模型输入时候的字典数据的key与对应name的Input层
input_layers = list(dense_input_dict.values()) + list(sparse_input_dict.values())

# 构建维度为k的embedding层,这里使用字典的形式返回,方便后面搭建模型
embedding_layer_dict = build_embedding_layers(dnn_feature_columns, sparse_input_dict, is_linear=False)

#将所有的dense特征拼接到一起
dense_dnn_list = list(dense_input_dict.values())
dense_dnn_inputs = Concatenate(axis=1)(dense_dnn_list) # B x n (n表示数值特征的数量)

# 因为需要将其与dense特征拼接到一起所以需要Flatten,不进行Flatten的Embedding层输出的维度为:Bx1xdim
sparse_dnn_list = concat_embedding_list(dnn_feature_columns, sparse_input_dict, embedding_layer_dict, flatten=True) 

sparse_dnn_inputs = Concatenate(axis=1)(sparse_dnn_list) # B x m*dim (n表示类别特征的数量,dim表示embedding的维度)

# 将dense特征和Sparse特征拼接到一起
dnn_inputs = Concatenate(axis=1)([dense_dnn_inputs, sparse_dnn_inputs]) # B x (n + m*dim)

# 输入到dnn中,需要提前定义需要几个残差块
output_layer = get_dnn_logits(dnn_inputs, block_nums=3)

model = Model(input_layers, output_layer)
return model

把模型做了打包

感觉还是没怎么搞明白,没有用心去实际操作,容易学习了又忘记,或者没有学深入,得花时间沉下心学习。

标签:inputs,dense,list,DeepCrossing,dnn,系统,sparse,input,推荐
来源: https://blog.csdn.net/m0_49978528/article/details/114907560

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有