自然语言处理有哪些方向适合独立研究？
泻药。笔者姑且做了几年NLP，最近正好在做NLP和持续学习的融合，也有同学来问我NLP最近有什么热点。这里给一下我自己的2022年哪些方向可以出paper的看法。 照着做就行，三天内确定方向，一周内开始实验。如果学过了直接跳关。 如果你想要快速入门几个新概念，请看博客： Prompt Tuning（提示微调、提示学习） Transfer Learning（迁移学习） Continuous Learning（持续学习） DST（对话状态跟踪） 如果你对精读paper没有概念，或者想通过论文理解上述概念，可以看下面的范例。这一篇是ACL 2022的Continual Prompt Tuning for Dialog State Tracking，里面包含Prompt Tuning, Transfer Learning, Continuous Learning这些基础概念。文章以对话作为task，但你完全可以自己找topic，据我所知，问答、推荐、匹配，用Prompt Tuning都是很有前途的方向。 有人问RNN不用学吗？你想做独立研究发paper，与热点方向无关的底层没必要学。学理解你要做的方向的基础即可。 一个理想的对话系统应该能够在不忘记旧技能的情况下不断学习新技能，从而在其生命周期中适应新的领域或任务。然而，不断训练模型通常会导致众所周知的灾难性遗忘问题。在本文中，我们提出了 Continual Prompt Tuning，这是一个参数高效的框架，不仅可以避免遗忘，还可以实现任务之间的知识转移。为了避免忘记，我们只为每个任务学习和存储一些提示标记的嵌入，同时冻结主干预训练模型。为了实现任务之间的双向知识转移，我们提出了几种技术（持续提示初始化、查询融合和记忆重放）来转移来自先前任务的知识，以及一种记忆引导技术来转移来自后续任务的知识。与最先进的基线相比，大量实验证明了我们提出的对话状态跟踪持续学习方法的有效性和效率。 最近，大多数研究都集中在以离线方式开发特定领域的对话系统，假设数据分布保持不变。然而，这远非现实，因为通常需要部署的对话系统来支持新领域并随着时间的推移不断提供更多服务。因此，对于对话系统而言，高效地不断学习新任务而不忘记旧任务至关重要。 之前关于持续学习的研究（Kirkpatrick 等人，2017 年；Li 和 Hoiem，2018 年）主要集中在解决灾难性遗忘（CF）问题（McCloskey 和 Cohen，1989 年）：当神经模型在一系列任务上进行训练时，新任务可能会严重干扰旧任务。随着任务数量的增加，特别是当模型规模很大时，简单地为每个任务存储一个模型版本以减轻遗忘是令人望而却步的。为了通过低计算和存储开销来减轻灾难性遗忘，最近的方法冻结了主干模型并建议训练权重/特征掩码（Mallya 等人，2018；Geng 等人，2021）或适配器（Madotto 等人， 2021) 独立完成每项任务。然而，上述技术仍然不够高效，并且它们在很大程度上忽略了任务之间的知识转移。 在本文中，我们开发了用于持续学习的提示微调 (Lester et al., 2021)。 我们冻结了主干预训练模型，并为每个任务训练了一些提示标记的嵌入，这对于避免遗忘具有很高的参数效率。 如图 1 中的黄色组件所示，我们将输入与一些可调的特定于任务的提示标记连接起来，然后再将其提供给冻结的预训练模型。 由于这些提示标记只有少量参数（我们实验中预训练模型参数的 0.1%），因此我们可以有效地训练和存储每个任务的提示。 在推理过程中，同一个预训练模型可以通过输入不同的提示来处理不同的任务，便于部署。 与从头开始训练每个任务的提示并在之后修复它的普通方法不同，我们提出了持续提示调整，这是一个能够在任务之间进行知识转移的框架。 我们考虑从前面的任务（向前）和后面的任务（向后）转移知识。 为了实现前向传输，我们提出了几种技术，包括持续提示初始化、查询融合和内存重放（图 1 中的绿色实线箭头）。 为了实现正向反向迁移，我们提出了一种内存引导技术，该技术使用后续任务的数据有选择地更新先前任务的提示（图 1 中的红色虚线箭头）。 我们使用 Schema-Guided Dialog 数据集 (Rastogi et al., 2020) 对对话系统的核心组件对话状态跟踪 (DST) 进行了实验。 该模型不断学习有多个插槽要填充的新服务。 我们将所有槽的描述与输入连接起来，并在每个描述之后插入一个标记标记，将 DST 公式化为一个掩蔽跨度恢复任务，这类似于 T5 的预训练目标（Raffel 等人，2020）。 我们凭经验表明，我们提出的框架在 DST 的持续学习方面有效地优于最先进的基线，并且在计算和存储方面非常有效。 总而言之，我们的主要贡献是： 1. 我们首次开发了针对持续学习的Prompt Tuning，它可以有效地避免遗忘，并且便于部署。 2. 我们研究了几种基于快速调整的前向和后向知识转移技术，进一步提高了持续学习的性能。 3. 我们对连续 DST 的实验证明了我们提出的方法的优越性能和效率。 持续学习 (CL) 研究从数据流中不断获取知识并将其重用于未来学习同时避免遗忘的问题。已经开发了三种 CL 方法。Rehearsal方法存储和重放来自先前任务的一些训练样本（Rebuffi 等人，2017；Lopez-Paz 和 Ranzato，2017）。Regulation方法应用额外的损失来帮助巩固知识（Kirkpatrick 等人，2017；Li 和 Hoiem，2018）。Ensembling方法为新任务引入了特定于任务的参数，并为旧任务冻结了参数以防止遗忘，这是我们的方法所属的（更细化地说，本文提出的冻结法属于Emsembling方法）。以前的Ensembling方法包括动态扩展网络结构 (Rusu et al., 2016)、迭代网络修剪和重新训练 (Mallya and Lazebnik, 2018)、为每个任务单独学习参数掩码 (Mallya et al., 2018) 等. 对于对话系统中的持续学习，已经应用了通用 CL 方法的变体（Lee，2017；Shen 等人，2019；Wu 等人，2019；Mi 等人，2020；Geng 等人，2021）。 AdapterCL (Madotto et al., 2021) 与我们的工作最相关，它冻结了预训练模型并为每个任务独立地学习了一个适配器 (Houlsby et al., 2019)。与AdapterCL相比，我们的方法参数效率更高，并且探索了前向和后向传输的效果。 最近的研究发现，使用文本提示将下游任务转换为语言建模任务是使用预训练语言模型的一种比典型微调更有效的方法（Brown 等人，2020；Schick 和 Schütze，2021）。提示可以手动设计（Petroni 等人，2019 年）或自动生成（Shin 等人，2020 年；Jiang 等人，2020 年；Gao 等人，2021 年）。由于在离散空间中搜索提示是次优的，因此一些作品（Qin 和 Eisner，2021；Liu 等人，2021；Han 等人，2021）结合了硬文本提示和软提示，其嵌入是通过反向传播学习的。莱斯特等人 (2021) 表明，冻结预训练模型并仅调整软提示（称为Prompt Tuning）是参数有效的，并且随着模型大小的增长与微调变得更具竞争力。 提示调整不同于旨在解决多语言嵌入缺陷的嵌入适配器 (Zhu et al., 2021)。嵌入适配器转换所有令牌嵌入，但不影响Transformer层的计算，而提示调整不会更改令牌嵌入，而是将新的可调整提示令牌添加到输入中，用作上下文并影响所有后续转换器层。顾等人 (2021) 和 Vu 等人 (2021) 进一步探索了跨任务的软提示的可转移性。当他们研究一步适应时，我们对持续学习环境中的快速迁移感兴趣。 对话状态跟踪 (DST) 旨在以（槽、值）对的形式捕获用户目标。传统的基于本体的分类方法（Mrkšic et al., 2017; Lee et al., 2019）需要访问所有候选值。为了减轻对本体的依赖并提高对未见值的泛化能力，一些工作从对话上下文中提取值（Xu and Hu，2018；Gao 等人，2019），而另一些工作则直接生成值来处理从对话上下文中丢失值的情况，如（Wu 等人，2019 年；Hosseini-Asl 等人，2020 年）。 基于生成的模型要么一次性生成所有（插槽、值）对（Hosseini-Asl 等人，2020；Madotto 等人，2021），要么分别为每个给定插槽生成价值（Wu 等人，2019）。前者效率更高，但只能预测域内槽并且缺乏可迁移性，而后者可以包含更多关于槽的信息作为查询，例如简短的自然语言描述 (Rastogi et al., 2020)、槽类型信息 (Lin et al., 2021)、可能的值 (Lee et al., 2021) 以及任务定义和约束 (Mi et al., 2022)。我们提出的方法将多个槽描述集成到一个查询中，并一次生成所有值，这在不损失效率的情况下提高了性能。 这一部分我手动敲一下，公式比较多。看完包懂！ 图二：持续 DST 的微调和持续提示调整的插图。 (a) 微调将对话和当前服务的名称作为输入，并调整 T5 以生成槽值对。 (b) 持续提示调整将对话框、由槽描述和标记标记组成的查询以及提示标记提供给冻结的 T5，并调整提示的嵌入以生成查询中所有槽的值。 提出了持续提示初始化、查询融合和内存重放以增强前向传输，而后续服务的数据将用于后向传输。 我们展示了一个示例对话框、服务名称、融合查询和预期输出。 插槽名称和说明以斜体显示，值带有下划线。 请注意，查询中的第二个槽描述属于另一个服务（“银行”），并通过查询融合插入。 持续学习的目标是顺序地学习一个模型，这个模型是一个映射 f：X\times T\rightarrow Y 。其中，X是输入，T是任务，而Y是输出。之所以说是顺序学习，是因为有多个任务（T）。由于每个任务肯定有不同的数据，我们将任务 T_k 的数据表示为 D_k 。我们使用大型预训练模型，但是不进行精调（fine-tune），而是把模型冻结。所谓的“冻结”，其实是对预训练模型进行重新编程（reprogram）。重新编程就是使用 m 个新的软Prompt Token P_k=P^1_kP^2_k...P^m_k 加到文字输入里面，来解决任务 T_k 。注意，我们Tune的是Prompt P_k 的embeddings，而不对预训练的语言模型做任何Tune。由于Prompt的参数比模型的参数小的多（根本不在一个数量级上），Prompt P_k 可以被保存，从而防止被遗忘。 我们将每个服务（也可以理解成API）当成持续学习的DST中的任务，在本文中我们对这两个词不做区别。为了合并承载了信息的槽描述并且减轻decoding过程的负担，我们将描述转换成一个带有masked spans的query，从而将DST转换成一个恢复masked spans的任务（我们在下一节具体讨论如何建模）。为了增强几个任务之间的知识传递，对于前向传递，我们提出了持续提示初始化，query fusion，以及记忆重演（第三节）；对于反向传递，我们探索了一个由记忆引导的技巧（第四节）。 在DST中，我们将每个domain都建模成一个service（task），用 T_k 表示。对于这个task，有一组预先定义好的slot S_k=\{s_1,...,s_{n_k}\} ，而我们的目标就是track这个slot组。这个模型的输入 x 是一个对话，输出 y 是一组slot-value对 \{(s_1,v_1),(s_2,v_2),...,(s_{n_k},v_{n_k})\} 。就跟我们接触到的许多其他NLP任务一样，DST也可以被建模成一个text-to-text的生成任务，相当于输入的是一段对话text，而输出的是一段生成的slot-value pair text。 现在我们定义一个函数 g_k:X\times Y\rightarrow V^*\times V^* ，这个函数是per-task的，也就是每个任务 T_k 都有一个函数 g_k 。其中， V 是vocabulary（最大词汇集合；词汇表）。这个函数执行转换： \tilde{x},\tilde{y}=g_k(x,y) ，将原本的DST输入 (x,y) 转换成模型的Prompt输入 (\tilde{x},\tilde{y}) ，这个 \tilde{x} 是 x 和task name的拼接，而 \tilde{y} 是每个task的全部slot value拼成的序列。这就是传统的DST建模方式，如下图所示。 之前的工作已经证明，在每个slot s_i 前加上一个自然语言描述 d_i 可以提升模型性能。这些工作将对话 x 与每个slot的description d_i 拼接起来，然后独立地decode值 v_i 。然而，当slot很多的时候，分别decode效率非常低。为了解决这个问题，我们将所有的slot description都拼到一起，并且在每个description的后面都插入一个哨兵token，来构造一个附加到输入的query，从而将DST建模成一个能够一次性生成所有slot values的masked spans recovering任务。 我们冻结与训练模型的参数 \theta ，仅仅优化针对每个任务 T_k 的Prompt的参数 \theta_{P_k} 。我们定义损失函数为： L_{\theta_{P_k}}(D_k)=-\sum^{|D_k|}_{j=1}\log{p_\theta(\tilde{y}^k_j|[x^k_j;Q_k;P_k])} 这个损失函数很好理解，本质是在模型参数为 \theta 固定时，给定输入 \tilde{x} ，计算输出为 \tilde{y} 的条件概率，然后去个对数。 持续学习的精髓就是前向传输。在学习完前几个任务后，模型拥有的参数往往可以提升模型学习后面任务的能力。因此，我们提出了三种可以被结合起来的知识前向传输方法。 持续Prompt初始化 想要传输知识，最直觉的想法就是用学到的参数初始化新任务的模型。这里我们提出两种可能的策略： 使用CLInit策略的初始Prompt本质上一直在针对之前所有的任务进行持续训练（有递归的思想），而SelectInit策略则是每次都只考虑最相关的任务，不会收到所选择的任务之后的任务的干扰。这两种策略会在实验部分比较。 我们希望模型能够学习到，根据任何slot description都能生成value的地步。这样的一个通用的skill可以帮助模型在future tasks上获得更好的性能。但是在对当前任务进行训练时，只有一个query由该任务的slot description按固定顺序组成，这可能会阻碍模型学习通用技能。 因此，我们建议通过混合来自当前和先前任务的slot description来增强query，以帮助Prompt更好地理解slot description和value之间的对应关系。这一步本质是一个query增强操作。 对于新的task的每一个样本，我们都使用三个步骤来fuse这个任务的query Q_k 和之前所有任务的query \{Q_j\}_{j<k} ： 仔细思考可以发现，一些原本的slot被丢弃了，而新增的slot被设成了None。 记忆重演（Memory Replay） 已经有研究指出，可以为每个之前的任务存储一些样本，并在训练新任务时replay它们以减轻遗忘。 由于我们的Prompt Tuning框架已经解决了遗忘问题，因此我们专注于这些样本如何使当前任务受益。我们假设，对于每个之前的任务，我们都存储 |M| 个样本（ |M| 是个小数字）。我们用 M_i 表示任务 T_i 的记忆。当一个新任务 T_k 到来时，我们在对话 D_k 上优化 P_k ，同时joint（联合）优化 M_{<k} ，这里 M_{<k}=\bigcup_{i<k}M_i 。由于现在问题变成了一个联合优化问题，loss function变成了原来的loss function乘上一个系数，也即 L_{\theta_{P_k}}(D_k+M_{<k}) 。 如果记忆重演想要和query fusion结合，那么为记忆 M_i 中的样本所设计的query Q_i 也应该与其他的task的queries \{Q_j\}_{j\le k,j\neq i} 进行fuse（包括目前正在进行的第k个task）。注意，通过这种方式，来自其他任务的样本可以被视为 Q_i^{'} 中那些添加的槽的“正”样本，因为这些样本对于那些添加的槽可能没有None值。 虽然在训练完任务 T_k 后立刻固定住它对应的Prompt P_k 确实可以防止遗忘，这种方法同时会防止未来的任务把知识传输给这个刚刚被完成的任务。我们想要探索当一个新任务到来时，是否能够使用之前任务的记忆，将之前任务的性能进一步提高，这称为知识的反向传输。严谨地说，对于每一个之前的任务 T_i (i<k) ，我们想要初始化一个新的Prompt P_i^{(k)} ，并且这个Prompt是在当前的任务数据 D_k 和这个之前的任务的记忆 M_i 上训练的。这种方法称为管制（Regulation）。在训练过程中，我们同步地采样一个 D_k 的batch和一个 M_i 的batch，并且把每个batch的梯度分别标记成 g_{ori} 和 g_{ref} 。我们根据这两个梯度的夹角来决定梯度要更新到什么值。如果夹角小于90度，更新后的梯度等于 g_{ori} ，否则更新后的梯度等于0。这意味着如果记忆的batch上的损失增大了，我们不更新。根据其他研究显示，这种abortion（丢弃）的方法比将 g_{ori} 投影到 g_{ref} 的法平面上有更好的效果。在训练后，如果新的Prompt P_i^{(k)} 的loss比老的Prompt P_i 小或者相等，我们将Prompt更新为新的。 在本文中，我们首次为持续学习开发了快速调整。 我们提出了Continual Prompt Tuning，这是一个参数效率很高的框架，可以避免遗忘并实现任务之间的前向/后向知识转移。 对于前向传输，我们探索了持续提示初始化、查询融合和内存重放技术。 对于反向传输，我们设计了一种记忆引导技术。 与最先进的基线相比，DST 持续学习的大量实验证明了我们提出的方法的有效性和效率。 我们的方法和发现将促进未来更多的研究，以构建更具可扩展性、适应性强的面向任务的对话系统。 