想象你是商场里的一位金牌导购。有位顾客几乎每周都来,但你渐渐发现:她并不是一整天都在买同一种东西——早上匆忙买一杯咖啡,中午帮家人挑生日礼物,晚上认真为新家挑选床垫。如果你把这一整天的行为全混在一起看,就完全搞不清她“此刻进店到底想买什么”。聪明的导购会下意识地把“同一次进店”单独拎出来看,先分清这次买咖啡、那次挑礼物,再观察她这几段购物行程之间兴趣的变化。DSIN(Deep Session Interest Network,深度会话兴趣网络)就是这样一个金牌导购:它先把用户行为序列按时间间隔切分成多个“会话”,在每个会话内用自注意力找出关键行为,再把这些会话串起来,读懂用户兴趣从“想买咖啡机”如何一步步演变成“想买床垫”。这套思路让推荐系统不再把用户几百次点击揉成一锅粥,而是像导购一样读懂了用户每一次独立的购物行程。

岗位关联

掌握 DSIN,意味着你学会用“会话”视角重新理解用户行为序列,这是推荐系统精准建模用户真实意图、大幅提升点击与转化效果的核心进阶能力。

目录
  1. 可视化演示
  2. 用户行为序列
  3. 会话切分原理
  4. 自注意力提取
  5. 兴趣演化建模
  6. 模型对比分析
  7. 工程落地实践
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

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

用户行为序列

商场的金牌导购每天会见到很多顾客,每位顾客从进门到离开都会留下一条“动线”:先在哪个柜台停留,拿起哪件商品翻看,最后在收银台结账哪件商品。记录这些动线很有意思,但如果导购只看一堆零散记录,不区分时间,她根本不知道这位顾客这次进来到底是为早餐咖啡,还是为新家床垫。

推荐系统面对的正是同样的问题。用户行为序列,就是把用户在一段时间内的点击、浏览、加购、下单等行为按时间顺序排成一条长序列。序列里的每个行为都至少包含“看了哪个商品”和“什么时候看的”两个信息。这条序列可能长达几百条,里面混着用户不同时期的兴趣——昨天看球鞋,今天看母婴用品,明天又搜旅行箱。推荐系统的任务,就是从这条混杂的序列里,预测用户此刻最可能点击哪个商品。

如果直接把所有行为一视同仁地送入模型,就像导购把顾客一年来的购物记录按时间顺序摊开,却完全不去想“那次是为了什么”。这会让短期意图被长期噪声淹没,模型分不清用户当下最想要什么。

回到商场的场景:动线太多、记不住,导购想要更聪明地工作,第一步就是把“某次进店”从一整天的记录里分出来。这就是 DSIN 的会话切分。

S={b1,b2,…,bN}S = \{ b_1, b_2, \ldots, b_N \}
公式含义:S 是一条按时间排列的用户行为序列,里面共有 N 次行为。这是 DSIN 的原始输入。
  1. 行为集合S 表示一整条用户行为序列,由 N 次行为构成,行为之间严格按照发生时间先后排序。
    S={b1,b2,…,bN}S = \{ b_1, b_2, \ldots, b_N \}
  2. 单个行为第 i 次行为 b_i 至少包含商品 ID 和行为时间戳两个关键信息,这是后续切分的基础。
    bi=(itemi,timei)b_i = (\text{item}_i, \text{time}_i)
  3. 行为总数N 表示这条序列的长度,用户活跃时 N 往往能达到数百,直接全部建模既慢又容易丢失重点。
    N=∣S∣N = |S|

会话切分原理

这位顾客一天之内可能进了三次商场:早上七点匆匆买一杯咖啡,中午十二点给家人挑生日礼物,晚上八点认真为新家选床垫。金牌导购不会把三次行程混成一次来理解,因为三次行程的意图完全不同。她会把每次进出商场的时段看作一个独立的“会话”,单独分析。

DSIN 的第一步就是做这件事:会话切分。所谓会话,就是用户在时间上连续、意图相对集中的一次行为集合。DSIN 的切分规则非常朴素——只要相邻两次行为的时间间隔超过一个阈值(比如 30 分钟),就认为上一个会话结束、新会话开始。这个阈值在工业界通常取 30 分钟:用户在 30 分钟内连续浏览,多半在同一个意图下;超过 30 分钟,大概率已经切换到其他任务或者放下了手机。

切分之后,原本一条长长的行为序列变成了 K 个较短的会话序列,每个会话只代表顾客某一段时间的真实兴趣。会话数量 K 是自动根据时间间隔决定的,而不是拍脑袋固定的。切分越合理,后续提取的兴趣就越纯净——就像导购把“买咖啡”和“挑床垫”分开分析,而不是把两者揉成一团。

导购分清了顾客的三次行程,但每次行程里顾客到底在为什么而停留,还需要进一步观察关键动作。下一步就是进入会话内部,用自注意力寻找重点。

S={S1,S2,…,SK},Sk={b1(k),b2(k),…,bT(k)}S = \{ S_1, S_2, \ldots, S_K \}, \quad S_k = \{ b_1^{(k)}, b_2^{(k)}, \ldots, b_T^{(k)} \}
公式含义:原始行为序列 S 被切分为 K 个会话,第 k 个会话内包含 T 次按时间排序的行为。
  1. 会话总数K 表示切分后得到的会话个数,每个会话都对应用户一段连续的浏览时段。
    S={S1,S2,…,SK}S = \{ S_1, S_2, \ldots, S_K \}
  2. 会话内行为第 k 个会话 S_k 内部有 T 次行为,T 通常远小于原始序列总长度 N,兴趣更纯。
    Sk={b1(k),b2(k),…,bT(k)}S_k = \{ b_1^{(k)}, b_2^{(k)}, \ldots, b_T^{(k)} \}
  3. 切分条件判断相邻两次行为是否属于同一会话,看两者时间差是否超过阈值 δ,超过就切开。
    tj+1(k)−tj(k)>δt_{j+1}^{(k)} - t_j^{(k)} > \delta

自注意力提取

导购把顾客的一次购物行程单独抽出后,会发现虽然顾客逛了十几个柜台,但真正引起她兴趣的只有两三个:她在运动鞋专柜反复试了四款,在袜子区扫了一眼就走,在收银台旁边的口香糖架前停了五秒。聪明导购会意识到,那次行程的重点是运动鞋。DSIN 在会话内部也做同样的事,工具就是自注意力。

自注意力机制让会话里的每个行为与其他所有行为两两打分,分数高说明两个行为关联强。于是,那些“孤立路过”的行为权重自然变低,“反复关注”的行为被彼此照亮。DSIN 使用多头自注意力,就是同时用好几组“打分规则”:一组关注商品品类是否一致,另一组关注价格区间是否相近,还有一组关注品牌偏好。多个头并行,能把不同角度的兴趣都捕捉到。

为了让模型知道行为的先后顺序,DSIN 还加入了偏差编码。自注意力本身不区分位置,把“先看球鞋再看袜子”颠倒成“先看袜子再看球鞋”结果一样,这显然不合理。偏差编码给每个行为补上一个位置信号,让模型知道“第 3 次点击”和“第 9 次点击”在会话中的意义不同。最后,把经过自注意力和偏差编码后的行为表征做平均池化,就得到了这个会话的兴趣向量。

导购看懂了顾客在“挑生日礼物”这次行程里重点看了手表和钢笔,可是顾客今天看完礼物,明天又会为什么而逛?兴趣不是静止的,它会在一次次行程之间流动。这就是跨会话的兴趣演化。

Bk=MultiHead(Sk,Sk,Sk)+BiasEncoding(Sk)B_k = \text{MultiHead}(S_k, S_k, S_k) + \text{BiasEncoding}(S_k)
公式含义:第 k 个会话内,行为向量经过多头自注意力交互后,再加上偏差编码保留顺序信息,得到会话内增强表征。
  1. 同源自注意力Q、K、V 都来自同一个会话 S_k,让会话内行为两两交互、互相发现关联。
    MultiHead(Sk,Sk,Sk)\text{MultiHead}(S_k, S_k, S_k)
  2. 偏差编码BiasEncoding 为每个行为补充位置信号,相当于在向量上加一个“第几次点击”的位置标记。
    BiasEncoding(Sk)\text{BiasEncoding}(S_k)
  3. 增强表征把注意力输出与位置信号相加,B_k 是既含内容关系、又含顺序信息的会话内行为向量。
    Bk=MultiHead(Sk,Sk,Sk)+BiasEncoding(Sk)B_k = \text{MultiHead}(S_k, S_k, S_k) + \text{BiasEncoding}(S_k)

兴趣演化建模

顾客上周连续三天逛商场,分别看了露营帐篷、睡袋和便携燃气灶。单独看每一天,她只是买了三件户外用品;但连起来看,导购恍然大悟:她在为一次多日徒步做系统准备,兴趣从“先买个帐篷”演化为“把整套装备配齐”。如果不把几次会话串起来看,就丢失了这条重要的演化线索。

DSIN 的会话兴趣交互层解决的就是这个问题。前面已经从每个会话提取出一个兴趣向量,现在把这些兴趣向量按时间顺序排成一列:第一个会话的兴趣、第二个会话的兴趣……直到第 K 个。然后对这些兴趣向量再做一次自注意力。与“会话内自注意力”不同,这次交互发生在会话和会话之间,让每个会话的兴趣向量都能“看到”其他会话的信息——后来的会话知道前面会话发生过什么,从而判断兴趣是延续、增强还是转移了。

经过这次交互,每个会话的兴趣向量都携带了全局演化信息。比如第三个会话的兴趣向量里,既保留了自己对燃气灶的关注,又融合了前两个会话中帐篷和睡袋的信号。这样,最终的用户兴趣不是 K 个孤立点的简单相加,而是一条有起承转合的演化路径。

导购把顾客几次行程连成了一条故事线,明白了“露营需求”如何在几周内逐步成形。但推荐系统最终只关心一个目标:顾客此刻会对哪个商品感兴趣?这就要用目标商品去“激活”这些演化后的会话兴趣。

I^=MultiHead(I,I,I),I=[I1;I2;…;IK]\hat{I} = \text{MultiHead}(I, I, I), \quad I = [I_1; I_2; \ldots; I_K]
公式含义:把 K 个会话兴趣向量按顺序拼接成序列 I,再做一次自注意力,每个输出向量都融合了跨会话的演化信息。
  1. 会话向量序列I 由 K 个会话向量拼接而成,顺序就是会话发生的先后顺序,代表用户兴趣的演化轨迹。
    I=[I1;I2;…;IK]I = [I_1; I_2; \ldots; I_K]
  2. 跨会话自注意力Q=K=V=I,每个会话向量都会与其他会话向量交互,从而感知前后兴趣的变化。
    MultiHead(I,I,I)\text{MultiHead}(I, I, I)
  3. 演化表征输出 Î 中每个向量都吸收了全局演化信息,作为后续加权融合的输入。
    I^=MultiHead(I,I,I)\hat{I} = \text{MultiHead}(I, I, I)

模型对比分析

推荐系统里,建模用户兴趣的模型走过三代。第一代导购(DIN)很勤快,把顾客所有历史行为都记得清清楚楚,等顾客一进门,就把与当前商品有关的历史行为挑出来重点参考,这叫做“局部激活”;第二代导购(DIEN)更进一步,不仅看行为,还看行为的变化过程,用循环网络记住兴趣从 A 演变到 B 的路径;第三代金牌导购(DSIN)则发现前两代都把顾客所有行为混在一起,没有区分“几次独立进店”,于是先切分会话、再提取兴趣、最后建模演化。

DSIN 并不推翻 DIN 的思想,而是把它从“行为粒度”升级到了“会话粒度”。DIN 的做法是:给定目标商品,对用户的所有历史行为计算注意力权重——与目标商品越相关的历史行为权重越高。DSIN 把同样思路用在会话上:给定目标商品,对 K 个演化后的会话兴趣向量计算权重——越能解释用户当前意图的会话,权重越高。这样既保留了对目标商品的“软搜索”,又避免了长序列中无关行为带来的噪声。

| 模型 | 建模粒度 | 兴趣提取 | 兴趣演化 | 核心思想 |

|------|---------|---------|---------|---------|

| DIN | 行为 | 目标商品激活每个行为 | 无 | 软搜索找出相关行为 |

| DIEN | 行为 | 序列 GRU 逐步编码 | 隐式演化 | 刻画兴趣变化路径 |

| DSIN | 会话 | 多头自注意力提取 | 跨会话交互 | 会话边界 + 演化建模 |

那“激活”具体怎么算?把目标商品的向量与每个会话兴趣向量做相似度打分,分数越高,说明这个会话越能代表用户当前的需求,权重越大;再经过 softmax 归一化,所有权重之和为 1。

三个时代的导购各有绝活,但金牌导购的核心优势在于第一次把“会话”当作理解用户的基本单位。这个理念不但让模型更精细,也为工业落地铺平了道路。

αk=exp⁡(β⋅Vtarget⋅I^k⊤)∑j=1Kexp⁡(β⋅Vtarget⋅I^j⊤)\alpha_k = \frac{\exp(\beta \cdot V_{\text{target}} \cdot \hat{I}_k^\top)}{\sum_{j=1}^{K} \exp(\beta \cdot V_{\text{target}} \cdot \hat{I}_j^\top)}
公式含义:目标商品向量对第 k 个演化后会话兴趣向量打分,分数经 softmax 变成权重,代表该会话对当前决策的重要程度。
  1. 目标商品向量V_target 是候选商品(模型此刻要预测用户会不会点它)的嵌入向量。
    VtargetV_{\text{target}}
  2. 相似度打分V_target 与 Î_k 做点积,点积越大说明该会话兴趣与当前目标商品越匹配。
    Vtarget⋅I^k⊤V_{\text{target}} \cdot \hat{I}_k^\top
  3. 温度系数β 控制打分差异的放大程度,让权重分布更尖锐或更平滑。
    β⋅Vtarget⋅I^k⊤\beta \cdot V_{\text{target}} \cdot \hat{I}_k^\top
  4. 归一化权重对所有会话的得分取指数并求和,把原始分数变成加起来等于 1 的注意力权重 α_k。
    αk=exp⁡(⋅)∑jexp⁡(⋅)\alpha_k = \frac{\exp(\cdot)}{\sum_j \exp(\cdot)}

工程落地实践

把金牌导购的整套经验写成培训手册,复制到连锁商场的每一位导购手里,这就是 DSIN 工程落地的意义。在真实的推荐系统里,DSIN 被用来回答一个问题:用户此刻打开 App,最可能点击哪个商品?

工程上,DSIN 的输入是用户的原始行为序列,输出是一个点击率预测。落地时主要分三步走。第一步是嵌入层设计:把用户 ID、商品 ID、行为时间等离散特征映射为稠密向量,形成行为序列的嵌入表示。第二步是会话特征预计算:会话切分完全由时间间隔决定,这部分可以在离线阶段把每个用户的行为序列切成会话、算好会话内注意力结果,缓存下来供线上直接读取,大大降低线上时延。第三步是模型服务:线上拿到目标商品后,只计算跨会话交互与最终加权融合,轻量且快速。

从效果评估的角度看,会话切分相当于给模型提供了一项高质量的“先验特征”——用户行为天然具有会话聚落结构,电商的“加购车再下单”、短视频的“连续刷半小时”都是会话的体现。DSIN 在多个工业数据集上的 CTR 提升,主要就来自这种对真实行为结构的尊重。

从金牌导购的经验,到一套可复制的工程流程,DSIN 把“按会话读懂用户”从直觉变成了可训练的模型。下面看看它在真实业务中如何发挥作用。

y^=σ(MLP([U;Vtarget])),U=∑k=1Kαk⋅I^k\hat{y} = \sigma(\text{MLP}([U; V_{\text{target}}])), \quad U = \sum_{k=1}^{K} \alpha_k \cdot \hat{I}_k
公式含义:所有演化后的会话兴趣按权重 α_k 加权求和得到 U,再与目标商品向量拼接,经过多层感知机和 sigmoid 输出最终点击概率。
  1. 加权兴趣融合U 是演化后的会话兴趣向量按 α_k 的加权和,α_k 就是上一个公式算出的会话权重。
    U=∑k=1Kαk⋅I^kU = \sum_{k=1}^{K} \alpha_k \cdot \hat{I}_k
  2. 特征拼接把用户会话兴趣 U 和目标商品向量 V_target 拼成一个更长的向量,同时包含“用户想要什么”与“商品是什么”。
    [U;Vtarget][U; V_{\text{target}}]
  3. 映射到概率MLP 学习两者交互特征,sigmoid 函数把输出压缩到 0 到 1 之间,即点击概率。
    y^=σ(MLP([U;Vtarget]))\hat{y} = \sigma(\text{MLP}([U; V_{\text{target}}]))

AI 应用场景

电商大促场景的会话级召回

阶段:召回与粗排阶段

解决的问题:大促期间用户行为序列极长,零食、家电、服饰交替浏览,传统 DIN 把所有行为视为平等序列,用户“此刻真正想买”的兴趣被无关行为稀释。DSIN 先把行为切成多个会话,再用目标商品对会话兴趣做加权激活,让召回更能命中当前意图。

具体案例:某综合电商“猜你喜欢”频道中,一位用户晚上分三段浏览:第一段看球鞋评测,第二段帮家人看血压计,第三段搜旅行箱。DSIN 识别出三个会话后,最近会话的旅行箱兴趣获得更高权重,系统优先召回旅行箱相关商品,CTR 相比 DIN 显著提升。

短视频信息流的会话感知推荐

阶段:排序阶段

解决的问题:用户在不同时段有完全不同的视频偏好:通勤时看新闻,午休看搞笑视频,睡前看治愈系内容。把整天行为混在一起会让模型产生目标偏差,DSIN 按时间间隔切分会话,让“此刻所在的会话”主导排序。

具体案例:某短视频 App 发现用户睡前会话的完播率远高于白天。引入 DSIN 后,模型识别出“睡前放松”会话的兴趣特征,在晚间 session 中提高治愈系、助眠类内容的排序权重,用户人均观看时长提升。

Python 演示

python76 行
import torchimport torch.nn as nn def split_sessions(behaviors, time_gap=1800):    """把 [(item_id, timestamp), ...] 行为序列切成多个会话"""    sessions = []    cur = [behaviors[0][0]]    for i in range(1, len(behaviors)):        item_id, ts = behaviors[i]        prev_ts = behaviors[i - 1][1]        if ts - prev_ts > time_gap:            sessions.append(cur)            cur = []        cur.append(item_id)    sessions.append(cur)    return sessions  class DSINModel(nn.Module):    """简化版 DSIN:会话切分 + 会话内自注意力 + 跨会话交互"""    def __init__(self, num_items, embed_dim=8, num_heads=2, max_session_len=10):        super().__init__()        self.dim = embed_dim        self.item_emb = nn.Embedding(num_items, embed_dim)        self.pos_emb = nn.Embedding(max_session_len, embed_dim)        self.attn = nn.MultiheadAttention(embed_dim, num_heads, batch_first=True)        self.fc = nn.Sequential(            nn.Linear(embed_dim * 2, 32),            nn.ReLU(),            nn.Linear(32, 1),        )     def forward(self, session_seqs, session_lens, target_item):        session_vecs = []        for k in range(session_seqs.size(1)):            lens = session_lens[:, k]            max_len = lens.max().item()            if max_len == 0:                session_vecs.append(torch.zeros(session_seqs.size(0), self.dim))                continue            sess = session_seqs[:, k, :max_len]            emb = self.item_emb(sess)            pos = self.pos_emb(torch.arange(max_len)).unsqueeze(0)            attended, _ = self.attn(emb + pos, emb + pos, emb)            session_vecs.append(attended.mean(dim=1))        session_vecs = torch.stack(session_vecs, dim=1)        session_vecs, _ = self.attn(session_vecs, session_vecs, session_vecs)        session_vecs = session_vecs.mean(dim=1)        target_emb = self.item_emb(target_item)        feature = torch.cat([session_vecs, target_emb], dim=-1)        return torch.sigmoid(self.fc(feature))  if __name__ == '__main__':    torch.manual_seed(42)    behaviors = [(3, 0), (5, 100), (8, 200), (2, 4000), (4, 4100), (7, 4200), (1, 9000)]    print("切分结果:", split_sessions(behaviors))     B, K, T, num_items = 4, 3, 5, 50    session_seqs = torch.randint(1, num_items, (B, K, T))    session_lens = torch.randint(1, T + 1, (B, K))    target = torch.randint(1, num_items, (B,))    labels = torch.rand(B, 1)     model = DSINModel(num_items)    loss_fn = nn.BCELoss()    opt = torch.optim.Adam(model.parameters(), lr=0.01)     for ep in range(20):        pred = model(session_seqs, session_lens, target)        loss = loss_fn(pred, labels)        opt.zero_grad()        loss.backward()        opt.step()        if ep % 10 == 0:            print('epoch', ep, 'loss', round(loss.item(), 4))
目的:用 PyTorch 实现一个可运行的简化 DSIN,先演示会话切分,再完成会话内自注意力提取、跨会话交互和点击率预测的完整前向流程。
  1. def split_sessions(behaviors, time_gap=1800)把带时间戳的行为序列按 30 分钟间隔切成多个会话,模拟 DSIN 的会话切分层。
  2. self.attn = nn.MultiheadAttention(...)定义多头自注意力模块,既用于会话内行为交互,也用于跨会话兴趣交互。
  3. attended, _ = self.attn(emb + pos, emb + pos, emb)会话内自注意力:行为向量加位置编码后自身交互,得到增强表征。
  4. attended.mean(dim=1)平均池化:把所有行为向量压缩成一个向量,代表当前会话的兴趣。
  5. session_vecs, _ = self.attn(session_vecs, session_vecs, session_vecs)第二层自注意力:让 K 个会话向量互相感知,建模兴趣演化。
  6. torch.cat([session_vecs, target_emb], dim=-1)把演化后的会话兴趣与目标商品拼接,交给 MLP 学习交叉特征。

常见误区

误区用户的行为不都是一条时间线吗?只要按时间排好,放进 DIN 用注意力激活就够了,为什么非要切分会话?感觉切分只是多此一举。

正解恰恰相反,切分是 DSIN 最核心的一步。一条横跨数小时甚至数天的行为序列里,兴趣主题会切换多次——早上看咖啡、中午看礼物、晚上看床垫。不切分时,目标商品“床垫”要跟“咖啡机”“生日礼物”竞争注意力,相关行为的权重被稀释。切分后,每个会话内兴趣单一,自注意力才能精准聚焦。就像导购必须先把“买咖啡”和“挑床垫”分成两次行程,才能准确判断顾客此刻的需求。

为何常见:因为早期的 DIN 模型确实直接把整个序列送入注意力层,很多人形成了“序列就是一条到底”的思维定式,忽略了现实行为天然分段的特性。

误区用户一天的行为就算一个会话吧?把凌晨到深夜的所有浏览当成一段,或者按日期分成“今天”“昨天”这样几段不就行了?

正解DSIN 的会话切分依据是相邻行为的时间间隔是否超过阈值,而不是日历时间。用户可能早上在一个会话里看新闻,中午间隔一小时后又开始看球鞋,这已经是两个会话;反过来,如果用户深夜连续使用到凌晨两点,跨天的时间段反而可能属于同一个会话。正确做法是:遍历行为序列,每当相邻行为间隔超过 δ(通常 30 分钟),就切开一个新会话。

为何常见:人天然习惯用“天”作为时间单位,但用户真实的行为节奏是由“连续使用时段”决定的,用固定时间窗口会切断或合并真实的兴趣段。

误区DSIN 用的是自注意力,而自注意力不像 GRU、LSTM 那样天然顺序建模,那它一定把“先看什么后看什么”的信息丢掉了。

正解DSIN 通过偏差编码补回了顺序信息。会话内,每个行为的向量会加上一个位置编码,让模型知道“第 3 次点击”和“第 9 次点击”的顺序关系;跨会话时,会话向量按时间顺序排列后再做自注意力,顺序结构同样被保留。自注意力不是没有顺序,而是把顺序“显式编码”进向量里,这甚至比循环网络更容易并行计算。

为何常见:很多人从 Transformer 的“位置编码”概念想当然地认为自注意力天然无序,忽略了 DSIN 已经通过偏差编码解决了这个问题。

误区DSIN 是更先进的模型,效果一定比 DIN、DIEN 更好,那 DIN 和 DIEN 是不是就过时了,不需要再学了?

正解DSIN 不是凭空推翻前两者,而是站在它们肩膀上。DIN 的“目标商品激活历史兴趣”思想被 DSIN 继承——只不过从激活单个行为变成了激活整个会话兴趣;DIEN 的“兴趣演化”目标也被 DSIN 继承——只不过从行为级 GRU 改成了跨会话自注意力。在长序列、多会话场景下 DSIN 优势明显,但在行为很短、会话数很少的场景,DIN 或 DIEN 可能更简洁高效。

为何常见:人们总喜欢用“新模型取代旧模型”的简单叙事,忽略了技术演进通常是继承与扩展而非颠覆。

面试题

Q1. DSIN 中将会话划分的核心依据是什么?

单选题 · easy

  • A.相邻行为间隔是否足够大← 正确答案
  • B.用户是否切换了登录设备
  • C.商品是否来自不同的店铺
  • D.用户是否打开过商品详情

答案:A。DSIN 的会话切分依据是相邻两次行为的时间间隔是否超过阈值(通常 30 分钟)。间隔大说明意图可能已切换;间隔小说明仍在同一意图下连续浏览。设备切换、店铺差异、详情页打开都不是会话边界的判据。

Q2. 推荐系统中“用户行为序列”通常指什么?

单选题 · easy

  • A.用户在多个 App 之间的切换记录
  • B.用户历史行为按时间排列的记录← 正确答案
  • C.商品在多个用户间的流转记录
  • D.模型在训练时的参数更新记录

答案:B。用户行为序列是同一用户在一段时间内的点击、浏览、加购等行为按发生时间顺序排列的序列。它描述的是“用户做了什么”,而非 App 切换、商品流转或模型参数,是 DSIN 等推荐模型最核心的原始输入。

Q3. 关于 DSIN 的会话切分与提取阶段,下列说法正确的有?

多选题 · mid

  • A.切分依赖行为时间间隔← 正确答案
  • B.会话内需自注意力提取← 正确答案
  • C.跨会话层建模兴趣演化← 正确答案
  • D.会话长度必须完全相同

答案:ABC。DSIN 用时间间隔切分会话(A 对),会话内用多头自注意力提取兴趣(B 对),会话间再用自注意力建模演化(C 对)。会话长度完全由用户行为决定,长短不一,不需要统一(D 错)。

Q4. 偏差编码在 DSIN 会话内起到什么作用?

单选题 · mid

  • A.编码用户 ID 的高维表示
  • B.编码目标商品的价格
  • C.提供会话内位置顺序信息← 正确答案
  • D.提供用户画像附加特征

答案:C。自注意力本身不分顺序,把“先看球鞋再看袜子”颠倒结果也一样。偏差编码给会话内每个行为补充位置信号,让模型知道“第几次点击”的先后关系,从而在提取会话兴趣时保留顺序语义。

Q5. 会话内多头自注意力中的 Q、K、V 来源于哪里?

单选题 · mid

  • A.都是当前会话的 Embedding← 正确答案
  • B.来自用户画像与商品向量
  • C.来自多个不同会话的拼接
  • D.来自上一层的隐藏状态

答案:A。DSIN 的会话内自注意力中,查询 Q、键 K、值 V 全部来自当前会话的行为嵌入,所以叫“自”注意力。它的目标是让同一个会话内部的行为两两交互,而非让不同会话混合。

Q6. 相比 DIN,DSIN 做了哪些重要改变?

多选题 · hard

  • A.用 GRU 替代了自注意力
  • B.先切分会话再提取兴趣← 正确答案
  • C.增加了大量人工特征
  • D.加入跨会话交互建模← 正确答案

答案:BD。DSIN 的两个核心改变是:一是先按时间间隔切分会话,再在会话内提取兴趣(B 对);二是增加跨会话交互层,用自注意力建模会话间的演化关系(D 对)。DSIN 并不用 GRU 替代自注意力(A 错),也不依赖增加人工特征(C 错)。

Q7. 会话兴趣向量 I_k 通常是如何得到的?

单选题 · mid

  • A.取会话最后一个行为向量
  • B.取会话内所有向量的最大值
  • C.对注意力表征做平均池化← 正确答案
  • D.直接复用目标商品的嵌入

答案:C。DSIN 在会话内完成多头自注意力与偏差编码后,对所有行为向量做平均池化,得到这个会话的兴趣向量 I_k。平均池化能把会话内所有关键信号压缩进一个固定维度的向量,保留整体兴趣而非只取局部。

Q8. 关于 DIN、DIEN、DSIN 三者的继承关系,正确说法是?

单选题 · extreme

  • A.DSIN 继承 DIN 的激活思想并引入会话边界← 正确答案
  • B.DSIN 完全推翻了 DIN 和 DIEN 的建模思路
  • C.DIEN 的演化建模被 DSIN 完全舍弃了
  • D.DSIN 只是把 DIN 的层变深了

答案:A。DSIN 把 DIN 的“目标商品激活历史信息”思想从行为粒度升级为会话粒度,同时继承了 DIEN 对兴趣演化的重视,用跨会话自注意力实现演化建模。它没有推翻前两者,也没有舍弃演化,更不只是加深网络。

Q9. DSIN 中跨会话兴趣交互的目的是什么?

多选题 · hard

  • A.让不同会话向量相互感知← 正确答案
  • B.让所有行为都变成相同值
  • C.建模用户兴趣的演化趋势← 正确答案
  • D.压缩商品数量减少参数

答案:AC。跨会话兴趣交互把 K 个会话向量排列后做自注意力,每个会话向量都能与其他会话交互,从而感知前后兴趣的变化(A 对),最终目的是建模“兴趣从帐篷演化为整套露营装备”这类趋势(C 对)。它不会把行为变相同值,也不负责压缩商品参数。

Q10. “会话”最适合用生活里的哪个比喻理解?

单选题 · easy

  • A.商品在货架上的一类分类
  • B.用户账号里保存的会员卡
  • C.顾客一次完整的购物行程← 正确答案
  • D.商场里一次随机调查问卷

答案:C。会话就像顾客一次完整的购物行程:从进门到离开,有明确的时间范围和相对集中的目的。同一天可能有好几次行程(买咖啡、挑礼物、选床垫),就像同一用户一天有多个会话。货架分类、会员卡、调查问卷都无法体现“时间段内的连续意图”。