PNN模型指出: 对特征进行embeddding,然后输入到DNN中进行特征的自动交叉,这样的方式并不充分,因此提出了一种Product-base 的方式。具体的模型结构如下:从上到下的方式介绍上图中的各个结构。首先是输出层,即图中的CTR层,这里采用的就是全连接+sigmoid的做法。然后是l2层,具体做法如下面公式所示:接下来就到本文的核心部分了,从上述公式中可以看出l1层的输入为lz和lp。这里的b1是偏置项,不做过多介绍。因此,Product Layer可以分为两部分: 线性部分lz和非线性部分lp。二者的具体形式如下:其中代表的是矩阵的点乘。看上面的公式,首先需要知道z和p分别代表了什么。z是线性信号向量,即embedding层得到的:论文中使用的等号加一个三角形,其实就是相等的意思,你可以认为z就是embedding层的复制。对于p来说,这里是通过一个公式进行映射的:g函数的选择不同使得我们有两种PNN的计算方法。一种叫做Inner PNN,即IPNN;一种叫做Outer PNN, 即OPNN。下面分别介绍这两种计算方式。首先我们定义嵌入向量的维度为M,特征数为N, lz和lp的长度为D1。如上图所示,IPNN的计算方式就是将两两特征之间的嵌入向量进行内积计算。pij代表特征i和特征j之间嵌入向量的内积,显然pij就是一个标量。得到一个pij的时间复杂度为M,那么得到所有的p的时间复杂度为N*N*M。再由p到lp,时间复杂度为N*N*D1。因此,最后的IPNN的时间复杂度变为N*N*(M+D1)。文章对此结构进行了优化,从上述的计算中可以看出p肯定是个对称阵。因此,我们的权重矩阵也可以是个对称阵,对权重矩阵分解:然后计算其中此时,权重只需要D1*N。最后的时间复杂度变为了D1*M*N。若一个特征向量的维度为M×1,另一个特征向量的维度也是M×1,这pij的维度为(M×1)*(1×M) = (M×M)。因此,计算一个pij的时间复杂度就是M*M,那么计算出整个p的时间复杂度就是N*N*M*M。进而计算lp的时间复杂度就是D1*N*N*M*M。显然时间复杂度非常高,论文采用了叠加的思路重新定义了p矩阵:对于输入层和Embedding层,就是将所有的特征嵌入成一个等长的稠密向量,然后送入Product Layer进行计算。实验部分
可以发现IPNN、OPNN、PNN在不同的数据集上的表现不相上下。
参考文献:
https://www.jianshu.com/p/be784ab4abc2
代码实现:
https://github.com/shawroad/DeepCTR-pytorch/tree/main/PNN
相关素材