30u30 中文导读 / 30 天目录 / 第 18 天

第 18 天 · 输出不是词,而是指向输入的位置

第 4 单元Pointer NetworksOriol Vinyals, Meire Fortunato, Navdeep JaitlyNeurIPS 2015 · 2015
这是导读,不是翻译。先用 10 分钟拿到这篇论文的思想地图,再去读 原论文 →,去原仓库的 18_pointer_networks/ 目录 → 动手写代码。
给孩子讲:这一天有 10 岁孩子能听懂的讲义,带猜字游戏和动手活动,可打印。打开儿童讲义 → · PDF 简体 · PDF 繁體

一句话

论文把注意力权重直接当作输出分布:解码器每一步从输入元素里选一个,输出的是位置,而不是固定词表里的词。输出类别数因此随输入长度变化。模型从样例中学会近似求解凸包、Delaunay 三角剖分和小规模旅行商问题。

论文讲了什么

问题。标准 seq2seq 的输出是固定词表上的 softmax。很多问题的答案却是"输入里的某几个元素"。例如给 10 个点求凸包,答案是其中几个点的编号。点数一变,可选答案的个数也跟着变。固定大小的输出词表做不到这一点。

方法。作者给第 15 天的加性注意力换了一个用途。原来,注意力权重用来混合编码器状态,得到上下文向量。指针网络不再混合,直接把权重当作输出:

输出类别数等于输入长度。输入 50 个点,每一步就是 50 选 1。输入 500 个点,就是 500 选 1。模型参数量不随输入长度变化,所以同一个模型能处理不同长度的输入。

3 个任务。输入都是平面上的点坐标:

结果。凸包任务上,指针网络远好于带注意力的普通 seq2seq。用最多 50 个点训练的模型,可以直接用于 500 个点的输入。这时完全正确的比例很低,但预测的凸包覆盖了真实凸包的绝大部分面积。TSP 任务上,城市数不超过 20 时,模型给出的环路长度接近最优解。城市数超出训练范围后,质量明显下降。论文全程使用监督学习,需要现成的解作为标签。

例子。输入 5 个点 [A, B, C, D, E],其中 B 在其他 4 个点围成的区域内部。理想输出是 [A, C, D, E] 这样按逆时针排列的 4 个下标,B 不出现。解码器第 1 步指向 A,第 2 步指向 C,依此类推,最后输出结束符。

关键概念

指针(Pointer)
解码器每一步在输入位置上的概率分布,取最大值即选中一个输入元素。它复用注意力的打分,但不再做加权求和。
可变输出词表(Variable-Size Output Dictionary)
输出类别数等于当前输入长度,而不是训练前固定的词表大小。这是指针网络能处理不同规模输入的原因。
凸包(Convex Hull)
包住全部点的最小凸多边形。经典算法复杂度为 O(n log n),论文用它测试模型能否从样例中学会几何算法。
旅行商问题(Traveling Salesman Problem)
给定城市坐标,找出访问每个城市一次并回到起点的最短环路。它是 NP 难问题,常作为组合优化的基准。
组合优化(Combinatorial Optimization)
在有限但数量巨大的离散方案中找最优解,例如排序、路径和分配问题。指针网络开启了用神经网络直接输出这类方案的路线。
教师强制(Teacher Forcing)
训练时把标签中上一步的正确答案喂给解码器,而不是模型自己的预测。指针网络喂入的是被指向点的坐标。

历史位置:为什么值得读

第一作者 Vinyals 也是 2014 年 seq2seq 论文的作者之一。seq2seq 解决了"序列到序列",指针网络解决了"输出就是输入的一部分"。几个月后,同一团队发表了第 16 天的 Order Matters,继续处理输入无序的问题。

指针网络的影响分 3 条线:

值得读原文的理由:论文只改了一个小地方,就是把注意力的用途从"读"换成"选"。读懂这个改动,就能理解后来大量"从输入中挑选"的模型。

学前准备

在原仓库怎么学

  1. 读 README.md,看它把指针注意力对应到论文的哪个公式。
  2. 对照 paper_notes.md 读原论文第 2.3 节和第 4 节实验。
  3. 读 implementation.py,先看 PointerAttention,再看 PointerNetwork 怎么在解码循环中调用它。
  4. 做 exercises/ 里的 5 个练习:exercise_01_pointer_attention.py 写指针注意力,exercise_02_masking.py 写掩码防止重复选择,exercise_03_convex_hull.py 生成凸包的指针标签,exercise_04_tsp_cost.py 计算环路总长度,exercise_05_greedy_decoding.py 写贪心解码循环。答案在 exercises/solutions/。
  5. 运行 train_minimal.py,在排序任务上训练,用 --seq_len 改变序列长度,看准确率怎么变化。
  6. 用 visualization.py 画指针分布热力图,检查排序结果。
  7. 用 notebook.ipynb 串一遍,用 CHEATSHEET.md 复习。

今天再看

"从输入里挑选"这个想法今天无处不在:

论文用监督学习,需要现成的最优解,这个限制已被强化学习方法绕开。论文的另一个局限是推广:训练 20 个城市、测试 50 个城市时质量明显下降。这仍是神经组合优化的核心难题。

容易卡住的地方

延伸阅读