【DNN】PNN(Product Net )

0.前言

相比Embedding+MLP的传统结构,PNN在embedding层后设计了Product Layer,以显示捕捉基于Field的二阶特征相关性。

motivation

Embedding+MLP结构是DNN应用在CTR预估的标准模式。通常,NN层之间都使用“add operation” ,通过激活函数来引入非线性。作者认为,单纯的“add”也许不足以捕获不同的Filed特征间的相关性,原文表述为:"The ‘add’ operations of the perceptron layer might not be useful to explore the interactions of categorical data in multiple fields. ”

文中指出,一些相关研究表明“product”相比“add”能更好得捕捉特征间的dependence,因此作者希望在NN中显示地引入“product”操作,从而更好地学习不同Field特征间的相关性,在DNN结构中引入product layer即是这样的一个尝试。

1.网络结构

PNN包括三层:Embedding Layer、Product Layer、Full-connect Layer。

  1. 最开始的输入太稀疏维度太高,没法直接放到DNN中去学习,所以比较通用的做法就是通过Embedding到一个低维的稠密的实数向量中,作为原始特征的在Embedding空间中的表示。
  2. 然后PNN利用Product Layer来学习filed之间的交互特征,这也就引入了非线性的组合特征。可以采用内积、外积、内积+外积的形式。
  3. 最后利用全连接层充分的学习高阶组合特征,并得到最终CTR预测概率。

作者提出Product-based Neural Network(PNN),PNN的结构非常直观,如下图所示:

PNN与标准的「Embedding+MLP」差异仅在于引入了Product Layer。上图中Product Layer左边Z部分其实就是将Embedding层学到的嵌入直接原封不动地搬来,右边P部分才是我们讨论的重点。注意,product layer 中每个节点(见蓝色节点)是两两Field的embedding对应的“product”结果,而非所有Field的。

根据 product 函数的不同选择,PNN也有不同实现,这里的想象空间就很多了。文中尝试了相对常见的向量内积(inner product)和外积(outer product),对应 IPNN 和OPNN。

虽然结构简单,但这里存在一个大问题:product层的节点数至少是输入Field数的平方级别。在业界现实场景中,输入Field的规模往往很大,这大大增加了网络复杂度,对PNN的实际落地构成了挑战。作者把L1层每个节点的输入来源拆分为两部分,分别来自Embedding层与Product层。

Embedding Layer

Embedding Layer跟DeepFM中相同,将每一个field的特征转换成同样长度的向量,这里用f来表示。

Product layer

  • Product Layer中z中每个圈都是一个向量,向量大小为Embedding Vector大小向量个数 = Field个数 = Embedding向量的个数
  • Product Layer中如果是内积,p中每个圈都是一个值;如果是外积,p中每个圆圈都是一个二维矩阵

IPNN

IPNN中p的计算方式如下,即使用内积来代表pij:

所以,pij其实是一个数(标量),得到一个pij的时间复杂度为M,p的大小为N*N,因此计算得到p的时间复杂度为N*N*M。而再由p得到lp的时间复杂度是N*N*D1。因此 对于IPNN来说,总的时间复杂度为N*N(D1+M)。文章对这一结构进行了优化,可以看到,我们的p是一个对称矩阵,因此我们的权重也是一个对称矩阵,对这个对称矩阵进行如下的分解:

总结:得到一个标量,通过一阶矩阵分解来近似W,从而降低复杂度。

OPNN

此时pij为M*M的矩阵,计算一个pij的时间复杂度为M*M,而p是N*N*M*M的矩阵,因此计算p的事件复杂度为N*N*M*M。从而计算lp的时间复杂度变为D1 * N*N*M*M。这个显然代价很高的。

如何跟送入到L1层?

如果Product Layer使用外积运算,就得到OPNN。外积得到的是一个矩阵,所以p中的每个神经元都是一个矩阵。针对两个M维的嵌入向量e1和e2. 它们外积得到的是M*M的二维矩阵。一共有N个嵌入向量,那么矩阵就有N(N-1)/2个。那么一个二维矩阵怎么输入到神经网络中去那?

针对外积产生的每一个二维矩阵,我们都通过另外一个矩阵W,大小为M*M。这两个矩阵对应位置相乘,再相加,就得到了最终的结果。

也就是说,最终外积产生的二维矩阵,通过和另外一个需要学习的参数矩阵,对应位置相乘,再相加,得到了一个标量,一个实数值。

L1层

L1 = z + p +b.

可以认为z就是embedding层的复制。对于p来说,这里需要一个公式进行映射:p= f(f1, f2).f()函数由上述两种方法计算得到。

损失函数

交叉熵损失函数。

2.代码

作者公开的代码

3.总结:

  1. PNN的动机很直观,通过在NN的嵌入层和隐层之间引入product层,显示地引入基于field的“product”,从而加强单纯基于“add”的NN的特征相关性学习能力。
  2. product函数的选择有不少想象空间;而引入product后的模型复杂度,将直接影响落地可行性。构造怎样的product函数以及如何降低复杂度是使用product layer的关键,例如文中对IPNN和OPNN的处理。一个实用的落地trick是基于先验知识,只在指定的Field间作product,从而降低复杂度,当然这也导致了需要human effort的坑。
  3. PNN从FM何FNN的角度出发,提出利用内积或者外积来学习高阶的非线性特征,还是挺有创新的。
    基本上使用DNN的模型,最开始都是经过Embedding把原始高纬度稀疏的输入转换为低维度稠密的向量,PNN也不例外。对于FM来说,这就是隐向量,FNN也是利用FM来进行Embedding Vector的初始化的。

4.其他

工作中使用的pnn比较简单了,内积的形式,选择一部分特征手动进行交叉,类似FM的操作。

参考:

1.作者源代码:https://github.com/Atomu2014/product-nets

2.论文:https://arxiv.org/pdf/1611.00144.pdf

3.https://zhuanlan.zhihu.com/p/56651241

4.https://zhuanlan.zhihu.com/p/74726919

5.跟作者讨论过:https://blog.csdn.net/u010352603/article/details/82670323

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章