Jiahong 的个人博客

凡事预则立,不预则废


  • Home

  • Tags

  • Archives

  • Navigation

  • Search

CA——生成式拍卖-Contextual-Generative-Auction(CGA)

  • 参考链接:
    • 原始论文:Contextual Generative Auction with Permutation-level Externalities for Online Advertising, KDD 2025, Alibaba
    • 博客:KDD’25 | 生成式拍卖:感知排列外部性的整页优化机制 - 阿里妈妈技术的文章 - 知乎

整体思路总结(摘要)

  • 问题提出 :传统的拍卖机制(如GSP)依赖于独立的点击率(CTR)假设,未能考虑其他同时被展示 item 的影响(即外部性)。近年来,基于学习的拍卖机制(learning-based auctions)在高维上下文特征编码方面取得了进展。然而,现有方法受限于“预测后分配”的设计范式,仅在候选广告集内建模Set-level外部性(the candidate ad set),未能考虑最终分配的序列上下文,导致次优结果
  • 论文解法 :论文提出了上下文生成拍卖(Contextual Generative Auction,CGA),这是一个在多槽广告拍卖中引入Permutation-level外部性的新框架。基于论文理论推导的最优解结构,CGA将分配和支付的优化解耦。论文构建了一个自回归生成模型用于分配,并将激励兼容性(IC)约束重新表述为 最小化 支持梯度计算的事后遗憾(ex-post regret),从而实现最优支付规则的端到端学习
  • 有效性论证 :大量的离线和在线实验表明,CGA在平台收入和CTR方面显著优于现有方法,同时有效逼近了具有近乎最大收入和最小遗憾的最优拍卖

前置讨论

  • 最优广告拍卖 :目标是在满足经济属性(如激励兼容性(IC)和个体理性(IR))的同时最大化平台收入。当然,线上部署时还要考虑在线部署的计算复杂性约束

  • 传统的广告拍卖(不考虑外部性):同时考虑广告主的出价和广告的点击率(CTR)。广义第二价格(GSP)拍卖由于其可解释性和易于实现的特点,长期以来一直是广告拍卖的基准,并进一步演变为诸如 uGSP 和 DeepGSP 等变体。尽管现有方法表现出显著的性能,但 GSP 采用的独立 CTR 假设(即用户的点击仅取决于广告本身)限制了模型的预测能力,因为它忽略了其他同时被展示的广告。实际上,呈现给用户的结果页面包含多个广告,用户在做出决策之前会比较价格和外观等因素;因此,其他同时被展示的广告会影响目标广告的 CTR

  • 外部性 :外部广告的影响被定义为在线广告中的外部性。关于用户行为的实证研究也表明,最优的广告拍卖设计必须考虑外部性

  • 基于学习的拍卖方法(如深度神经拍卖(DNA)和加权 VCG(SW-VCG)),被提出以更好地捕捉外部性并提升平台收入。然而,这些方法受到“预测后分配”设计范式的限制,因为预测过程仍然对分配结果中的上下文信息一无所知。本质上,这些方法仅对候选广告集中的信息进行建模(Set-level外部性),未能纳入影响最终分配中每个广告 CTR 的序列上下文(Permutation-level外部性),从而导致次优的分配。推荐系统中的重排序研究同样考虑了展示列表中的广告相关性。然而,它们专注于提升整体用户反馈,忽略了广告主的策略行为,因此未能纳入 IC 和 IR 等经济约束,阻碍了它们在在线拍卖环境中最大化收入的适用性

  • 为在线广告平台设计具有Permutation-level外部性的最优拍卖面临三个关键挑战:

    • (i) 现有的“预测后分配”设计范式无法在预测广告价值时感知序列上下文
    • (ii) 采用类似 VCG 的方法遍历所有排列可以实现最优分配,但其高计算复杂性使其无法适用于在线应用。挑战在于如何在排列空间的阶乘级别内高效探索最优序列
    • (iii) IC 条件要求每个广告主的预期价值随其出价非递减。虽然大多数现有方法确保更高的出价能为广告主赢得相同或更高的广告位,但Permutation-level外部性可能导致更高的广告位产生更低的 CTR。如图1所示,来自淘宝平台的工业数据表明,广告的Permutation-level CTR 并不随其分配的广告位单调递增。因此,在Permutation-level外部性下设计具有 IC 约束的广告拍卖是一个 non-trivial 的问题
  • 论文提出了上下文生成拍卖(CGA) ,旨在优化平台收入并保证经济属性(IC和IR)。CGA 的框架遵循论文从理论上推导出的最优 DSIC(占优策略激励兼容)拍卖的结构,将分配和支付的优化解耦。CGA 采用生成器-评估器(G-E)范式来捕捉Permutation-level外部性。具体来说,生成器利用自回归方法生成广告序列作为分配,由训练过的评估器指导,评估器在广告序列中细化上下文交互。此外,直接计算最优支付规则是不可行的,因为 CGA 的分配规则是通过生成模型实现的。受多物品拍卖设计中使用神经网络有效恢复解析解的启发,论文将 IC 约束 重新表述为 要求广告拍卖的预期事后遗憾为零 ,并通过最小化可微分的事后遗憾来学习最优支付规则

  • 论文的主要贡献总结如下:

    • 论文提出了具有Permutation-level外部性的多广告位拍卖问题,并从理论上推导出最优的 DSIC 拍卖,为生成拍卖设计提供了理论保证
    • 为了建模Permutation-level外部性,论文打破了基于学习的拍卖中的“预测后分配”设计范式,引入了一个自回归生成模型,直接生成分配。基于最优机制的结构,提出的 CGA 利用 G-E 范式优化分配,并通过最小化可微分的事后遗憾来学习最优支付规则
    • 在大规模工业数据和在线 A/B 测试中的实验表明,CGA 在平台收入和 CTR 方面优于现有方法,并有效逼近了具有近乎最大收入和可忽略遗憾的最优 DSIC 拍卖

问题定义及讨论

多槽拍卖与Permutation-level外部性

  • 多槽拍卖。在线广告的广告拍卖可以抽象为一个典型的多槽拍卖设计问题。形式上,当用户请求到达时,有 \(n\) 个广告主竞标 \(k\) 个广告位,每个广告主 \(i\) 根据其点击广告 \(ad_{i}\) 的私人价值 \(v_{i}\) 提交一个出价 \(b_{i}\) 。广告主 \(i\) 的私人价值是从分布 \(f_{i}(\cdot)\) 中独立抽取的, \(F_{i}(\cdot)\) 表示概率密度函数(pdf) \(f_{i}(\cdot)\) 的累积分布函数(cdf)。令 \(\boldsymbol{v}=(v_{1},v_{2},\cdots,v_{n})\) 表示所有广告主的价值分布, \(\boldsymbol{v}_{-i}\) 表示排除元素 \(a_{i}\) 的价值分布,类似地定义 \(\boldsymbol{b}\) 和 \(\boldsymbol{b}_{-i}\) 。拍卖者,即广告平台,知道分布 \(f=(f_{1},f_{2},\cdots,f_{n})\) (从历史数据中推导),但不知道真实的价值分布 \(\boldsymbol{v}\)
  • 给定出价分布 \(\boldsymbol{b}\) 、用户特征向量 \(\boldsymbol{u}\) 以及所有广告特征向量的集合 \(\boldsymbol{X}=(\boldsymbol{x}_{1},\boldsymbol{x}_{2},\cdots,\boldsymbol{x}_{n})\) ,广告拍卖机制被形式化为 \(\mathcal{M}(\mathcal{A}(\boldsymbol{b};\boldsymbol{X},\boldsymbol{u}),\mathcal{P}(\boldsymbol{b};\boldsymbol{X},\boldsymbol{u}))\) 。分配规则 \(\mathcal{A}\) 决定广告位的分配,表示为分配矩阵 \(\boldsymbol{A}=(a_{ij})_{n\times k}\in\{0,1\}^{n\times k}\) ,其中 \(a_{ij}=1\) 表示广告 \(i\) 被分配到广告位 \(j\) ,否则 \(a_{ij}=\mathbf{0}\) 。注意,一个广告最多分配到一个广告位,每个广告位必须分配一个广告,因此可行的分配矩阵 \(\boldsymbol{A}\) 满足 \(\sum_{j=1}^{k}a_{ij}\leq 1,\forall i\) 和 \(\sum_{i=1}^{n}a_{ij}=1,\forall j\) ;支付规则 \(\mathcal{P}\) 决定每个广告的支付,表示为支付向量 \(\boldsymbol{p}=(p_{i})_{n}\in\mathbb{R}^{n}\)
  • Permutation-level外部性。广告拍卖中的外部性意味着获胜广告的效用也受到其他获胜广告的影响[15]。对于多槽广告拍卖,外部性效应体现在广告的CTR中。具体来说,CTR模型可以抽象为从广告特征和用户特征映射到用户点击广告概率的函数。论文进一步考虑一个排列感知的CTR模型 \(\Theta\) ,它以分配 \(\boldsymbol{A}\) 和相关特征为输入,并捕捉 \(\boldsymbol{A}\) 内的广告间影响。注意,模型 \(\Theta\) 是排列感知的,这意味着即使两个分配包含相同的广告集,如 \(\boldsymbol{A}_{1}=(ad_{1},ad_{2},ad_{3})\) 和 \(\boldsymbol{A}_{2}=(ad_{3},ad_{2}.ad_{1})\) ,不同的排列会导致广告 \(ad_{2}\) 的外部影响差异。形式上,论文将广告 \(ad_{i}\) 的CTR表示为 \(\Theta(\boldsymbol{x}_{i};\boldsymbol{A},\boldsymbol{X},\boldsymbol{u})\) 。为简化表示,令 \(\Theta_{i}(\boldsymbol{b};\boldsymbol{X},\boldsymbol{u})=\Theta(\boldsymbol{x}_{i};\mathcal{A}(\boldsymbol{b};\boldsymbol{X},\boldsymbol{u}),\boldsymbol{X},\boldsymbol{u})\) 。Permutation-level外部性通过模型 \(\Theta\) 从分配 \(\boldsymbol{A}\) 到CTR的映射过程中编码
  • 问题表述。给定机制 \(\mathcal{M}(\mathcal{A},\mathcal{P})\) ,具有估值 \(v_{i}\) 的广告主的预期效用为:
    $$u_{i}(v_{i};\boldsymbol{b};\boldsymbol{X},\boldsymbol{u})=(v_{i}-p_{i}(\boldsymbol{b};\boldsymbol{X},\boldsymbol{u}))\cdot\Theta _{i}(\boldsymbol{b};\boldsymbol{X},\boldsymbol{u}).$$
  • 考虑到广告主可以通过虚报其价值来最大化其效用,论文引入广告拍卖的两个基本属性以确保广告平台的稳定性:主导策略激励兼容性(DSIC,或IC)和个体理性(IR)
  • 定义1 :一个拍卖是DSIC或IC的,如果每个广告主通过如实报告其价值来最大化其效用,无论其他广告主如何报告。形式上,
    $$u_{i}(v_{i};v_{i},\boldsymbol{b}_{-i};\boldsymbol{X},\boldsymbol{u})\geq u_{i}(v_{i};\boldsymbol{b}_{i},\boldsymbol{b}_ {-i};\boldsymbol{X},\boldsymbol{u}),\forall i\in[n],\forall v_{i},\boldsymbol{b}_{i}\in\mathbb{R}^{+}.$$
  • 定义2 :一个拍卖是IR的,如果每个广告主的支付不超过其提交的出价。形式上,
    $$p_{i}(\boldsymbol{b};\boldsymbol{X},\boldsymbol{u})\leq b_{i},\forall i\in[n].$$
  • 目标是找到一个拍卖机制 \(\mathcal{M}\) ,最大化广告平台的预期收入:
    $$\mathbb{E}_{\boldsymbol{v}\sim F}Rev^{\mathcal{M}}(\boldsymbol{b},\boldsymbol{X},\boldsymbol{u})=\sum_{i=1}^{n }p_{i}(\boldsymbol{b};\boldsymbol{X},\boldsymbol{u})\Theta_{i}(\boldsymbol{b};\boldsymbol{X},\boldsymbol{u}),$$
  • 同时需要满足IC和IR约束,可以表述为问题(1) :
    $$
    \begin{align}
    \max_{\mathcal{M}(\mathcal{A},\mathcal{P})}\mathbb{E}_{\boldsymbol{v}\sim F} Rev^{ \mathcal{M}}(\boldsymbol{b},\boldsymbol{X},\boldsymbol{u}),\\
    \text{s.t.} \ \text{ IC and IR constraints.}
    \end{align}
    $$

最优多槽拍卖

  • 为了解决上述具有IC和IR约束的收入最大化拍卖设计问题,一种直观的方法是遵循著名的Myerson拍卖[26]。Myerson拍卖可以适应Permutation-level外部性的设置如下:
  • 定义3 :(具有Permutation-level外部性的Myerson拍卖):
    • 分配 :
      $$\mathcal{A}\in\text{argmax}_{\boldsymbol{A}}\sum_{i=A_{i}}^{A_{k}}\hat{\phi}( \boldsymbol{b},F_{i})\Theta(\boldsymbol{x}_{i};\boldsymbol{A},\boldsymbol{X},\boldsymbol{u});$$
    • 支付 :
      $$p_{i}=\begin{cases}b_{i}-\frac{\int_{0}^{b_{i}}\Theta_{i}(\boldsymbol{t}, \boldsymbol{b}_{-i};\boldsymbol{X},\boldsymbol{u})d\mathbf{t}}{\Theta_{i}(\boldsymbol{b};\boldsymbol{X},\boldsymbol{u})}&if \ \Theta_{i}(\boldsymbol{b};\boldsymbol{X},\boldsymbol{u})>0;\\ 0,&\text{Otherwise},\end{cases}$$
    • 其中 \(\hat{\phi}(0,F_{i})\) 表示熨平虚拟价值函数(ironed virtual value function),它在 \(v\) 中是单调的,注意这里用户的私有价值是点击价值,所以排序时要乘以CTR \(\Theta(\boldsymbol{x}_{i};\boldsymbol{A},\boldsymbol{X},\boldsymbol{u})\)
      • 熨平虚拟价值函数(ironed virtual value function):当虚拟价值函数非单调时,通过“熨平”(ironed)处理使其单调(用常数替代非单调区间使其单调),熨平后的函数简化了优化问题,确保机制设计的可实施性
  • 回顾Myerson引理,如下述定理1所述。注意,引入Permutation-level外部性与传统的Myerson拍卖不同,因为它根据分配结果影响每个广告的CTR。因此,广告 \(ad_{i}\) 的出价增加并不一定会增加其CTR,因为分配结果中的广告间影响可能会违反定理1的单调分配要求。论文通过证明,即使存在Permutation-level外部性,如果分配规则最大化虚拟福利,Myerson引理中的单调分配条件仍然成立,如引理1所示。由于篇幅限制,论文将证明放在附录A.1中
  • 定理1 :(Myerson引理)。对于单参数环境,分配规则 \(\mathcal{A}\) 是可实现的,如果存在支付规则 \(\mathcal{P}\) 使得机制 \(\mathcal{M}(\mathcal{A},\mathcal{P})\) 是DSIC的。以下两个命题成立:
    • (1)分配规则是可实现的,当且仅当它是单调的
    • (2)如果分配规则 \(\mathcal{A}\) 是单调的,则存在唯一的支付规则 \(\mathcal{P}\) 使得机制 \(\mathcal{M}(\mathcal{A},\mathcal{P})\) 是DSIC的。它由下式给出:
      $$\mathcal{P}_{i}(\boldsymbol{b}_{i},\boldsymbol{b}_{-i})=b_{i}\mathcal{A}_{i}(b_{i},\boldsymbol{b}_{-i}) -\int_{0}^{b_{i}}\mathcal{A}_{i}(\boldsymbol{t},\boldsymbol{b}_{-i})d\mathbf{t}.$$
  • 引理1 :(具有Permutation-level外部性的单调分配)。对于每个广告 \(ad_{i}\) 和 \(\boldsymbol{b}_{-i}\) ,获得的CTR \(\Theta(\boldsymbol{x}_{i};\mathcal{A}(b_{i},\boldsymbol{b}_{-i}),\boldsymbol{X},\boldsymbol{u})\) 在其出价 \(b_{i}\) 中是非递减的(或者说 \(\mathcal{A}\) 是单调的),如果分配规则 \(\mathcal{A}\) 最大化预期虚拟福利
  • 定理2 :对于单参数环境,在DSIC拍卖空间中最大化预期收入等于最大化预期虚拟福利
  • 基于定理1、定理2和引理1,我们可以推导出推论1,即定义3中具有Permutation-level外部性的Myerson拍卖构成了问题(1)的最优解
  • 推论1 :广告拍卖机制 \(\mathcal{M}\) ,由定义3中的分配规则 \(\mathcal{A}\) 和支付规则 \(\mathcal{P}\) 表征,代表了具有Permutation-level外部性的最优机制,能够在满足IC和IR约束的同时最大化平台的预期收入

拍卖设计作为基于学习的问题

  • 直接实现定义3中的分配规则 \(\mathcal{A}\) 涉及枚举所有排列以选择最大化虚拟福利的排列,计算复杂度为 \(P(n,k)=\frac{n!}{(n-k)!}\) (\(n\) 个广告主竞标 \(k\) 个广告位)。然而,对于在线广告,以淘宝为例,其中 \(n\approx 50\) 和 \(k\approx 5\) ,高计算复杂度无法满足在线实时推理需求。因此,论文将拍卖机制参数化为 \(\mathcal{M}^{\text{w}}=\langle\mathcal{A}^{\text{w}_{a}},\mathcal{P}^{\text{w}_ {p}}\rangle\) ,参数为 \(\text{w}_{a}\) 和 \(\text{w}_{p}\) ,并通过解决学习问题来确定这些参数
  • 为了在基于学习的拍卖中施加IC约束并确保优化过程的可微性,类似于基于学习的多物品拍卖的原始工作,论文引入了每个广告主的事后遗憾概念,以量化偏离IC条件的程度。具体来说,广告主 \(ad_{i}\) 的事后遗憾定义为通过虚报 \(b^{\prime}_{i}\) 可以获得的最大效用增加:
    $$rgt_{i}(v_{i},\boldsymbol{X},\boldsymbol{u})=\max_{b^{\prime}_{i}}{u_{i}(v_{i};b^{ \prime}_{i},\boldsymbol{b}_{-i};\boldsymbol{X},\boldsymbol{u})-u_{i}(v_{i};\boldsymbol{b};\boldsymbol{X},\boldsymbol{u})}.$$
  • 因此,当且仅当每个广告主 \(ad_{i}\) 的事后遗憾为零时,IC约束得到满足。给定从分布F中抽取的 \(L\) 个估值样本,论文得到广告主 \(ad_{i}\) 的经验事后遗憾:
    $$\widehat{rgt}_{i}=\frac{1}{L}\sum_{l=1}^{L}rgt_{i}(v^{\prime}_{i}, \boldsymbol{X},\boldsymbol{u}).$$
  • 然后论文将拍卖设计问题(1)重新表述为问题(3) ,即最小化预期负收入,约束条件是每个广告主 \(ad_{i}\) 的经验事后遗憾为零:
    $$
    \begin{align}
    &\ \min_{\text{w}}-\mathbb{E}_{v\sim F}Rec^{\mathcal{M}^{\text{w}}}\\
    &\text{s.t.} \ \widehat{rgt}_{i}=0, \forall i\in[n].
    \end{align}
    $$

CGA 架构说明

  • 本节详细讨论上下文生成拍卖(CGA)。为了克服“预测后分配”范式在捕捉Permutation-level外部性方面的局限性,CGA采用了生成器-评估器(G-E)架构,如图2所示。生成器利用自回归模块,感知已建立的先前上下文以生成广告序列。评估器估计整个广告序列中的排列感知奖励,通过策略梯度引导生成器实现最优分配。对于在线推理,仅部署生成器,确保广告分配期间的计算延迟最小。此外,引入了一个专用的PaymentNet模块来学习最优支付规则,通过优化可微的事后遗憾进行训练

生成器:自回归生成模块

  • 根据定理2和推论1,生成器的目标是从 \(n\) 个候选广告中生成长度为 \(k\) 的广告序列 \(A\) ,以最大化预期虚拟福利。论文开发了一个自回归生成模块,包括两个关键组件:排列不变的集级编码器和排列等变的解码器。排列不变性[42]是一种架构属性,其中输出对输入的排列保持不变,DNA已证明其在提高广告拍卖平台收入方面的有效性。排列等变性[42]意味着任何输入的排列都会导致输出的相同排列。该属性在自动拍卖设计中被广泛采用[31, 18, 10],Qin等[30]证明了其在提高基于学习的拍卖的泛化能力方面的有效性。(注:这里刻意保留论文引用序号方便查看原文)
  • 排列不变的集级编码器。广告编码器旨在通过建模Set-level外部性来增强每个广告的表示。它编码候选广告集并提供上下文嵌入 \(\boldsymbol{c}\) 作为解码器的初始输入。首先,论文采用自注意力层来捕捉 \(n\) 个候选广告之间的相互影响,生成每个广告 \(i\) 的集级增强嵌入 \(\boldsymbol{h}_{i}\) :
    $$[\boldsymbol{h}_{1},\boldsymbol{h}_{2},\cdots,\boldsymbol{h}_{\boldsymbol{n}}]=self\cdot attention([\boldsymbol{e}_{1}, \boldsymbol{e}_{2},\cdots,\boldsymbol{e}_{\boldsymbol{n}}]),$$
  • 其中 \(\boldsymbol{e}_{i}\) 表示广告 \(a_{i}\) 的嵌入。由于编码器处理的是无序的广告集,上述注意力层排除了位置编码,论文对 \(\boldsymbol{h}_{i},i\in[n]\) 进行求和池化,确保改变输入广告的排列保持相同的输出上下文嵌入 \(\boldsymbol{c}\) :
    $$\boldsymbol{c}=MLP([\sum_{i=1}^{n}\boldsymbol{h}_{i};\boldsymbol{h}_{\boldsymbol{u}}]),$$
  • 其中 \(\boldsymbol{h}_{\boldsymbol{u}}\) 表示用户表示
  • 排列等变的自回归解码器。为了解决拍卖设计中“预测后分配”范式的局限性,论文引入了一个自回归解码器。该模型有效地捕捉输出广告序列的联合分布[4]以生成广告序列。给定上下文嵌入 \(\boldsymbol{c}\) ,概率生成模型学习每个广告序列 \(\boldsymbol{A}_{m}\) 的条件概率 \(p(\boldsymbol{A}_{m}|\boldsymbol{c})\) 。在推理过程中,模型根据此条件概率从其输出空间中选择特定的分配。在多槽拍卖设置中, \(\boldsymbol{A}_{m}\) 由 \(k\) 个广告组成: \(a_{A_{m_{1}}},a_{A_{m_{2}}},\cdots,a_{A_{m_{k}}}\) ,且 \(a_{A_{m_{l}}}\) 不是独立的,自回归解码器使用乘积规则对联合输出分布进行建模:
    $$p(a_{A_{m_{1}}},a_{A_{m_{2}}},\cdots,a_{A_{m_{k}}}|\boldsymbol{c})= p(a_{A_{m_{1}}}|\boldsymbol{c})p(a_{A_{m_{2}}}|\boldsymbol{c},a_{A_{m_{1}}})\cdots$$ $$p(a_{A_{m_{k}}}|\boldsymbol{c},a_{A_{m_{1}}},a_{A_{m_{2}}},\cdots,a_{A_{m _{k-1}}}).$$
  • 论文进一步采用GRU单元来建模每个候选广告 \(a_{i}\) 在槽 \(t\in[k](a_{A_{m_{0}}}=\emptyset)\) 的条件概率 \(p(a_{i}|\boldsymbol{c},a_{A_{m_{1}}},\cdots,a_{A_{m_{l-1}}})\) 。在解码开始时,上下文嵌入 \(\boldsymbol{c}\) 初始化GRU的隐藏状态,并将表示“开始”的特殊标记作为初始输入馈入GRU。迭代地,第 \(t\) 个GRU单元公式化为:
    $$\boldsymbol{s}_{t}=GRU(\boldsymbol{s}_{t-1},\boldsymbol{h}_{\mathcal{A}_{1}-1}), t=1,2,\cdots,k,$$
  • 其中 \(\boldsymbol{h}_{\mathcal{A}_{1}-1}\) 表示在槽 \(t-1\) 中选择的广告的编码表示( \(\boldsymbol{h}_{\mathcal{A}_{0}}=START\) ), \(\boldsymbol{s}_{t-1}\) 表示先前的上下文信息( \(\boldsymbol{s}_{0}=c\) )。因此,给定槽 \(t\) 的状态 \(\boldsymbol{s}_{t}\) ,论文得到每个候选广告 \(a_{i}\) 的分配概率 \(z_{i}^{t}\) (公式(5)):
    $$z_{i}^{t}=softmax([MLP([\boldsymbol{s}_{t};\boldsymbol{h}_{i}])+e^{w}\tilde{\phi}_{i}]_{t=1}^{n })_{i},$$
    • 其中 \(w\) 是一个可学习参数,使得 \(e^{w}\) 保持正数,确保更高的虚拟价值导致更大的分配概率,与最大化虚拟福利的目标一致。在槽 \(t\) 之前分配的广告被屏蔽,基于 \(\boldsymbol{z}^{t}\) 的采样策略确定分配到槽 \(t\) 的广告。此采样仅在训练期间进行,以探索多样化的序列生成策略。在推理过程中,选择 \(\boldsymbol{z}^{t}\) 中值最高的广告。此选择过程重复 \(k\) 次以生成长度为 \(k\) 的广告序列,表示为 \(\boldsymbol{A}=\left[\boldsymbol{a}_{A_{1}},\boldsymbol{a}_{A_{2}},\cdots,\boldsymbol{a}_{A_{k}}\right]\)
  • 此外,由于生成器中的MLP和GRU单元在每个状态-广告对上操作,并且编码器满足排列不变性,解码器表现出排列等变性

评估器:排列感知预测模块

  • 评估器的目标是预测广告分配 \(\boldsymbol{A}\) 中每个广告 \(\boldsymbol{a}_{A_{i}}\) 的排列感知CTR \(\Theta(\boldsymbol{x}_{i};\boldsymbol{A},\boldsymbol{X},\boldsymbol{u})\) 。评估器以分配嵌入 \(\boldsymbol{H}_{\boldsymbol{A}}=\left[\boldsymbol{h}_{A_{1}},\boldsymbol{h}_{A_{2}},\cdots,\boldsymbol{h}_{A_{k}}\right]\) 、用户嵌入 \(\boldsymbol{e}_{u}\) 和点级CTR \(\boldsymbol{\alpha}_{\boldsymbol{A}}\in[0,1]^{k}\) 为输入,并输出排列感知CTR。每个广告 \(\boldsymbol{a}_{A_{i}}\) 的嵌入 \(\boldsymbol{h}_{A_{i}}\) 来自生成器的编码器,如公式(4)所定义。由于CGA在三阶段广告系统(匹配、预测和拍卖)的末尾运行,为了充分利用在前几个阶段捕捉到的用户兴趣,评估器利用从预测阶段输出的点级CTR \(\boldsymbol{\alpha}_{\boldsymbol{A}}\) ,并构建一个Permutation-level广告编码器来估计个性化的外部性感知校准向量 \(\boldsymbol{y}_{\boldsymbol{A}}\in(0,2)^{k}\) 。这两个向量随后逐元素相乘以获得排列感知CTR: \(\Theta_{\boldsymbol{A}}=min(\boldsymbol{\alpha}_{\boldsymbol{A}}\odot\boldsymbol{y}_{\boldsymbol{A}},1)\)
  • 具体来说,论文采用Bi-LSTM层和多头自注意力层来编码广告序列嵌入 \(\boldsymbol{H}_{\boldsymbol{A}}\) ,其中Bi-LSTM有效捕捉双向序列信息,而自注意力有效捕捉序列中远距离广告之间的交互。形式上,自注意力层的序列表示定义为:
    $$\boldsymbol{H}_{\boldsymbol{A}}^{\boldsymbol{s}}=softmax\left(\frac{\mathcal{Q}_{\boldsymbol{A}}\boldsymbol{K}_{\boldsymbol{A }}^{\top}}{\sqrt{d}}\right)\boldsymbol{V}_{\boldsymbol{A}},$$
  • 其中 \(d\) 表示嵌入的维度, \(\mathcal{Q}_{\boldsymbol{A}},\boldsymbol{K}_{\boldsymbol{A}},\boldsymbol{V}_{\boldsymbol{A}}\) 表示查询、键和值矩阵,它们从分配嵌入 \(\boldsymbol{H}_{\boldsymbol{A}}\) 和位置编码 \(\boldsymbol{P}\boldsymbol{E}_{\boldsymbol{A}}\) 的线性变换中得出。论文采用的位置编码机制遵循中的正弦版本,赋予自注意力层辨别排列信息的能力
  • 接下来,论文通过Bi-LSTM层获得 \(\boldsymbol{H}_{\boldsymbol{A}}\) 的前向输出状态 \(\boldsymbol{H}_{\boldsymbol{A}}^{f}\) 和后向输出状态 \(\boldsymbol{H}_{\boldsymbol{A}}^{b}\):
    $$\boldsymbol{H}_{\boldsymbol{A}}^{f} =\text{Bi-LSTM}_{\text{forward}}(\boldsymbol{H}_{\boldsymbol{A}})$$ $$\boldsymbol{H}_{\boldsymbol{A}}^{b} =\text{Bi-LSTM}_{\text{backward}}(\boldsymbol{H}_{\boldsymbol{A}}).$$
  • 为简洁起见,论文省略了Bi-LSTM的实现细节,包括输入门、遗忘门、输出门和单元状态

支付计算

  • 根据推论1,最优支付在定义3中定义,其中积分项可以重写为期望:
    $$\int_{0}^{b_{i}}\Theta_{i}(t,\boldsymbol{b}_{-i};\boldsymbol{X},\boldsymbol{u})dt=b_{i}E_{t_{i}-U[0,b_{i}] }[\Theta_{i}(t_{i},\boldsymbol{b}_{-i};\boldsymbol{X},\boldsymbol{u})],$$
  • 可以使用蒙特卡罗采样进行近似。然而,注意 \(\Theta_{i}(t_{i},\boldsymbol{b}_{-i};\boldsymbol{X},\boldsymbol{u})=\Theta(\boldsymbol{x}_{i};\mathcal{A}(t_{i}, \boldsymbol{b}_{-i};\boldsymbol{X},\boldsymbol{u}),\boldsymbol{X},\boldsymbol{u})\) 。处理每个样本需要调用生成器 \(\mathcal{A}\) 和评估器 \(\Theta\) ,导致推理期间的高计算成本。减少样本数量可以缓解这一问题,但会增加支付方差,直接影响平台收入和广告主效用
  • 受[11]中神经网络在多物品拍卖设置中有效逼近最优机制的成功应用启发,论文引入PaymentNet来学习最优支付规则。具体来说,输入包括分配嵌入 \(\boldsymbol{H}_{\boldsymbol{A}}\in\mathbb{R}^{K\times d}\) 、自排除出价分布 \(\boldsymbol{B}^{-}=[\boldsymbol{b}_{-\boldsymbol{A}_{1}},\boldsymbol{b}_{-\boldsymbol{A}_{2}},\cdots,\boldsymbol{b}_{- \boldsymbol{A}_{k}}]\in\mathbb{R}^{K\times(k-1)}\) ,以及预期价值分布 \(\boldsymbol{Z}\cdot\Theta\in\mathbb{R}^{L\times 1}\) ,其中 \(\boldsymbol{Z}=[ z^{1}_{\boldsymbol{A}_{1}},z^{2}_{\boldsymbol{A}_{2}},\cdots,z^{k}_{\boldsymbol{A}_{k}} ]\) 表示公式(5)中定义的分配概率, \(\boldsymbol{\Theta}=[\Theta_{\boldsymbol{A}_{1}},\Theta_{\boldsymbol{A}_{2}},\cdots,\Theta_{\boldsymbol {A}_{k}}]\) 表示评估器估计的排列感知CTR。此外,为了满足IR约束,如定义2所述,PaymentNet采用sigmoid激活函数计算支付率 \(\tilde{\boldsymbol{p}}\in[0,1]^{k}\) ,随后输出支付 \(\boldsymbol{p}=\tilde{\boldsymbol{p}}\odot\boldsymbol{b}\) 。形式上,支付率定义为:
    $$\tilde{\boldsymbol{p}}=\sigma(r(r(\lfloor\boldsymbol{H}_{\boldsymbol{A}};\boldsymbol{B}^{-};\boldsymbol{Z}\cdot\Theta \rfloor))),$$
  • 其中 \(\sigma(\cdot)\) 和 \(r(\cdot)\) 分别表示具有sigmoid和ReLU激活函数的全连接层

优化与训练

  • 根据推论1,最优分配规则仅需要最大化虚拟福利,并且与支付规则无关。因此,论文将G-E框架和PaymentNet的优化解耦,这保持了CGA的最优性

G-E框架的优化

  • 在G-E框架中,评估器负责捕捉Permutation-level外部性并引导生成器获得最优分配
  • 首先进行评估器训练 :使用 List-wise 广告点击数据训练评估器 \(\Theta\) 至收敛。每个样本 \(l\in\mathcal{D}\) 是暴露给用户的长度为 \(k\) 的广告序列,标签 \(y^{l}_{i}\in\{0,1\}\) 表示用户是否点击了第 \(i\) 个广告。二元交叉熵损失定义为:
    $$\mathcal{L}_{E}=-\frac{1}{|\mathcal{D}|}\sum_{l\in\mathcal{D}}\sum_{i=1}^{k}(y ^{l}_{i}\log\theta^{l}_{i}+(1-y^{l}_{i})\log(1-\theta^{l}_{i})),$$
    • 其中 \(\theta^{l}_{i}\) 表示评估器预测的广告序列 \(l\) 中第 \(i\) 个广告的排列感知CTR
  • 在训练评估器 \(\Theta\) 至收敛后,论文冻结其参数并使用来自评估器的奖励通过策略梯度训练生成器。在每个槽 \(t\) ,上下文信息 \(\boldsymbol{s}_{t}\) 作为状态,生成器输出的分配概率 \(z^{t}_{i}\) 作为动作。由于 \(\boldsymbol{s}_{t}\) 仅编码先前的上下文,为了捕捉双向上下文信息,论文使用训练有素的评估器来估计完整广告序列 \(\boldsymbol{A}\) 中每个候选广告的排列感知奖励。类似于,论文将此排列感知奖励分解为两部分
  • 自身奖励(Self-Reward):与最优分配的目标一致,论文使用评估器 \(\Theta\) 来估计每个选定广告 \(a_{A_{i}}\) 的预期虚拟福利,称为自我奖励:
    $$r^{self}_{A_{i}}=\hat{\phi_{i}}\cdot\Theta_{i}(\boldsymbol{b};\boldsymbol{A},\boldsymbol{u}).$$
  • 外部奖励(External-Reward):每个选定的广告不仅贡献其奖励,还由于Permutation-level外部性影响其他广告的CTR。类似于经典VCG机制中应用的边际贡献,论文将此外部效应建模为外部奖励:
    $$r^{external}_{A_{i}}=\sum_{j\in\boldsymbol{A}_{-i}}\tilde{\phi_{j}}\Theta_{j}(\boldsymbol{b}; \boldsymbol{A},\boldsymbol{u})-\sum_{j\in\boldsymbol{A}_{-i}}\tilde{\phi_{j}}\Theta_{j}(\boldsymbol{b}_{-i}; \boldsymbol{A}_{-i},\boldsymbol{u}),$$
    • 其中 \(\boldsymbol{A}_{-i}\) 表示排除 \(a_{A_{i}}\) 的广告序列
  • 结合上述两个奖励,论文得到选择 \(a_{A_{i}}\) 的排列感知奖励,定义为:
    $$
    \begin{align}
    r_{A_{i}} &=r^{self}_{A_{i}}+r^{external}_{A_{i}} \\
    &=\hat{\phi_{i}}\Theta_{i}(\boldsymbol{b};\boldsymbol{A},\boldsymbol{u})+\sum_{j\in\boldsymbol{A}_ {-i}}\tilde{\phi_{j}}\Theta_{j}(\boldsymbol{b};\boldsymbol{A},\boldsymbol{u})-\sum_{j\in\boldsymbol{A}_{-i}} \tilde{\phi_{j}}\Theta_{j}(\boldsymbol{b}_{-i};\boldsymbol{A}_{-i},\boldsymbol{u})\\
    &=\sum_{j\in\boldsymbol{A}}\tilde{\phi_{j}}\Theta_{j}(\boldsymbol{b};\boldsymbol{A},\boldsymbol{u })-\sum_{j\in\boldsymbol{A}_{-i}}\tilde{\phi_{j}}\Theta_{j}(\boldsymbol{b}_{-i};\boldsymbol{A}_{-i}, \boldsymbol{u}).
    \end{align}
    $$
  • 最后,生成器的损失函数定义为:
    $$\mathcal{L}_{G}=-\frac{1}{|\mathcal{D}|}\sum_{s\in\mathcal{D}}\sum_{i\in k}r_{ A^{s}_{i}}\log z_{A^{s}_{i}},$$
    • 其中 \(s\) 表示数据集 \(\mathcal{D}\) 中的一个样本,代表请求的候选广告集, \(A^{s}_{i}\) 表示生成器基于输入广告集 \(s\) 输出的广告分配中的第 \(i\) 个广告, \(z_{A^{s}_{i}}\) 表示Generator 公式(5)中的分配概率

PaymentNet的优化

  • 在训练生成器 \(\mathcal{A}\) 和评估器 \(\Theta\) 至收敛后,论文冻结其参数,然后应用增广拉格朗日方法来解决约束优化问题(3)以优化PaymentNet。增广拉格朗日函数定义为:
    $$\mathcal{L}_{P}=-\frac{1}{|\mathcal{D}|}\sum_{s\in\mathcal{D}}(\sum_{i\in k} \mathcal{P}_{i}(\boldsymbol{A}^{s})\Theta_{i}(\boldsymbol{A}^{s})-\sum_{i\in k}\lambda_{i} \widehat{rgt}^{s}_{i}-\frac{\rho}{2}\sum_{i\in k}(\widehat{rgt}^{s}_{i})^{2}),$$
    • 其中 \(\boldsymbol{A}^{s}\) 表示冻结生成器 \(\mathcal{A}\) 基于广告集 \(s\) 的输入输出的分配, \(\lambda_{i}\) 表示拉格朗日乘数, \(\rho>0\) 表示IC惩罚项的超参数
  • 类似于[11],基于上述拉格朗日函数(10)的优化过程包括
    • (i)更新PaymentNet: \(\boldsymbol{w}_{\boldsymbol{p}}^{\boldsymbol{n}\boldsymbol{e}\boldsymbol{w}}=\textit{argmin}_{\lambda\boldsymbol{w}\rho} \mathcal{L}_{P}(\boldsymbol{w}_{\boldsymbol{p}}^{\sigma Id};\boldsymbol{\lambda}^{\sigma Id})\)
    • (ii)更新拉格朗日乘数: \(\boldsymbol{\lambda}^{\boldsymbol{n}\boldsymbol{e}\boldsymbol{w}}=\boldsymbol{\lambda}^{\sigma Id}+\rho\ \overline{r} \boldsymbol{g}^{\intercal}(\boldsymbol{w}_{\boldsymbol{p}}^{\boldsymbol{n}\boldsymbol{e}\boldsymbol{w}})\)
  • 注意问题(3)是非凸的。因此,上述拉格朗日方法不能保证收敛到全局最优。然而,实验结果表明,优化后的CGA可以逼近最优收入,且遗憾最小,如原始论文第5.2节实验所述

Experiments

  • 在本节中,论文进行了离线实验和在线A/B测试,以评估CGA的有效性,主要关注以下问题:
    • RQ1 :与现有广告拍卖相比,CGA在平台收入和CTR等关键指标上的表现如何?
    • RQ2 :与集级和无外部性相比,建模Permutation-level外部性的效果如何?
    • RQ3 :CGA的各种设计如何影响其性能?
    • RQ4 :论文提出的CGA在高效部署的实际广告拍卖场景中表现如何?

Experiment Setup

数据集
  • 在离线实验中,论文使用从2024年1月期间从领先的电子商务平台淘宝收集的真实日志来评估CGA的性能。训练集包括从1月20日至1月23日随机选择的500,000次拍卖,涉及1,100,875个唯一广告主,而测试集包括从1月25日随机选择的100,000次拍卖,涉及452,671个唯一广告主。对于数据集中的每个拍卖样本,广告系统选择大约30个广告主作为拍卖阶段的候选者,他们提交出价以竞争广告位。论文在离线实验中设置广告位数量 \(k=3\)
基线方法
  • 论文将CGA与代表性的拍卖机制进行比较。基线方法根据外部性建模的粒度分为三组
  • 无外部性(W/O externalities) :
    • GSP :GSP根据出价和预测CTR的乘积对广告进行排名,不建模外部性
  • Set-level外部性(Set-level externalities) :
    • DNA :在GSP的基础上,DNA通过建模候选广告的Set-level外部性来预测每个广告的排名分数,并相应地进行分配,不考虑广告列表中广告之间的相互影响
    • SW-VCG :SW-VCG将多槽拍卖设计形式化为广告和广告位之间的最大加权二分匹配问题,仅捕捉候选广告的Set-level外部性以估计边权重
  • Permutation-level外部性(Permutation-level externalities) :
    • 具有Permutation-level外部性的VCG拍卖(VCG):VCG选择最大化社会福利的广告排列进行分配,并结合支付规则以满足IC。论文使用CGA的评估器评估所有候选广告的排列,使VCG能够捕捉Permutation-level外部性
    • EdgeNet :EdgeNet利用Transformer替换DNA的集编码器,并采用贪婪策略依次分配广告,建模部分Permutation-level外部性
    • Optimal :为了评估CGA对理论上界的逼近,根据推论1,论文通过遍历所有排列以最大化虚拟福利并使用蒙特卡罗采样计算支付来构建此基线
性能指标
  • 论文考虑以下指标来分别衡量平台收入、用户体验和广告主的事后遗憾
    • 每千次展示收入: \(\text{RPM}=\frac{\sum click\textit{$\times$payment}}{\sum impression}\times 1000\)
    • 点击率: \(\text{CTR}=\frac{\sum click}{\sum impression}\)
    • IC指标: \(\Psi=\frac{1}{|D|}\sum_{s\in D}\sum_{i\in k}\frac{\overrightarrow{rg^{i}_{i}}}{ u_{i}(v^{i}_{h},\boldsymbol{b}^{s};\boldsymbol{X}^{i},\boldsymbol{u}^{s})}\) ,其中 \(\overrightarrow{rg^{i}_{i}}\) 在公式(2)中定义。这是广告拍卖机制IC测试的常用指标[7, 23, 25, 33],衡量广告主通过操纵出价可以获得的效用相对增加。与[38]中的评估过程一致,论文对每个广告主的出价进行反事实扰动,将 \(b_{i}\) 替换为 \(a\times b_{i}\) ,其中 \(a\in{0.2\times j\mid j=1,2,\cdots,10}\)
实现
  • 在CGA中,论文将特征的嵌入大小设置为8。为了从不同的表示子空间中捕捉更丰富的信息,所有注意力层都使用具有4个注意力头的多头注意力机制。外部性感知校准向量 \(\boldsymbol{\gamma_{A}}\) 和支付率 \(\hat{\boldsymbol{p}}\) 使用具有128和32大小隐藏层的MLP得出。CGA使用Adam优化器以1e-3的学习率和512的批量大小进行训练。所有基于学习的基线方法通过网格搜索调整超参数,探索学习率{1e-5, 1e-4, 1e-3, 1e-2}、批量大小{256, 512, 1024, 2048}和隐藏大小{8,16,32,64}

离线比较(RQ1 & RQ2)

  • CGA和基线-Optimal涉及铁虚拟价值函数,这需要了解每个广告主的价值分布 \(f_{i}(\cdot)\) 。从历史数据中估计 \(f_{i}(\cdot)\) 在现有研究中已有充分覆盖[6, 21, 27, 28]。论文不深入探讨此估计,因为CGA专注于使用生成模型捕捉Permutation-level外部性,与分布估计技术无关。为了避免分布估计方法在比较实验中的偏差,遵循[22],论文预设每个广告主的价值的条件分布为均匀分布和指数分布 ,并相应地重新生成出价。对于SW-VCG,由于其预测的广告分数 \(Scr_{i}\) 旨在拟合虚拟价值,论文直接将 \(Scr_{i}\) 设置为 \(\hat{\phi}_{i}\) 进行比较

  • 在上述两种分布下的实验结果如表I所示。论文的主要观察结果如下:

    • (1) 随着外部性建模从无外部性到集级再到Permutation-level,拍卖性能在三个指标上都有所提高(更高的RPM和CTR,更低的遗憾)5。这突显了在拍卖设计中建模细粒度外部性的重要性(RQ2)。为了进一步研究外部性的影响,论文在CTR预测任务上进行了比较实验。结果如表2所示,其中“无外部性”表示使用点级pCTR,“集级”表示使用集级广告编码器(如第3.2节所述)替换评估器的Permutation-level广告编码器。结果表明,具有Permutation-level外部性的评估器提高了预测值的准确性,解释了拍卖指标的改进
    • (2) 与基于枚举的基线-Optimal相比,CGA实现了约95%的收入最大化,且事后遗憾可忽略不计。这表明CGA能够高效地进行广告分配,并紧密逼近最优拍卖机制

消融研究(RQ3)

  • 为了验证CGA各种设计考虑的有效性,论文构建了以下变体:
    • CGA- \(\Theta\) 移除了评估器 \(\Theta\) ,并使用点级CTR来评估每个广告分配的虚拟福利
    • CGA(端到端)直接使用公式(10)中的 \(\mathcal{L}_{P}\) 训练生成器和PaymentNet。相比之下,CGA首先训练生成器至收敛,冻结其参数,然后训练PaymentNet
    • CGA- \(r^{self}\) 移除了生成器损失函数 \(\mathcal{L}_{G}\) 中的自我奖励 \(r^{self}\) (公式(7))
    • CGA- \(r^{external}\) 移除了生成器损失函数 \(\mathcal{L}_{G}\) 中的外部奖励 \(r^{external}\) (公式(8))
    • CGA- \(\tilde{\phi}\) 将虚拟价值 \(\hat{\phi_{i}}\) 替换为 \(b_{i}\) 在 \(\mathcal{L}_{G}\) 中
  • 结果如表3所示,论文观察到:
    • (1) CGA- \(\Theta\) 表现不如CGA,表明生成器本身无法完全捕捉Permutation-level外部性,因为自回归模型仅感知先前的上下文。G-E框架通过策略梯度将完整的序列知识提炼到生成器中
    • (2) CGA(端到端)表现较差。一个可能的原因是CGA使用PaymentNet来学习最优支付,因此在端到端训练时,收入梯度必须通过PaymentNet才能到达生成器,这使得收敛到最优分配变得复杂。此外,推论1确保解耦优化保持最优性,因此生成器可以专注于最大化虚拟福利
    • (3) CGA- \(r^{self}\) 表现最差,因为缺少每个选定广告的自身价值增量。CGA优于CGA- \(r^{external}\) ,因为它使用外部奖励来建模每个选定广告对最终分配列表的影响
    • (4) 估计价值分布 \(\hat{f}(\cdot)\) 需要对出价策略进行经验假设,因为广告平台只能观察到出价,导致估计的 \(\hat{f}(\cdot)\) 存在偏差。为了评估移除价值分布对CGA性能的影响,论文构建了变体CGA- \(\tilde{\phi}\) 。如表3所示,CGA- \(\tilde{\phi}\) 在收入(2.6%)和CTR(1.9%)方面仅略有下降。这一小幅下降可能是由于CGA对外部性的建模,捕捉了广告间的相关性,并通过其他广告主的出价部分反映了缺失的价值分布信息

在线A/B测试(RQ4)

  • 为了验证CGA在现实世界中的有效性,论文通过在线A/B测试将CGA与完全部署在淘宝广告系统中的DNA进行比较。表4展示了2023年8月19日至8月25日期间使用2%总生产流量进行的在线A/B测试结果。CGA在RPM上实现了3.2%的提升,同时在线响应时间(RT)每请求平均增加了3毫秒(相对增加1.6%),表明CGA能够通过生成模型高效探索分配空间并提升平台收入。此外,广告主的投资回报率(ROI)提高表明,CGA的收入提升并非来自虚高的支付,而是通过捕捉Permutation-level外部性优化广告分配,这一点从CTR和总商品交易额(GMV)的显著提升中得到了证明

相关工作(论文直译)

  • GSP(Kumar等,2019)及其变体,如uGSP(Berger等,2020),由于其可解释性和高收入保证,在在线广告中广泛使用,但它们没有考虑其他广告对用户点击的影响,忽略了外部性(Hwang等,2018;Kumaran等,2020),导致次优性能
  • 计算能力的进步促使研究人员探索基于学习的拍卖(Zhang等,2022)。DeepGSP(Zhang等,2022)和DNA(Wang等,2022)利用在线反馈扩展了GSP,进行端到端学习。然而,DNA的排名分数预测面临评估先于排名的问题(Zhang等,2022),限制了其范围仅为Set-level外部性,导致次优分配。SW-VCG(Wang等,2022)将最优拍卖设计分离为设计单调分数函数和解决广告位最大二分匹配问题。然而,SW-VCG仍然忽略了最终序列中广告的相互影响,因为二分图中的边权重无法预先确定考虑Permutation-level外部性。遵循VCG,NMA(Wang等,2022)提出了一个基于枚举的框架来选择最优分配。虽然全局最优,但其高计算复杂度使其无法用于实时在线推理(Wang等,2022)。EdgeNet(Wang等,2022)采用基于PointerNet的结构进行贪婪广告分配,但忽略了后续广告的影响,仍然不足以实现最优结果
  • 推荐系统中的重排序研究与外部性建模类似,通过利用上下文信息优化 item 序列。重排序方法可分为单阶段和两阶段方法(Wang等,2022)。单阶段方法(Chen等,2020;Wang等)估计初始列表中每个 item 的细化分数,并贪婪地重新排序。这些方法遇到与DNA类似的评估先于排名的问题:重排序改变了排列,引入了不同的相互影响。两阶段方法(Wang等;Wang等,2022;Zhang等)通常采用G-E框架。生成器生成多个可行序列,而评估器根据估计的列表价值选择最优序列。这种方法能够全面探索排列空间(Wang等),为CGA的实现提供了宝贵的见解。虽然G-E框架有效捕捉了Permutation-level外部性,但它缺乏表达关键经济约束(如IC)的能力,无法直接优化平台收入。论文的理论结果将Permutation-level外部性下的最优拍卖中的分配和支付解耦。这使得分配可以采用专注于最大化预期虚拟福利的通用G-E框架,而最优支付规则通过可微的事后遗憾学习。因此,CGA可以被视为连接推荐系统中的重排序和广告拍卖理论的统一框架
  • 注:以上内容刻意保留了所有的引用,方便check原始论文

结论

  • 一句话总结 :论文提出了上下文生成拍卖(CGA),旨在将Permutation-level外部性引入在线多槽广告拍卖中
  • 方案细节 :论文的主要理论结果表明,经典的Myerson拍卖在适应Permutation-level外部性时保持了它的最优性。这一见解推动了CGA框架的设计,该框架将分配和支付的优化解耦。具体来说,论文开发了一个具有G-E学习范式的自回归生成模型来优化分配,并通过将IC约束量化为预期事后遗憾来学习最优支付
  • 有效性论证 :大量的离线和在线实验验证了CGA的有效性
  • 特别说明 :CGA的自回归生成过程不限于特定的生成模型,可以适应各种先进的解决方案
  • 未来展望 :未来的研究将扩展这种上下文生成机制,以整合来自不同渠道的异构 item 。

CA——Google-Ad-Click-Prediction

  • 参考文献:Google KDD 2013,Ad Click Prediction: a View from the Trenches(引用量500+)
  • 介绍了截止到2013年之前的点击率预估常用算法,FTRL是Google三年的结晶(2010-2013)
  • 在线学习优化算法的发展历程:SGD->TG->FOBOS->RDA->FTRL-Proximal

核心贡献

  • 基于传统的逻辑回归算法(Regularized Logistic Regression,正则化的逻辑回归)在点击率预估时的不足,提出一种在线逻辑回归算法,FTRL(Follow The Regularized Leader)
  • per-coordinate learning rate

一些模型的比较和介绍

  • 传统逻辑回归算法中使用OGD(Online Gradient Descent)是非常高效的,使用很小的计算资源就能得到较好的精确度.
  • 但是OGD在生成稀疏模型方面表现不好(OGD + L1)
  • 其他在稀疏性方面表现良好的方法有FOBOS, 截断梯度(Truncated Gradient)和 RDA(Regularized Dual Averaging)
    • RDA在精确度和稀疏性方面做tradeoff, 效果好于FOBOS
  • FTRL-Proximal号称可以同时获得RDA的稀疏性和OGD的精确度
  • RDA模型是微软提出的一种在线优化算法,与OGD完全不同,能得到更加稀疏的模型,但是精确度不如OGD

FTRL-Proximal Learning (Online Learning And Sparsity)

  • 也是通过L1正则化控制模型的稀疏度

推导过程

FTL(Follow The Leader)的介绍
OGD的更新方式
  • 更新规则:
    $$
    \begin{align}
    \mathbf{w}_{t+1} &= \mathbf{w}_t-\eta_t\mathbf{g}_t
    \end{align}
    $$
FTLR(Follow The Regularized Leader)

加上正则项的FTL

  • 更新规则:
    $$
    \begin{align}
    \mathbf{w}_{t+1} &= \mathop{\arg\min}_{\mathbf{w}}\left ( \mathbf{g}_{1:t}\cdot \mathbf{w} + \frac{1}{2}\sum_{s=1}^t \sigma_s || \mathbf{w} - \mathbf{w}_s||_2^2 + \lambda_1||\mathbf{w}||_1 \right ) \\
    \mathbf{g}_{1:t} &= \sum_{i=1}^t\mathbf{g}_i
    \end{align}
    $$
    • 第一项是对损失函数梯度的贡献的一个估计
    • 第二项是控制参数 \(\mathbf{w}\) 在每次迭代中变化不要太大
    • 第三项是L1正则化,用于使模型变得稀疏(除了L1正则化项以外,也可以再加上L2正则化)
    • 去掉正则化项就是FTL(Follow The Leader)
    • \(\sigma_s\) 是学习速率
    • 这个学习速率可以用Per-Coordinate Learning Rate:
      $$
      \begin{align}
      \eta_{t, i} &= \frac{\alpha}{\beta + \sqrt{\sum_{s=1}^t g_{s,i}^2}} \\
      \mathbf{g}_s &= \nabla l_s(\mathbf{w})
      \end{align}
      $$

Per-Coordinate Learning Rates

  • 对参数的每一维度分开训练,每个维度有自己的学习率
  • 某个特征出现的次数越多,说明当前该特征对应的参数值越可信,学习率就应该越小
  • 考虑了数据在每个特征上的分布不均匀性
    • 参数某个维度上的样本数越少,这些样本就会得到越大的利用(具体表现就是该特征的学习率会比较大)

一个思考

  • 问题:为什么机器学习中的学习率都是越来越小?
  • 答案:因为刚开始训练时,参数的值不太可信(也就是说最终参数与当前参数的置信度比较低),所以更新时应该更新的步骤大一些,让当前的参数变化大一些,训练到后来,随着参数的值越来越可信(当前参数的置信度比较高),更新的步骤就应该小一些,让当前的变化小一些

一些工程上的Trick

Saving Memory at Massive Scale

Probabilistic Feature Inclusion
  • 在高维数据中,大量的特征是出现频率非常低的(rare),半数的唯一特征甚至只出现一次
  • 统计这些特征的代价是非常昂贵的,有些特征可能永远不会被实际使用(这里如何理解昂贵?也就是说训练了也没用?)
  • 额外的读写数据是昂贵的,如果能丢弃一部分出现评论特别低的特征(比如出现频率低于k次)
  • 实现稀疏可以使用L1正则化,也可以使用Probabilistic Feature Inclusion
  • 关于Probabilistic Feature Inclusion的做法
    • 当一个特征第一次出现时,以一定的概率接受这个新特征
    • 效果作用于数据预处理阶段,但是可以在在线执行中设置
Possion Inclusion
  • 对于新的特征,以概率p添加入模型
  • 对于已经存在模型中的特征,正常更新其系数
Bloom Filter Inclusion
  • 用布隆过滤器仅仅保留出现次数在n次以上的特征
Encoding Values with Fewer Bits
  • 常用的OGD使用32或者64位浮点数编码来存储模型的系数
  • Google提出可以使用16位浮点数来存储系数,同时加上一些策略
  • 实验结果:将64位的浮点值换为为系数存储节省了75%的RAM内存空间(这还用实验?直接计算就得到了啊)
Training Many Similar Models
  • 同时训练多个模型是超参数选择常用的方法
  • 将可以共享的东西共享
  • 在节省内存的同时,还可以节约网络带宽(存储一份Per-coordinate学习率,节省内存和带宽等),CPU(用同一个hash表检索特征,节省CPU)和硬盘空间
A Single Value Structure
  • 有时候我们希望评估大量的模型在只有少量的特征组(groups of features)添加或者删除时的变化
  • 对于每一维度(coordinate),仅仅存储一个系数值而不是多个(正常应该为每个模型存储一个)
  • 存储该维度对应特征组的模型共享该系数
  • 对每个特征,训练时每个模型都会计算自己的值,然后所有模型的取平均作为所有包含该维度特征模型的共享
Computing Learning Rates with Counts
  • 对于每个特征来说,梯度和以及梯度平方和是必须计算的
  • 梯度的计算必须准确,但是计算学习率却是可以粗糙计算的
  • 仅仅统计样本出现次数(Counts)就能大概计算学习率
推导
  • 假设包含一个给定特征的所有事件(events)具有有相同的概率(一般来说,这个近似是不可能的,但是在这个目标里面是可行的)
    • 如何理解这个假设的意义呢?*对于具有某个特征的所有样本,其取值为(正负例)是的概率是相等的,正例(click)概率都为 \(p\) *
  • 进一步假设模型已经精确地学习到了概率
  • 如果有分别有 \(P,N\) 个正负样本(events),则有 \(p=\frac{P}{N+P}\)
  • 则有对于逻辑回归(\(p(1-p)\))来说,正例的梯度为 \(p-1\),负例的梯度为 \(p\)
    $$
    \begin{align}
    \sum g_{t,i}^2 &= \sum_\text{positive events}(1-p_t)^2 + \sum_\text{negative events}p_t^2 \\
    &\approx P(1-\frac{P}{N+P})^2 + N(\frac{P}{N+P})^2 \\
    &= \frac{PN}{N+P}
    \end{align}
    $$
  • 也就是说,为了近似计算 \(\sum g_{t,i}^2\),我们仅需要记录 \(P,N\) 即可
Subsampling Traning Data
  • 典型的CTRs是远远低于50%,数据偏差很大,正例(点击)的样本很稀疏
  • 在模型训练中正例样本相对而言更有价值
  • 使用下采样:很大程度上降低数据量,同时保证对精度最小程度的影响
采样方法:
  • 保留所有至少被点击过一次的请求(Query,也就是样本)
  • 以一定比例 \(r\in(0, 1]\) 采样没有被点击过的请求
  • 因为包含通用的特征(Feature Phase)计算,所以这种方法是合理的,但是需要纠偏(直接用采样后的样本训练会造成预测偏差)
  • 加入一个重要性权重 \(w_t\)
    • \(w_t = 1\) for clicked queries
    • \(w_t = \frac{1}{r}\) for queries with no clicks
    • 本质上可以理解为这里是将采样时造成的负例比例偏差补齐

模型性能评估

Progressive Validation

  • Progressive验证又称为在线损失(online loss)
  • 与交叉验证(cross-validation)或留出法(hold out)验证是不同的
  • 在服务查询中,在线损失能很好的代表我们的精度,因为在训练模型前,它仅仅在最新数据上评估其性能(因为这准确的模拟了当模型进行服务查询时发生了什么)
  • 由于用了100%的数据作为训练和测试,在线损失比留出法验证有更好的统计数据
  • 绝对指标往往会带来误导
    • 即使预测是完美的,对数损失和其他指标的差异也依赖着问题的困难程度
    • 不同的国家,不同请求的点击率不同(同为对数损失的最佳实践,50%的点击率会好于2%的点击率)
  • 所以使用相对变化,看指标相对于base line改变了多少
  • 从经验来看,相对指标在整个时间段内都很稳定
  • 相同的指标计算应该对应在完全相同的数据(比如不同时段的损失比较是没有意义的)

置信度评估(Confidence Estimates)

  • 对很多应用来说,除了评估广告的CTR,还要量化预测的期望精确度(the expected accuracy of the prediction)

校正预测(Calibrating Predictions)

  • 系统偏差(Systematic Bias)指平均预测CTR(Average Predicted CTR)和观测CTR(Observed CTR)的差异
  • 造成系统偏差的原因包括:
    • 不精确的模型假设
    • 学习算法的缺陷
    • 在训练或者服务(预测)时不可用的隐藏特征
  • 解决方案:
    • 添加一个校正层将预测CTRs与观测CTR做匹配(match predicted CTRSs to observed click-through rates)
    • 暂时不能提供有效的保证,保证校正影响的有效
    • 校正的本质是找到(拟合)一个函数映射 \(g\),使得模型输出值与真实概率值一一对应
    • 逻辑回归中的sigmoid函数可以看做是一个校正预测的函数吗?
  • 更多参考
    • 风险模型 - 概率校准
    • 机器学习:概率校准, 文中有代码示例
    • 概率校准 Probability Calibration

一些说明

参考博客:https://blog.csdn.net/fzcoolbaby/article/details/99174601?utm_source=distribute.pc_relevant.none-task

  • 概率模型的搭建过程中,由于抽样与正则化等原因,导致模型的输出概率值明显偏离真实概率值
    • [待更新:为什么抽样和正则化会影响模型的输出概率发生变化?]
  • 此时的模型输出概率值仅仅有排序的意义,其绝对值没有意义(定序值,而非定距数值)
  • 校正预测的过程就是把模型输出概率值的校正成真实的概率的过程,使得校正后的概率有绝对值意义

自动特征管理(Automated Feature Management)

  • 将特征空间描绘成上下文和语义信号,每个信号都可以被翻译成一个在学习时有真实值的特征集合
  • [待更新]

一些不成功的实验记录(Unsuccessful Experiments)

本节记录google的一些失败的尝试方向(有些可能会让人很惊讶),这些方向模型没有明显收益

Aggressive Feature Hashing

关于特征哈希(Feature Hashing)的相关知识可参考Feature-Hashing

  • Feature Hashing for Large Scale Multitask Learning论文指出,Feature Hashing方法效果显著
    • 报告显示使用特征hashing技巧,可以能将学习一个垃圾邮件过滤模型的特征空间映射成包含 \(2^24\) 个特征的特征空间(疑问:这里的特征原来不止 \(2^24\) 个吗?)
  • 但是实验证明,使用 Feature Hashing 方法并不能提升我们的方法,所以建议保留 interpretable(non-hashed)的特征向量

Dropout

  • Google用网格搜索的方法测试了从0.1到0.5的Dropout特征丢弃概率
  • 所有情况均没有带来任何收益(包括精度指标和泛化能力),还往往给模型带来损害(detriment)
  • Google给出的一个解释是:Dropout在图像领域取得较好收益的原因是因为图像领域的数据特征分布与计算广告领域不同
    • 图像领域:稠密特征,此时Dropout把结果(effect)从强相关的特征中分离开来,从而得到泛化效果更好的分类器
    • 计算广告:稀疏特征,且有噪音

Feature Bagging

  • 对特征进行overlapping采样(注意,样本Bagging和特征Bagging不同),然后训练多个独立的模型,最后取平均值
  • 实验证明模型的的AucLoss降低了0.1%-0.6%

Feature Vector Normalization

  • \(\mathbf{x} = \frac{\mathbf{x}}{||\mathbf{x}||}\)
  • 开始有一点精度上的收益,但是后面也出现了一定程度的detriment
  • Google的解释是可能是由于per-coordinate learning rates和正则化的影响

Hexo——Next主题搜索窗口无法弹出

  • 参考博客: https://www.sqlsec.com/2017/12/hexosearch.html

问题描述

  • 有时候会遇到在Mac上Next主题窗口无法弹出的问题
  • 问题分为两类
    • 一类为找不到 search.xml 文件:加载 search.xml 时错误为404
    • 另一类为文章中有特殊字符:加载 search.xml 检查时错误为304

解决方案

404类

  • 修改最外层配置文件./_config.yml,添加以下语句(实测这一步非必须)

    1
    2
    3
    4
    5
    search:
    path: search.xml
    field: post
    format: html
    limit: 10000
  • 安装搜索插件

    1
    npm install hexo-generator-searchdb --save

304类

  • 304状态说明是加载文件存在,但是无法正常解析文件
  • 直接用浏览器访问 search.xml 文件链接,然后查看文件解析异常出现在哪个地方,然后删除特殊字符即可
    • 个人理解,从哪个文件不能搜索,特殊字符就出现在哪个文件中
    • 说明:目前还没遇到过这种情况,后面遇到会再补充

NLP——困惑度-Perplexity

本文主要介绍困惑度(Perplexity,简称为 PPL)在语言模型评估中的作用


困惑度的整体说明

  • 困惑度(Perplexity,PPL)本质是交叉熵损失 \(H(p|q)\) 的一个等价指标
    $$\text{Perplexity} = e^{H(p|q)}$$

    • 其中 \(H(p|q)\) 衡量真实标签和模型输出概率之间的差异
  • 语言模型中损失函数即交叉熵损失,此时有 \(loss = H(p|q)\),即:
    $$\text{Perplexity} = e^{\text{loss}}$$

    • 特别是预训练和 SFT 阶段,一般符合这个情况,RL 阶段则根据不同的损失归一化方式有所不同
    • 注:一般语言模型中是先计算单个样本的困惑度(对应指数上是单个样本的 Loss),然后再平均后上报
    • 参考链接:How to calculate perplexity for a language model using Pytorch, StackOverflow
      1
      perplexity = torch.exp(loss)
  • 给测试集的句子赋予较高概率值的语言模型较好,在测试集上困惑度越小,模型越好

  • 当一个语言模型训练完成后,测试集中的句子(一般是正常的自然语言句子)出现概率越高越好,概率越大,困惑度越小


单文档困惑度的定义

  • 给定模型 \(\mathcal{M}\),测试文档 \(d = (w_{1}, w_{2},\cdots,w_{N})\),则模型 \(\mathcal{M}\) 下评估测试文档 \(d\) 的困惑度 \(\text{Perplexity}_\mathcal{M}(d)\) 原始定义为:
    $$
    \begin{align}
    \text{Perplexity}_\mathcal{M}(d) &= P_\mathcal{M}(d)^{-\frac{1}{N}} \\
    &= P_\mathcal{M}(w_{1}, w_{2},\cdots,w_{N})^{-\frac{1}{N}}
    \end{align}
    $$
  • 常常会使用以下形式:
    $$ \text{Perplexity}_\mathcal{M}(d) = \exp\left (-\frac{1}{N}\log P_\mathcal{M}(w_{1}, w_{2},\cdots,w_{N})\right ) $$
  • 进一步有:
    $$
    \begin{align}
    \text{Perplexity}_\mathcal{M}(d) &= \exp\left (-\frac{1}{N}\log P_\mathcal{M}(w_{1}, w_{2},\cdots,w_{N})\right ) \\
    &= \exp\left (-\frac{1}{N}\log\prod_{n=1}^{N}P_\mathcal{M}(w_{n}|w_1,\cdots,w_{n-1})\right ) \\
    &= \exp\left (-\frac{1}{N}\sum_{n=1}^{N}\log P_\mathcal{M}(w_{n}|w_1,\cdots,w_{n-1})\right ) \\
    \end{align}
    $$
    • 计算时,常常使用上面加法的形式
  • 以上多种形式等价,两边取对数在变成自然数的指数即可证明:
    • 取对数:
      $$
      \begin{align}
      Log(\text{Perplexity}_\mathcal{M}(d) ) &= -\frac{1}{N}\log P_\mathcal{M}(w_{1}, w_{2},\cdots,w_{N}) \\
      \end{align}
      $$
    • 变指数:
      $$
      \begin{align}
      \text{Perplexity}_\mathcal{M}(d) &= e^{-\frac{1}{N}\log P_\mathcal{M}(w_{1}, w_{2},\cdots,w_{N})} \\
      &= \exp\left (-\frac{1}{N}\log P_\mathcal{M}(w_{1}, w_{2},\cdots,w_{N})\right ) \\
      \end{align}
      $$
    • 特别说明,一些地方会将对数和指数的底同时换成 2,实际上从推导上看,可以换成任意底数

多文档困惑度的定义

  • 基本思路:将多文档拼接起来,视作单个文档,然后计算困惑度即可(但需要考虑文档间词概率相互独立)
  • 以上是一个文档的表述,对于多个文档 \(D = (d_{1}, d_{2},\cdots,d_{M})\) ,其中 \(d_m = (w_{1}^{m}, w_{2}^{m},\cdots,w_{N_{m}})\),则多文档的困惑度定义为:
    $$
    \begin{align}
    \text{Perplexity}_\mathcal{M}(D) &= P_\mathcal{M}(D)^{-\frac{1}{\sum_{m=1}^{M}N_{m}}} \\
    &= \left(\prod_{m=1}^{M} P_\mathcal{M}(d_{m})\right)^{-\frac{1}{\sum_{m=1}^{M}N_{m}}}
    \end{align}
    $$
    • 文档之间互相独立,所以能推出上面的结论
  • 也常常写作如下形式
    $$
    \begin{align}
    \text{Perplexity}_\mathcal{M}(D) &= \exp\left(-\frac{1}{\sum_{m=1}^{M}N_{m}}\sum_{m=1}^{M}\log P_\mathcal{M}(w_{1}^{m}, w_{2}^{m},\cdots,w_{N_{m}}^{m})\right) \\
    \end{align}
    $$
  • 进一步可得
    $$
    \begin{align}
    \text{Perplexity}_\mathcal{M}(D) &= \exp \left ( -\frac{1}{\sum_{m=1}^{M}N_{m}}\sum_{m=1}^{M}\log P_\mathcal{M}(w_{1}^{m}, w_{2}^{m},\cdots,w_{N_{m}}^{m}) \right ) \\
    &= \exp \left ( -\frac{1}{\sum_{m=1}^{M}N_{m}}\sum_{m=1}^{M}\log\prod_{n=1}^{N_{m}}P_\mathcal{M}(w_{n}^{m}|w_{1}^{m},\cdots,w_{n-1}^{m}) \right ) \\
    &= \exp \left ( -\frac{1}{\sum_{m=1}^{M}N_{m}}\sum_{m=1}^{M}\sum_{n=1}^{N_{m}}\log P_\mathcal{M}(w_{n}^{m}|w_{1}^{m},\cdots,w_{n-1}^{m}) \right ) \\
    \end{align}
    $$
  • 注意:多个文档的困惑度不是简单的等于所有文档困惑度的积或和 ,而是等于把所有文档合并成一个大文档,大文档的困惑度则是最终所有文档的困惑度
  • 特别说明:一些地方也会使用平均法,使用每个文档的平均困惑度代表示多文档的困惑度

LDA 的困惑度

  • LDA中 \(w_{1},w_{2},\cdots,w_{n}\) 在参数已知的情况下是互相独立的,则有
    $$
    \begin{align}
    \text{Perplexity}_\mathcal{M}(d) &= e^{-\frac{1}{\sum_{m=1}^{M}N_{m}}\sum_{m=1}^{M}\log P_\mathcal{M}(w_{1}^{m}, w_{2}^{m},\cdots,w_{N_{m}}^{m})} \\
    &= \exp \left ( -\frac{1}{\sum_{m=1}^{M}N_{m}}\sum_{m=1}^{M}\log P_\mathcal{M}(w_{1}^{m}, w_{2}^{m},\cdots,w_{N_{m}}^{m}) \right ) \\
    &= \exp \left ( -\frac{1}{\sum_{m=1}^{M}N_{m}}\sum_{m=1}^{M}\log\prod_{n=1}^{N_{m}}P_\mathcal{M}(w_{n}) \right ) \\
    &= \exp \left ( -\frac{1}{\sum_{m=1}^{M}N_{m}}\sum_{m=1}^{M}\log\prod_{n=1}^{N_{m}}\sum_{k=1}^{K}P_\mathcal{M}(w_{n}=t|z_{n}=k;\mathcal{M})P_\mathcal{M}(z_{n}=k|d=d_{m};\mathcal{M})\right ) \\
    &= \exp \left ( -\frac{1}{\sum_{m=1}^{M}N_{m}}\sum_{m=1}^{M}\log\prod_{n=1}^{N_{m}}\sum_{k=1}^{K}\theta_{m,k}\phi_{k,t}\right ) \\
    &= \exp \left ( -\frac{1}{\sum_{m=1}^{M}N_{m}}\sum_{m=1}^{M}\log\prod_{n=1}^{N_{m}}\theta_{m,:}\phi_{:,t}\right ) \\
    &= \exp \left ( -\frac{1}{\sum_{m=1}^{M}N_{m}}\sum_{m=1}^{M}\sum_{n=1}^{N_{m}}\log\theta_{m,:}\phi_{:,t}\right ) \\
    \end{align}
    $$
  • 其中 \(\phi_{k,t}\) 表示单词t在主题k中出现的概率,\(\theta_{m,k}\) 表示主题k在文档m中出现的概率
  • \(\sum_{k=1}^{K}\theta_{m,k}\phi_{k,t} = (\theta_{m,:}\phi_{:,t})\) 就是单词t出现在文档m中的概率(对隐变量主题k积分)
  • 上面式子中 \((\theta_{m,:}\phi_{:,t})\) 就是两个向量的内积,在这里: \(\theta_{m,:}\) 代表行向量,表示当前文档 \(d_{m}\) 的主题分布, \(\phi_{:,t}\) 代表列向量,表示当前每个主题生成词 \(w_{t}\) 的概率
  • 计算公式的代码可参考L-LDA模型的实现GitHub仓库: Labeled-LDA-Python 中的perplexity函数和log_perplexity函数

CA——Feature-Hashing

  • 参考文献: Feature Hashing for Large Scale Multitask Learning, 2009, Yahoo! Research
  • 特征哈希(Feature Hashing)常用于数据特征降维,同时尽量保留原始特征的表达能力

论文贡献

  • 给出了一种高维数据降维方法,特征哈希(Feature Hashing)
  • 严格证明了特征哈希的可用性

Background

  • 一种构造组合特征的方法是笛卡尔乘积
  • 计算广告领域往往有数十亿的高维特征
  • 一种表达方式是使用词表法,对每个特征从词表里面进行查询
    • 缺陷一:拓展问题,每次拓展词表时难度较大(难以进行模型升级,因为特征维度在变化)
    • 缺陷二:无法处理词表中不存在的特征(Unknown特征)
  • 一般的降维方法容易带来特征表达能力的损失

特征哈希

  • 哈希函数定义(参考自博客:https://blog.csdn.net/qjf42/article/details/82387559)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    def feature_hashing(features, m):
    """
    Args:
    features: 输入特征序列,可以是数字,字符串(本质还是数字)
    m: 输出的特征维度,通常是2**26(vw),2**20(scikit-learn)
    Returns:
    m维的(稀疏)向量
    """
    # 这里的x一般是稀疏表示的(如:scipy.sparse.csr_matrix),这里是为了方便说明
    x = np.zeros(m)
    for feature in features:
    # hash_func_1保证散列尽量平均且散列速度快
    idx = hash_func_1(feature) % m
    # 这里在原始论文中
    sign = hash_func_2(feature) % 2
    if sign == 1:
    x[idx] += 1
    else:
    x[idx] -= 1
    return x
    • 输出特征维度一般为 \(m = 2^24\) 等,是一个认为给定的数字
  • 与词表法比较:

    • 解决了模型升级时的特征拓展问题(增加新特征时,特征的维度不会变化)
    • 解决了Unknown特征问题(个人理解:因为hash函数不管是什么特征,都可以一视同仁)
    • 无需查表,节省了查表的时间(个人理解:其实查表时一般实现方式也是用哈希表构建索引,所以这里不能算是优势)
    • 完成了降维(这里是把字典法里面对邮件或者文档的id也算作一个特征,这个特征one hot表示一下将会造成数据维度变得非常大?但是id算做特征有什么意义吗?)

一些说明

  • 冲突总会发生,也就是说不同一个特征总有一定的概率被映射到同一个维度(即两个不同特征的idx值可能相等)上
  • Paper中的垃圾邮件过滤模型实验证明:冲突造成的损失漏召率在 \(m=2^22\) 时影响约为1%,接近不做hash时的效果(特征维度在不做hash约为 \(2^{25}\))且在 \(m=2^{18}\) 时为1.12%,也只升高了一点点
  • 另外:无论如何,总有特殊情况,比如重要的特征如用户的性别特征“男”和“女”二者可能被映射到同一个维度上
    • 这里编码时是男:(1, 0), 女(0, 1)这样的,所以如果二者映射到同一个维度上,那么这两个特征丢失了原本的表达能力
    • 真实环境中如果遇到这些问题将会很难调试,如果找到了相关的问题,可以通过修改映射函数的输入参数字符串等方式来错开两个特征
  • 特征哈希本身可以类比于机器学习中的核技巧,所以特征哈希也称为哈希技巧

一些理解

知乎用户

  • 参考Ainika Peng的博客:https://www.zhihu.com/question/264165760/answer/279676705
  • 一般而言这类技术是为了解决两个问题:
    • 一是将categorical的特征编码为模型可理解的格式 , 这是个基础问题。One-Hot Serializing就可以达到这个效果,例如将训练样本中出现过的的每个deviceid按顺序递增编号(比如deviceid@xxx:1 -> feature@10000:1)
      • 缺点1:这个映射表需要传递给引擎端,在prediction的时候照着再查一遍,数据量大且数据结构设计不好的时候很费时间;
      • 缺点2:有些频次很低的特征置信度不高,单独出现对模型无益(甚至over-fitting)。这时候可以使用按频次截断技术进行降维。比如微软在deep crossing中提到的特征工程方法:只保留曝光最多的10k个campaign id编码为0-9999,其余的id全部编码为10000,但辅以poCTR等连续特征作为辅助。事实上这是一种手工的Hashing方法
    • 二是尽可能在保留有效信息的基础上降低训练和预测过程的时间复杂度
  • 自动Hashing方法的好处是:
    • 只要训练和预测时使用的hashing方法一致,对同一个特征的编码结果即一致,因此引擎预测或提供数据dump的时候无需查找编码表。所以其最大优点在于数据一致性和速度提升,这在极大规模特征和在线学习中至关重要
  • 我们说的Hashing算法一般而言均特意设计为低碰撞率
    • 因此一般hashing算法本身不会大幅降低特征维度,自然也不会大幅损失特征信息。真正可能存在问题的是hashing之后的降维过程
    • 一个非常常见的陷阱是string哈希到int64后取模m,试图将特征压缩至m维one-hot空间。在这种情况下,对于不知情的随机hashing过程,不同特征的碰撞率为1/m。举个例子,对于“性别”特征,将male哈希为一个int64,female哈希为另一个int64,很难发生碰撞;但如果你试图使用mod2将其压缩,如果你的算法哈希出的这两个int64奇偶性相同,则会导致特征失效。在你有很多feature需要哈希而又不清楚hashing算法细节的情况下,这在概率意义上是很容易发生的
      • 这里的mod2是极端举例,其实m的取值小于原始维度的情况下都有一定概率造成冲突
  • 因此我们会更倾向于所谓的embedding算法
    • 例如将70万维的userid通过weight embedding到32维的连续值特征上(不同于传统hashing的低维离散值特征)。这意味着训练过程更加复杂(有更多的weight需要optimize);但对于预测过程,其特征性能十分良好且时间复杂度得以降低。同时,由于连续值特征空间的表达能力大幅高于离散值特征空间,整个模型的表达能力并不会明显下降,也基本不会发生离散hashing的碰撞问题
    • 当然,如果是FM这类倾向于接受离散值的模型,手工serializing+精心设计的hashing是较好的选择
  • 优点:
    • 训练和预测的时间复杂度大幅降低;
    • 数据的一致性强,不存在同一个特征今天编码成这个、明天编码成那个的情况,便于跟踪单特征效果;
    • 对new feature可以直接编码并加入训练,无需等待编码表统计并反馈;
    • 降低feature space大小,(精心设计可以)降低over-fitting的几率
  • 缺点
    • 在不清楚hashing function细节的情况下,容易导致特征碰撞失效,且难以排查;
    • 难以通过hashing出的特征反推源特征;
    • embedding会降低模型的可解释性。

General——各种包的管理总结


编程语言相关

  • 参考链接: https://help.github.com/en/github/managing-packages-with-github-packages/about-github-packages#supported-clients-and-formats
Package client Language Package format Description
npm JavaScript package.json Node package manager
gem Ruby Gemfile RubyGems package manager
mvn Java pom.xml Apache Maven project management and comprehension tool
gradle Java build.gradle or build.gradle.kts Gradle build automation tool for Java
docker N/A Dockerfile Docker container management platform
nuget .NET nupkg NuGet package management for .NET
pip Python requirements.txt use pip install -r requirements.txt

操作系统

  • 参考链接: https://www.iteye.com/blog/justcoding-1937171
软件管理方式 线下安装命令 线上安装命令 distribution 操作系统
RPM rpm, rpmbuild yum Red Hat/Fedora
DPKG dpkg apt, apt-get Debian/Ubuntu

rpm和dpkg常用命令总结

  • 参考链接: http://cha.homeip.net/blog/archives/2005/08/rpm_vs_dpkg.html
操作描述 rpm dpkg
安装指定套件 rpm -i pkgfile.rpm dpkg -i pkgfile.deb
显示所有已安装的套件名称 rpm -qa dpkg -l
显示套件包含的所有档案 rpm -ql [softwarename] dpkg -L [softwarename]
显示特定档案所属套件名称 rpm -qf [/path/to/file] dpkg -S [/path/to/file]
显示制定套件是否安装 rpm -q [softwarename] dpkg -l [softwarename], -s或-p显示详细咨询, -l只列出简洁咨询
移除指定套件 rpm -e [softwarename] dpkg -r softwarename, -r 留下套件设定, -P完全移除

apt和yum常用命令总结

  • 参考博客: https://cnblogs.com/lanbosm/p/9130211.html
操作描述 yum apt
软件源配置文件路径 /etc/yum.conf /etc/apt/sources.list
安装软件包 yum install [package] apt-get install [package]
删除软件包 yum uninstall [package] apt-get remove [package]
删除有依赖关系的软件包和配置文件 yum uninstall [package] apt-get autoremove [package] –purge
查看安装包信息 yum info [package] apt-cache show [package]
更新软件包列表 yum update apt-get update
清空缓存 yum clean apt-get clean
搜索包名 yum apt-cahce search

一些特殊命令

apt

  • 列出所有可用包名

    1
    apt-cache pkgnames
  • 通过描述列出包名

    1
    apt-cache search [keys]
  • 指定包的版本号

    1
    apt-get install [package]=[version]

yum

  • 搜索包的可用版本

    1
    apt --showduplicates list [package] | expand
    • expand命令用于将文件的制表符tab转换成空格符space
      • 默认一个tab对应8个space
      • 若不指定文件名(或者文件名为-), 则expand会从标准输入读取数据
    • unexpand命令与expand相反
  • 安装时指定包的版本号

    1
    apt install [package]-[version]

yum和apt安装的常用参数

  • -y: 指定在询问是否安装时均选择yes
  • -q: quiet,安装途中不打印log信息

General——各种压缩方式总结


.tar.gz

.tar.bz2

.tar.xz

.tgz

Centos——clamav安装与杀毒

clam是一款Linux上免费的杀毒软件


安装与配置

命令行安装

  • 命令行安装clamav会自动创建clamav用户和clamav组

  • Centos(笔者在Centos7亲测)

    1
    apt install –y clamav clamav-update
  • ubuntu(笔者在Ubuntu16.04上亲测)

    1
    apt-get install clamav

源码安装

  • 如果因为某些原因无法从命令行安装,可以尝试用源码安装,此时需要首先手动创建相关组和用户
安装前的配置
  • 创建clamav组

    1
    groupadd clamav
  • 创建用户并添加到clamav组

    1
    useradd -g clamav clamav
源码下载和安装
  • 下载流程:

    • 下载链接: http://www.clamav.net/downloads, 因为版本可能会有更新,这里我们直接给出网站下载地址,可以随时查看版本信息
    • 找到软件包下载链接后,使用wget下载即可,比如
      1
      wget http://www.clamav.net/downloads/production/clamav-0.102.0.tar.gz
  • 安装流程:

    • 解压

      1
      tar -xf clamav-0.102.0.tar.gz
    • 切换目录

      1
      cd clamav-0.102.0
    • 安装依赖

      1
      yum/apt install gcc openssl openssl-devel

使用

升级病毒库

  • 升级命令

    • 命令行安装后更新命令

      1
      freshclam
    • 源码安装后更新命令, 也可以建立软连接后直接使用上面的命令行启动

      1
      /usr/local/clamav/bin/freshclam
    • 建立链接指令

      1
      ln -s [source path] [target path]

查找病毒文件

  • 常用命令

    1
    nohup clamscan / -r --infected -l clamscan.log > clamscan.out &
    • -r 指明递归查杀
    • --infected 表示仅仅输出被感染的部分文件, 否则没有被感染的文件会输出文件名: OK这样无用的信息
    • -l 指明日志文件路径
    • / 是查找的目标目录,如果是整个机器查找则使用/
    • 由于查杀病毒需要很长时间,所以建议使用后台进程进行, 如果是远程, 建议使用nohup
    • 由于输出非常多,所以一般我们使用clamscan.out和clamscan.log分别存储输出和日志
  • 列出被感染文件

    1
    cat clamscan.out | grep FOUND

DL——Transformer

本文主要介绍Transformer和Attention相关内容

  • 由于LaTex中矩阵的黑体表示过于复杂,在不会引起混淆的情况下,本文中有些地方会被简写为非黑体

相关论文介绍

  • Transformer原始文章:
    • Google Brain, NIPS 2017: Attention Is All You Need
    • 文章中介绍了一种应用Attention机制的新型特征提取器,命名为Transformer, 实验证明Transformer优于RNN(LSTM),CNN等常规的特征提取器
  • Transformer的使用:
    • GPT: Improving Language Understanding by Generative Pre-Training
    • BERT: BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding
    • 以上两个工作都使用了Transformer作为特征提取器, 使用两阶段训练的方式实现迁移学习(Pre-Training and Fine-Training)

相关博客介绍

  • 强烈推荐看看jalammar的博客: illustrated-transformer
  • 另一篇不错的Attention和Transformer讲解自然语言处理中的自注意力机制(Self-Attention Mechanism)
  • 一篇很多个人理解的博客 《Attention is All You Need》浅读

Transformer讲解

  • 最直观的动态图理解
  • 本文讲解主要按照Google Brain, NIPS 2017: Attention Is All You Need的思路走,该论文的亮点在于:
    • 不同于以往主流机器翻译使用基于 RNN 的 Seq2Seq 模型框架,该论文用 Attention 机制代替了 RNN 搭建了整个模型框架, 这是一个从换自行车零件到把自行车换成汽车的突破
    • 提出了多头注意力(Multi-Head Attention)机制方法,在编码器和解码器中大量的使用了多头自注意力机制(Multi-Head self-attention)
    • 在WMT2014语料库的英德和英法语言翻译任务上取得了先进结果

Transformer是什么?

  • Transformer 是个序列转换器 :
  • 进一步讲,是个 Encoder-Decoder 模型的序列转换器 :
  • 更进一步的讲,是个 6层Encoder + 6层Decoder 结构的序列转换器:
  • 上面的图中,每个 Encoder 是:
  • 详细的讲, 每个Encoder是
  • 展开看里面 Encoder 中的数据流向
  • 更进一步的展开看 Encoder 中的数据流向
  • 两层 Encoder + 两层Decoder (其中一个Decoder没有完全画出来) 的数据流向
  • 带细节动图查看数据流向
  • 最后,我们给出Transformer的结构图(来自原文中)

Transformer中的Attention

Transformer中使用了 Multi-Head Attention, 同时也是一种 Self Attention

  • 由于Transformer的Multi_Head Attention中 Query == Key == Query , 所以也是一种 Self Attention
    • 即
      $$\boldsymbol{Y_{AttentionOutput}} = Self Attention(\boldsymbol{Q},\boldsymbol{K},\boldsymbol{V}) = Attention(\boldsymbol{X},\boldsymbol{X},\boldsymbol{X})$$
  • 更多关于广义Attention的理解请参考: DL——Attention

Multi-Head Attention

  • Muti-Head Attention,也称为多头Attention,由 \(h\) 个 Scaled Dot-Product Attention和其他线性层和Concat操作等组成
  • Scaled Dot Product Attention中Mask操作是可选的
  • Scaled Dot Product Attention数学定义为(没有Mask操作)
    $$
    \begin{align}
    Attention(\boldsymbol{Q},\boldsymbol{K},\boldsymbol{V}) = softmax\left(\frac{\boldsymbol{Q}\boldsymbol{K}^{\top}}{\sqrt{d_k}}\right)\boldsymbol{V}
    \end{align}
    $$
    • Softmax前除以 \(\sqrt{d_k}\) 的原因是防止梯度消失问题,基本思想是(原始论文脚注中有提到):假设 \(\boldsymbol{Q},\boldsymbol{K}\) 中每个元素是服从均值为0,方差为1的正太分布( \(\sim N(0,1)\) ),那么他们任意取两个列向量 \(\boldsymbol{q}_i,\boldsymbol{k}_i\) 的内积服从均值为0,方差为 \(d_k\) 的正太分布( \(\sim N(0,d_k)\) ),具体证明可参考没有比这更详细的推导 attention为什么除以根号dk——深入理解Bert系列文章,过大的方差会导致softmax后梯度消失
  • Multi-Head Attention的某个输出的数学定义为
    $$
    \begin{align}
    MultiHead(\boldsymbol{Q}, \boldsymbol{K}, \boldsymbol{V}) &= Concat(head_1,\dots,head_h)\boldsymbol{W}^{O} \\
    where \quad head_i &= Attention(\boldsymbol{Q}\boldsymbol{W}_i^Q,\boldsymbol{K}\boldsymbol{W}_i^K,\boldsymbol{V}\boldsymbol{W}_i^V)
    \end{align}
    $$
    • 注意,在一般的Attention中,没有 \(\boldsymbol{W}^{O}\) 这个参数,这个是用于多头Attention中,将多头的输出Concat后映射一下再输出
      • 理解:若不是多头,其实加不加这个参数,本质都是一样的,因为连续的两个权重矩阵线性相乘,本质就是一个权重矩阵而已
      • 补充:在实现时,这里的 \(\boldsymbol{W}^{O}\) 实际上是一个线性层 nn.Linear 的含义,就是一个简单的矩阵,不包含非线性信息的
    • 一般来说, \(head_i\) 的维度是 \(\frac{d_{model}}{N_{head}}=\frac{d_{model}}{h}=d_v = d_k\),所以Multi-Head Attention的参数数量与head的数量无关,且无论多少个头,其的输出结果还是 \(d_{model} = d_v * h\) 维
    • 原始论文中常用 \(d_{model} = h * d_k = h * d_v\),且base模型的参数设置为 \(512 = 8 * 64\)
有关Multi-Head Attention的理解
  • 原论文的描述:

    Multi-head attention allows the model to jointly attend to information from different representation subspaces at different positions,

  • 理解:

    • 所谓多头,就是多做几次(\(h\) 次)同样的事情(参数 \((W_i^Q, W_i^K, W_i^V)\) 不共享, 即当 \(i \neq j \) 时, \((W_i^Q, W_i^K, W_i^V) \neq (W_j^Q, W_j^K, W_j^V)\)),然后把结果拼接
    • Multi-Head Attention中, 每个头(Scaled Dot-Product Attention)负责不同的子空间(subspaces at differect positions)
    • 每个头权重不同, 所以他们的关注点也会不同,注意, 初始化时他们的参数不能相同, 否则会造成他们的参数永远相同, 因为他们是同构的
    • 个人理解: 多头的作用可以类比于CNN中的卷积层, 负责从不同的角度提取原始数据的特征

Self Attention

  • Self Attention是只 Key和Query相同的 Attention, 这里因为 Key 和 Value 也相同,所以有 Query == Key == Query
  • 即$$ \boldsymbol{Y_{AttentionOutput}} = Self Attention(\boldsymbol{Q},\boldsymbol{K},\boldsymbol{V}) = Attention(\boldsymbol{X},\boldsymbol{X},\boldsymbol{X})$$

Transformer中的Attention

  • 既是Multi-Head Attention, 也是 Self Attention
  • 所以有$$\boldsymbol{Y_{AttentionOutput}} = MultiHead(\boldsymbol{X},\boldsymbol{X},\boldsymbol{X})$$

Masked Multi-Head Attetion

  • MaskedMHA,掩码多头Attention,用于Decoder中防止前面的token看到后面的token,Encoder中不需要MaskedMHA
  • 一般性的,Masked Self-Attention是更一般的实现,不一定非要和Multi-Head绑定
  • 代码实现时,主要是在计算Softmax前,按照掩码将看不到的token对应的q,k内积替换为一个大负数,比如 \(-1e9\)

Cross Multi-Head Attention

  • CrossMHA不是Self-Attention,CrossMHA的Q,K是Encoder的输出,V来自Decoder

Transformer 输入层

  • Transformer的输入层使用了 Word Embedding + Position Embedding
  • 由于Transformer去除RNN的Attention机制完全不考虑词的顺序, 也就是说, 随机打乱句子中词的顺序 (也就是将键值对 \((\boldsymbol{K}, \boldsymbol{V})\) 对随机打乱), Transformer中Attention的结果不变
  • 实际上, 目前为止, Transformer中的Attention模型顶多是个非常精妙的”词袋模型” (这句话来自博客:https://kexue.fm/archives/4765)

Word Embedding

  • 和之前的词嵌入一样, 将One-Hot值映射成词向量嵌入模型中
  • Tie Embedding :嵌入层(Embedding Layer)和输出投影层(Unembedding Layer / Output Projection Layer)绑定(即共享权重)
    • 基本思路:一个是 token 到 Embedding 映射,另一个是 Embedding 到 token 映射,绑定方式是W_out = W_embed^T
    • 这种绑定的优势是节约存储、训练稳定;缺点是表达能力受限、梯度冲突可能严重(比如输入和输入的词分布差异大)
  • 原始论文中关于参数绑定(Weight-Tying)的说明在3.4节:

    In our model, we share the same weight matrix between the two embedding layers and the pre-softmax linear transformation, similar to [24]. In the embedding layers, we multiply those weights by \(\sqrt{d_{\text{model}}}\)

Position Embedding

FaceBook的《Convolutional Sequence to Sequence Learning》中曾经用过Position Embedding

  • 在不使用RNN的情况下建模词的顺序, 弥补”词袋模型”的不足
  • 用 Position Embedding来为每个位置一个向量化表示
    • 将每个位置编号,然后每个编号对应一个向量
    • 通过结合位置向量和词向量,就给每个词都引入了一定的位置信息,这样Attention就可以分辨出不同位置的词了
  • 原始论文中, 作者提出了一种周期性位置编码的表示, 数学公式如下:
    $$
    \begin{align}
    PE(pos,2i) &= sin(pos/10000^{2i/d_{\text{model}}}) \\
    PE(pos, 2i+1) &= cos(pos/10000^{2i/d_{\text{model}}})
    \end{align}
    $$
  • 我觉得上述公式太丑了,转换一下写法可能更容易理解
    $$
    \begin{align}
    PE(pos,2i) &= sin\left (\frac{pos}{10000^{\frac{2i}{d_{\text{model}}}}}\right) \\
    PE(pos, 2i+1) &= cos\left (\frac{pos}{10000^{\frac{2i}{d_{\text{model}}}}}\right)
    \end{align}
    $$
    • \(pos\) 是位置编号
    • \(i\) 表示位置向量的第 \(i\) 维
    • 从公式来看,为什么选择 \(10000^{\frac{2i}{d_{\text{model}}}}\) ?
      • \(i\) 表示频率随模型embedding维度变动(模型embedding不同维度频率不同,低维度高频,高维度低频)
      • \(pos\) 表示周期,随着位置变化,每个维度的值呈现周期变化,但是不同维度的变化周期(频率)不同
      • 10000是一个放缩因子,理论上可以换,在transformer原始论文实现中用了这个,且效果不错
    • 选择正弦函数的原因是假设这将允许模型学到相对位置信息
      • 因为对于固定的 \(k\), \(PE_{pos+k} = LinearFuction(PE_{pos})\),所以这给模型提供了表达相对位置的可能性
与之前的Position Embedding的区别
  • Position Embedding对模型的意义不同:
    • 以前在RNN、CNN模型中Position Embedding是锦上添花的辅助手段,也就是“有它会更好、没它也就差一点点”的情况,因为RNN、CNN本身就能捕捉到位置信息
    • 在Transformer这个纯Attention模型中,Position Embedding是位置信息的唯一来源,因此它是模型的核心成分之一,并非仅仅是简单的辅助手段
  • Position Embedding的向量构造方式不同
    • 在以往的Position Embedding中,基本都是根据任务训练出来的向量
    • 而Google直接给出了一个构造Position Embedding的公式:
      $$
      \begin{align}
      PE(pos,2i) &= sin\left (\frac{pos}{10000^{\frac{2i}{d_{\text{model}}}}}\right) \\
      PE(pos, 2i+1) &= cos\left (\frac{pos}{10000^{\frac{2i}{d_{\text{model}}}}}\right)
      \end{align}
      $$
    • Google经过实验, 学到的位置嵌入和这种计算得到的位置嵌入结果很相近
    • Google选用这种嵌入方式的原因是这种方式允许模型以后可以扩展到比训练时遇到的序列长度更长的句子

输入层的输出(Attention的输入)

  • 综合词嵌入和位置嵌入信息,我们可以得到下面的公式
    $$
    \begin{align}
    \boldsymbol{x} = \boldsymbol{x}_{WE} + \boldsymbol{x}_{PE}
    \end{align}
    $$
    • \(\boldsymbol{x}\) 为输入层经过词嵌入和位置嵌入后的 输出, 也就是Attention的输入
    • \(\boldsymbol{x}_{WE}\) 指词嵌入的结果
    • \(\boldsymbol{x}_{PE}\) 指位置嵌入的结果

FFN

  • FFN,Feed Forward Network,前馈网络层
    $$
    FFN(\mathbf{X}) = ReLU(\mathbf{X}\mathbf{W}^U + \mathbf{b}_1)\mathbf{W}^D + \mathbf{b}_2
    $$
  • 原始 Transformer 使用的是 ReLU 作为激活函数,现在很多时候也会选用 sigmoid
  • 可以看到前馈神经网络包含了两层
  • 注:原始 Transformer 论文中,使用的 \(H = d_\text{model} = 512\),\(d_{ff} = 2048\),FFN 中间隐藏维度是 \(d_\text{model} = 512\) 的 4 倍
    • 即 FFN 的参数量为:\(2 \times 4H \times H = 8H^2\)

Layer Normalization

  • 层归一化,是Transformer特有的一种归一化方法
  • Batch Normalization(BN)不适用与Transformer中,至少有以下原因:
    • Transformer训练样本通常(特别是模型很大时)可能会比较小,在Batch较小时BN不再适用
    • BN是按照token维度(特征维度)来归一化的,不利于处理变长输入序列
      $$
      LayerNorm(\mathbf{x}) = \frac{\mathbf{x}-\mathbf{\mu}}{\mathbf{\sigma}}\cdot \mathbf{\gamma} + \mathbf{\beta} \\
      \mathbf{\mu} = \frac{1}{H}\sum_{i=1}^H x_i, \quad \mathbf{\sigma} = \sqrt{\frac{1}{H}\sum_{i=1}^H(x_i-\mathbf{\mu})^2} \\
      $$
  • 代码实现是会在分母的更号内增加一个极小量 \(\epsilon\),防止出现除0的情况
  • 显然,LayerNorm是基于token来归一化的,当前token的归一化结果与其他token无关,不受其他token影响
  • 可能出现不同的token向量LayerNorm归一化以后输出相同的值,比如[1,2,3,4]、[2,3,4,5]和[2,4,6,8]的输出结果都相同
    • 可以看到是因为这些向量维度之间的分布很相似,或者呈现倍数关系,才导致输出值为0,实际模型中,维度一般是64维或者128维等,而且是小数,几乎不会出现两个不同的token经过LayerNorm后输出相同的值

LN是token维度的

  • 按照Transformer源码实现来看,LayerNorm是Token维度的,不是Seq维度,也就是说,token向量LayerNorm的结果只与token向量自身相关,与所在序列的其他token无关

    • 这一点是Decoder可以增量解码的关键,这一点保证了Decoder的前序词不会受到后续词的影响
    • 增量解码是指:Decoder中输出下一个词时,可以使用前序词的缓存结果,由于前面的词看不到后面的词,所以增加词前后Transformer-Decoder中前序每个词的输出在每一层都不会受到影响
  • 一个LayerNorm的示例如下,Transformer源码中实现与这个类似

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    import torch.nn as nn
    import torch

    # 假设d_model=4,d_model在有些实现中为hidden_size
    layer_norm = nn.LayerNorm(4) # 这里使用LayerNorm,也可以使用RMSNorm,两者作用维度相同,只是公式不同
    # test case 1:
    input_tensor = torch.Tensor([[[1, 2, 3, 4],
    [2, 3, 4, 5]]])
    output_tensor = layer_norm(input_tensor)
    print(output_tensor)
    # output:
    # tensor([[[-1.3416, -0.4472, 0.4472, 1.3416],
    # [-1.3416, -0.4472, 0.4472, 1.3416]]],
    # grad_fn=<NativeLayerNormBackward0>)

    # test case 2:
    input_tensor = torch.Tensor([[[1, 2, 3, 4],
    [200, 3, 4, 5]]])
    output_tensor = layer_norm(input_tensor)
    print(output_tensor)

    # tensor([[[-1.3416, -0.4472, 0.4472, 1.3416],
    # [ 1.7320, -0.5891, -0.5773, -0.5655]]],
    # grad_fn=<NativeLayerNormBackward0>)
  • 从示例中可以看出:

    • 修改第二个token的某个元素值,只影响第二个token的LN输出,不影响第一个token

Transformer改进-LN

原始LN参见论文之前的内容

LN的改进——RMSNorm

  • RMSNorm 的公式如下:
    $$
    \begin{align}
    RMSNorm(\mathbf{x}) &= \frac{\mathbf{x}-\mathbf{\mu}}{RMS(\mathbf{x})}\cdot \mathbf{\gamma} \\
    RMS(\mathbf{x}) &= \sqrt{\frac{1}{H}\sum_{i=1}^H x_i^2} \\
    \end{align}
    $$
    • 代码实现是会在分母的更号内增加一个极小量 \(\epsilon\),防止出现除 0 的情况
    • 其中 \(\mu\) 和 \(\gamma\) 是可学习参数,但一般的实现中没有 \(\mu\),只有一个参数 \(\gamma\)
  • 截止到24年,PyTorch 官方还没有提供标准的 RMSNorm 实现,下面是 HuggingFace Transformers 中的实现:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    @use_kernel_forward_from_hub("RMSNorm")
    class LlamaRMSNorm(nn.Module):
    def __init__(self, hidden_size, eps=1e-6):
    """
    LlamaRMSNorm is equivalent to T5LayerNorm
    """
    super().__init__()
    self.weight = nn.Parameter(torch.ones(hidden_size))
    self.variance_epsilon = eps

    def forward(self, hidden_states):
    input_dtype = hidden_states.dtype
    hidden_states = hidden_states.to(torch.float32)
    variance = hidden_states.pow(2).mean(-1, keepdim=True)
    hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)
    return self.weight * hidden_states.to(input_dtype)

    def extra_repr(self):
    return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}"

LN的改进——DeepNorm

$$
DeepNorm(\mathbf{x}) = LayerNorm(\alpha\cdot \mathbf{x} + \text{Sublayer}(\mathbf{x})) \\
$$

  • 这里的 \(\text{Sublayer}(\mathbf{x})\) 是指Transformer中的前馈神经网络层或自注意力模块(两者都会作为LN的输入)
  • 实际上,原始的Transformer中,每次LN的内容都是加上残差的,这里根据归一化位置的不同还有会有不同的实现
  • 原始的Transformer中,相当于 \(\alpha=1\) 的DeepNorm
  • 这里叫做DeepNorm的原因是因为缩放残差 \(\mathbf{x}\) 可以扩展Transformer的深度,有论文提到利用该方法可将深度提升到1000层(DeepNet: Scaling Transformers to 1,000 Layers)

归一化的位置

  • 归一化的位置包括Post-Norm、Pre-Norm和Sandwich-Norm等
  • Post-Norm
    • 原始Transformer使用的方法
    • 将归一化模块使用到加法(需要把残差加到FFN/MHA的输出上)之后,详细公式是:
      $$
      \text{Post-Norm}(\mathbf{x}) = Norm(\mathbf{x} + \text{Sublayer}(\mathbf{x}))
      $$
    • \(\text{Sublayer}\)
  • Pre-Norm
    • 归一化模块放到FFN/MHA之前,详细公式是:
      $$
      \text{Pre-Norm}(\mathbf{x}) = \mathbf{x} + \text{Sublayer}(Norm(\mathbf{x}))
      $$
  • Sandwich_Norm
    • 三明治归一化,从字面意思可以知道,是两个Norm将某个层夹起来,实际上,该层是前馈神经网络层或自注意力模块
      $$
      \text{Sandwish-Norm}(\mathbf{x}) = \mathbf{x} + Norm(\text{Sublayer}(Norm(\mathbf{x})))
      $$

归一化位置的比较

DeepNet: Scaling Transformers to 1,000 Layers中也有有关Pre-Norm和Post-Norm的探讨

  • 一般来说,使用Post-Norm比较多,效果也更好
  • Pre-Norm在深层Transformer中容易训练(容易训练不代表效果好,Pre-Norm的拟合能力一般不如Post-Norm)
    • 所以有些模型还是会使用Pre-Norm,因为它更稳定
  • 浅层中建议使用Post-Norm
  • 详情参考苏神的回答为什么Pre Norm的效果不如Post Norm?,其中引用到了 如何评价微软亚研院提出的把 Transformer 提升到了 1000 层的 DeepNet? - 唐翔昊的回答 - 知乎

    Pre Norm的深度有“水分”!也就是说,一个 L 层的Pre Norm模型,其实际等效层数不如 L 层的Post Norm模型,而层数少了导致效果变差了
    Pre Norm结构无形地增加了模型的宽度而降低了模型的深度,而我们知道深度通常比宽度更重要,所以是无形之中的降低深度导致最终效果变差了

  • 直观上来说就是:
    • Pre-Norm 是(不严谨的变换)近似将深度转换成了宽度
      $$
      \begin{align}
      \mathbf{x}_{t+1} &= \mathbf{x}_t + f(Norm(\mathbf{x}_t)) \\
      &= \mathbf{x}_{t-1} + f(Norm(\mathbf{x}_{t-1})) + f(Norm(\mathbf{x}_t)) \\
      &\approx \mathbf{x}_{t-1} + 2f(Norm(\mathbf{x}_{t}))
      \end{align}
      $$
      • 注:这里大家认为可假定在 \(t\) 较大时, \(\mathbf{x}_t\) 和 \(\mathbf{x}_{t-1}\) 是基本相似的
      • 我们称 \(x_1,x_2,\cdots,x_t\) 为主干,在 Pre-Norm 中,主干一直在加入新的东西,所以方差越来越大,且单层网络对主干的影响越来越小
      • 此外,如何评价微软亚研院提出的把 Transformer 提升到了 1000 层的 DeepNet? - 唐翔昊的回答 - 知乎中还认为不同层的 \(f\) (MHA 或 FFN)在统计上是相似的
        • TODO:这一点有待考证和理解
    • Post-Norm 则是保持深度
      $$
      \begin{align}
      \mathbf{x}_{t+1} &= Norm(\mathbf{x}_t + f(\mathbf{x}_t)) \\
      &= Norm(Norm(\mathbf{x}_{t-1} + f(\mathbf{x}_{t-1})) + f(\mathbf{x}_t))
      \end{align}
      $$
      • Post-Norm 中,保证了主干方差是恒定的

Transformer改进-激活函数

原始激活函数是ReLU(Rectified Linear Unit)

Swish(SiLU)

  • 参考文章:Sigmoid-Weighted Linear Units for Neural Network Function Approximation in Reinforcement Learning
  • Swish 的全称为 “Scaled Exponential Linear Unit with Squishing Hyperbolic Tangent”,直译为“带有压缩的缩放指数线性单元”
    $$
    \text{Swish}_\beta(x) = x \cdot sigmoid(\beta x)
    $$
    • 许多实现中常常设置 \(\beta=1\)
  • 注:Swish, 简称为 Sigmoid-weighted Linear Unit,所以一些文章中也称为 SiLU,

GELU

  • GELU, Gaussion Error Linear Unit,有时候也写作GeLU
    $$
    \text{GELU}(x) = 0.5x \cdot [1+\text{erf}(\frac{x}{\sqrt{2}})], \quad \text{erf}(x) = \frac{2}{\sqrt{\pi}}\int_1^x e^{-t^2} dt
    $$
    • erf 是 Gauss Error function 的缩写,在很 Torch 和 TensorFlow 中都是定义好的
  • 从公式可以看出GELU的本质是对一个正太分布的概率密度函数进行积分,实际上就是累积分布函数
  • GELU和ReLU的比较如下(图片来自简单理解GELU 激活函数):

FastGELU

  • FastGELU, Fast Gaussion Error Linear Unit,出自论文 CodeGeeX: A Pre-Trained Model for Code Generation with Multilingual Benchmarking on HumanEval-X, KDD 2024, THU & Huawei,该方案作为 GELU 的近似,在升腾 910 芯片上能加速
    $$ \text{FastGELU}(X_i) = \frac{X_i}{1+\exp(-1.702*|X_i|) \cdot \exp(0.851\cdot (X_i - |X_i|))} $$
  • FastGELU vs GELU图像对比如下:
  • 从图中可以看出:\(x\) 在 0 附近,以及 \(x \geq 0\) 时,FastGELU 和 GELU 的曲线几乎一致(未完全重合)

补充:GLU及其变换

  • GLU,Gated Linear Units,是一种利用门的思想实现的激活函数,该激活函数可以理解为对输入进行门控选择,一些维度的值可以通过门,一些则不可以,门一般是一个基础的非线性激活函数
  • 原始GLU形式如下:
    $$
    GLU = \sigma(\mathbf{W}_1\mathbf{x} + \mathbf{b}_1) \odot (\mathbf{W}_2\mathbf{x} + \mathbf{b}_2)
    $$
  • \(\sigma\) 可以替换成其他非线性激活函数
    • 注意整个公式中始终只有一个非线性激活函数,其他部分都是线性映射(线性激活函数)
  • \(\odot\) 表示矩阵按照元素相乘, \(W_1,W_2,b_1,b_2\) 是可学习的参数
  • 该激活函数非常特殊,首先使用两个权重矩阵对输入数据进行线性变换,然后通过sigmoid激活函数进行非线性变换。这种设计使得GLU在前馈传播过程中能够更好地捕捉输入数据的非线性特征,从而提高模型的表达能力和泛化能力
  • 原始论文GLU Variants Improve Transformer中也写作下面的形式(其中 \(W,V,b,c\) 是可学习的参数):
    $$
    GLU(\mathbf{x,W,V,b,c}) = \sigma(\mathbf{W}\mathbf{x} + \mathbf{b}) \odot (\mathbf{V}\mathbf{x} + \mathbf{c})
    $$
  • 去掉激活函数的版本也叫作Bilinear,写作
    $$
    Bilinear(\mathbf{x,W,V,b,c}) = (\mathbf{W}\mathbf{x} + \mathbf{b}) \odot (\mathbf{V}\mathbf{x} + \mathbf{c})
    $$
  • 其他相关形式
    $$
    ReGLU(x, W, V, b, c) = max(0, xW + b) \odot (xV + c) \\
    GEGLU(x, W, V, b, c) = GELU(xW + b) \odot (xV + c) \\
    SwiGLU(x, W, V, b, c, \beta) = Swish_\beta(xW + b) \odot (xV + c) \\
    $$

补充:FFN激活函数形式

  • FFN的ReLU激活函数形式
    $$
    \text{FFN}(x, W_1, W_2, b_1, b_2) = max(0, xW_1 + b_1)W_2 + b_2
    $$
  • 为了表示方便,也因为在一些文章中使用了简化,后续该形式会被简化成没有偏置项(bias)的形式:
    $$
    \text{FFN}_{ReLU}(x, W_1, W_2) = max(xW_1, 0)W_2
    $$

FFN各种激活函数形式

  • 常用FFN的激活函数改进有,GLU,Bilinear,ReGLU,GEGLU(GeGLU),SwiGLU等
    $$
    \begin{align}
    \text{FFN}_{GLU}(x, W, V, W_2) &= (\sigma(xW) \odot xV )W_2 \\
    \text{FFN}_{Bilinear}(x, W, V, W_2) &= (xW \odot xV )W_2 \\
    \text{FFN}_{ReGLU}(x, W, V, W_2) &= (max(0, xW) \odot xV )W_2 \\
    \text{FFN}_{GEGLU}(x, W, V, W_2) &= (GELU(xW) \odot xV )W_2 \\
    \text{FFN}_{SwiGLU}(x, W, V, W_2) &= (Swish_1(xW) \odot xV )W_2 \\
    \end{align}
    $$
  • 可以理解为 \(\mathbf{W}^G,\mathbf{W}^U\) 中包含了偏置项 \(\mathbf{b}\),有些文章/模型中则会将偏置项 \(\mathbf{b}\) 去掉
  • 最常用的是SwiGLU
  • 从形式上看,可以知道相对原始FFN激活函数形式,SwiGLU等改进增加了一个参数矩阵,为了保证原始参数数量不变,原始论文GLU Variants Improve Transformer中提出了一种方法,通过将矩阵设置为如下的大小来保证参数数量相等
    • 原始FFN层参数为(下面 \(d = d_{model}\) 是模型的隐藏层大小,注意,同一层的不同token是共享FFN的):
      $$
      W_1^{d\times d} + W_2^{d\times d}
      $$
    • 使用SwiGLU且对齐参数数量后
      $$
      W^{r\times d} + V^{d\times r} + W_{2}^{r\times d}
      $$
    • 显然,当 \(r=\frac{2}{3}d\) 时,使用 SwiGLU 前后FFN层参数数量相同,都等于 \(2d^2\)
  • 一个疑问:原始的SwiGLU函数会引入两个参数矩阵 \(W,V\),原始的FFN包含两个参数矩阵 \(W_1, W_2\),为什么两者结合以后只剩下 \(\text{FFN}_{SwiGLU}\) 只剩三个参数 \(W,V,W_2\) 呢?
    • 回答:因为两个线性矩阵相乘,可以合并为 \(W = WV\),虽然还叫做 \(W\),但实际上是多了一个矩阵乘进去的,线上训练时也只需要训练这一个矩阵即可

Transformer总结

  • Transformer是一个特征提取能力非常强(超越LSTM)的特征提取器
  • 一些讨论
    • Transformer与CNN没关系,但是Transformer中使用多个 Scaled Dot-Product Attention 来最后拼接的方法(Multi-Head Attention), 就是CNN的多个卷积核的思想
    • Transformer论文原文中提到的残差结构也来源于CNN
    • 无法对位置信息进行很好地建模,这是硬伤。尽管可以引入Position Embedding,但我认为这只是一个缓解方案,并没有根本解决问题。举个例子,用这种纯Attention机制训练一个文本分类模型或者是机器翻译模型,效果应该都还不错,但是用来训练一个序列标注模型(分词、实体识别等),效果就不怎么好了。那为什么在机器翻译任务上好?我觉得原因是机器翻译这个任务并不特别强调语序,因此Position Embedding 所带来的位置信息已经足够了,此外翻译任务的评测指标BLEU也并不特别强调语序
    • Attention如果作为一个和CNN,RNN平级的组件来使用,可能会集成到各自的优点, 而不是”口气”很大的 “Attention is All You Need”

附录:关于 Dropout

  • 在 Transformer 原始论文中,在每个 sub-layer 的输出上使用了 Dropout,即 输出被加到 sub-layer 的输入和 归一化前进行 Dropout,称为 Residual Dropout
  • 同时,原始论文还在 Embedding 和 位置编码的和 上使用了 Dropout(包括 Encoder 和 Decoder)
  • \(P_\text{drop} = 0.1\)

附录:熵、损失和概率的关系图

  • 关键词:entropy curve;loss curve;熵和概率;概率和熵;熵和损失;损失和熵;损失和概率;概率和损失;曲线图;

  • 展示三者关系的代码如下(正确类别分配指定概率(横轴),其余均匀分配剩余概率):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    import numpy as np
    import matplotlib.pyplot as plt

    plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]

    def entropy(prob_dist):
    """计算概率分布的熵"""
    # 避免log(0)的情况
    prob_dist = np.clip(prob_dist, 1e-10, 1.0)
    return -np.sum(prob_dist * np.log(prob_dist))

    def cross_entropy(true_dist, pred_dist):
    """计算两个概率分布之间的交叉熵"""
    # 避免log(0)的情况
    pred_dist = np.clip(pred_dist, 1e-10, 1.0)
    return -np.sum(true_dist * np.log(pred_dist))

    num_classes = 100000 # 分类问题数

    # 创建一个真实分布(one-hot编码,表示第500类为正确类别)
    true_dist = np.zeros(num_classes)
    true_dist[499] = 1.0 # 索引从0开始,第500类

    # 计算真实分布的熵(应该为0,因为是确定的)
    true_entropy = entropy(true_dist)
    print(f"真实分布的熵: {true_entropy:.6f}")

    # 生成一系列预测分布,从非常不准确到非常准确
    num_steps = 100
    accuracies = np.linspace(0.01, 0.99, num_steps)
    entropies = []
    cross_entropies = []

    for acc in accuracies:
    # 创建预测分布:正确类别分配acc的概率,其余均匀分配剩余概率
    pred_dist = np.ones(num_classes) * ((1.0 - acc) / (num_classes - 1))
    pred_dist[499] = acc

    # 计算熵和交叉熵
    entropies.append(entropy(pred_dist))
    cross_entropies.append(cross_entropy(true_dist, pred_dist))

    # 绘制结果
    plt.figure(figsize=(12, 6))

    plt.subplot(1, 2, 1)
    plt.plot(accuracies, entropies, 'b-')
    plt.title('预测分布的熵随准确率的变化')
    plt.xlabel('正确类别的概率')
    plt.ylabel('熵')
    plt.grid(True, alpha=0.3)

    plt.subplot(1, 2, 2)
    plt.plot(accuracies, cross_entropies, 'r-')
    plt.title('交叉熵损失随准确率的变化')
    plt.xlabel('正确类别的概率')
    plt.ylabel('交叉熵损失')
    plt.grid(True, alpha=0.3)

    plt.tight_layout()
    plt.show()

    print("\nExample:")
    example_acc = 0.8
    pred_dist = np.ones(num_classes) * ((1.0 - example_acc) / (num_classes - 1))
    pred_dist[499] = example_acc

    print(f"当正确类别的概率为 {example_acc} 时:")
    print(f"预测分布的熵: {entropy(pred_dist):.6f}")
    print(f"交叉熵损失: {cross_entropy(true_dist, pred_dist):.6f}")
  • 当类别为 1000 时,图像如下

  • 当类别为 10000 时,图像如下

  • 当类别为 100000 时,图像如下

  • 当类别为 150000 时,图像如下

CA——COEC特征

  • 参考: http://d0evi1.com/positionbias/
  • COEC(Click on Expected Click):点击与期望点击的比值

Background

  • 在评价一个广告的质量好坏时,单纯使用广告的点击率作为指标是不可行的
  • 广告的点击率与广告的曝光位置相关【包括slot或position引起的问题】
    • 从position上来讲,越靠前的广告越容易被点击

COEC

  • 为了抵消广告曝光位置对广告的点击率的影响,我们引入期望点击
  • 在计算商家的点击率时,使用点击与期望点击的比值作为商家点击率质量的衡量指标
    $$
    \begin{align}
    COEC = \frac{\sum_{i=1}^N isClick_i}{\sum_{i=1}^N expCTR_i}
    \end{align}
    $$
    • \(isClick_i\) 为0或1,表示真实点击情况
    • \(expCTR_i\) 为广告真实曝光位置的期望点击率,不同slot和position对应的期望点击率不同

COEC特征

  • 在广告相关指标预估模型中,使用COEC作为广告的特征可提升模型的效果
  • 由于COEC的分母上考虑了位置因素,使得COEC更能真实的反应广告实际点击率的真实质量
1…363738…63
Joe Zhou

Joe Zhou

Stay Hungry. Stay Foolish.

630 posts
53 tags
GitHub E-Mail
© 2026 Joe Zhou
Powered by Hexo
|
Theme — NexT.Gemini v5.1.4