点击上方,选择星标,每天给你送干货!


来自:AI部落联盟

上一篇收藏|2021年浅谈多任务学习文章对“多任务学习”(Multi-Task Learning,以下简称MTL)的概念、优势、改进方向进行了全面的介绍,并提到MTL一个重要的改进方向:优化算法的改进。在阅读NeurIPS2020一篇关于多任务学习优化算法改进的文章(PCGrad)后,突然想到:如果回顾一下深度学习基本优化算法改进历史,是否会对MTL优化算法的改进有启发呢?于是便记录一下笔者对优化算法改进的理解以及多任务学习优化算法的脑爆改进

本文包括以下几部分内容:

  1. 神经网络参数优化的基本背景

  2. “时间域”里的优化算法(SGD/SGDM/AdamGrad/Adam等)进化史

  3. “空间域“里的多任务学习优化算法改进PCGrad

  4. “时空“里的MTL优化算法改进狂想曲

1. 神经网络参数优化的基本背景

假设输入为  (特征),   (标签);神经网络的参数为  ;那么神经网络的输出  可以简单表示为:

一开始神经网络的参数  是随机的,那么  也是随机的。为了让  尽可能接近  ,我们需要不断优化  。

如何优化?

我们定义一个优化目标  简写为  ,来表示预测与标签之间的差异,比如我们可以简单使用  来表示标签和预测结果之间的差异。我们希望可以调整  来让  和  尽可能的接近。于是就有了基本的优化公式:

其中  为学习率Learning Rate;   为目标函数对  的梯度(Gradient) 。  的具体求解方法(包括链式法则)不在本文范畴,现在假设求得  。

代表第  个任务的权重,一般来说可以直接让  ;并且当  的时候,退化为单任务学习。

注意上面式子的  严格来说是多任务学习里共享的参数  而不是所有参数。

为了方便讲述,下文统一将  或者  称为 梯度 。神经网络根据以上公式,按照batch计算梯度并开始迭代更新参数  。

于是对于第  次更新:  各类优化算法所重点研究的便是:如何优化  的计算使得  的调整能够让目标函数  有更大的概率,更快的速度到达最优(最小)点。

2.  “时间域”里的优化算法(SGD->Adam)进化

本文希望从“时间域“的角度来观察SGD到Adam的进化历史。“时间域”宽泛的指按时间  或者说按epoch不断更新神经网络参数。

参数更新流程:

神经网络参数  更新一般按照以下步骤进行,对于第  个epoch而言:

1.  计算第目标函数在  时刻对神经网络参数  的梯度:  。

2. 根据  时刻前后的梯度  来优化  时刻的梯度 得到   。

3. 将优化后的  乘上学习率  得到  。

4. 更新梯度:  。

那我们根据以上步骤概括一下“时间域”里的优化算法改进。

SGD

最简单的版本,第2个步骤仅仅使用  ,直接使用当前梯度对参数进行更新。

SGD以后的优化引入了一阶动量和二阶动量的概念。具体为:

SGD Momentum

引入一阶动量的概念,不仅考虑当前时刻的  还考虑了  时刻以前的的梯度,对于历史的梯度使用方式(指数滑动平均)如下:

指数滑动平均得到的  约等于过去  时刻内的平均梯度。使用历史的梯度信息对当前时刻梯度进行平滑之后,一定程度上比只使用当前时刻或者只使用全部历史的梯度信息更好。

优于别人,并不高贵, 真正的高贵应该是 优于过去的自己。

海明威

SGD Nesterov Accerleration

优化点在于步骤1,改变为  ,意思是:不使用当前时刻的梯度,而是假设参数先更新一步,再算出来一个未来的梯度,然后再进行步骤2,并结合以前的历史梯度信息来更新梯度。这也是步骤2里面有一个  的原因。

优于别人,并不高贵, 真正的高贵应该是 优于过去的自己,更要优于可见未来的自己!

多多笔记

AdaGrad

优化点在步骤1,不仅考虑参数的历史的梯度信息(SGD Momentum),还考虑历史梯度出现频繁程度(二阶动量)  ,一个参数的梯度在历史上出现的次数越多  越大。最终  。在  时刻以前出现次数约多,则梯度小,出现次数少的参数,在  时刻的梯度就大一点。

AdaDelta/RMSProp

优化点在步骤2,把时间窗口,滑动平均的概念融合到  上,  ,避免二阶动量一直相加越来越大。

Adam

既考虑一阶动量,也考虑二阶动量:

Nadam

把SGD Nesterov Accerleration再结合Adam就是Nadam了。

到目前为止不难看出,整个经典深度学习优化算法的进化历史,都是围绕“时间域”这个维度在进行的:

那么对于多任务学习,怎么样结合当前时刻  的梯度和历史梯度、假象的未来梯度,甚至是当前时刻多任务学习特有的梯度特点,让  时刻的梯度更优秀?下一章先谈谈如何结合多任务学习的特点对当前时刻的梯度进行改善。

3. "空间域“里的多任务学习优化算法改进PCGrad

有了第1部分多任务学习的参数(重点指共享参数)优化公式  ,第2部分在  时刻的参数优化步骤和,我们开始谈一谈PCGrad是如何在“空间域”上对优化算法进行改进的。

将第2部分的优化流程结合上PCGrad:

对于每一个btach,也就是在第  个epoch:

1.  计算目标函数在  时刻对神经网络参数  的梯度:

1.1 先分别计算每个目标函数对参数  的梯度

1.2 然后两两梯度之间看是否存在冲突

1.2.1如果存在冲突,则通过向量正交  映射减缓冲突

1.2.2 如果不存在冲突,不变

1.3 多个任务梯度求和得到  时刻参数的梯度

2. 根据  时刻前后的梯度  来优化  时刻的梯度 得到

3. 将优化后的  乘上学习率  得到

4. 更新梯度:

PCGrad特点:

  1. PCGrad的改进位置:步骤1。从“空间”上优化对于当前时刻的梯度  计算。这里的“空间”广泛的指多任务学习对共享参数会有不同方向的梯度(多维梯度向量的方向不一样)。

  2. 改进的出发点是:在  时刻,多任务学习里多个目标对于共享参数  的梯度可能存在冲突。因为存在多个监督信息,那么多个监督信号可能想让共享参数往不同的方向调整。

  3. 具体改进是:将冲突减小,不存在冲突的梯度保持不变。当然论文中还有很多理论分析和证明,这里就不一一描述了。

为了让冲突变小,我们首先需要知道什么是冲突(这个冲突是作者自己定义的),然后想办法将冲突减小。简单来讲,不同任务对于参数的梯度冲突和不冲突的梯度是这个样子的(a和d):

图1 梯度冲突示意图

如图1a,任务  和任务  的梯度存在冲突。在  时刻,这两个任务的梯度在多维空间里指向了不同的方向(且角度大于90度,相当于两个向量合成的新向量的时候会相互抵消一部分,如果一个任务的梯度幅度远大于另一个任务的梯度幅度,那合成向量的方向将会直接变成了大梯度那个任务所要调整的方向了)。那么解决冲突的方式如图1b,c所示,把  往  的正交向量上映射,把  往  上的正交向量上映射。简单理解为:把朝向两个不同方向的向量往各自正交向量上折中一下,大家互相抵消也就小一些了。

结合前面的流程和图示,看到整个流程是不是觉得其实并不难?而且也很符合直觉。这也是笔者分享该方法的原因,但该算法还有改进的地方吗?有的,把该算法结合上“时间域”的改进,也就是下一章:“时空“里的MTL优化算法改进狂想曲,具体说说咱还能做的地方。

另外,看完原作者开源的tensorflow的写法:

https://github.com/tianheyu927/PCGrad/blob/master/PCGrad_tf.py

感觉不太习惯tensorflow的调试,因此本文在这里也分享一种比较容易看懂的pytorch写法方便大家上手:改一改深度学习参数优化过程的命脉--梯度

def PCGrad_backward(net, optimizer,X, y, loss_layer=nn.CrossEntropyLoss()):# net:训练的神经网络# optimizer 优化器比如Adam# X:神经网络d的输入# y:标签# loss_layer 目标函数num_tasks = len(y)  # T 任务数量grads_task = [] #用来保存多个任务的梯度losses = []grad_shapes = [p.shape if p.requires_grad is True else Nonefor group in optimizer.param_groups for p in group['params']] #获取梯度的shapegrad_numel = [p.numel() if p.requires_grad is True else 0for group in optimizer.param_groups for p in group['params']] #获取梯度的参数数量    optimizer.zero_grad() #t时刻优化前将梯度清零    # 针对每个任务先分别计算梯度for i in range(num_tasks):result = net(X)loss = loss_layer(result[i], y[i])losses.append(loss)loss.backward()devices = [p.device for group in optimizer.param_groups for p in group['params']]grad = [p.grad.detach().clone().flatten() if (p.requires_grad is True and p.grad is not None)else None for group in optimizer.param_groups for p in group['params']]# 对于当前任务该参数没有梯度,任务specific的参数,梯度设置为0grads_task.append(torch.cat([g if g is not None else torch.zeros(grad_numel[i], device=devices[i]) for i, g in enumerate(grad)]))optimizer.zero_grad()# 由于我们要在任务间两两配对看梯度是否冲突,先整体shuffle一下random.shuffle(grads_task)# 开始梯度冲突消除grads_task = torch.stack(grads_task, dim=0)  # (T, # of params)proj_grad = grads_task.clone()def _proj_grad(grad_task):for k in range(num_tasks):inner_product = torch.sum(grad_task*grads_task[k])proj_direction = inner_product / (torch.sum(grads_task[k]*grads_task[k])+1e-12)grad_task = grad_task - torch.min(proj_direction, torch.zeros_like(proj_direction)) * grads_task[k]return grad_task# 减缓多个任务对应的梯度冲突并最后合并多个任务对应的梯度。proj_grad = torch.sum(torch.stack(list(map(_proj_grad, list(proj_grad)))), dim=0)  # (of params, )# 根据梯度的shape还原梯度。indices = [0, ] + [v for v in accumulate(grad_numel)]params = [p for group in optimizer.param_groups for p in group['params']]assert len(params) == len(grad_shapes) == len(indices[:-1])#把减缓了冲突d的梯度放回参数中,之后便可以进行进行梯度下降了for param, grad_shape, start_idx, end_idx in zip(params, grad_shapes, indices[:-1], indices[1:]):if grad_shape is not None:param.grad[...] = proj_grad[start_idx:end_idx].view(grad_shape)  # copy proj grad#输出losses 方便查看return losses

完整的例子参考:

https://github.com/wgchang/PCGrad-pytorch-example/blob/master/pcgrad-example.py

4. “时空“里的MTL优化算法改进狂想曲

再次放上基本优化流程+PCGrad:

对于每一个btach,也就是第  个epoch:

1.  计算目标函数在  时刻对神经网络参数  的梯度:

1.1 先分别计算每个目标函数对参数  的梯度

1.2 然后两两梯度之间看是否存在冲突

1.2.1如果存在冲突,则通过向量正交  映射减缓冲突

1.2.2 如果不存在冲突,不变

1.3 多个任务梯度求和得到  时刻参数的梯度

2. 根据  时刻前后的梯度  来优化  时刻的梯度 得到

3. 将优化后的  乘上学习率  得到

4. 更新梯度:

咱再看一下这个PCGrad流程,发现仅仅在第1步计算梯度的时候对冲突进行改善。那结合咱们的SGD-》Adam的改进历史来看看PCGrad还有哪些地方没有可以探讨探讨的(下文为笔者脑爆时间,如果存在不合理不正确指出望读者见谅,也希望读者能一起思考)

咱们结合“时间”“空间“的改进来一波排列组合:

PCGrad Momentum 

引入“梯度冲突”的一阶动量,也就是考虑了最近一段时间的历史梯度信息,看看多任务学习里不同任务对于共享参数在历史梯度里是否一直在发生冲突。如果是?咱们的PCGrad虽然在每个  时刻进行了修正,但“梯度冲突“是否也会累积呢?冲突累积多了是不是还是存在使用PCGrad之前的问题?

PCGrad Nesterov Accerleration

提前预测下一个时刻是否存在“梯度冲突”来帮助一下当前时刻?

AdaPCGrad

不仅仅考虑  时刻以前以及当前的“梯度冲突“,还要考虑“梯度冲突”发生的频繁程度(二阶动量)。如果两个任务之间“梯度冲突”的频率很高,应该如何是好?发生“梯度冲突”的频率低又应当如何?

AdaDelta/RMSProp PCGrad

把时间窗口,滑动平均的概念融合到“梯度冲突”二阶动量中去,看看最近一段时间的“梯度冲突”。

Adam PCGrad

既考虑“梯度冲突”的一阶动量,也要考虑二阶动量。

最后,“梯度冲突”反应的是两个任务之间的不相关性,那么“梯度契合”是不是可以反应两个任务之间的相关性?也可以把上面的流程走一遍,思考一遍。

以上便是笔者对于多任务学习优化算法的一点脑爆想法,由于笔者水平有限,不免有错误之处。欢迎读者朋友们批评指证!如果对您的研究思考有一丝启发,欢迎点赞哦~谢谢

说个正事哈

由于微信平台算法改版,公号内容将不再以时间排序展示,如果大家想第一时间看到我们的推送,强烈建议星标我们和给我们多点点【在看】。星标具体步骤为:

(1)点击页面最上方深度学习自然语言处理”,进入公众号主页。

(2)点击右上角的小点点,在弹出页面点击“设为星标”,就可以啦。

感谢支持,比心

投稿或交流学习,备注:昵称-学校(公司)-方向,进入DL&NLP交流群。

方向有很多:机器学习、深度学习,python,情感分析、意见挖掘、句法分析、机器翻译、人机对话、知识图谱、语音识别等。

记得备注呦

推荐两个专辑给大家:

专辑 | 李宏毅人类语言处理2020笔记

专辑 | NLP论文解读

专辑 | 情感分析


整理不易,还望给个在看!

参考文献:

1. https://ruder.io/optimizing-gradient-descent

2. https://arxiv.org/abs/2001.06782

3. https://zhuanlan.zhihu.com/p/32230623?utm_source=wechat_session&utm_medium=social&utm_oi=758092967545171968&utm_content=first

敢问多任务学习优化算法路在何方?|附代码相关推荐

  1. 多任务学习优化总结 Multi-task learning(附代码)

    目录 一.多重梯度下降multiple gradient descent algorithm (MGDA) 二.Gradient Normalization (GradNorm) 三.Uncertai ...

  2. 智能优化算法:闪电搜索算法-附代码

    智能优化算法:闪电搜索算法-附代码 文章目录 智能优化算法:闪电搜索算法-附代码 1.算法原理 1.1 过渡放电体 1.2 空间放电体 1.3 引导放电体 2.算法结果 3.参考文献 4.Matlab ...

  3. 智能优化算法:布谷鸟搜索算法-附代码

    智能优化算法:布谷鸟搜索算法-附代码 文章目录 智能优化算法:布谷鸟搜索算法-附代码 1.算法原理 2.算法结果 3.参考文献 4.Matlab代码 摘要:谷鸟搜索算法(cuckoo search , ...

  4. NILM-组合优化算法 combinationrial optimization(附代码)

    这里简单介绍以下电荷负载分解实验中的组合优化算法,这里先只贴代码,后面会对其进行相应的解读. 组合优化(CO)这个代码是基于NILMTK这个包开发的,所以先要安装NILMTK这个电荷负载分解包.具体的 ...

  5. 智能优化算法:麻雀搜索算法-附代码

    2020智能优化算法:麻雀搜索算法 文章目录 2020智能优化算法:麻雀搜索算法 1.算法原理 2.算法结果 3.参考文献 4.Matlab代码 5.Python代码 摘要:麻雀搜索算法(Sparro ...

  6. 麻雀优化算法_多种智能优化算法应用案例分享-附代码

    1.智能优化算法应用:基于灰狼算法的Otsu图像多阈值分割 智能优化算法应用:基于灰狼算法的Otsu图像多阈值分割-附代码_Jack旭的博客-CSDN博客​blog.csdn.net 2.智能优化算法 ...

  7. 灰狼优化算法(GWO)附代码

    文章目录 1 算法介绍 2 算法原理 3. 实现步骤 4. MATLAB代码实现GWO算法 4.1 main.m 4.2 运行结果 1 算法介绍 灰狼优化算法(Grey Wolf Optimizer, ...

  8. 智能优化算法:爬行动物搜索算法-附代码

    智能优化算法:爬行动物搜索算法 文章目录 智能优化算法:爬行动物搜索算法 1.算法原理 1.1 初始化 1.2 包围阶段(探索) 1.3 狩猎阶段(开发) 2.实验结果 3.参考文献 4.Matlab ...

  9. Adam 那么棒,为什么还对 SGD 念念不忘?一个框架看懂深度学习优化算法

    作者|Juliuszh 链接 | https://zhuanlan.zhihu.com/juliuszh 本文仅作学术分享,若侵权,请联系后台删文处理 机器学习界有一群炼丹师,他们每天的日常是: 拿来 ...

  10. 深度学习优化算法,Adam优缺点分析

    优化算法 首先我们来回顾一下各类优化算法. 深度学习优化算法经历了 SGD -> SGDM -> NAG ->AdaGrad -> AdaDelta -> Adam -& ...

最新文章

  1. 文本框自动提示_Excel办公小技巧,使用艺术字与文本框,就是那么的简单
  2. ​孙家广院士:大数据软件的机遇与挑战
  3. C strcpy和strcat
  4. [译]用AngularJS构建大型ASP.NET单页应用(二)
  5. 看完这13张图,不得不佩服还是外国人会玩人工智能
  6. python输入的字符串转换为对应的数字类型_Python合集之Python运算符(四)
  7. python和arduino串口通信_利用串行通信实现python与arduino的同步
  8. 蓝牙连接不上车要hfp_如何正确使用车载蓝牙播放器呢?
  9. Maven学习(一)————Maven技术概述
  10. MATLAB图像处理之二值化以及灰度处理
  11. C++ Primer 第二章 学习笔记及习题答案
  12. RHEL6.4 NFS文件共享服务搭建
  13. 国二c语言程序设计技巧,计算机二级C语言考试必看技巧
  14. 那些漂亮的sci论文图一般用什么软件制作的?
  15. 计算流体力学漫谈-1 (可压缩向)
  16. android上下居中,android Spinner:在spinner中垂直居中文本
  17. VBA笔记 退出循环、Sub、Fuction等的Exit语句
  18. 如何重装mac系统,u盘安装苹果macos系统教程
  19. 最佳Icon图标库推荐,收藏等于学会
  20. 管理驾驶舱,老板的数据看板,移动报表,让数据更直观

热门文章

  1. zookeeper相关知识与集群搭建
  2. 洛谷1004方格取数
  3. IOS推送通知的实现步骤
  4. 微软开放技术热烈祝贺开源社成立!
  5. Git中的‘HEAD’是什么?- Git名词解释
  6. SVN教程 -- 基于自己学习记录
  7. java学习日记-基础-列出2~100内的素数
  8. Fragment-传递参数
  9. python对拍程序
  10. ASP.NET MVC3中的路由系统 Routes