NFM(神经因子分解机)

概述

NFM(Neural Factorization Machines)是 2017 年由新加坡国立大学的何向南教授等人在 SIGIR 会议上提出的一个模型。

顾名思义,NFM 就是 DNN 和 FM 的结合。

根据前面 DeepFM 等模型的解析我们了解到,引入 FM 是为了让模型学习到一二阶这样的低阶特征,但它是线性特征交叉(预测变量是模型参数的线性组合),不能有效捕捉真实数据里的非线性复杂结构,能学到的表示模式受限。引入 DNN 则是为了学习更高阶的特征和非线性特征交叉。

本文提出的 NFM 可以对稀疏特征建模,该模型综合考虑了:

  • (1)FM 里线性的二阶特征交叉和
  • (2)NN 模型非线性的高阶特征交叉。此外,FM 可以看作是 NFM 不带隐层的一种特殊情况。通过在两个数据集上做回归任务实验,可得结论:只有一个隐层的 NFM 相比 FM 有较大幅度提升;相比 Wide&Deep 和 DeepCrossing 这些深度网络,NFM 只用一个隐层的浅网络就可以得到更好的效果,由此在实际应用里更易训练和调参。

模型结构

NFM 是一个可以接受任何实值特征向量的机器学习模型。对于稀疏向量 x x x, x i x_i xi 表示第 i i i 个特征在当前样本存在与否。NFM 模型的公式表示:

y ^ N F M ( x ) = w 0 + ∑ i = 1 n w i x i + f ( x ) \hat{y}{NFM}(x) = w_0 + \sum{i=1}^{n} w_i x_i + f(x) y^NFM(x)=w0+i=1∑nwixi+f(x)

虽然 FM 很巧妙地提取了交叉特征的信息,但是,它到底局限于线性表达和二阶交互,对于特征之间的非线性交互作用很难近似表达,因此前两项和 FM 类似,第三项 f ( x ) f(x) f(x) 是 NFM 做特征交叉的核心模块,是多层前馈网络用来替代 FM 中二阶隐向量内积的部分。如下所示:

f ( x ) = h T σ L ( W L ( ... σ 1 ( W 1 ⋅ f B I ( V x ) + b 1 ) ...   ) + b L ) f(x) = h^T \sigma_L(W_L (\dots \sigma_1(W_1 \cdot f_{BI}(V_x) + b_1) \dots) + b_L) f(x)=hTσL(WL(...σ1(W1⋅fBI(Vx)+b1)...)+bL)

如果说 DeepFM 是 DNN 和 FM 并联在一起的话,那么 NFM 就是他们俩串联在一起的了。结构如下:

从结构图可以看出 NFM 共有四个部分:

Input 和 Embedding 层

输入层为稀疏特征向量,Embedding 层是一个全连接层,它将每个稀疏特征映射成一个稠密向量表示。令 v i v_i vi 为第 i i i 个特征的 embedding 向量,在经过 Embedding 之后可以获得一个 embedding 向量集合 V = { v 1 , v 2 , ... , v n } V = \{v_1, v_2, \dots, v_n\} V={v1,v2,...,vn},由于 x x x 的稀疏性,这里只包含了 embedding 向量中非零的部分来传入下一层。

Bi-Interaction Pooling Layer(二阶特征交叉池化层)

本层为 NFM 的最大创新点。上层的 embedding 向量集合 V V V 传过来以后将在本层通过执行池化操作将 embedding 向量集合转换成单个向量。

f B I ( V x ) = ∑ i = 1 n ∑ j = i + 1 n x i x j ( v i ⊙ v j ) f_{BI}(V_x) = \sum_{i=1}^{n} \sum_{j=i+1}^{n} x_i x_j (v_i \odot v_j) fBI(Vx)=i=1∑nj=i+1∑nxixj(vi⊙vj)

其中 x i x_i xi 表示特征取值, v i v_i vi 表示特征 i i i 对应的 embedding 向量, ⊙ \odot ⊙ 表示两个向量的元素积操作,表示两个向量间对应元素相乘。因此,Bi-Interaction 池化后的输出是与 embedding 同纬度的向量,也就是将特征间的二阶交叉效应映射到 embedding 空间中。

通过对所有特征域进行两两交叉后,可以得到一系列特征交叉后的结果,最后将所有结果进行 sum pooling 操作。

得到最终特征交叉后特征向量表示。Bi-Interaction 的优势为将特征间的交叉以向量表示,同时,没有引入额外的参数,且也是在线性时间复杂度内完成的。类似 FM 的公式化简方法,我们可以将上式化简为:

f B I ( V x ) = 1 2 ( ∑ i = 1 n x i v i ) 2 − ∑ i = 1 n x i 2 v i 2 f_{BI}(V_x) = \frac{1}{2} \left \\left( \\sum_{i=1}\^{n} x_i v_i \\right)\^2 - \\sum_{i=1}\^{n} x_i\^2 v_i\^2 \\right fBI(Vx)=21 (i=1∑nxivi)2−i=1∑nxi2vi2

隐藏层

这一层就是全连接的神经网络,DNN 在进行特征的高层非线性交互上有着天然的学习优势,公式如下:

z 1 = σ 1 ( W 1 f B I ( V x ) + b 1 ) z_1 = \sigma_1(W_1 f_{BI}(V_x) + b_1) z1=σ1(W1fBI(Vx)+b1)

z 2 = σ 2 ( W 2 z 1 + b 2 ) z_2 = \sigma_2(W_2 z_1 + b_2) z2=σ2(W2z1+b2)

... \dots ...

z L = σ L ( W L z L − 1 + b L ) z_L = \sigma_L(W_L z_{L-1} + b_L) zL=σL(WLzL−1+bL)

这里,使用非线性激活函数 sigmoid、tanh、ReLU 可以让模型学习高阶非线性特征交叉。

如果不加这个 DNN,这个 NFM 就退化成了 FM,所以改进的关键就在于加了一个这样的层,组合了一下二阶交叉的信息,然后又给了 DNN 进行高阶交叉的学习。

映射层

最后一个隐层的输出,通过 h h h 向量加权映射出预测分:

y ^ N F M ( x ) = w 0 + ∑ i = 1 n w i x i + h T z L \hat{y}{NFM}(x) = w_0 + \sum{i=1}^{n} w_i x_i + h^T z_L y^NFM(x)=w0+i=1∑nwixi+hTzL

所以,NFM 模型的前向传播过程总结如下:

y ^ N F M ( x ) = w 0 + ∑ i = 1 n w i x i + h T σ L ( W L ( ... σ 1 ( W 1 f B I ( V x ) + b 1 ) ...   ) + b L ) \hat{y}{NFM}(x) = w_0 + \sum{i=1}^{n} w_i x_i + h^T \sigma_L(W_L (\dots \sigma_1(W_1 f_{BI}(V_x) + b_1) \dots) + b_L) y^NFM(x)=w0+i=1∑nwixi+hTσL(WL(...σ1(W1fBI(Vx)+b1)...)+bL)


NFM 与别的模型对比

与 FM 对比

FM 是 NFM 的一种特殊结构。让 NFM 的隐层数为 0,将 Bi 层直接连到映射层,记该结构为 NFM-0,公式表达如下:

y ^ ( x ) = w 0 + ∑ i = 1 n w i x i + h T f B I ( V x ) \hat{y}(x) = w_0 + \sum_{i=1}^{n} w_i x_i + h^T f_{BI}(V_x) y^(x)=w0+i=1∑nwixi+hTfBI(Vx)

将 NFM-0 的权重 h h h 置为全 1 向量,对应的结构即是 FM。

NFM 对比 Wide&Deep

NFM 相比多层神经网络结构,最大的不同在于 BI 交叉池化层。如果将 BI 交叉池化层替换成 concat,后接 MLP 或残差单元,即变成了 Wide&Deep 或 DeepCrossing 结构。

直接 concat 特征 embedding 的操作,没考虑任何特征交叉,由此需要依赖后置的深层网络学习有意义的特征交叉,这使得网络难训练。

用 BI 交叉池化层在低层捕获二阶特征交叉交叉,这种方式能获得更有信息的特征交叉,也使后续的隐层学习高阶特征交叉更容易。


时间复杂度分析

从下式可见:

f B I ( V x ) = ∑ i = 1 n ∑ j = i + 1 n x i x j ( v i ⊙ v j ) f_{BI}(V_x) = \sum_{i=1}^{n} \sum_{j=i+1}^{n} x_i x_j (v_i \odot v_j) fBI(Vx)=i=1∑nj=i+1∑nxixj(vi⊙vj)

BI 交叉层的计算时间复杂度是 O ( k n 2 ) O(k n^2) O(kn2),和 FM 一样。额外产生的计算在于隐层,对于隐层 l l l,权重矩阵计算复杂度为 O ( k l k l − 1 ) O(k_l k_{l-1}) O(klkl−1)。映射层只和隐层输出做内积,复杂度为 O ( k L ) O(k_L) O(kL)。

由此,NFM 模型总的时间复杂度为 O ( k n 2 + ∑ l = 1 L k l k l − 1 + k L ) O(k n^2 + \sum_{l=1}^{L} k_l k_{l-1} + k_L) O(kn2+∑l=1Lklkl−1+kL),和 Wide&Deep 相同。


学习过程

NFM 可以用于回归任务、分类任务和排序任务等。考虑回归任务,目标函数是对 train 集样本求平方损失:

L = ∑ x ∈ X ( y ^ ( x ) − y ( x ) ) 2 \mathcal{L} = \sum_{x \in X} (\hat{y}(x) - y(x))^2 L=x∈X∑(y^(x)−y(x))2

这里省去了正则化项,因为在 NN 结构里,用 dropout 可以防止过拟合。

SGD 优化算法,每次随机选一个 train 集的样本,求梯度对参数更新。在多层 NN 结构里,预测值 y ^ \hat{y} y^ 关于模型参数的梯度,用链式法则求。BI 交叉池化层可以如下求导:

∂ f B I ( V x ) ∂ v i = ∑ j ≠ i x i x j ⋅ v j \frac{\partial f_{BI}(V_x)}{\partial v_i} = \sum_{j \neq i} x_i x_j \cdot v_j ∂vi∂fBI(Vx)=j=i∑xixj⋅vj

由此,即使插入 BI 交叉池化层,也可以实现端到端求导。

SGD 优化依赖训练 batch 的选取,mini-batch SGD 结合了向量化和并行计算加速的优势。

我们后续选用的 mini-batch Adagrad 算法,基于此思想,并可以进行自适应学习率调节,相比普通的 SGD 能更快收敛。

训练多层 NN 网络会出现方差偏移:在训练过程,由于前面层的参数改变,每层的输入分布会变化。

由此,后面层需要更新其参数,以适应这些改变,这一动作会损害模型的训练速度。

BN 的提出就是为了解决以上现象,即针对每个 mini-batch 样本,将其在每层都归一化成 N ( 0 , 1 ) N(0,1) N(0,1) 分布。

BN 可以加快训练收敛速度,并能提升训练效果。


总结

FM 模型与 DNN 结合的模型------NFM,它将 FM 模型的有效性和非线性神经网络强大的表达能力结合起来,可以用于稀疏特征的预测分析。

而将这两者连接起来的关键就是 NFM 的 Bi-Interaction Pooling Layer,它使 DNN 可以在二阶特征交互的基础上学习更高阶的特征交互。


NFM 完整业务场景与数据推导(手算演示)

场景设定

场景:预测用户"张三"是否会下载 App "抖音"。

  • 真实标签 :假设张三下载了 ( y = 1 y = 1 y=1)。
  • 特征(选取 3 个,方便手算)
特征域 特征类型 原始值 One-hot 编码后 取值 x i x_i xi
性别 类别型 1, 0 x 1 = 1 x_1 = 1 x1=1
城市 类别型 北京 1, 0, 0 x 2 = 1 x_2 = 1 x2=1
日均使用时长(小时) 数值型 2.5 归一化为 0.5 x 3 = 0.5 x_3 = 0.5 x3=0.5

参数设定(为了手算):

  • Embedding 维度 : k = 3 k = 3 k=3。
  • Embedding 表(假设已随机初始化):
特征值 隐向量 v i v_i vi(3维)
0.1 , 0.2 , 0.3 0.1, 0.2, 0.3 0.1,0.2,0.3
0.4 , 0.5 , 0.6 0.4, 0.5, 0.6 0.4,0.5,0.6
北京 0.7 , 0.8 , 0.9 0.7, 0.8, 0.9 0.7,0.8,0.9
上海 0.2 , 0.3 , 0.4 0.2, 0.3, 0.4 0.2,0.3,0.4
深圳 0.5 , 0.6 , 0.7 0.5, 0.6, 0.7 0.5,0.6,0.7
日均时长(数值特征) 0.4 , 0.5 , 0.6 0.4, 0.5, 0.6 0.4,0.5,0.6(虚拟特征,可学习)
  • DNN 结构单隐藏层(3 → 2) ,激活函数 ReLU
  • 输出层 :2 → 1,激活函数 Sigmoid

步骤 1:Input & Embedding Layer

输入特征为:北京日均时长 = 0.5

查表得到 Embedding:

  • v 1 = v 男 = 0.1 , 0.2 , 0.3 v_1 = v_{男} = 0.1, 0.2, 0.3 v1=v男=0.1,0.2,0.3,对应 x 1 = 1 x_1 = 1 x1=1
  • v 2 = v 北京 = 0.7 , 0.8 , 0.9 v_2 = v_{北京} = 0.7, 0.8, 0.9 v2=v北京=0.7,0.8,0.9,对应 x 2 = 1 x_2 = 1 x2=1
  • v 3 = v 时长 = 0.4 , 0.5 , 0.6 v_3 = v_{时长} = 0.4, 0.5, 0.6 v3=v时长=0.4,0.5,0.6,对应 x 3 = 0.5 x_3 = 0.5 x3=0.5

步骤 2:Bi-Interaction Pooling Layer(核心创新)

2.1 计算原理

Bi-Interaction 层对所有特征对元素积(Hadamard Product),然后求和:

f B I = ∑ i = 1 n ∑ j = i + 1 n x i x j ⋅ ( v i ⊙ v j ) f_{BI} = \sum_{i=1}^{n} \sum_{j=i+1}^{n} x_i x_j \cdot (v_i \odot v_j) fBI=i=1∑nj=i+1∑nxixj⋅(vi⊙vj)

其中 v i ⊙ v j = v i 1 ⋅ v j 1 , v i 2 ⋅ v j 2 , v i 3 ⋅ v j 3 v_i \odot v_j = v_{i1} \\cdot v_{j1}, \\ v_{i2} \\cdot v_{j2}, \\ v_{i3} \\cdot v_{j3} vi⊙vj=vi1⋅vj1, vi2⋅vj2, vi3⋅vj3

2.2 手算三对交叉

1. 男 × 北京 ( x 1 = 1 , x 2 = 1 x_1 = 1, x_2 = 1 x1=1,x2=1):

v 1 ⊙ v 2 = 0.1 × 0.7 , 0.2 × 0.8 , 0.3 × 0.9 = 0.07 , 0.16 , 0.27 v_1 \odot v_2 = 0.1 \\times 0.7,\\ 0.2 \\times 0.8,\\ 0.3 \\times 0.9 = 0.07, 0.16, 0.27 v1⊙v2=0.1×0.7, 0.2×0.8, 0.3×0.9=0.07,0.16,0.27

乘以 x 1 x 2 = 1 x_1 x_2 = 1 x1x2=1,贡献为 0.07 , 0.16 , 0.27 0.07, 0.16, 0.27 0.07,0.16,0.27

2. 男 × 日均时长 ( x 1 = 1 , x 3 = 0.5 x_1 = 1, x_3 = 0.5 x1=1,x3=0.5):

v 1 ⊙ v 3 = 0.1 × 0.4 , 0.2 × 0.5 , 0.3 × 0.6 = 0.04 , 0.10 , 0.18 v_1 \odot v_3 = 0.1 \\times 0.4,\\ 0.2 \\times 0.5,\\ 0.3 \\times 0.6 = 0.04, 0.10, 0.18 v1⊙v3=0.1×0.4, 0.2×0.5, 0.3×0.6=0.04,0.10,0.18

乘以 x 1 x 3 = 1 × 0.5 = 0.5 x_1 x_3 = 1 \times 0.5 = 0.5 x1x3=1×0.5=0.5,贡献为 0.5 × 0.04 , 0.5 × 0.10 , 0.5 × 0.18 = 0.02 , 0.05 , 0.09 0.5 \\times 0.04, \\ 0.5 \\times 0.10, \\ 0.5 \\times 0.18 = 0.02, 0.05, 0.09 0.5×0.04, 0.5×0.10, 0.5×0.18=0.02,0.05,0.09

3. 北京 × 日均时长 ( x 2 = 1 , x 3 = 0.5 x_2 = 1, x_3 = 0.5 x2=1,x3=0.5):

v 2 ⊙ v 3 = 0.7 × 0.4 , 0.8 × 0.5 , 0.9 × 0.6 = 0.28 , 0.40 , 0.54 v_2 \odot v_3 = 0.7 \\times 0.4,\\ 0.8 \\times 0.5,\\ 0.9 \\times 0.6 = 0.28, 0.40, 0.54 v2⊙v3=0.7×0.4, 0.8×0.5, 0.9×0.6=0.28,0.40,0.54

乘以 x 2 x 3 = 1 × 0.5 = 0.5 x_2 x_3 = 1 \times 0.5 = 0.5 x2x3=1×0.5=0.5,贡献为 0.14 , 0.20 , 0.27 0.14, 0.20, 0.27 0.14,0.20,0.27

Bi-Interaction 层最终输出(三项求和):

f B I = 0.07 + 0.02 + 0.14 , 0.16 + 0.05 + 0.20 , 0.27 + 0.09 + 0.27 = 0.23 , 0.41 , 0.63 f_{BI} = 0.07 + 0.02 + 0.14, \\quad 0.16 + 0.05 + 0.20, \\quad 0.27 + 0.09 + 0.27 = 0.23, 0.41, 0.63 fBI=0.07+0.02+0.14,0.16+0.05+0.20,0.27+0.09+0.27=0.23,0.41,0.63

2.3 与 FM 的区别(关键!)

  • FM 的二阶交叉 :输出是一个标量 : 0.07 + 0.16 + 0.27 + 0.02 + 0.05 + 0.09 + 0.14 + 0.20 + 0.27 = 1.27 0.07 + 0.16 + 0.27 + 0.02 + 0.05 + 0.09 + 0.14 + 0.20 + 0.27 = 1.27 0.07+0.16+0.27+0.02+0.05+0.09+0.14+0.20+0.27=1.27。
  • NFM 的 Bi-Interaction :输出是一个向量 0.23 , 0.41 , 0.63 0.23, 0.41, 0.63 0.23,0.41,0.63,每个维度都保留了交叉信息,后续 DNN 可以在此基础上继续学习。

创新点总结 :Bi-Interaction 将"特征交叉"从标量 升级为向量 ,相当于把二阶交叉的结果"展开"了,而不是压扁成一个数字。这让 DNN 能够基于丰富的二阶信息去构建更高阶的模式。


步骤 3:Hidden Layer(DNN 部分)

DNN 的输入是 f B I = 0.23 , 0.41 , 0.63 f_{BI} = 0.23, 0.41, 0.63 fBI=0.23,0.41,0.63(维度 3)。

设第一层权重矩阵 W 1 W_1 W1(2 × 3)和偏置 b 1 b_1 b1(2 维):

W 1 = 0.1 0.2 0.3 0.4 0.5 0.6 , b 1 = 0.1 , 0.1 W_1 = \begin{bmatrix} 0.1 & 0.2 & 0.3 \\ 0.4 & 0.5 & 0.6 \end{bmatrix}, \quad b_1 = 0.1, 0.1 W1=0.10.40.20.50.30.6,b1=0.1,0.1

计算线性输出 Z 1 = W 1 ⋅ f B I + b 1 Z_1 = W_1 \cdot f_{BI} + b_1 Z1=W1⋅fBI+b1:

  • 神经元 1 : 0.1 × 0.23 + 0.2 × 0.41 + 0.3 × 0.63 + 0.1 = 0.023 + 0.082 + 0.189 + 0.1 = 0.394 0.1 \times 0.23 + 0.2 \times 0.41 + 0.3 \times 0.63 + 0.1 = 0.023 + 0.082 + 0.189 + 0.1 = 0.394 0.1×0.23+0.2×0.41+0.3×0.63+0.1=0.023+0.082+0.189+0.1=0.394
  • 神经元 2 : 0.4 × 0.23 + 0.5 × 0.41 + 0.6 × 0.63 + 0.1 = 0.092 + 0.205 + 0.378 + 0.1 = 0.775 0.4 \times 0.23 + 0.5 \times 0.41 + 0.6 \times 0.63 + 0.1 = 0.092 + 0.205 + 0.378 + 0.1 = 0.775 0.4×0.23+0.5×0.41+0.6×0.63+0.1=0.092+0.205+0.378+0.1=0.775

应用 ReLU ( max ⁡ ( 0 , x ) \max(0, x) max(0,x)):

h 1 = 0.394 , 0.775 h_1 = 0.394, 0.775 h1=0.394,0.775


步骤 4:Prediction Score(输出层)

设输出权重 W 2 = 0.5 , 0.8 W_2 = 0.5, 0.8 W2=0.5,0.8,偏置 b 2 = 0.2 b_2 = 0.2 b2=0.2。

计算 logit:

logit = 0.5 × 0.394 + 0.8 × 0.775 + 0.2 = 0.197 + 0.62 + 0.2 = 1.017 \text{logit} = 0.5 \times 0.394 + 0.8 \times 0.775 + 0.2 = 0.197 + 0.62 + 0.2 = 1.017 logit=0.5×0.394+0.8×0.775+0.2=0.197+0.62+0.2=1.017

Sigmoid 计算点击概率:

p = σ ( 1.017 ) = 1 1 + e − 1.017 ≈ 1 1 + 0.3617 ≈ 0.734 p = \sigma(1.017) = \frac{1}{1 + e^{-1.017}} \approx \frac{1}{1 + 0.3617} \approx 0.734 p=σ(1.017)=1+e−1.0171≈1+0.36171≈0.734

预测结果 :张三下载抖音的概率为 73.4%


步骤 5:损失函数(交叉熵)

真实标签 y = 1 y = 1 y=1:

L = − log ⁡ ( p ) = − log ⁡ ( 0.734 ) ≈ 0.309 L = -\log(p) = -\log(0.734) \approx 0.309 L=−log(p)=−log(0.734)≈0.309


损失函数与反向传播的数值推导(重点)

1. 求最终 logit 的梯度

δ t o t a l = ∂ L ∂ logit = p − y = 0.734 − 1 = − 0.266 \delta_{total} = \frac{\partial L}{\partial \text{logit}} = p - y = 0.734 - 1 = -0.266 δtotal=∂logit∂L=p−y=0.734−1=−0.266

2. 输出层(2 → 1)的梯度

  • ∂ L ∂ W 2 , 1 = δ t o t a l × h 1 , 1 = − 0.266 × 0.394 = − 0.1048 \frac{\partial L}{\partial W_{2,1}} = \delta_{total} \times h_{1,1} = -0.266 \times 0.394 = -0.1048 ∂W2,1∂L=δtotal×h1,1=−0.266×0.394=−0.1048
  • ∂ L ∂ W 2 , 2 = − 0.266 × 0.775 = − 0.2062 \frac{\partial L}{\partial W_{2,2}} = -0.266 \times 0.775 = -0.2062 ∂W2,2∂L=−0.266×0.775=−0.2062
  • ∂ L ∂ b 2 = − 0.266 \frac{\partial L}{\partial b_2} = -0.266 ∂b2∂L=−0.266

3. 误差反向传播到隐藏层 h 1 h_1 h1

δ h 1 = W 2 T ⋅ δ t o t a l = 0.5 , 0.8 T × ( − 0.266 ) = − 0.133 , − 0.213 \delta_{h1} = W_2^T \cdot \delta_{total} = 0.5, 0.8^T \times (-0.266) = -0.133, -0.213 δh1=W2T⋅δtotal=0.5,0.8T×(−0.266)=−0.133,−0.213

(因为 ReLU 输入 Z 1 = 0.394 , 0.775 > 0 Z_1 = 0.394, 0.775 > 0 Z1=0.394,0.775>0,导数为 1)。

4. 误差反向传播到隐藏层权重 W 1 W_1 W1

以第 1 行第 1 列为例: ∂ L ∂ W 1 , 1 , 1 = δ h 1 , 1 × f B I , 1 = − 0.133 × 0.23 = − 0.0306 \frac{\partial L}{\partial W_{1,1,1}} = \delta_{h1,1} \times f_{BI,1} = -0.133 \times 0.23 = -0.0306 ∂W1,1,1∂L=δh1,1×fBI,1=−0.133×0.23=−0.0306。

5. 误差反向传播到 Bi-Interaction 层输出 f B I f_{BI} fBI

∂ L ∂ f B I = W 1 T ⋅ δ h 1 = 0.1 0.4 0.2 0.5 0.3 0.6 × − 0.133 , − 0.213 T \frac{\partial L}{\partial f_{BI}} = W_1^T \cdot \delta_{h1} = \begin{bmatrix} 0.1 & 0.4 \\ 0.2 & 0.5 \\ 0.3 & 0.6 \end{bmatrix} \times -0.133, -0.213^T ∂fBI∂L=W1T⋅δh1= 0.10.20.30.40.50.6 ×−0.133,−0.213T

  • 第 1 维: 0.1 × ( − 0.133 ) + 0.4 × ( − 0.213 ) = − 0.0133 − 0.0852 = − 0.0985 0.1 \times (-0.133) + 0.4 \times (-0.213) = -0.0133 - 0.0852 = -0.0985 0.1×(−0.133)+0.4×(−0.213)=−0.0133−0.0852=−0.0985
  • 第 2 维: 0.2 × ( − 0.133 ) + 0.5 × ( − 0.213 ) = − 0.0266 − 0.1065 = − 0.1331 0.2 \times (-0.133) + 0.5 \times (-0.213) = -0.0266 - 0.1065 = -0.1331 0.2×(−0.133)+0.5×(−0.213)=−0.0266−0.1065=−0.1331
  • 第 3 维: 0.3 × ( − 0.133 ) + 0.6 × ( − 0.213 ) = − 0.0399 − 0.1278 = − 0.1677 0.3 \times (-0.133) + 0.6 \times (-0.213) = -0.0399 - 0.1278 = -0.1677 0.3×(−0.133)+0.6×(−0.213)=−0.0399−0.1278=−0.1677

即 ∇ f B I ≈ − 0.0985 , − 0.1331 , − 0.1677 \nabla f_{BI} \approx -0.0985, -0.1331, -0.1677 ∇fBI≈−0.0985,−0.1331,−0.1677

6. 误差继续反向传播到 Embedding(Bi-Interaction 的梯度分发,关键!)

Bi-Interaction 层的前向公式为 f B I = ∑ i < j x i x j ( v i ⊙ v j ) f_{BI} = \sum_{i < j} x_i x_j (v_i \odot v_j) fBI=∑i<jxixj(vi⊙vj)。

v 1 v_1 v1(男) 为例,它同时出现在交叉项 (1,2)(1,3) 中。根据链式法则:

∂ L ∂ v 1 = ∑ j ≠ 1 x 1 x j ⋅ ( ∂ L ∂ f B I ⊙ v j ) \frac{\partial L}{\partial v_1} = \sum_{j \neq 1} x_1 x_j \cdot \left( \frac{\partial L}{\partial f_{BI}} \odot v_j \right) ∂v1∂L=j=1∑x1xj⋅(∂fBI∂L⊙vj)

(其中 ⊙ \odot ⊙ 是元素积)

代入数值:

  • 与 v 2 v_2 v2(北京)的贡献: x 1 x 2 = 1 x_1 x_2 = 1 x1x2=1, ∇ f B I ⊙ v 2 = − 0.0985 × 0.7 , − 0.1331 × 0.8 , − 0.1677 × 0.9 = − 0.06895 , − 0.10648 , − 0.15093 \nabla f_{BI} \odot v_2 = -0.0985 \\times 0.7, \\ -0.1331 \\times 0.8, \\ -0.1677 \\times 0.9 = -0.06895, -0.10648, -0.15093 ∇fBI⊙v2=−0.0985×0.7, −0.1331×0.8, −0.1677×0.9=−0.06895,−0.10648,−0.15093
  • 与 v 3 v_3 v3(时长)的贡献: x 1 x 3 = 0.5 x_1 x_3 = 0.5 x1x3=0.5, ∇ f B I ⊙ v 3 = 0.5 × − 0.0985 × 0.4 , − 0.1331 × 0.5 , − 0.1677 × 0.6 = 0.5 × − 0.0394 , − 0.06655 , − 0.10062 = − 0.0197 , − 0.03328 , − 0.05031 \nabla f_{BI} \odot v_3 = 0.5 \times -0.0985 \\times 0.4, \\ -0.1331 \\times 0.5, \\ -0.1677 \\times 0.6 = 0.5 \times -0.0394, -0.06655, -0.10062 = -0.0197, -0.03328, -0.05031 ∇fBI⊙v3=0.5×−0.0985×0.4, −0.1331×0.5, −0.1677×0.6=0.5×−0.0394,−0.06655,−0.10062=−0.0197,−0.03328,−0.05031

v 1 v_1 v1 的总梯度(相加):

∇ v 1 = − 0.06895 − 0.0197 , − 0.10648 − 0.03328 , − 0.15093 − 0.05031 = − 0.08865 , − 0.13976 , − 0.20124 \nabla v_1 = -0.06895 - 0.0197, \\ -0.10648 - 0.03328, \\ -0.15093 - 0.05031 = -0.08865, -0.13976, -0.20124 ∇v1=−0.06895−0.0197, −0.10648−0.03328, −0.15093−0.05031=−0.08865,−0.13976,−0.20124

更新 v 1 v_1 v1 (学习率 η = 0.01 \eta = 0.01 η=0.01):

v 1 n e w = 0.1 , 0.2 , 0.3 − 0.01 × − 0.08865 , − 0.13976 , − 0.20124 = 0.10089 , 0.20140 , 0.30201 v_1^{new} = 0.1, 0.2, 0.3 - 0.01 \times -0.08865, -0.13976, -0.20124 = 0.10089, 0.20140, 0.30201 v1new=0.1,0.2,0.3−0.01×−0.08865,−0.13976,−0.20124=0.10089,0.20140,0.30201

这揭示了 NFM 反向传播的精髓 :损失函数的误差信号通过 DNN 传回 Bi-Interaction 层后,会通过"元素积"的链式法则,精准地分发到每一个底层特征 Embedding 上 。如果"男"和"北京"的组合对预测贡献大, v 1 v_1 v1 就会朝着与 v 2 v_2 v2 更相似的方向更新(因为梯度是 ∇ f ⊙ v 2 \nabla f \odot v_2 ∇f⊙v2,乘以 v 2 v_2 v2 的对应维度)。


防止过拟合措施:Dropout 和 Batch Normalization

1. Dropout(随机失活)

  • 作用位置 :通常加在 Hidden Layers 的全连接层之后。
  • 原理 :训练时,以概率 p p p(如 0.5)随机将某些神经元输出置为 0。这相当于每次训练都使用不同的子网络,强迫模型不依赖任何单个特征,从而增强泛化能力。
  • 在我们的例子中 :如果对 h 1 = 0.394 , 0.775 h_1 = 0.394, 0.775 h1=0.394,0.775 应用 Dropout( p = 0.5 p = 0.5 p=0.5),可能随机丢弃第二个神经元(变为 0),那么输出层的输入就变成了 0.394 , 0 0.394, 0 0.394,0,模型被迫只用"第一个神经元"的信息去预测,增强了鲁棒性。

2. Batch Normalization(批归一化)

  • 作用位置 :通常加在全连接层的线性变换之后、激活函数之前 (即 Z = W x + b Z = Wx + b Z=Wx+b 之后,ReLU 之前)。
  • 原理 :对每个 mini-batch 的 Z Z Z 做标准化(减均值,除标准差),使其分布稳定在 N ( 0 , 1 ) N(0,1) N(0,1),然后再进行缩放和平移。这解决了"内部协变量偏移"(Internal Covariate Shift),让深层网络训练更稳定、收敛更快。
  • 在我们的例子中 :如果在隐藏层计算 Z 1 = 0.394 , 0.775 Z_1 = 0.394, 0.775 Z1=0.394,0.775 后,对这批样本的 Z 1 Z_1 Z1 做归一化,即使前一层参数变化, Z 1 Z_1 Z1 的分布也不会剧烈波动,ReLU 的输入更稳定,梯度更健康。

完整数据推导链路总结表

阶段 模块 操作 输入维度 输出维度 关键数值
输入 Sparse One-hot / 数值 稀疏 3 个激活值 男 = 1, 北京 = 1, 时长 = 0.5
嵌入 Embedding 查表映射 稀疏 → 稠密 3 维/个 v 1 = 0.1 , 0.2 , 0.3 v_1 = 0.1,0.2,0.3 v1=0.1,0.2,0.3, v 2 = 0.7 , 0.8 , 0.9 v_2 = 0.7,0.8,0.9 v2=0.7,0.8,0.9, v 3 = 0.4 , 0.5 , 0.6 v_3 = 0.4,0.5,0.6 v3=0.4,0.5,0.6
二阶交叉 Bi-Interaction 元素积 + 求和 3 个向量 3 维向量 f B I = 0.23 , 0.41 , 0.63 f_{BI} = 0.23, 0.41, 0.63 fBI=0.23,0.41,0.63
隐藏层 DNN FC(3 → 2)+ ReLU 3 维 2 维 h 1 = 0.394 , 0.775 h_1 = 0.394, 0.775 h1=0.394,0.775
输出 Output FC(2 → 1)+ Sigmoid 2 维 标量 p = σ ( 1.017 ) = 0.734 p = \sigma(1.017) = 0.734 p=σ(1.017)=0.734
损失 Loss 交叉熵 - 标量 L = − log ⁡ ( 0.734 ) = 0.309 L = -\log(0.734) = 0.309 L=−log(0.734)=0.309
反向传播 整体 链式法则 - - δ t o t a l = − 0.266 \delta_{total} = -0.266 δtotal=−0.266
Embedding 更新 反向传播到 v 1 v_1 v1 ∑ x 1 x j ( δ B I ⊙ v j ) \sum x_1 x_j (\delta_{BI} \odot v_j) ∑x1xj(δBI⊙vj) - 3 维 ∇ v 1 ≈ − 0.0887 , − 0.1398 , − 0.2012 \nabla v_1 \approx -0.0887, -0.1398, -0.2012 ∇v1≈−0.0887,−0.1398,−0.2012

总结

  1. NFM 的核心创新Bi-Interaction Pooling 层。它把 FM 的二阶交叉从"标量"升级为"向量",在低层显式建模特征交互,让高层 DNN 能够基于丰富的二阶信息学习高阶非线性交叉。

  2. 与 FM 的区别 :FM 输出一个标量( ∑ ⟨ v i , v j ⟩ \sum \langle v_i, v_j \rangle ∑⟨vi,vj⟩),NFM 输出一个向量( ∑ ( v i ⊙ v j ) \sum (v_i \odot v_j) ∑(vi⊙vj))。前者丢了维度信息,后者保留了完整的交叉结构。

  3. 与 DeepFM 的区别 :DeepFM 是并联 (FM 和 DNN 分别计算后相加),NFM 是串联(先 Bi-Interaction,再 DNN)。NFM 更强调"逐级提升"------先做二阶,再在此之上做高阶。

  4. 训练技巧:Dropout 防止过拟合,Batch Normalization 加速收敛。

  5. 实际优势 :论文实验表明,NFM 只需一个隐层即可达到甚至超过 Wide&Deep 等复杂模型的效果,更易训练和调参。

面试可能追问:Bi-Interaction 和直接 Concat Embedding 有什么区别?

答:Concat 只是把向量拼在一起,特征之间没有显式交互,DNN 必须靠大量数据和复杂的非线性层去"摸索"出交叉关系,效率低、训练难。Bi-Interaction 直接给出了明确的二阶交叉信号(元素积),相当于给 DNN 提供了一个高质量的"预处理特征",让后续的高阶学习事半功倍。

参考资料

相关推荐
深圳市快瞳科技有限公司1 小时前
从人工录入到秒级识别:保单OCR识别厂家选型指南
人工智能·算法·计算机视觉·ocr
小欣加油1 小时前
leetcode1331 数组序号转换
数据结构·c++·算法·leetcode·职场和发展
ZZZMMM.zip1 小时前
基于鸿蒙PC与鸿蒙Flutter框架的AI紧急求助应用开发实践
人工智能·flutter·华为·harmonyos·鸿蒙
Coffeeee1 小时前
搞Android的怎么可能搞不懂Context Engineering?
android·人工智能·ai编程
学究天人1 小时前
数学公理体系大全:第五章 序数与基数理论:超限算术与集合的大小
人工智能·线性代数·算法·机器学习·数学建模·原型模式
阿里云云原生1 小时前
Qoder 企业版全球发布:让 AI Coding 从“个人工具”长出“组织能力”
人工智能
阿米亚波1 小时前
【C++ STL】std::deque
数据结构·c++·笔记·算法·stl
byte轻骑兵2 小时前
【LE Audio】CSIS精讲[1]: 从核心定义到协议基础,读懂多设备协同的底层逻辑
人工智能·音视频·人机交互·蓝牙耳机·le audio·低功耗蓝牙音频
sunneo2 小时前
S16.5 第一性原理做产品(5):从《与运气竞争》看AI产品价值——用户到底在“雇佣“什么
人工智能·产品运营·产品经理·用户运营·用户体验