【DNN】DCN(Deep & Cross Network)网络结构和代码

0.思考

DNN网络对特征进行不断的抽象,获得更高阶的特征,这个跟特征交叉不太一样。为什么呐?我理解更高阶特征表示为描述同一个东西的共性,看山是山的样子;特征交叉表示为特征A且特征B的时候,会产生什么样的效果,多种因素组合起来,刻画对象。DNN捕捉非线性高阶特征,特征交叉捕捉有限阶特征组合。

那么存在一个问题,特征交叉时,会出现某一个特征为0的情况,这时交叉项得到的组合特征也是0,怎么办?

对于这个问题的解决,有FM,学习每一维特征的隐向量,即使在历史行为中,这个特征没有出现,即为0,但,依然可以学出一个向量来表示这个特征,那么在后续线上遇见这种行为了,便可以参与计算,精准预测。

目的:

通过网络的形式进行特征交叉。

优点:

WDL中,wide侧的交叉组合特征依然需要依靠hand-craft来完成。而DCN能对sparse和dense的输入自动学习特征交叉,可以有效地捕获有限阶(bounded degrees)上的有效特征交叉,无需人工特征工程或暴力搜索(exhaustive searching),并且计算代价较低。

DCN主要有以下几点贡献:

  • 提出一种新型的交叉网络结构,可以用来提取交叉组合特征,并不需要人为设计的特征工程;
  • 这种网络结构足够简单同时也很有效,可以获得随网络层数增加而增加的多项式阶(polynomial degree)交叉特征;
  • 十分节约内存(依赖于正确地实现),并且易于使用;
  • 实验结果表明,DCN相比于其他模型有更出色的效果,与DNN模型相比,较少的参数却取得了较好的效果。

1.网络结构

DCN模型以一个嵌入和堆叠层(embedding and stacking layer)开始,接着并列连一个cross network和一个deep network,接着通过一个combination layer将两个network的输出进行组合。网络结构如下图所示:

cross网络

在完成一个特征交叉f后,每个cross layer会将它的输入加回去,对应的mapping function F ,刚好等于残差xl+1 -  想xl  ,这里借鉴了残差网络的思想。

特征的高阶交叉(high-degree interaction):cross network的独特结构使得交叉特征的阶(the degress of cross features)随着layer的深度而增长。

一个cross network的时间和空间复杂度对于输入维度是线性关系。因而,比起它的deep部分,一个cross network引入的复杂度微不足道,DCN的整体复杂度与传统的DNN在同一水平线上。如此高效(efficiency)是受益于 X0 * Xl^T (体现特征交叉的地方)的rank-one特性(两个向量的叉积),它可以使我们生成所有的交叉项,无需计算或存储整个matrix。

deep网络

交叉网络的参数数目少,从而限制了模型的能力(capacity)。为了捕获高阶非线性交叉,我们平行引入了一个深度网络。

深度网络就是一个全连接的前馈神经网络,每个深度层具有如下公式:

Combination Layer

最后,将两个network的输出进行拼接(concatenate),然后将该拼接向量(concatenated vector)喂给一个标准的逻辑回归模型。

类似于WDL模型,我们对两个network进行jointly train,在训练期间,每个独立的network会察觉到另一个。下面给出整个模型的实现代码:

2.代码

cross网络代码

根据cross层的计算逻辑,有一个优化的代码形式,先计算Xl ^T* W = C,再计算X0 *C,计算量大大降低。X0* Xl是一个矩阵,而Xl ^T* W是一个标量。

def cross_layer2(x0, x, name):
  with tf.variable_scope(name):
    input_dim = x0.get_shape().as_list()[1]
    w = tf.get_variable("weight", [input_dim], initializer=tf.truncated_normal_initializer(stddev=0.01))
    b = tf.get_variable("bias", [input_dim], initializer=tf.truncated_normal_initializer(stddev=0.01))
    xb = tf.tensordot(tf.reshape(x, [-1, 1, input_dim]), w, 1)
    return x0 * xb + b + x

def build_cross_layers(x0, params):
  num_layers = params['num_cross_layers']
  x = x0
  for i in range(num_layers):
    x = cross_layer2(x0, x, 'cross_{}'.format(i))
  return x

deep网络的代码:

def build_deep_layers(x0, params):
  # Build the hidden layers, sized according to the 'hidden_units' param.
  net = x0
  for units in params['hidden_units']:
    net = tf.layers.dense(net, units=units, activation=tf.nn.relu)
  return net

Combination Layer

def dcn_model_fn(features, labels, mode, params):
  x0 = tf.feature_column.input_layer(features, params['feature_columns'])
  last_deep_layer = build_deep_layers(x0, params)
  last_cross_layer = build_cross_layers(x0, params)
  last_layer = tf.concat([last_cross_layer, last_deep_layer], 1)
  my_head = tf.contrib.estimator.binary_classification_head(thresholds=[0.5])
  logits = tf.layers.dense(last_layer, units=my_head.logits_dimension)
  optimizer = tf.train.AdagradOptimizer(learning_rate=params['learning_rate'])
  return my_head.create_estimator_spec(
    features=features,
    mode=mode,
    labels=labels,
    logits=logits,
    train_op_fn=lambda loss: optimizer.minimize(loss, global_step=tf.train.get_global_step())
  )

3.thinking

这里的cross方法和FM的交叉组合方式有没有联系?或者说有何异同?

论文中,3.2小结简单有分析,两者思想近似,DCN是FM的一个升级版本。

一、在参数上,FM的xixj交叉特征取决于<vi, vj>。DCN是参数共享的,这样虽然有点慢,但会产生产生一些意想不到的特征组合方式,对噪声更加鲁棒。

二、交叉的特征维度上,FM只能交叉2维,DCN可以对全部特征进行交叉。


论文精读记录

收获:

DCN和FM和DNN在做特征交叉上有何区别?

FM是二阶特征交叉,DNN是特征的高阶交叉,非线性组合,是隐式的组合;DCN是有限阶的特征交叉组合,是显示的组合;随着特征交叉阶数的增加,参数线性增加;FM如果更高阶的交叉,参数会指数增长。

 

abstract:

特征工程是模型预测的关键,特征工程需要人工处理。DNN可以学到特征的交叉,得到隐式的结果(interactions implicitly ),对学习全部类型的交叉特征(cross features )不高效。DCN网络保留了DNN的优势,对特征交叉也提供了更加便捷的方式。显式的在每层使用特征交叉,不需要求人工特征工程。给DNN增加额外的开销几乎可以忽略不计。

Cross network由多层组成,交叉阶数随着深度增加而增加。DNN跟cross net相比,需要更多的参数,不能像cross net那样显式的交叉特征。

FM将稀疏特征映射到低维稠密向量中,通过内积的形式进行特征交叉。

FFm,允许一个特征学习出几个向量,每一个向量跟一个field有关。

FM和FFM这种浅层结构限制了他们的表达能力,一些工作将二者推向更高阶,但是一个受限的方面是参数梳理较大,对计算性能要求较高。

DNN可以学习出抽象的高阶交互特征(因为embeding向量和非线性激活方程)。deep crossing借鉴了残差网络,实现了通过堆叠方式,自动学习交叉特征。

DNN强在它的表示能力。在足够的隐层单元下,DNN可以拟合任意的方程。在实践中,也证明了DNN在一定参数下,达到不错的效果。一个关键因素是One key reason is that most func- tions of practical interest are not arbitrary. 

另一个留存的问题是DNN是否高效的,在表示practical interest的方程时。kaggle比赛中,手动交叉的一些方案是低阶的,显式且高效;DNN学到的特征,是隐式的,高阶非线性的,这就需要设计一个模型,它有能力学习一些有界阶数的交互特征,表现出显式组合(bounded-degree feature interactions more efficiently and explicitly than a universal DNN ).

Wide and deep模型,有特征交叉的那么一点意思,手动交叉特征作为线性模型的输入,联合训练线性和dnn模型。不足的地方是:过于依赖特征交叉的方式,交叉特征的方式不高效。

Main contribution

对稀疏和稠密的输入,自动学习特征。高效捕捉有限阶的交互特征,和高阶非线性交互。不需要人工特征工程或者遍历搜索,计算代价小。

本文的主要贡献:

1.提出了一种显示的特征交叉网络,高效的学习有限阶交叉特征,无需人工交叉和遍历搜索。

2.交叉网络是高效的。经过设计,随着层数的增加多项式的阶数也在增加,每层参数不同。

3.交叉网络记忆高效,易于实现。

4.DCN比DNN有更小的log loss,二者参数接近。

2 DEEP & CROSS NETWORK (DCN) 

DCN结构:开始于embeding和stacking层, 随后是并行的cross 和deep 层,然后combination 层,输出结果。

2.1 Embedding and Stacking Layer 

类别特征进行onthot编码后,维度太大,将其embedding为稠密向量。

映射的权重矩阵Wembed ,随着网络不断的优化。

将embedding的向量跟dense特征stack起来,就是concat起来,变成一个向量作为模型的输入。

2.2 Cross Network 

Cross network的主要思想是:用高效的方式,进行显示的特征交叉。

每一层都在拟合当前层跟前一层的残差。

复杂度分析:d* L*2,d是输入的维度,L是cross的层。复杂度是线性的。相比dnn,cross的复杂度可以忽略不计。得益于X0*Xl_T,是一维,不用计算存储矩阵,又能产生全部的交叉项目。

2.3 Deep Network 

Fnn,激活函数是relu。

复杂度分析:d*M+ M + (M^2 + M) * (Ld - 1)

2.4 Combination Layer 

Concat两个网络的输出,链接为一个向量,将其输入到一个标准的逻辑层logits layer ,输出两个类别的概率。

损失函数仍然是logloss,带上正则项。

3 CROSS NETWORK ANALYSIS 

分析下DCN中的crossnet的效率。从三个方面:多项式、FM、efficient projection. 

多项式方面:一通证明,说明给一个道理:有多少层,就多少层+1维的特征交叉,比如2层,那么就有三个维度的特征交叉,3层,就有四个维度的特征交叉。哪一维度出现在交叉项中,取决于阿发参数。

FM的泛化:具有FM的灵魂,比FM的结构更深。

模型中的每一个特征的学习,也独立于其他特征。交叉项的权重是对应参数的组合。参数共享可能使得模型学习起来不那么高效,但或许能学到一些意想不到的特征组合,抗造能力更强。相比于FM的高阶形式,crossnet的参数是线性增长,比FM节省参数。

Efficient Projection 高效投影?

每一层,相等于x0和xl的一对映射,维度还是原来输入的维度=x0的维度。x0和xl相乘组合后,会有d^2个,w矩阵需要是[d^2, d]维,将cross之后的结果再映射回到d维。

 

参考:

1.论文:https://arxiv.org/pdf/1708.05123.pdf

2.https://zhuanlan.zhihu.com/p/43364598

3.代码:https://github.com/yangxudong/deeplearning/blob/master/DCN/deep_cross_network.py

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值