深度学习到底在干什么?---关于深度学习的方法论


前言

内容总结于深度学习圣经。
通常我们从事深度学习会有两个方向:一个是以落地到产品的应用为主要目的;一个是以做前沿性的研究,做技术储备为目的。后者比较深奥,大多数公司主要以前者为主。那么问题来了,当我们以应用为目的的时候,我们对深度学习这门课程需要了解到什么程度?仅仅知道存在那些算法以及解释他们为何有效吗?这显然是不够的。

我们要做的是:知道如何针对具体应用挑选一个合适的算法以及如何监控(这与好马配好鞍的道理是一样的),
并能根据实验反馈改进机器学习系统。

通常涉及流程可以参考如下:

确定目标:使用怎样的误差度量,并为此误差度量指定目标值。这些目标和误差度量取决于该应用希望解决的问题;

建立一个端到端的工作流程,包括估计合适的性能度量;

搭建系统,并确定性能瓶颈;

根据具体观察反复进行增量式的改动,如收集数据,调整超参数或者改进算法。

接下来我们描述每个步骤都发生了什么。

确定目标

这里的目标是指我们要做到什么级别的误差度量,这一步很重要。因为对于大多数应用而言,不可能实现零误差。这时候,在我们力求打造最好的服务或者体验的时候就必须给误差指定一个值,这个值越小,付出的代价越高。
如何合理的确定这个误差的目标呢?在学术界,通常我们是根据先前公布的基准结果来估计预期错误率。现实中,一个应用的错误率有必要是安全的,具有成本效益的或吸引消费者的。一旦确定了想要表达的错误率,那么设计将由如何达到这个错误率来指导。

有时候,一种错误可能比另一种错误更加严重。例如,垃圾邮件检测系统的两种错误:将正常邮件归为垃圾邮件;将垃圾邮件归为正常邮件。哪个严重大家一目了然。

因此正确的设置目标性能(误差度量)在我们深度学习的开始阶段非常重要。如果没有明确的目标或者目标方向有偏差,那么我们很难判断机器学习系统上的改动是否有意义。

选择合适的基准模型

确认好目标后,我们需要做的就是选择一个合适的算法作为基准模型。

#选择基准模型的标准根据问题的复杂性
if 项目不需要深度学习,只需要选择几个线性权重即可解决问题
	'统计模型:逻辑回归'

if 项目属于'AI-完全'类,例如对象识别、语音识别、机器翻译等
	'深度学习模型'

#关于深度模型的选择依据
if 项目以固定大小的向量作为输入的监督学习 #含有标签
	'全连接前馈网络'

if 输入已知拓扑结构#输入图像
	'卷积网络'
	#包括(ReLU或者其拓展,Leaky ReLU, PReLU 和 maxout)
	if 输入或者输出一个序列
		'门控循环网络'#LSTM GRU

模型优化方式的选择

确定好基本的算法模型之后,我们还需要选择优化的方法。比如具有衰减学习率以及动量的SGD优化算法(流行的衰减方法有,衰减到固定最低学习率的线性衰减,指数衰减,或者每次发生验证错误停滞时将学习率降低2-10倍,这些不同的方法在不同的问题上表现好坏不一)。
另外一个合理选择是Adam算法。批标准化对优化性能有着显著的影响,特别是对卷积网络和具有sigmoid非线性函数的网络而言。
当样本包含的数据集数量不足时,项目开始应该包含一些温和的正则化。提前终止也被普遍采用。Dropout也是一个容易实现且兼容很多模型和训练算法的出色正则化项。批标准化有时候也能降低泛化误差,此时可以省略Dropout步骤,因为用于标准化变量的统计量估计本身就存在噪声。
如果我们的任务和另一个被广泛研究的任务相似,那么就可以直接利用先前研究中的已知性能良好的模型和算法,这样可以极大的减少我们的设计时间,并取得不错的效果。例如我们常常使用在ImageNet上训练好的卷积网络的特征来解决其他计算机视觉任务。

正所谓它山之石,可以攻玉。就是这个道理。

关于是否使用监督学习的问题:这个问题和特定领域有关。比如自然语言处理,能够大大受益于无监督学习技术,如学习无监督词嵌入。而有些领域,如计算机视觉,则需要应用监督学习。

是否需要收集更多数据

这里需要说明的一点是,提高算法精度最直接有效的办法就是收集更多的数据。

但是收集更多的数据集需要付出的代价是巨大的。

怎么判断是否需要收集更多的数据集?首先,确定训练集上的性能是否可以接受。如果模型在训练集上的性能就很差,学习算法都不能在训练集上学习出良好的模型,那么就没有必要收集更多的数据。反之,可以尝试增加更多的网络层或者每层增加更多的隐藏单元,以增加模型的规模。此外,也可以尝试调整学习率等超参数的措施改进学习算法。如果更大的模型和仔细调试的优化算法效果不佳,那么问题可能源自训练数据的质量。数据可能含太多噪声,或者可能不包含预测输出所需要的正确输入。这意味着我们要重新开始,收集更干净的数据或者收集特征更丰富的数据集。

在决定收集更多的数据时,也需要确定收集多少数据。通常,
加入总数目一小部分样本不会对泛化误差产生显著的影响。因此,
建议在对数尺度上考虑训练集的大小,例如在后续的试验中倍增样本数目。

关于超参数

首先声明一点,超参数和参数是有区别的。在机器学习的上下文中,超参数是在开始学习过程之前设置值的参数,而非通过训练得到的参数数据。通常情况下,需要对超参数进行优化,给学习机选择一组最优的超参数,以提高学习的性能和效果。
下面介绍一下各自超参数对模型容量的影响。
在这里插入图片描述

关于调整超参数,既可以选择手动调整,也可以选择自动调整。具体做法及如何选择,这里不做赘述。但是我们有必要搞清楚他们的区别。这需要读者自行查询。将来有时间,我也会查找相关资料并整理下来。

模型调试策略

当一个机器学习系统效果不好时,通常很难判断效果不好的原因是算法本身,还是算法实现错误。换句话说,机器学习系统很难调试。

在大多数情况下,我们不能提前知道算法的行为。事实上,使用机器学习的整个出发点是,它会发现一些我们自己无法发现的有用行为。如果我们在一个新的分类任务上训练一个神经网络,它达到5%的测试误差,我们无法直接知道这是期望的结果,还是次优的结果。

另一个情况是,大部分机器学习模型有多个自适应的部分。如果一个部分失效,其他部分仍然可以自适应,并获得大致可以接受的性能。例如,假设我们正在训练多层神经网络,其中参数为权重W 和偏置b 。进一步假设,我们单独手动实现了每个参数的梯度下降规则。但是我们犯了一个错误:
b = b − α
其中α αα是学习率。这个错误更新没有使用梯度。它会导致模型的偏置在整个学习中不但变为负值,对于一个学习算法来说显然是错误的。然而只是检查模型输出的话,该错误可能并不是显而易见的。根据输入的分布,权重可能可以自适应的步长负的偏置。
而大部分神经网络的调试策略都是解决这两个难题中的一个或者两个。此时我们可以设计一个测试,来独立检查神经网络实现的各个部分。
一些重要的测试如下所示:

1可视化计算中模型的行为;

2可视化最严重的错误;

3根据训练和测试误误差检测软件;

4拟合极小的数据集;

5比较反向传播导数和数值导数。

总结

通过上述的说明,大家不难发现,仅仅是了解存在哪些算法对于解决实际问题是远远不够的。我们需要知道的是

'是否需要收集更多的数据'
'是否需要增加或者减少模型容量'
'是否需要添加或者删除正则化'
'如何对模型进行优化'
'如何改进模型的近似推断或者调试模型的软件实现'

以上才是我们在解决实际问题时候所要面临的真正挑战。这不仅需要我们对所要使用的模型,所要用的算法有足够的了解,更需要我们大量的实践去练习。