推荐系统遇上深度学习(五)--DeepCross Network模型理论和实践
全文共6215字,8张图,预计阅读时间15分钟。
原理
Deep&Cross Network模型我们下面将简称DCN模型:
一个DCN模型从嵌入和堆积层开始,接着是一个交叉网络和一个与之平行的深度网络,之后是最后的组合层,它结合了两个网络的输出。完整的网络模型如图:
嵌入和堆叠层
我们考虑具有离散和连续特征的输入数据。在网络规模推荐系统中,如CTR预测,输入主要是分类特征,如“country=usa”。这些特征通常是编码为独热向量如“[ 0,1,0 ]”;然而,这往往导致过度的高维特征空间大的词汇。
为了减少维数,我们采用嵌入过程将这些离散特征转换成实数值的稠密向量(通常称为嵌入向量):
然后,我们将嵌入向量与连续特征向量叠加起来形成一个向量:
拼接起来的向量X0将作为我们Cross Network和Deep Network的输入
cross network
交叉网络的核心思想是以有效的方式应用显式特征交叉。交叉网络由交叉层组成,每个层具有以下公式:
一个交叉层的可视化如图所示:
可以看到,交叉网络的特殊结构使交叉特征的程度随着层深度的增加而增大。多项式的最高程度(就输入X0而言)为L层交叉网络L + 1。如果用Lc表示交叉层数,d表示输入维度。然后,参数的数量参与跨网络参数为:d * Lc * 2 (w和b)
交叉网络的少数参数限制了模型容量。为了捕捉高度非线性的相互作用,模型并行地引入了一个深度网络。
Deep Network
深度网络就是一个全连接的前馈神经网络,每个深度层具有如下公式:
Combination Layer
链接层将两个并行网络的输出连接起来,经过一层全链接层得到输出:
如果采用的是对数损失函数,那么损失函数形式如下:
总结
DCN能够有效地捕获有限度的有效特征的相互作用,学会高度非线性的相互作用,不需要人工特征工程或遍历搜索,并具有较低的计算成本。
论文的主要贡献包括:
1)提出了一种新的交叉网络,在每个层上明确地应用特征交叉,有效地学习有界度的预测交叉特征,并且不需要手工特征工程或穷举搜索。
2)跨网络简单而有效。通过设计,各层的多项式级数最高,并由层深度决定。网络由所有的交叉项组成,它们的系数各不相同。
3)跨网络内存高效,易于实现。
4)实验结果表明,交叉网络(DCN)在LogLoss上与DNN相比少了近一个量级的参数量。
这个是从论文中翻译过来的,哈哈。
实现解析
本文的代码根据之前DeepFM的代码进行改进,我们只介绍模型的实现部分,其他数据处理的细节大家可以参考我的github上的代码:
https://github.com/princewen/tensorflow_practice/tree/master/Basic-DCN-Demo
数据下载地址:https://www.kaggle.com/c/porto-seguro-safe-driver-prediction
不去下载也没关系,我在github上保留了几千行的数据用作模型测试。
模型输入
模型的输入主要有下面几个部分:
self.feat_index = tf.placeholder(tf.int32, shape=[None,None], name='feat_index')self.feat_value = tf.placeholder(tf.float32, shape=[None,None], name='feat_value')
self.numeric_value = tf.placeholder(tf.float32,[None,None],name='num_value')
self.label = tf.placeholder(tf.float32,shape=[None,1],name='label')self.dropout_keep_deep = tf.placeholder(tf.float32,shape=[None],name='dropout_deep_deep')
可以看到,这里与DeepFM相比,一个明显的变化是将离散特征和连续特征分开,连续特征不再转换成embedding进行输入,所以我们的输入共有五部分。
feat_index是离散特征的一个序号,主要用于通过embedding_lookup选择我们的embedding。feat_value是对应离散特征的特征值。numeric_value是我们的连续特征值。label是实际值。还定义了dropout来防止过拟合。
权重构建
权重主要包含四部分,embedding层的权重,cross network中的权重,deep network中的权重以及最后链接层的权重,我们使用一个字典来表示:
def _initialize_weights(self): weights = dict()
#embeddings weights['feature_embeddings'] = tf.Variable( tf.random_normal([self.cate_feature_size,self.embedding_size],0.0,0.01),name='feature_embeddings')weights['feature_bias'] = tf.Variable(tf.random_normal([self.cate_feature_size,1],0.0,1.0),name='feature_bias')#deep layersnum_layer = len(self.deep_layers)glorot = np.sqrt(2.0/(self.total_size + self.deep_layers[0]))weights['deep_layer_0'] = tf.Variable(np.random.normal(loc=0,scale=glorot,size=(self.total_size,self.deep_layers[0])),dtype=np.float32)weights['deep_bias_0'] = tf.Variable(np.random.normal(loc=0,scale=glorot,size=(1,self.deep_layers[0])),dtype=np.float32)for i in range(1,num_layer):glorot = np.sqrt(2.0 / (self.deep_layers[i - 1] + self.deep_layers[i]))weights["deep_layer_%d" % i] = tf.Variable(np.random.normal(loc=0, scale=glorot, size=(self.deep_layers[i - 1], self.deep_layers[i])),dtype=np.float32) # layers[i-1] * layers[i]weights["deep_bias_%d" % i] = tf.Variable(np.random.normal(loc=0, scale=glorot, size=(1, self.deep_layers[i])),dtype=np.float32) # 1 * layer[i]for i in range(self.cross_layer_num):weights["cross_layer_%d" % i] = tf.Variable(np.random.normal(loc=0, scale=glorot, size=(self.total_size,1)),dtype=np.float32)weights["cross_bias_%d" % i] = tf.Variable(np.random.normal(loc=0, scale=glorot, size=(self.total_size,1)),dtype=np.float32) # 1 * layer[i]
# final concat projection layer
input_size = self.total_size + self.deep_layers[-1]
glorot = np.sqrt(2.0/(input_size + 1))weights['concat_projection'] = tf.Variable(np.random.normal(loc=0,scale=glorot,size=(input_size,1)),dtype=np.float32)weights['concat_bias'] = tf.Variable(tf.constant(0.01),dtype=np.float32)
return weights
计算网络输入
这一块我们要计算两个并行网络的输入X0,我们需要将离散特征转换成embedding,同时拼接上连续特征:
# modelself.embeddings = tf.nn.embedding_lookup(self.weights['feature_embeddings'],self.feat_index) # N * F * Kfeat_value = tf.reshape(self.feat_value,shape=[-1,self.field_size,1])self.embeddings = tf.multiply(self.embeddings,feat_value)
self.x0 = tf.concat([self.numeric_value, tf.reshape(self.embeddings,shape=[-1,self.field_size * self.embedding_size])] ,axis=1)
根据论文中的计算公式,一步步计算得到cross network的输出:
# cross_partself._x0 = tf.reshape(self.x0, (-1, self.total_size, 1))x_l = self._x0for l in range(self.cross_layer_num):x_l = tf.tensordot(tf.matmul(self._x0, x_l, transpose_b=True), self.weights["cross_layer_%d" % l],1) + self.weights["cross_bias_%d" % l] + x_l
self.cross_network_out = tf.reshape(x_l, (-1, self.total_size))
Deep Network
这一块就是一个多层全链接神经网络:
self.y_deep = tf.nn.dropout(self.x0,self.dropout_keep_deep[0])
for i in range(0,len(self.deep_layers)):self.y_deep = tf.add(tf.matmul(self.y_deep,self.weights["deep_layer_%d" %i]), self.weights["deep_bias_%d"%i])self.y_deep = self.deep_layers_activation(self.y_deep)self.y_deep = tf.nn.dropout(self.y_deep,self.dropout_keep_deep[i+1])
Combination Layer
最后将两个网络的输出拼接起来,经过一层全链接得到最终的输出:
# concat_partconcat_input = tf.concat([self.cross_network_out, self.y_deep], axis=1)
self.out = tf.add(tf.matmul(concat_input,self.weights['concat_projection']),self.weights['concat_bias'])
定义损失
这里我们可以选择logloss或者mse,并加上L2正则项:
# lossif self.loss_type == "logloss":self.out = tf.nn.sigmoid(self.out)self.loss = tf.losses.log_loss(self.label, self.out)elif self.loss_type == "mse":self.loss = tf.nn.l2_loss(tf.subtract(self.label, self.out))# l2 regularization on weightsif self.l2_reg > 0:self.loss += tf.contrib.layers.l2_regularizer(self.l2_reg)(self.weights["concat_projection"])for i in range(len(self.deep_layers)):self.loss += tf.contrib.layers.l2_regularizer( self.l2_reg)(self.weights["deep_layer_%d" % i])for i in range(self.cross_layer_num):self.loss += tf.contrib.layers.l2_regularizer( self.l2_reg)(self.weights["cross_layer_%d" % i])
剩下的代码就不介绍啦!
好啦,本文只是提供一个引子,有关DCN的知识大家可以更多的进行学习呦。
参考文章
1、https://blog.csdn.net/roguesir/article/details/7976320
2、论文:https://arxiv.org/abs/1708.05123
原文链接:https://mp.weixin.qq.com/s/XK0doAhDfyzxzJVgMlnc1g
查阅更为简洁方便的分类文章以及最新的课程、产品信息,请移步至全新呈现的“LeadAI学院官网”:
www.leadai.org
请关注人工智能LeadAI公众号,查看更多专业文章
大家都在看
LSTM模型在问答系统中的应用
基于TensorFlow的神经网络解决用户流失概览问题
最全常见算法工程师面试题目整理(一)
最全常见算法工程师面试题目整理(二)
TensorFlow从1到2 | 第三章 深度学习革命的开端:卷积神经网络
装饰器 | Python高级编程
今天不如来复习下Python基础
推荐系统遇上深度学习(五)--DeepCross Network模型理论和实践相关推荐
- 推荐系统遇上深度学习(九)--评价指标AUC原理及实践
预计阅读时间15分钟. 引言 CTR问题我们有两种角度去理解,一种是分类的角度,即将点击和未点击作为两种类别.另一种是回归的角度,将点击和未点击作为回归的值.不管是分类问题还是回归问题,一般在预估的时 ...
- 推荐系统遇上深度学习,9篇阿里推荐论文汇总!
作者 | 石晓文 转载自小小挖掘机(ID: wAIsjwj) 业界常用的推荐系统主要分为两个阶段,召回阶段和精排阶段,当然有时候在最后还会接一些打散或者探索的规则,这点咱们就不考虑了. 前面九篇文章中 ...
- 推荐系统遇上深度学习(八十七)-[阿里]基于搜索的用户终身行为序列建模
本文介绍的论文是<Search-based User Interest Modeling with Lifelong Sequential Behavior Data for Click-Thr ...
- 推荐系统遇上深度学习(九十二)-[腾讯]RecSys2020最佳长论文-多任务学习模型PLE
今天介绍的是腾讯提出的一种新的多任务学习个性化推荐模型,该论文荣获了RecSys2020最佳长论文奖,一起来学习下! 1.背景 多任务学习通过在一个模型中同时学习多个不同的目标,如CTR和CVR,最近 ...
- 推荐系统遇上深度学习(三十九)-推荐系统中召回策略演进!
推荐系统中的核心是从海量的商品库挑选合适商品最终展示给用户.由于商品库数量巨大,因此常见的推荐系统一般分为两个阶段,即召回阶段和排序阶段.召回阶段主要是从全量的商品库中得到用户可能感兴趣的一小部分候选 ...
- 知识图谱论文阅读(八)【转】推荐系统遇上深度学习(二十六)--知识图谱与推荐系统结合之DKN模型原理及实现
学习的博客: 推荐系统遇上深度学习(二十六)–知识图谱与推荐系统结合之DKN模型原理及实现 知识图谱特征学习的模型分类汇总 知识图谱嵌入(KGE):方法和应用的综述 论文: Knowledge Gra ...
- 推荐系统遇上深度学习(十五)--强化学习在京东推荐中的探索
强化学习在各个公司的推荐系统中已经有过探索,包括阿里.京东等.之前在美团做过的一个引导语推荐项目,背后也是基于强化学习算法.本文,我们先来看一下强化学习是如何在京东推荐中进行探索的. 本文来自于pap ...
- 推荐系统遇上深度学习(二十二):DeepFM升级版XDeepFM模型强势来袭!
今天我们要学习的模型是xDeepFM模型,论文地址为:https://arxiv.org/abs/1803.05170.文中包含我个人的一些理解,如有不对的地方,欢迎大家指正!废话不多说,我们进入正题 ...
- 推荐系统遇上深度学习(十九)--探秘阿里之完整空间多任务模型ESSM
欢迎关注天善智能,我们是专注于商业智能BI,人工智能AI,大数据分析与挖掘领域的垂直社区,学习,问答.求职一站式搞定! 对商业智能BI.大数据分析挖掘.机器学习,python,R等数据领域感兴趣的同学 ...
最新文章
- 【面试精选】关于大型网站系统架构你不得不懂的10个问题
- C++ Boost库初步使用 - 使用CFree
- 转载:SVN插件的手动安装
- 浅析NameNode/DataNode/SecondaryNameNode源码注释
- 使用cl_htmlb_manager获得用户输入
- 配置审计(Config)变配报警设置
- 嘉年华回顾丨周振兴带你解密POLARDB产品架构与实现
- 改善CSS的10种最佳做法,帮助你从样式中获得最大的收益
- swing怎么监听其他类的按钮_舍得酒因资金违规占用被ST,“其他类风险”爆雷到底怎么防?...
- Java Jersey2使用总结
- SQL各个关键字的顺序
- [poj2449]Remmarguts' Date(spfa+A*)
- git学习笔记(1-集中式与分布式版本控制工具对比)
- Win7+MATLAB2017a+虚拟光驱
- C语言中IO模型实现并发服务器
- 怎么利用好公众号后台做好分析报告
- MobaXterm SSH 保持连接
- 解析春运玄学:携程飞猪去哪儿们的抢票加速包,到底灵不灵?
- ffmpeg AVFrame 插入静音帧
- gradle Illegal entry in Gradle Dependencies d:/eclipse
热门文章
- 两用物项许可证办理流程_办理医疗器械经营许可证流程
- 解决“Linux无法登录,显示module is unknown”问题
- sql replace替换多个字符_牛客网数据库SQL实战详细剖析(4150)
- python把数字逐一存入列表_python实现将range()函数生成的数字存储在一个列表中...
- 如何检查python的库是否安装成功_机器学习之Python编程库的安装
- 前端基础之CSS属性
- [HNOI 2011]数学作业
- Java中PO、DO、TO、DTO、 VO、 BO、POJO 、DAO的概念
- Java与.net的区别delegate和event
- linux logrotate进行日志分割