如上图所知,其原始输入X0是由连续特征(Dense feature)和类别特征(Sparse feature)拼接而成。
因此同样需要先建立一个[M,K]的embedding矩阵,然后通过tf.lookup函数从emb matrix取出一批次的类别特征[B,F,K]
X0:[B,F*K+D] ==> [B,d] 注:为方便用d代替(F*K+D)
可以着重研究一下为什么是这种交叉方式,他实现了怎样的交叉
图源自知乎https://zhuanlan.zhihu.com/p/96010464
从上可以推断,当cross layer叠加至L层时 ,特征实现了L+1阶的所有交叉组合,真的是很强!
复杂度分析:假设有L个cross层,每层的需要训练的参数是w,b有2*d个参数,因此共有L*2*d个参数。时间和空间复杂度均是随输入维度增长而线性增长的。
在计算时,因为x'w为标量,因为可先计算后两项,再和x0相乘,维度代码如下
xl_w = tf.tensordot(xl, w, axes=[1,0]) # (B, )
x0_xl_w = tf.multiply(x0, tf.expand_dims(xl_w, -1)) #[B,d]
x = tf.add(x0_xl_w, b) # [B,d]
x = x+xl # [B,d]
deep层就是普通DNN模型了,也是帮助特征进行交叉,实现特征的非线性变化,维度和思想都比较简单,就不多赘述了。
最后将两层拼接起来,再经过一个fc layer,得到[B,1]的输出,经过sigmoid函数的洗礼就是最终的预测值了
# concat_part
concat_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'])