目录

一 Deep & Cross Network 网络结构

1. 输入部分

2.嵌入和堆叠层 Embedding and stacking layer

3. 交叉网络 Cross Network

4.深度网络

5. Combination Layer

二 总结


Deep & Cross Network(DCN)在 2017 年由 google 和 Stanford 共同发表的一篇论文中被提出,类似于Wide & Deep Network(WDL),是用复杂网络预估CTR的一种方法。DCN 不需要特征工程来获得高阶的交叉特征,对比 FM 系列[3][4]的模型,DCN 拥有更高的计算效率并且能够提取到更高阶的交叉特征

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

DCN是一个可以同时高效学习低维特征交叉和高维非线性特征的深度模型,不需要人工特征工程的同时需要的计算资源非常低。


一 Deep & Cross Network 网络结构

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

可以看到DCN分成4部分。最底下是“Embedding and stacking layer”,中间部分是“Cross network”和“Deep network”,最上面是“Combination output layer”。

从网络结构上面来看,该模型是非常简单明了的,特征分为类别型与数值型,类别型特征经过 embedding 之后与数值型特征直接拼接作为模型的输入。所有的特征分别经过 cross 和 deep 网络,如果把这两个网络看作特征提取的话,经过提取后的特征向量拼接之后是常规的二分类,如果训练数据是曝光和点击,最后输出的就可以看作点击率了。

下面分别对每个部分进行讲解

1. 输入部分

输入部分包括:

(1)对sparse特征进行embedding,对于multi-hot的sparse特征,embedding之后再做一个简单的average pooling;

(2) 对dense特征归一化,然后和embedding特征拼接,作为随后Cross层与Deep层的共同输入,

2.嵌入和堆叠层 Embedding and stacking layer

这一层是模型的输入层。我们知道输入的特征分为稠密和稀疏特征。

考虑具有稀疏和稠密特征的输入数据。在网络规模推荐系统的CTR预测任务中,输入主要是分类特征,如“country=usa”。这些特征通常是编码为独热向量one hot encoding 如[0,1,0];然而,这通常会产生超高维度的特征空间。为了减少维数,我们采用嵌入过程将这些二进制特征转换成实数值的稠密向量(通常称为嵌入向量)

最终的实现是将一个上万维的词独热表示嵌入到了只有几百维的稠密向量中。而嵌入的本质其实是构建一张随机初始化的向量查找表,通过我们的训练目标做有监督学习来得到不同词在特定目标下,处于向量空间中的位置。

最后,将稠密特征和经过转换的稀疏特征对应的稠密向量concat起来组成模型的最终输入,也就是图中的x0,再喂入到下一层网络

3. 交叉网络 Cross Network

在广告场景下,特征交叉的组合与点击率是有显著相关的,例如,“USA”与“Thanksgiving”、“China”与“Chinese New Year”这样的关联特征,对用户的点击有着正向的影响。换句话说,来自“China”的用户很可能会在“Chinese New Year”有大量的浏览、购买行为,而在“Thanksgiving”却不会有特别的消费行为。这种关联特征与label的正向相关性在实际问题中是普遍存在的,如“化妆品”类商品与“女性”,“球类运动配件”的商品与“男性”,“电影票”的商品与“电影”品类偏好等。因此,引入特征的组合是非常有意义的。看到这种需要,我们很容易就能想到 SVM 里面的多项式核函数,FM 就是在多项式核的基础上,优化了稀疏问题以及计算复杂度的产物。

DCN新的算子,用另一种形式来得到交叉特征, 在cross network里面主要使用以下的公式进行一层一层的叠加:

假如我们要叠加3层,则每一层计算如下

在完成一个特征交叉f后,每个cross layer会将它的输入加回去,并且该模型还用了残差的思想,解决网络性能退化的问题

公式化表达如下:

w和b是我们要学习的参数,可以看到在cross network里面,输入和输出的维度是一样的。

考虑 x₀ 为输入的特征及第一层的输入,x 为 第 L 层的输入,我们可以看到它的基本思路还是用矩阵乘法来实现特征的组合。

所以使用它很容易能得到高于二阶的交叉特征,此公式还有一个小的优化技巧,三矩阵相乘那个算子,用乘法结合律先计算后面两个矩阵的积,这样可以减少三分之一的计算复杂度。

特征的高阶交叉(high-degree interaction):cross network的独特结构使得交叉特征的阶(the degress of cross features)随着layer的深度而增长。对于第 L层layer,它的最高多项式阶(在输入 x0上)是 L+1。

复杂度分析:假设 Lc表示cross layers的数目, d表示输入 X0的维度。由于每一层 cross layer 的权重 w 和偏置 b  都是向量, 那么,在该cross network中涉及的参数数目为:d × Lc × 2.

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

由于 Cross Network 的参数数量相对较少, 这限制了模型的表达能力, 因此需要配合 Deep Network 一起使用.

为什么这么设计?

cross network为1层的时候,我们可以得到的最高是2维的特征交叉;cross network为2层的时候,我们得到的是最高3维的特征交叉;cross network为3层的时候,我们得到的是最高4维的特征交叉;以此类推。。。

因此cross network以一种参数共享的方式,通过对叠加层数的控制,可以高效地学习出低维的特征交叉组合,避免了人工特征工程。

下面看看 DeepCTR-Torch 对 CrossNet 的 PyTorch 实现:

class CrossNet(nn.Module):
    """The Cross Network part of Deep&Cross Network model,
    which leans both low and high degree cross feature.
      Input shape
        - 2D tensor with shape: ``(batch_size, units)``.
      Output shape
        - 2D tensor with shape: ``(batch_size, units)``.
      Arguments
        - **in_features** : Positive integer, dimensionality of input features.
        - **input_feature_num**: Positive integer, shape(Input tensor)[-1]
        - **layer_num**: Positive integer, the cross layer number
        - **l2_reg**: float between 0 and 1. L2 regularizer strength applied to the kernel weights matrix
        - **seed**: A Python integer to use as random seed.
      References
        - [Wang R, Fu B, Fu G, et al. Deep & cross network for ad click predictions[C]//Proceedings of the ADKDD'17. ACM, 2017: 12.](https://arxiv.org/abs/1708.05123)
    """

    def __init__(self, in_features, layer_num=2, seed=1024, device='cpu'):
        super(CrossNet, self).__init__()
        self.layer_num = layer_num
        self.kernels = torch.nn.ParameterList(
            [nn.Parameter(nn.init.xavier_normal_(torch.empty(in_features, 1))) for i in range(self.layer_num)])
        self.bias = torch.nn.ParameterList(
            [nn.Parameter(nn.init.zeros_(torch.empty(in_features, 1))) for i in range(self.layer_num)])
        self.to(device)

    def forward(self, inputs):
        x_0 = inputs.unsqueeze(2)
        x_l = x_0
        for i in range(self.layer_num):
            xl_w = torch.tensordot(x_l, self.kernels[i], dims=([1], [0]))
            dot_ = torch.matmul(x_0, xl_w)
            x_l = dot_ + self.bias[i] + x_l
        x_l = torch.squeeze(x_l, dim=2)
        return x_l

其中 layer_num 表示 Cross Network 的层数, 由于权重W和 Bias 均为向量, 代码中使用 PyTorch 中的 Parameter 来表示, 每一层权重Bias 的大小为 [in_features, 1], 为了方便我们设 in_features = d.

forward 方法中实现 Cross Network 的前向传播逻辑. 其中 inputs 的大小为 [Batch, d], 其中 B 表示一个 Batch 的大小, d 表示每个样本的维度, 即输入特征的维度.

x_0 = inputs.unsqueeze(2)

这一步对 inputsdim=2 进行扩展, 此时 x0 的 Shape 为 [Batch, d, 1]. 之后在 for 循环中, 实现公式

的效果.

第一步X(l)*W先完成 , 即:

xl_w = torch.tensordot(x_l, self.kernels[i], dims=([1], [0]))

这里需要了解下 torch.tensordot, 它将 x_l : [Batch, d, 1]dim=1 这个维度的数据, 即 d 这个维度的数据, 也即特征, 和第 l  层的权重 kernels[i] : [d, 1]dim=0 这个维度的数据, 也就是权重, 进行 element-wise 相乘并求和. 最终的效果就是 Shape 为 [Batch, d, 1] 的特征和 Shape 为 [d, 1] 的权重进行 tensordot 后得到 Shape 为 [B, 1, 1] 的结果.

第二步进行X0*X(l)*W, 代码中表示为 xl_w, 那么这一步的结果为, 这时候得到的 dot_ Shape 和 x_0 相同, 均为 [Batch, d, 1]

dot_ = torch.matmul(x_0, xl_w)

最后一步是加上偏置以及输入自身:

x_l = dot_ + self.bias[i] + x_l

经过 layer_num 次循环后, 也即特征经过了 l l层后, 代码中的 x_l Shape 为 [Batch, d, 1], 因此还需进行最后一步:

x_l = torch.squeeze(x_l, dim=2)

得到大小为 [B, d] 的输入结果.

为什么是先算X<L>*W,再用X0乘

4.深度网络

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

里面可能会用到 Dropout, BN 之类的, 但作者在论文 4.2 节的实现细节中说没有发现 Dropout 或者 L2 正则化有效.

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

5. Combination Layer

,公式如下图所示

最后的输出层, 需要先将 Cross Network 与 Deep Network 的结果进行 Concatenation, 输入到 LR 模型, 从而得到预测概率.

损失函数为 LR 模型的 Negative Log Likelihood, 再加上 L2 正则项:

使用 Adam 算法进行优化.

二 总结

DCN主要有以下几点贡献:

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

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

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

参考:

  1. 玩转企业级Deep&Cross Network模型你只差一步
  2. [深度模型] Deep & Cross Network (DCN)
  3. Deep & Cross Networkfor Ad Click Predictions 论文资料
  4. DeepCTR-Torch 实现了经典的各种 CTR 模型, 非常推荐看源码学习.
  5. (读论文) 推荐系统之ctr预估-DCN模型解析 深入读论文系列
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐