DCN
动机
Wide&Deep 模型的提出不仅综合了 “记忆能力” 和 “泛化能力”, 而且开启了不同网络结构融合的新思路。 所以后面就有各式各样的模型改进 Wide 部分或者 Deep 部分, 而 Deep&Cross 模型 (DCN) 就是其中比较典型的一个,这是 2017 年斯坦福大学和谷歌的研究人员在 ADKDD 会议上提出的, 该模型针对 W&D 的 wide 部分进行了改进, 因为 Wide 部分有一个不足就是需要人工进行特征的组合筛选, 过程繁琐且需要经验, 而 2 阶的 FM 模型在线性的时间复杂度中自动进行特征交互,但是这些特征交互的表现能力并不够,并且随着阶数的上升,模型复杂度会大幅度提高。于是乎,作者用一个 Cross Network 替换掉了 Wide 部分,来自动进行特征之间的交叉,并且网络的时间和空间复杂度都是线性的。 通过与 Deep 部分相结合,构成了深度交叉网络(Deep & Cross Network),简称 DCN。
模型结构及原理
这个模型的结构是这个样子的:
这个模型的结构也是比较简洁的, 从下到上依次为:Embedding 和 Stacking 层, Cross 网络层与 Deep 网络层并列, 以及最后的输出层。下面也是一一为大家剖析。
Embedding 和 Stacking 层
Embedding 层我们已经非常的熟悉了吧, 这里的作用依然是把稀疏离散的类别型特征变成低维密集型。
其中对于某一类稀疏分类特征(如 id),
最后,该层需要将所有的密集型特征与通过 embedding 转换后的特征进行联合(Stacking):
一共
Cross Network
这个就是本模型最大的亮点了【Cross 网络】, 这个思路感觉非常 Nice。设计该网络的目的是增加特征之间的交互力度。交叉网络由多个交叉层组成, 假设第
可以看到, 交叉层的二阶部分非常类似 PNN 提到的外积操作, 在此基础上增加了外积操作的权重向量
可以看到, 每一层增加了一个
我们根据上面这个公式, 尝试的写前面几层看看:
我们暂且写到第 3 层的计算, 我们会发现什么结论呢? 给大家总结一下:
中包含了所有的 的 1,2 阶特征的交互, 包含了所有的 的 1、2、3 阶特征的交互, 中包含了所有的 , 与 的交互, 的 1、2、3、4 阶特征交互。 因此, 交叉网络层的叉乘阶数是有限的。 第 层特征对应的最高的叉乘阶数Cross 网络的参数是共享的, 每一层的这个权重特征之间共享, 这个可以使得模型泛化到看不见的特征交互作用, 并且对噪声更具有鲁棒性。 例如两个稀疏的特征
, 它们在数据中几乎不发生交互, 那么学习 的权重对于预测没有任何的意义。计算交叉网络的参数数量。 假设交叉层的数量是
, 特征 的维度是 , 那么总共的参数是:这个就是每一层会有
和 。且 维度和 的维度是一致的。交叉网络的时间和空间复杂度是线性的。这是因为, 每一层都只有
和 , 没有激活函数的存在,相对于深度学习网络, 交叉网络的复杂性可以忽略不计。Cross 网络是 FM 的泛化形式, 在 FM 模型中, 特征
的权重 , 那么交叉项 的权重为 。在 DCN 中, 的权重为 , 交叉项 的权重是参数 和 的乘积,这个看上面那个例子展开感受下。因此两个模型都各自学习了独立于其他特征的一些参数,并且交叉项的权重是相应参数的某种组合。FM 只局限于 2 阶的特征交叉 (一般),而 DCN 可以构建更高阶的特征交互, 阶数由网络深度决定,并且交叉网络的参数只依据输入的维度线性增长。还有一点我们也要了解,对于每一层的计算中, 都会跟着
, 这个是咱们的原始输入, 之所以会乘以一个这个,是为了保证后面不管怎么交叉,都不能偏离我们的原始输入太远,别最后交叉交叉都跑偏了。 , 这个东西其实有点跳远连接的意思,也就是和 ResNet 也有点相似,无形之中还能有效的缓解梯度消失现象。
好了, 关于本模型的交叉网络的细节就介绍到这里了。这应该也是本模型的精华之处了,后面就简单了。
Deep Network
这个就和上面的 D&W 的全连接层原理一样。这里不再过多的赘述。
具体的可以参考 W&D 模型。
组合输出层
这个层负责将两个网络的输出进行拼接, 并且通过简单的 Logistics 回归完成最后的预测:
其中
Cross&Deep 模型的原理就是这些了,其核心部分就是 Cross Network, 这个可以进行特征的自动交叉, 避免了更多基于业务理解的人工特征组合。 该模型相比于 W&D,Cross 部分表达能力更强, 使得模型具备了更强的非线性学习能力。
代码实现
下面我们看下 DCN 的代码复现,这里主要是给大家说一下这个模型的设计逻辑,参考了 deepctr 的函数 API 的编程风格, 具体的代码以及示例大家可以去参考后面的 GitHub,里面已经给出了详细的注释, 这里主要分析模型的逻辑这块。关于函数 API 的编程式风格,我们还给出了一份文档, 大家可以先看这个,再看后面的代码部分,会更加舒服些。
从上面的结构图我们也可以看出, DCN 的模型搭建,其实主要分为几大模块, 首先就是建立输入层,用到的函数式 build_input_layers
,有了输入层之后, 我们接下来是 embedding 层的搭建,用到的函数是 build_embedding_layers
, 这个层的作用是接收离散特征,变成低维稠密。 接下来就是把连续特征和 embedding 之后的离散特征进行拼接,分别进入 wide 端和 deep 端。 wide 端就是交叉网络,而 deep 端是 DNN 网络, 这里分别是 CrossNet()
和 get_dnn_output()
, 接下来就是把这两块的输出拼接得到最后的输出了。所以整体代码如下:
def DCN(linear_feature_columns, dnn_feature_columns):
# 构建输入层,即所有特征对应的Input()层,这里使用字典的形式返回,方便后续构建模型
dense_input_dict, sparse_input_dict = build_input_layers(linear_feature_columns + 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)
concat_dense_inputs = Concatenate(axis=1)(list(dense_input_dict.values()))
# 将特征中的sparse特征筛选出来
sparse_feature_columns = list(filter(lambda x: isinstance(x, SparseFeat), linear_feature_columns)) if linear_feature_columns else []
sparse_kd_embed = concat_embedding_list(sparse_feature_columns, sparse_input_dict, embedding_layer_dict, flatten=True)
concat_sparse_kd_embed = Concatenate(axis=1)(sparse_kd_embed)
dnn_input = Concatenate(axis=1)([concat_dense_inputs, concat_sparse_kd_embed])
dnn_output = get_dnn_output(dnn_input)
cross_output = CrossNet()(dnn_input)
# stack layer
stack_output = Concatenate(axis=1)([dnn_output, cross_output])
# 这里的激活函数使用sigmoid
output_layer = Dense(1, activation='sigmoid')(stack_output)
model = Model(input_layers, output_layer)
return model
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
这个模型的实现过程和 DeepFM 比较类似,这里不画草图了,如果想看的可以去参考 DeepFM 草图及代码之间的对应关系。
下面是一个通过 keras 画的模型结构图,为了更好的显示,类别特征都只是选择了一小部分,画图的代码也在 github 中。
思考
- 请计算 Cross Network 的复杂度,需要的变量请自己定义。
- 在实现矩阵计算
的过程中,有人说要先算前两个,有人说要先算后两个,请问那种方式更好?为什么?
参考资料
- 《深度学习推荐系统》 --- 王喆
- Deep&Cross 模型原论文
- AI 上推荐 之 Wide&Deep 与 Deep&Cross 模型(记忆与泛化并存的华丽转身)
- Wide&Deep 模型的进阶 ---Cross&Deep 模型