• [其他] AdversarialTraining自对抗训练
    这是一种新的数据扩充技术,该技术分前后两个阶段进行。在第一阶段,神经网络改变原始图像而不是网络权值。通过这种方式,神经网络对自身执行一种对抗性攻击,改变原始图像,从而造成图像上没有目标的假象。在第二阶段,训练神经网络对修改后的图像进行正常的目标检测。CmBN表示CBN的修改版本,如下图所示,定义为跨微批量标准化(CmBN)。这仅收集单个批中的小批之间的统计信息。
  • [其他] 分享对话式人工智能(1)
    在对话式人工智能(ConvAI)领域,我更偏爱面向目标的系统,因为知识图谱和结构化数据自然而然地扩展了它们的能力。首先,Campagna 等人在论文「Zero-Shot Transfer Learning with Synthesized Data for Multi-Domain Dialogue State Tracking」(https://www.aclweb.org/anthology/2020.acl-main.12.pdf)中提出了一种合成面向目标的对话作为附加训练数据的方法,用于对话状态跟踪(DST)任务。作者创建了一个定义基本状态、动作和转移函数的抽象模型(也可以将其称之为本体)。它的贡献在于:(1)该模型可以应用于各种领域,如餐厅预订或训练带有任意空槽和值的连接搜索;(2)合成的数据允许在你在有监督数据十分有限的域内进行零样本迁移;(3)事实上,实验表明,(在真实的 MultiWoz 2.1 测试中)仅使用合成的语料库进行训练和评估的准确性达到使用原始完整训练集时的约 2/3。我相信在研发特定领域的对话系统或已标注训练数据十分有限时,该方法可以作为一个通用的数据增强方法。
  • [其他] 深度学习项目代码阅读建议
       搞深度学习的人,两大必备日常除了读论文之外就是读代码。读论文笔者在第4问的时候讲了阅读路线,但如何读用什么技巧读每个人都有不同的见解,这里不多说。读代码跟读论文、读书多少有相似的地方,毕竟都是读的性质。但话又说回来,读代码又跟读paper读书大有不同,代码是一种将论文中的模型和算法进行实现的过程,是一种需要你思维时刻在线的过程。又因为我们读的是深度学习项目代码,不是像Linux内核代码那样的鸿篇巨制,所以在代码性质上多少又有些不同。      笔者这里说的一份深度学习项目代码,小到几百行的测试demo,大到成千万行的开源项目,读起来方法肯定各有不同。如下图Mask R-CNN项目代码和PyTorch源码的对比:  可以看到,Mask R-CNN作为一个经典的实例分割框架,其代码量可以说是中规中矩,3k的代码量在我们读完论文后集中花几天时间差不多可以过一遍。但PyTorch的源码对大多数人而言就不那么友善了,750k的代码量,而且底层的C++代码占到整个项目中的一半之多,作为深度学习研究而言,堪称巨无霸级别了。这样的代码量,就像初学者拿到一本PRML,往往投入巨大精力后不了了之。所以,对于这两种类型的项目代码,阅读方法肯定会有所区别。      因为我们读代码的目的、场景和对象不尽相同,下面笔者从三个方面来和大家探讨如何阅读一份深度学习项目代码。      首先读代码的一些通用方法。这一点而言不局限于深度学习项目代码,任何项目、任何语言的代码阅读都适用。我们日常读代码无非是两个工具,一是将代码下载到本地,打开IDLE,在IDLE里安静的阅读: 第二个就是直接在GitHub的web端直接阅读,但GitHub没有像编辑器那样在左侧设置阅读目录,每次进入一个代码文件就必须退出来才能进入另一个文件,用户体验极差。当然了,这都不是事。chrome给我们提供了Octotree这样的辅助阅读插件,直接在chrome扩展程序里搜索安装即可。   安装后我们就可以直接在web端就有IDLE读代码的体验: 可以看到在页面左侧有一个类似IDLE的目录栏,大大方便了我们查看和阅读项目代码。这是通用方法中的工具层面,我们再来看一些基本的阅读规矩。有了IDLE和Octotree工具,我们第一点一定是仔细看代码目录,对整个项目代码结构和分布有一个整体的认识,对于深度学习而言通常目录中各个模块相对比较固定,比如是models目录下放着模型搭建和训练的代码,conifg目录下放着模型的一些配置文件,data目录下放着项目所使用的数据信息等等。如下面语义分割项目的目录结构: 对深度学习项目代码的结构熟络之后,读的多了自然就会轻车熟路起来,后面阅读效率也就提高了。            通用方法的第二个是快速找到readme文档。通常来说,根目录下的readme文档包含了这份代码的使用方法,里面有可以让你快速了解这个项目的关键信息。一般来说,开源项目的readme里作者都会写明如何使用代码和进行部署。下图是DenseNet的readme文档:  对于大型项目,可能每一个子目录下都有readme文档,这都是我们需要仔细阅读的部分,作者把关键信息都放里面了。所以不管这样,第一时间读找到readme进行阅读是你了解该项目的必备步骤和通用方法。           第三个通用方法就是具体如何读的问题。就是我们得确定一个阅读主线。这一点是针对于深度学习项目代码的通用方法,对于一个深度学习项目,我们一般想要了解的最关键点无非就是数据、模型和如何训练等几个方面。如果你想快速看看这个开源项目的测试效果,直接读readme看使用方法即可。如果这个项目作者提出了一个新的模型框架,比如说bert,你想了解它的模型框架细节,直接定位到models目录下的带有model字眼的.py文件开始读。或者是你想看这个项目是如何训练的,都用了哪些训练的tricks,它的参数初始化是如何做的,batchsize用的多大,训练过程中学习率如何调整的等等,那么话不多说,直接定位到带train的.py文件即可。如下图faster-rcnn的3个训练文件。   根据目的不管是model还是train的主线,在阅读过程中一定会涉及到其他分支,比如说数据和配置等其他分支线。在主线阅读过程中不断完善对分支的理解,久而久之,一个完整的项目就会被你消化了。      以上说的是深度学习项目代码阅读的一些通用方法。下面再具体讲两个场景的代码阅读。毕竟大家做事讲究目的性,往往带有较强的目的性去做某事效率一般会特别高。      第一个场景是在大家做研究做项目时遇到问题时。不知道这个问题如何解决,直接谷歌又找不到好合适的方法的时候。这时候我们可能会寄希望于在GitHub上搜罗一番。比如说我们想要知道对于极度数据不平衡时如何给损失函数加权重的方法,再比如对于多标签问题进行模型预测时如何找到最佳分类阈值等等。这些问题都是我们在做实际项目时都可能会碰上的,在这种情况下若是能在GitHub上找到类似场景的处理方法,相信你会瞬间来了精神。     下述基于keras的CNN多标签分类项目对于多标签分类阈值寻优使用了matthews_corrcoef来确定最佳分类预测阈值。至于什么是matthews_corrcoef,这些都是你在解决问题过程中需要学习和吸收的地方。总之,带有目的性的读某个项目的代码往往是只读某个block甚至是某几个关键行,数量不在多,在于能够解决你的问题。     第二个场景就是为了自我个人精进的读代码。所谓个人精进,就是有大量可支配的个人学习和研究时间,高度的自律性和超强的学习力的人进行能力跃迁的关键所在。笔者虽然平时偶尔会有去GitHub读一些代码,但说要达到个人精进的level,还远远不够。比如说前面的PyTorch 750k的源码,这么大的代码量,阅读策略一定是分治思想,分散包围和各个击破。把项目进行分解,设定阅读计划和目标,在超强的执行力下还是有可能完成的。这不是普通人干的事,但我相信能在深度学习领域精进的人都不会是普通人。   诚然,无论是读教材、读论文还是本篇所说的读代码,这些本身都是一个个人学习能力提升和知识汲取的过程。对于从事深度学习工作的我们而言,arxiv上的论文和GitHub上的代码都无穷尽,关键在于保持学习的劲头,做一名终身学习者。
  • [其他] 深度学习之参数初始化策略
    有些优化算法本质上是非迭代的,只是求解一个解点。有些其它优化算法本质上是迭代的,但是应用于这一类的优化问题时,能在可接受的时间内收敛到可接受的解,并且与初始值无关。深度学习训练算法通常没有这两种奢侈的性质。深度学习模型的训练算法通常是迭代的,因此要求使用者指定一些开始迭代的初始点。此外,训练深度模型是一个足够困难的问题,以致于大多数算法都很大程度地受到初始化选择的影响。初始点能够决定算法是否收敛,有些初始点十分不稳定,使得该算法会遭遇数值困难,并完全失败。当学习收敛时,初始点可以决定学习收敛得多块,以及是否收敛到一个代价高或低的点。此外,差不多代价的点可以具有区别极大的泛化误差,初始点也可以影响泛化。
  • [其他] 深度学习之动量举例
    为什么要特别使用 −v(t) 和粘性阻力呢?部分原因是因为 −v(t) 在数学上的便利——速度的整数幂很容易处理。然而,其他物理系统具有基于速度的其他整数幂的其他类型的阻力。例如,颗粒通过空气时会受到正比于速度平方的湍流阻力,而颗粒沿着地面移动时会受到恒定大小的摩擦力。这些选择都不合适。湍流阻力,正比于速度的平方,在速度很小时会很弱。不够强到使粒子停下来。非零值初始速度的粒子仅受到湍流阻力,会从初始位置永远地移动下去,和初始位置的距离大概正比于O(log t)。因此我们必须使用速度较低幂次的力。如果幂次为零,相当于干摩擦,那么力太强了。当代价函数的梯度表示的力很小但非零时,由于摩擦导致的恒力会使得粒子在达到局部极小点之前就停下来。粘性阻力避免了这两个问题——它足够弱,可以使梯度引起的运动直到达到最小,但又足够强,使得坡度不够时可以阻止运动。这解释了动量更新的基本形式,但具体什么是力呢?力正比于代价函数的负梯度 −∇θJ(θ)。该力推动粒子沿着代价函数表面下坡的方向移动。梯度下降算法基于每个梯度简单地更新一步,而使用动量算法的牛顿方案则使用该力改变粒子的速度。我们可以将粒子视作在冰面上滑行的冰球。每当它沿着表面最陡的部分下降时,它会累积继续在该方向上滑行的速度,直到其开始向上滑动为止。
  • [其他] 深度学习之动量
    虽然随机梯度下降仍然是非常受欢迎的优化方法,但其学习过程有时会很慢。动量方法 (Polyak, 1964) 旨在加速学习,特别是处理高曲率、小但一致的梯度,或是带噪声的梯度。动量算法积累了之前梯度指数级衰减的移动平均,并且继续沿该方向移动。动量的效果。动量的主要目的是解决两个问题:Hessian 矩阵的病态条件和随机梯度的方差。我们通过此图说明动量如何克服这两个问题的第一个。等高线描绘了一个二次损失函数(具有病态条件的 Hessian 矩阵)。横跨轮廓的红色路径表示动量学习规则所遵循的路径,它使该函数最小化。我们在该路径的每个步骤画一个箭头,表示梯度下降将在该点采取的步骤。我们可以看到,一个病态条件的二次目标函数看起来像一个长而窄的山谷或具有陡峭边的峡谷。动量正确地纵向穿过峡谷,而普通的梯度步骤则会浪费时间在峡谷的窄轴上来回移动。比较图 4.6 ,它也显示了没有动量的梯度下降的行为。
  • [其他] 深度学习之学习率
    学习率可通过试验和误差来选取,通常最好的选择方法是监测目标函数值随时间变化的学习曲线。与其说是科学,这更像是一门艺术,我们应该谨慎地参考关于这个问题的大部分指导。使用线性策略时,需要选择的参数为 ϵ0,ϵτ,τ。通常 τ 被设为需要反复遍历训练集几百次的迭代次数。通常 ϵτ 应设为大约 ϵ0 的 1%。主要问题是如何设置 ϵ0。若 ϵ0 太大,学习曲线将会剧烈振荡,代价函数值通常会明显增加。温和的振荡是良好的,容易在训练随机代价函数(例如使用 Dropout 的代价函数)时出现。如果学习率太小,那么学习过程会很缓慢。如果初始学习率太低,那么学习可能会卡在一个相当高的代价值。通常,就总训练时间和最终代价值而言,最优初始学习率的效果会好于大约迭代 100 次左右后最佳的效果。因此,通常最好是检测最早的几轮迭代,选择一个比在效果上表现最佳的学习率更大的学习率,但又不能太大导致严重的震荡。
  • [其他] 深度学习之小更新
    梯度下降和基本上所有的可以有效训练神经网络的学习算法,都是基于局部较也许能计算目标函数的一些性质,如近似的有偏梯度或正确方向估计的方差。在这些情况下,难以确定局部下降能否定义通向有效解的足够短的路径,但我们并不能真的遵循局部下降的路径。目标函数可能有诸如病态条件或不连续梯度的问题,使得梯度为目标函数提供较好近似的区间非常小。在这些情况下,步长为 ϵ 的局部下降可能定义了到达解的合理的短路经,但是我们只能计算步长为 δ ≪ ϵ 的局部下降方向。在这些情况下,局部下降或许能定义通向解的路径,但是该路径包含很多次更新,因此遵循该路径会带来很高的计算代价。有时,比如说当目标函数有一个宽而平的区域,或是我们试图寻求精确的临界点(通常来说后一种情况只发生于显式求解临界点的方法,如牛顿法)时,局部信息不能为我们提供任何指导。在这些情况下,局部下降完全无法定义通向解的路径。在其他情况下,局部移动可能太过贪心,朝着下坡方向移动,却和所有可行解南辕北辙,如图8.4所示,或者是用舍近求远的方法来求解问题,目前,我们还不了解这些问题中的哪一个与神经网络优化中的难点最相关,这是研究领域的热点方向。小更新。之前的小节主要集中于为何这些局部范围更新的正确方向难以计算。
  • [其他] 深度学习之局部和全局结构间的弱对应
    迄今为止,我们讨论的许多问题都是关于损失函数在单个点的性质——若 J(θ)是当前点 θ 的病态条件,或者 θ 在悬崖中,或者 θ 是一个下降方向不明显的鞍点,那么会很难更新当前步。如果该方向在局部改进很大,但并没有指向代价低得多的遥远区域,那么我们有可能在单点处克服以上所有困难,但仍然表现不佳。大多数优化研究的难点集中于训练是否找到了全局最小点、局部极小点或是鞍点,但在实践中神经网络不会到达任何一种临界点。图 8.1 表明神经网络通常不会到达梯度很小的区域。甚至,这些临界点不一定存在。例如,损失函数 − log p(y | x; θ)可以没有全局最小点,而是当随着训练模型逐渐稳定后,渐近地收敛于某个值。对于具有离散的 y 和 softmax 分布 p(y | x) 的分类器而言,若模型能够正确分类训练集上的每个样本,则负对数似然可以无限趋近但不会等于零。同样地,实值模型p(y | x) = N (y; f(θ), β−1) 的负对数似然会趋向于负无穷——如果 f(θ) 能够正确预测所有训练集中的目标 y,学习算法会无限制地增加 β。给出了一个失败的例子,即使没有局部极小值和鞍点,该例还是不能从局部优化中找到一个良好的代价函数值。
  • [其他] 深度学习之非精度梯度
    大多数优化算法的先决条件都是我们知道精确的梯度或是Hessian 矩阵。在实践中,通常这些量会有噪声,甚至是有偏的估计。几乎每一个深度学习算法都需要基于采样的估计,至少使用训练样本的小批量来计算梯度。在其他情况,我们希望最小化的目标函数实际上是难以处理的。当目标函数不可解时,通常其梯度也是难以处理的。在这种情况下,我们只能近似梯度。这些问题主要出现在第三部分中更高级的模型中。例如,对比散度是用来近似玻尔兹曼机中难以处理的对数似然梯度的一种技术。各种神经网络优化算法的设计都考虑到了梯度估计的缺陷。我们可以选择比真实损失函数更容易估计的代理损失函数来避免这个问题。
  • [其他] 深度学习之悬崖和梯度爆炸
    多层神经网络通常存在像悬崖一样的斜率较大区域,如图8.3所示。这是由于几个较大的权重相乘导致的。遇到斜率极大的悬崖结构时,梯度更新会很大程度地改变参数值,通常会完全跳过这类悬崖结构。不管我们是从上还是从下接近悬崖,情况都很糟糕,但幸运的是我们可以用使用介绍的启发式梯度截断(gradient clipping)来避免其严重的后果。其基本想法源自梯度并没有指明最佳步长,只说明了在无限小区域内的最佳方向。当传统的梯度下降算法提议更新很大一步时,启发式梯度截断会干涉来减小步长,从而使其不太可能走出梯度近似为最陡下降方向的悬崖区域。悬崖结构在循环神经网络的代价函数中很常见,因为这类模型会涉及到多个因子的相乘,其中每个因子对应一个时间步。因此,长期时间序列会产生大量相乘。
  • [其他] 深度学习之梯度下降
    对于牛顿法而言,鞍点显然是一个问题。梯度下降旨在朝“下坡”移动,而非明确寻求临界点。而牛顿法的目标是寻求梯度为零的点。如果没有适当的修改,牛顿法就会跳进一个鞍点。高维空间中鞍点的激增或许解释了在神经网络训练中为什么二阶方法无法成功取代梯度下降。Dauphin et al. (2014) 介绍了二阶优化的无鞍牛顿法(saddle-free Newton method),并表明和传统算法相比有显著改进。二阶方法仍然难以扩展到大型神经网络,但是如果这类无鞍算法能够扩展的话,还是很有希望的。除了极小值和鞍点,还存在其他梯度为零的点。例如从优化的角度看与鞍点很相似的极大值,很多算法不会被吸引到极大值,除了未经修改的牛顿法。和极小值一样,许多种类的随机函数的极大值在高维空间中也是指数级稀少。
  • [其他] 深度学习之鞍点激增
    鞍点激增对于训练算法来说有哪些影响呢?对于只使用梯度信息的一阶优化算法而言,目前情况还不清楚。鞍点附近的梯度通常会非常小。另一方面,实验中梯度下降似乎可以在许多情况下逃离鞍点。Goodfellow et al. (2015) 可视化了最新神经网络的几个学习轨迹,给了一个例子。这些可视化显示,在突出的鞍点附近,代价函数都是平坦的,权重都为零。但是他们也展示了梯度下降轨迹能够迅速逸出该区间。Goodfellow et al. (2015) 也主张,应该可以通过分析来表明连续时间的梯度下降会逃离而不是吸引到鞍点,但对梯度下降更现实的使用场景来说,情况或许会有所不同。
  • [其他] 深度学习之泛化误差
    当然,这个解释只能用于样本没有重复使用的情况。然而,除非训练集特别大,通常最好是多次遍历训练集。当多次遍历数据集更新时,只有第一遍满足泛化误差梯度的无偏估计。但是,额外的遍历更新当然会由于减小训练误差而得到足够的好处,以抵消其带来的训练误差和测试误差间差距的增加。随着数据集的规模迅速增长,超越了计算能力的增速,机器学习应用每个样本只使用一次的情况变得越来越常见,甚至是不完整地使用训练集。在使用一个非常大的训练集时,过拟合不再是问题,而欠拟合和计算效率变成了主要的顾虑。读者也可以参考 Bottou and Bousquet (2008a) 中关于训练样本数目增长时,泛化误差上计算瓶颈影响的讨论。
  • [其他] 深度学习之小批量误差
    很多机器学习上的优化问题都可以分解成并行地计算不同样本上单独的更新。换言之,我们在计算小批量样本 X 上最小化 J(X) 的更新时,同时可以计算其他小批量样本上的更新。这类异步并行分布式方法将在进一步讨论。小批量随机梯度下降的一个有趣动机是,只要没有重复使用样本,它将遵循着真实泛化误差的梯度。很多小批量随机梯度下降方法的实现都会打乱数据顺序一次,然后多次遍历数据来更新参数。第一次遍历时,每个小批量样本都用来计算真实泛化误差的无偏估计。第二次遍历时,估计将会是有偏的,因为它重新抽取了已经用过的样本,而不是从和原先样本相同的数据生成分布中获取新的无偏的样本。我们不难从在线学习的情况中看出随机梯度下降最小化泛化误差的原因。这时样本或者小批量都是从数据流(stream)中抽取出来的。换言之,学习器好像是一个每次看到新样本的人,每个样本 (x, y) 都来自数据生成分布 pdata(x, y),而不是使用大小固定的训练集。这种情况下,样本永远不会重复;每次更新的样本是从分布pdata 中采样获得的无偏样本。
总条数:5195 到第
上滑加载中