深夜的「陈记小馆」门口排着长队,老板老陈却对着本子发愁——他必须判断每一个路过的客人,有多大几率点一碗招牌牛肉面。这,就是推荐系统每天都在做的 CTR 预估。客人会不会下单,绝不能只看“牛肉面”这一个因素:深夜、下雨、客人怕辣、附近没有别的店……每个因素单独看都平平无奇,可一旦组合起来,结论就完全不同。这正是推荐模型要解决的“特征交互”问题。 老陈想出的办法,是让两位师傅同台献艺:面点老师傅擅长“两两搭配”,知道凌晨两点该少放葱油;年轻创意主厨则擅长把七八种食材揉进一碗汤头,产生奇妙的新口感。前者叫 FM(因子分解机),后者叫 DNN(深度神经网络)。把两位师傅放在同一个灶台上,共享同一套统一切配的食材——也就是共享 Embedding——这道招牌菜,就叫 DeepFM。本篇文章就从这间小馆的后厨讲起,带你亲手端出这道推荐算法里的招牌硬菜。

岗位关联

掌握 DeepFM 的建模思路与工程落地细节,是推荐算法工程师做 CTR 预估的必修课,能让你从“调包跑模型”进阶到“读懂模型并落地部署”。

目录
  1. 可视化演示
  2. 特征交互问题
  3. FM 二阶交互
  4. 共享 Embedding
  5. DNN 高阶学习
  6. DeepFM 融合
  7. 对比与部署
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

展示FM一阶二阶特征交互、DNN高阶特征学习、DeepFM共享Embedding架构及模型对比的交互式动画。

本节配有交互动效(进入视口后自动加载,约 3KB)。

FM一阶二阶特征交互 一阶项线性加权各特征贡献 二阶项隐向量内积捕捉特征交叉 FM = Σw_i×x_i + ΣΣ⟨v_i,v_j⟩x_ix_j FM用隐向量内积替代显式交叉参数

特征交互问题

老陈的待客本上密密麻麻记着各种信息:现在是深夜、外面下着雨、客人是常客、他上次点了微辣……这些信息单独看,哪一条都不足以决定“他会不会点牛肉面”。真正让老陈拍板的,是这些信息在脑子里飞快组合的结果——比如“深夜 + 下雨 + 常客”,几乎等于自动下单。推荐系统面临的处境一模一样:用户是否点击,取决于多个特征的共同作用。

CTR 预估的任务,就是根据一条样本的特征向量 \(\mathbf{x}\),预测用户点击的概率 \(P(y=1|\mathbf{x})\)。在工业界,特征大多是类别型离散值,比如“性别=男”“时段=深夜”。为了让数学公式能处理它们,工程师会做 one-hot 编码:把每个取值展开成一个很长的向量,只有对应位置是 1,其余全是 0。这就导致特征向量极其稀疏且高维——就像一张几十万行的勾选清单,每行只有一个格子被打上勾。

如果用线性模型,模型只能学到每个特征单独的权重,“深夜”和“年轻用户”各自加一分,永远表达不出“深夜的年轻用户”这个组合的爆发力。如果人工构造所有两两组合特征,那特征数量会变成天文数字,训练与存储都不可行。于是,让模型自己学会“特征交互”,成了推荐系统的核心课题。

这就像老陈不会傻到去培训厨师把所有 200 种食材的两两组合都练一遍——人力根本不够。他需要一种更聪明的办法:让模型从数据里自动领悟,哪些组合值得重视,哪些组合只是噪音。

x=[x1,x2,…,xn]\mathbf{x} = [x_1, x_2, \ldots, x_n]
一条样本被表示为一个 n 维特征向量,其中绝大多数维度在 one-hot 编码下取值 0。
  1. 特征向量\(\mathbf{x}\) 代表一条样本的所有特征拼成的向量,是模型输入的起点。
    x=[x1,x2,…,xn]\mathbf{x} = [x_1, x_2, \ldots, x_n]
  2. 单个特征取值\(x_i\) 表示第 i 个特征——经过 one-hot 后,它通常是 0 或 1。
    xi∈{0,1}x_i \in \{0, 1\}
  3. 稀疏性n 可能高达百万级,但非零的 \(x_i\) 很少,绝大多数维度都是 0。
    ∑i=1n1[xi≠0]≪n\sum_{i=1}^{n} \mathbb{1}[x_i \neq 0] \ll n

FM 二阶交互

面点老师傅的绝活,是“单样食材本味”与“经典搭配表”两件事。他知道牛肉的醇厚、面条的筋道,也背得下番茄炒蛋、葱爆牛肉这些两两绝配;而搭配的默契程度,只需要用一个数字打分。FM 要做的,正是把这种本事数学化。

FM 首先给每个特征 \(x_i\) 配一个一阶权重 \(w_i\),再加上一个全局偏移 \(w_0\)——这构成了信号的“基线味道”;更重要的是,它给每个特征都学习一个低维隐向量 \(\mathbf{v}_i\),两个特征的交叉强度就用它们隐向量的内积 \(\langle \mathbf{v}_i, \mathbf{v}_j \rangle\) 来表示。为什么不用一个独立的权重 \(w_{ij}\)?因为特征组合的数量是 O(n²) 级别,稀疏数据下绝大多数组合从未出现过,根本学不出可靠参数。把 \(w_{ij}\) 分解成两个向量内积后,参数总量降到 O(nk),且只要单独出现过某个特征,它的隐向量就能被训练,交叉权重也随之“泛化”到从未见过的组合上。

y^FM(x)=w0+∑i=1nwixi+∑i=1n∑j=i+1n⟨vi,vj⟩xixj\hat{y}_{FM}(\mathbf{x}) = w_0 + \sum_{i=1}^{n} w_i x_i + \sum_{i=1}^{n} \sum_{j=i+1}^{n} \langle \mathbf{v}_i, \mathbf{v}_j \rangle x_i x_j

1. 全局偏差:\(w_0\) 是所有样本的基准分数,相当于“不管什么菜,先给个基础分”。

w0w_0

2. 一阶线性部分:每个特征单独贡献的分数之和,刻画“单样食材本身的味道”。

∑i=1nwixi\sum_{i=1}^{n} w_i x_i

3. 二阶交叉部分:所有两两特征组合的贡献之和,刻画“番茄配鸡蛋”这种默契。

∑i=1n∑j=i+1n⟨vi,vj⟩xixj\sum_{i=1}^{n} \sum_{j=i+1}^{n} \langle \mathbf{v}_i, \mathbf{v}_j \rangle x_i x_j

4. 隐向量内积:\(\langle \mathbf{v}_i, \mathbf{v}_j \rangle\) 用两个向量的内积代替一个独立权重,是参数因子分解的核心。

⟨vi,vj⟩=∑f=1kvi,f⋅vj,f\langle \mathbf{v}_i, \mathbf{v}_j \rangle = \sum_{f=1}^{k} v_{i,f} \cdot v_{j,f}

老师傅的搭配表不是死记硬背 200 × 200 项,而是记住每种食材的“性格向量”:牛肉咸香、番茄酸甜、葱油提鲜……两个食材合不合拍,把向量点乘一下便知。这就是 FM 的智慧。

共享 Embedding

后厨的中央厨房里有一台切配机,把每种食材都切成统一规格的小丁。无论是面点师傅做经典搭配,还是创意主厨做融合菜,用的都是同一袋“标准牛肉丁”“标准胡萝卜丁”。口味体系完全一致,不会出现“这个菜里的牛肉是三厘米块,那个菜里是两厘米粒”的混乱。在 DeepFM 里,这台机器就是共享 Embedding 层。

每个类别型特征(比如“用户 ID=1024”“商品类目=零食”)经过 one-hot 编码后只有一个位置是 1。Embedding 层做的事情,就是按特征 ID 去查一张“向量表”:表里每一行是一个低维稠密向量(比如 32 维或 64 维),把特征 ID 映射到这一行。因为 one-hot 向量与查表矩阵相乘的结果,恰好等于“取出第 i 行”,所以这个过程也叫查表映射。

ei=vi⋅xi\mathbf{e}_i = \mathbf{v}_i \cdot x_i

1. 稀疏特征取值:\(x_i\) 表示第 i 个 one-hot 特征,绝大多数为 0。

xi∈{0,1}x_i \in \{0, 1\}

2. 嵌入向量:\(\mathbf{v}_i\) 是特征 i 对应的稠密向量,记录了该特征的“性格”。

vi∈Rk\mathbf{v}_i \in \mathbb{R}^{k}

3. 查表结果:\(\mathbf{e}_i\) 是取出的稠密向量——当 \(x_i=1\) 时就是 \(\mathbf{v}_i\),相当于查表。

ei=vi⋅xi\mathbf{e}_i = \mathbf{v}_i \cdot x_i

共享的关键在于:FM 支路的二阶交叉用这组向量,DNN 支路的高阶学习也用这组向量。两个子网络从同一套表示中提取信息,反向传播时梯度会同时更新这份共享表,互相促进。如果两位厨师的备菜标准不一样,做出来的菜就会“打架”;共享 Embedding 保证了整个后厨说同一种语言。

DNN 高阶学习

年轻的创意主厨不满足于两两搭配——他把牛肉、番茄、泡椒、陈皮、豆瓣酱……七八种食材层层叠加、慢火浓缩,产生一种无法一一拆解的复合鲜味。这种复杂风味,用“哪个食材和哪个食材的配对”根本说不清楚。在数学上,这就是高阶特征交互。

DNN 支路做的事,是把共享 Embedding 产出的那些稠密向量拼接或加和成一个长向量,然后送进多层全连接网络。每一层网络都对上一层的输出做线性变换加非线性激活,层与层之间的组合,等价于以隐式方式让多个特征发生交互——第 2 层可能组合了第 1 层的若干输出,第 3 层又组合了第 2 层的输出。经过足够深的网络,三阶、四阶甚至更高阶的特征关系都可以被表达。

a(l+1)=σ(W(l)a(l)+b(l))\mathbf{a}^{(l+1)} = \sigma\left( \mathbf{W}^{(l)} \mathbf{a}^{(l)} + \mathbf{b}^{(l)} \right)

1. 上一层输出:\(\mathbf{a}^{(l)}\) 是第 l 层神经元的激活向量,代表当前“半成品风味”。

a(l)\mathbf{a}^{(l)}

2. 线性变换:\(\mathbf{W}^{(l)} \mathbf{a}^{(l)} + \mathbf{b}^{(l)}\) 是仿射变换,相当于把上一层的信号重新调配比例。

W(l)a(l)+b(l)\mathbf{W}^{(l)} \mathbf{a}^{(l)} + \mathbf{b}^{(l)}

3. 非线性激活:\(\sigma(\cdot)\) 通常是 ReLU 等激活函数,给模型引入非线性,否则多层网络等价于一层。

σ(z)=max⁡(0,z)\sigma(z) = \max(0, z)

创意主厨说不出“第几克泡椒配第几克牛肉产生了什么化合物”,但当他把食材交给时间与火候——也就是网络的深度与非线性——复合鲜味自然涌现。FM 负责精确的两两搭配,DNN 负责说不清道不明的融合风味,两者互补。

DeepFM 融合

老陈做了个大胆决定:把两个厨房并成一个大开间。面点师傅和创意主厨各做各的,互不干扰,但最后把两碗合成一道招牌套餐端给客人。经典口味负责不出错,创意负责出彩——这就是 DeepFM 的架构哲学。

具体来说,DeepFM 的输入先经过共享 Embedding 层,得到所有特征的稠密向量;随后兵分两路:FM 支路计算一阶项和二阶交叉项,DNN 支路把 Embedding 展平后送入多层网络计算高阶隐式特征;两条支路的输出直接相加,再经过 Sigmoid 函数压缩到 0 到 1 之间,作为点击概率。

y^=σ(y^FM(x)+yDNN(x))\hat{y} = \sigma\left( \hat{y}_{FM}(\mathbf{x}) + y_{DNN}(\mathbf{x}) \right)

1. FM 支路得分:\(\hat{y}_{FM}(\mathbf{x})\) 是 FM 的一阶加二阶输出,刻画可解释的经典搭配。

y^FM(x)=w0+∑i=1nwixi+∑i=1n∑j=i+1n⟨vi,vj⟩xixj\hat{y}_{FM}(\mathbf{x}) = w_0 + \sum_{i=1}^{n} w_i x_i + \sum_{i=1}^{n} \sum_{j=i+1}^{n} \langle \mathbf{v}_i, \mathbf{v}_j \rangle x_i x_j

2. DNN 支路得分:\(y_{DNN}(\mathbf{x})\) 是高阶隐式特征的综合输出,捕捉复杂融合风味。

yDNN(x)=W(L)a(L)+b(L)y_{DNN}(\mathbf{x}) = \mathbf{W}^{(L)} \mathbf{a}^{(L)} + \mathbf{b}^{(L)}

3. 并行相加:两条支路的分数直接求和,FM 与 DNN 同时贡献、地位对等。

y^FM(x)+yDNN(x)\hat{y}_{FM}(\mathbf{x}) + y_{DNN}(\mathbf{x})

4. Sigmoid 输出:\(\sigma(\cdot)\) 把任意实数压到 0~1 区间,输出即为点击概率。

σ(z)=11+e−z\sigma(z) = \frac{1}{1 + e^{-z}}

这个“相加”看似简单,却体现了精心设计:FM 保底解决稀疏场景下最常见的二阶交互,DNN 负责挖掘更复杂的高阶关系。共享 Embedding 让两路从同一套表示出发,端到端地用交叉熵损失直接优化——不需要像早期 FNN 那样先预训练 FM 再训练 DNN。经典与创意同灶,成就了这道招牌菜。

对比与部署

老陈的招牌菜火了,隔壁面馆和分子料理店也来“借鉴”。隔壁面馆用“层层叠叠拉面”的方法做交叉——每一层都把面皮重新折叠、再次擀开,这就像 DCN 的 Cross 网络。分子料理店则用精密仪器,精确控制每一个食材分子的反应——这就像 xDeepFM 的 CIN 模块。

DCN 的 Cross 网络每一层都保留初始特征 \(x_0\),再让当前状态与初始特征做“逐元素相乘”的显式交叉,叠加多层后能显式建模有限阶的特征组合。但 DCN 缺少类似 DNN 的深层隐式表达,且本质上仍是“标量级”操作。xDeepFM 提出的 CIN(Compressed Interaction Network)则更进一步:它在向量维度上做显式高阶交叉,每一层的输出都是“向量级”的交互结果,可以精确控制要交叉到几阶。DeepFM 与 xDeepFM 名字相近,但 DeepFM 的高阶交互靠 DNN 隐式完成,xDeepFM 的高阶交互是显式逐维构造的,两者并不相同。

xl+1=x0⊙(Wlxl+bl)+xl\mathbf{x}_{l+1} = \mathbf{x}_0 \odot (\mathbf{W}_l \mathbf{x}_l + \mathbf{b}_l) + \mathbf{x}_l

1. 初始特征:\(\mathbf{x}_0\) 是交叉网络在第一层保留的原始 Embedding 拼接向量,每层都参考它。

x0\mathbf{x}_0

2. 线性变换:\(\mathbf{W}_l \mathbf{x}_l + \mathbf{b}_l\) 对当前状态做线性映射,产生新的交叉中间量。

Wlxl+bl\mathbf{W}_l \mathbf{x}_l + \mathbf{b}_l

3. 逐元素相乘:\(\odot\) 让初始特征与中间量逐维相乘,这就是“显式交叉”的核心操作。

x0⊙(Wlxl+bl)\mathbf{x}_0 \odot (\mathbf{W}_l \mathbf{x}_l + \mathbf{b}_l)

4. 残差连接:加上 \(\mathbf{x}_l\) 保证信息不丢失,避免深层网络退化。

+xl+ \mathbf{x}_l

回到现实部署:训练 DeepFM 的完整流程大致是——收集用户行为日志 → 特征工程(ID 化、分桶、构造交叉记忆)→ 构造正负样本 → 训练并评估 AUC/GAUC → 导出模型 → 上线在线推理服务。工程上要特别关注 Embedding 表的内存占用、线上推理的延迟优化(比如把 Embedding 查表结果预热到内存缓存),以及根据新日志定期增量更新模型。不同流派各有擅长,但 DeepFM 之所以成为经典,正是因为它用最简洁的“经典搭配 + 创意融合”结构,在效果与工程复杂度之间找到了黄金平衡点。

AI 应用场景

信息流广告 CTR 预估

阶段:离线训练 + 在线推理

解决的问题:广告平台需要预测用户是否会点击某条广告,传统 LR 模型依赖人工构造交叉特征,业务人员要手写大量组合规则,既费人力又容易遗漏。DeepFM 自动学习二阶与高阶特征交叉,显著减少人工特征工程。

具体案例:某广告平台把用户画像(年龄、兴趣标签、设备型号)与广告属性(行业、创意形式、投放时段)做 one-hot 后送入 DeepFM,线上 CTR 提升约 15%,AUC 提升 3 个百分点,同时上线周期从两周缩短到三天。

短视频推荐精排

阶段:召回后的精排打分

解决的问题:短视频平台从海量候选视频中粗筛出几百个后,需要用高精度模型精排。DeepFM 对“用户-视频”特征对打分,输出用户点击/完播的概率作为排序依据。

具体案例:某短视频 App 把多路召回结果输入 DeepFM,特征包括用户静态画像、历史观看序列、视频内容标签、当前上下文(时间、网络环境),精排后的平均播放时长提升 8%。

电商商品个性化排序

阶段:商品流排序的模型服务

解决的问题:电商场景用户与商品特征极其稀疏——一个用户只买过几十种商品,一个商品只有有限的曝光记录。DeepFM 的共享 Embedding 让冷门商品也能借由相似商品的向量获得泛化能力。

具体案例:某电商平台把用户行为序列、商品类目、价格带、促销类型等特征送入 DeepFM,作为主排序模型之一,在双十一大促期间依然保持稳定的点击率和 GMV 转化率。

Python 演示

python60 行
import torchimport torch.nn as nnimport torch.optim as optim  class DeepFM(nn.Module):    """DeepFM: FM 与 DNN 并行融合的 CTR 预估模型"""     def __init__(self, feature_size, embed_size, hidden_sizes):        super(DeepFM, self).__init__()        # 一阶线性权重(特征 ID -> 权重)        self.first_order = nn.Embedding(feature_size, 1)        # 共享 Embedding(FM 二阶与 DNN 共用)        self.shared_emb = nn.Embedding(feature_size, embed_size)        # DNN 深层网络        self.deep_layers = nn.ModuleList()        input_dim = embed_size        for hidden in hidden_sizes:            self.deep_layers.append(nn.Linear(input_dim, hidden))            input_dim = hidden        self.deep_out = nn.Linear(input_dim, 1)     def forward(self, x):        # 共享 Embedding 查表: (batch, fields, embed)        emb = self.shared_emb(x)        # FM 一阶部分        first = self.first_order(x).sum(dim=1)        # FM 二阶部分: 0.5 * ((sum v)^2 - sum(v^2))        sum_sq = emb.sum(dim=1) ** 2        sq_sum = (emb ** 2).sum(dim=1)        second = 0.5 * (sum_sq - sq_sum).sum(dim=1)        # DNN 高阶部分        deep_in = emb.reshape(emb.size(0), -1)        for layer in self.deep_layers:            deep_in = torch.relu(layer(deep_in))        dnn_out = self.deep_out(deep_in).squeeze(1)        # FM 与 DNN 并行相加, 再经 sigmoid 输出 CTR        logits = first + second + dnn_out        return torch.sigmoid(logits)  def main():    # 模拟 8 个特征, 每条样本有 3 个特征字段    torch.manual_seed(42)    model = DeepFM(feature_size=8, embed_size=4, hidden_sizes=[8, 8])    optimizer = optim.Adam(model.parameters(), lr=0.01)    x = torch.randint(0, 8, (64, 3))    y = torch.randint(0, 2, (64,)).float()    for epoch in range(50):        optimizer.zero_grad()        pred = model(x).squeeze(1)        loss = nn.functional.binary_cross_entropy(pred, y)        loss.backward()        optimizer.step()        if epoch % 10 == 0:            print("epoch", epoch, "loss", round(loss.item(), 4))  if __name__ == "__main__":    main()
目的:用 PyTorch 从零实现一个可训练的 DeepFM 模型,演示 FM 一阶/二阶项与 DNN 高阶项如何共享 Embedding 并端到端融合。
  1. self.shared_emb = nn.Embedding(feature_size, embed_size)建立共享 Embedding 表,FM 与 DNN 都从这里取特征向量,这是 DeepFM 的关键枢纽。
  2. first = self.first_order(x).sum(dim=1)用 Embedding 查表取出每个特征的一阶权重并求和,得到 FM 的一阶项。
  3. second = 0.5 * (sum_sq - sq_sum).sum(dim=1)利用数学恒等变换把 O(n²) 的二阶交叉化简为 O(nk) 的向量运算,代码里不出现任何双层循环。
  4. deep_in = emb.reshape(emb.size(0), -1)把多个字段的 Embedding 展平拼接,作为 DNN 部分的输入向量。
  5. logits = first + second + dnn_outFM 支路与 DNN 支路并行相加,体现 DeepFM 的融合方式。
  6. return torch.sigmoid(logits)Sigmoid 把融合分数压到 0~1,输出 CTR 点击概率。

常见误区

误区DeepFM 叫“FM 与 DNN 融合”,那不就是先把 FM 训练好、再训练 DNN,最后把两个模型的预测结果做加权平均吗?

正解DeepFM 不是集成学习,而是单一模型的内部并行结构。FM 支路和 DNN 支路共享同一个 Embedding 层,一起做反向传播、端到端联合优化,全程只有一个损失函数。就像两位厨师共用一个灶台、一套食材,而不是各自开两家店再拼桌。

为何常见:“融合”这个词容易让人联想到模型集成,而忽略了 DeepFM 架构里“共享参数 + 联合训练”的本质。

误区DNN 不是万能函数逼近器吗?那我把原始 one-hot 稀疏特征直接灌进 DNN,不也能学出高维交叉吗?

正解千万不能直接灌。原始 one-hot 特征动辄百万维,直接进入第一层全连接会让参数量爆炸,而且每个权重只能被极少数样本更新,学不出泛化。DeepFM 的做法是先用共享 Embedding 把稀疏特征压缩成几十维稠密向量,再送入 DNN。

为何常见:直觉上觉得“DNN 够强”,忽略了高维稀疏输入带来的维度灾难与严重过拟合。

误区看到公式里有两层求和符号,就以为代码里必须写双重 for 循环遍历所有 i < j 的特征组合,复杂度 O(n²)。

正解FM 可以通过恒等变换把二阶项改写为 \(\frac{1}{2}((\sum v_i x_i)^2 - \sum (v_i x_i)^2)\),计算复杂度从 O(n²) 降为 O(nk)。Python 演示代码正是用这种向量化技巧实现的。

为何常见:只看了公式没看推导,“双重求和”的第一印象根深蒂固。

误区DeepFM 里不是有 DNN 吗?那我把隐藏层加到 10 层、每层 1024 个神经元,效果肯定更好。

正解DNN 层数过深会带来过拟合、训练不稳、推理延迟高。CTR 场景特征稀疏、噪声大,过深的网络很容易把记忆性噪声学进去。实践中 2~3 层隐藏层通常就够,要结合 AUC 和线上效果综合调参。

为何常见:深度学习“越深越强”的印象在社会上过于深入人心,忽略了推荐场景数据稀疏的现实。

误区xDeepFM 名字里也有 DeepFM,所以只是 DeepFM 加了点小改动的版本,核心结构完全一样。

正解两者高阶特征的学习方式根本不同:DeepFM 的 DNN 是“隐式”高阶交叉,没有显式的交叉阶数概念;xDeepFM 的 CIN 是“显式”向量级高阶交叉,可以精确控制交叉到第几阶。名字相近但设计哲学不同。

为何常见:模型命名都以 DeepFM 为后缀,让人误以为只是工程优化,没注意到数学结构上的差异。

面试题

Q1. DeepFM 中 FM 部分的核心职责是?

单选题 · mid

  • A.学习一阶与二阶特征交互← 正确答案
  • B.学习三阶以上的深层交叉
  • C.独立生成全连接网络参数
  • D.完成用户物品的向量检索

答案:A。FM 在 DeepFM 中负责建模一阶线性项与二阶特征交叉,DNN 负责高阶隐式交叉。选项 B 是 DNN 的职责;C、D 与 FM 无关。就像面点老师傅只负责经典两两搭配,不负责分子料理。

Q2. DeepFM 的 FM 与 DNN 组件关系是?

单选题 · easy

  • A.两个组件并行融合输出结果← 正确答案
  • B.FM 为前置 DNN 做数据过滤
  • C.DNN 输出作为 FM 的输入项
  • D.两个组件交替更新各自参数

答案:A。DeepFM 是并行结构:共享 Embedding 后 FM 与 DNN 各算各的,输出直接相加再过 Sigmoid。B、C 描述的都是串行关系,D 的交替训练也不是 DeepFM 的做法——它是端到端联合训练。

Q3. 关于 DeepFM 共享 Embedding 的说法,正确的有哪些?

多选题 · hard

  • A.FM 与 DNN 共用同一个低维嵌入表← 正确答案
  • B.模型无需 FM 预训练即可端到端优化← 正确答案
  • C.每个子网络拥有独立的 Embedding 表
  • D.共享会让 FM 与 DNN 训练目标互相割裂

答案:AB。共享 Embedding 是 DeepFM 的核心:一份嵌入表同时服务 FM 与 DNN,梯度会同时更新它,无需像 FNN 那样先预训练 FM。C 错在“独立”,D 错在“割裂”——共享恰恰让两路目标统一。

Q4. DeepFM 最擅长处理的特征类型是?

单选题 · easy

  • A.稀疏高维的类别型离散特征← 正确答案
  • B.稠密连续的数值型评分特征
  • C.像素级别的图像纹理特征图
  • D.词级别的语义上下文特征串

答案:A。DeepFM 的 FM 与 Embedding 机制天生适合 one-hot 后的稀疏离散特征,比如用户 ID、商品类目、时段。图像和文本需要 CNN/RNN 等结构,不属于 DeepFM 的主场。

Q5. 与 DCN 的 Cross 网络相比,DeepFM 的差异化特点是什么?

单选题 · mid

  • A.用 FM 模块完成二阶交互表示← 正确答案
  • B.使用循环神经网络捕获时序
  • C.完全抛弃低维嵌入表示层
  • D.只在特征比特位做逻辑操作

答案:A。DCN 用 Cross 网络做显式有限阶交叉,DeepFM 则用 FM 做二阶交叉、DNN 做高阶隐式交叉。B、C、D 都不是 DeepFM 的设计。两者都依赖 Embedding,D 完全是干扰项。

Q6. DeepFM 中 DNN 部分的能力有哪些?

多选题 · mid

  • A.自动学习高阶非线性特征组合← 正确答案
  • B.通过多层网络捕获复杂语义交互← 正确答案
  • C.替代 FM 完成全部二阶交叉计算
  • D.使用激活函数引入非线性表达← 正确答案

答案:ABD。DNN 通过多层堆叠与非线性激活隐式学习高阶特征交互,A、B、D 正确。C 错误:二阶交叉由 FM 支路负责,DNN 不替代它,两者是分工而非竞争关系。

Q7. FM 参数因子分解能大幅降低复杂度的原因是?

单选题 · hard

  • A.交叉权重表示成隐向量的内积← 正确答案
  • B.每对特征都保留独立权重参数
  • C.只计算一阶特征的线性加权和
  • D.用树模型替代线性分类器

答案:A。FM 把每个特征对独有的权重 w_ij 分解为 v_i 与 v_j 的内积,参数从 O(n²) 降到 O(nk),且能泛化到未出现的特征对。B 恰恰是因子分解要避免的原始做法。

Q8. 实际部署 DeepFM 做 CTR 预估时,第一件要做的事是?

单选题 · mid

  • A.构造并清洗特征批次样本数据← 正确答案
  • B.直接加载预训练权重上线服务
  • C.将特征维度压缩到一维数值
  • D.删除所有稀疏类别特征字段

答案:A。任何推荐模型的落地都是从数据与特征工程开始的:采集日志、ID 化、分桶、构造样本。没有高质量训练数据,模型权重无从谈起;B、C、D 都是错误步骤。

Q9. 关于 xDeepFM 与 DeepFM 的差异,正确的是?

多选题 · extreme

  • A.CIN 模块显式建模高阶特征交叉← 正确答案
  • B.DeepFM 高阶依赖 DNN 隐式学习← 正确答案
  • C.两者在结构逻辑上完全同构等价
  • D.向量级逐维交叉比标量更精细← 正确答案

答案:ABD。xDeepFM 的 CIN 在向量维度上显式构造高阶交叉,DeepFM 的 DNN 则是隐式学习高阶特征。A、B 正确。C 错在两模型结构并不相同。D 正确:CIN 的逐维压缩操作确实比 DCN 的标量级交叉更精细。

Q10. DeepFM 在输出层使用哪个函数得到点击概率?

单选题 · easy

  • A.Sigmoid 压缩结果到零到一区间← 正确答案
  • B.Softmax 对所有类别做归一化概率
  • C.Tanh 将结果映射到负一到一区间
  • D.ReLU 直接输出原始非负数值

答案:A。CTR 预估是二分类问题,输出层用 Sigmoid 把融合分数压缩到 0~1 作为点击概率。Softmax 用于多分类,Tanh 输出含负值,ReLU 不产生概率,都不合适。