Why DCN? DCN 主要解决什么问题?
1.特征交叉对于预估任务建模至关重要. 所谓特征交叉建模其实就是建模特征之间的”且的关系”; 相比特征信号单独建模, 引入”且的关系”比单独的信号被认为是一种强力的信号增强
2.DCN 期望引入某种结构能够显示建模特征交叉. 当我们在设计神经网络结构显示建模特征交叉的时候, 我们在做怎样一件事? 假设我们采用神经网络的方式进行建模, 我们希望网络实现在二阶 (或更高阶) 的任意两两 feature inner product 结果前面都有一个合理而有用的 weight; 从模型表达上看, 我们希望建模出来的是
举个例子, 在搅拌机的广告点击率预估任务中, 假设我们有三个特征: 用户的国家/买了香蕉的次数/买到烹饪书的次数
经过 crossing 结构, 得到的模型结果应该类似如下
Deep & Cross Network
基于上式 (3), cross net针对每个特征维度, 采用 Polynomial (多项式) 结构去建模特征交叉, formulation:
exhuasitvely,
1.crossing net 由 $N$ 层网络堆叠构成, 其中对第 $l+1$ 层, 由原始特征 $x_0$ 和 $x_l$ 做向量积, 然后引入一个 $W$, 去学习特征交叉之间的 weight; 具体来说在 DCN 中
2.完整 DCN 结构: 通过引入 cross 的结构建模高阶的 feature cross, deep 的结构仍然采取MLP
3.deep 和 cross 的结合方式: 一种是 parallel structure (并行结构): 通过 concat deep 和 cross 的结果, 然后再跟一层网络; 另一种是 stacked structure (堆叠结构), 在 cross 网络上增加 deep 网络; 这两种哪个效果可能更好? 取决于在当前数据集的效果
4.这里的代码实现
def dcn_stack_net(self, input_layer, cross_layer_num, output_size):
"""
x_l = x_0 \odot (W \cdot x_l + b) + x_l
\odot 代表 element-wise 的tensor 乘法, 通常 tf.multiply() 实现
"""
name = 'dcn'
act_fun = tf.nn.tanh
with tf.variable_scope("dcn_stack_net"):
x_0 = input_layer
x_l = x_0
input_size = input_layer.shape1.value
for i in range(cross_layer_num):
w = tf.get_variable(shape=[input_size, input_size], name=f"{name}_kernerl_{i+1}", initializer=tf.random_normal_initializer(stddev=1.0 / math.sqrt(float(input_size))), trainable=True)
b = tf.get_variable(shape=[input_size], name=f"{name}_bias_{i+1}", initializer=tf.zeros_initializer, trainable=True)
dot_ = tf.multiply(x_0, tf.add(tf.matmul(x_l, w), b))
x_l = tf.add(dot_, x_l)
# x_l = act_fun(x_l)
output_w = tf.get_variable(shape=[input_size, output_size], name=f"{name}_output_w")
output_layer = tf.matmul(x_l, output_w)
return output_layer
Cross Network 有什么缺点?
The expressiveness of its cross network is limited. The polynomial class reproduced by the cross network is only characterized by 𝑂 (input size) parameters, largely limiting its flexibility in modeling random cross patterns.
The allocated capacity between the cross network and DNN is unbalanced. This gap significantly increases when applying DCN to large-scale production data. An overwhelming portion of the parameters will be used to learn implicit crosses in the DNN.
intuitively,
1.cross network 的表达能力不足. cross network 针对特征维度, 采用多项式交叉的范式, 交叉作用只作用在”特征数量”这种层面上; 假设有搅拌机广告点击率预估只有3个特征, 交叉作用最多只能发生在”3”这种数量规模的作用上
2.cross network和deep network容量分配不均衡. 在大量数据下, 学习过程中绝大多数参数都用在学dnn里面的交叉, 而不是cross里面的交叉; 我理解从原理上dnn由全连接网络学习到特征交叉, 交叉程度本身要远高于特征层面多项式交叉
3.个人理解 1 和 2 说的都是同一个问题
DCN-V2
DCN V2 在 DCN基础上做了几个改进
1.cross 层的 weight 矩阵从 $W_l\in \mathbb R^d$ 升级到了 矩阵$W_l\in \mathbb R^{d\times d}$ , 也可以理解为当 $W=1\times w^T$ (其中 $1 \in \mathbb R^d$为单位向量) 时, DCN-V2自动退化成了DCN
2.矩阵 $W$ 采用 Low-Rank (低秩分解) 技术降低计算开销. Low-Rank 对一个矩阵 $\mathcal M\in \mathbb R^{d\times d}$ , 分解成 $U, V$ 两个向量的乘积, 其中 $U, V \in R^{d\times r}, r\le d/2$ 通常情况下 $r<<d$; 在采用Low-Rank况下, cross net的结构为
这里的 weight 矩阵的低秩分解有两种解释,
第一种是我们让模型学习到的是特征子空间上的特征交叉, 启发我们的关键优化思路是”在子空间上做交叉”
第二种是我们将特征 $x$ 先投射到一个低纬度的空间 $\mathbb R^r$ , 然后再投射回到 $\mathbb R^b$, 启发我们的关键优化思路是”利用低维度投射空间的特性”
3.基于 Low-Rank 分解子空间的优化思路, 可以自然过渡到 Mixture of Experts (MoE) 方式; 为什么有这种思维的过渡呢? 我的理解是, 模型通过低秩分解事实上已经在一个子空间上搞交叉了, 既然是在一个子空间实现交叉, 那么也不必局限在单纯的矩阵分解子空间的方式; MoE 结构设置多个 Experts, 每个 experts 也是对不同的子空间上做特征交叉, 这么做同样也需要引入 gates, 去自适应地组合多项式模式下逐层交叉后的结果; 因此我们索性用MoE这种更通用的方式去做特征交叉: 假设有 $K$ 个experts, MoE的方式第 $x_{l+1}$ 层是由 $K$ 个 $E_i(x_l)$ 的结果通过gate机制去加权求和得到
4.基于 Low-Rank 分解的低维度投射思路, 既然是做特征投射, 也不必要马上把它投射回来, 而是引入一些非线性的变换, 想要把这些表达做的更好
其中 $g(\cdot)$ 可以用任何一种非线性激活函数
Reference
[1]. Ruoxi Wang et al. Deep & Cross Network for Ad Click Predictions. https://arxiv.org/pdf/1708.05123.pdf.
[2]. Ruoxi Wang et al. DCN V2: Improved Deep & Cross Network and Practical Lessons for Web-scale Learning to Rank Systems. https://arxiv.org/pdf/2008.13535.pdf
转载请注明来源, from goldandrabbit.github.io