构建神经网络前你需要先考虑这10件事

2019-09-04 16:42:01 浏览数 (1)

转载来源

公众号:机器学习算法工程师

阅读本文大概需要 4 分钟。

前言

在阅读了一篇 MNIST 的教程(或 10 篇)并了解了一些 Tensorflow / Keras 最佳实践后,你可能会认为将神经网络应用于预测任务是一种“即插即用”操作。

不幸的是,事情往往并非那么容易。 在实践中,即使是训练一个简单的网络结构(不用没有 GAN 或一些花哨的结构)来对你的数据进行预测,也是一项富有挑战的任务。

因此,当你在代码编辑器敲下 import tensorflow as tf 或引入其他 DL 框架的语句前,可以先了解以下 10 个问题,这将有助于你解决在工程实际中遇到的深度神经网络相关问题。

1. 你的数据量够吗?

当前深度学习技术的流行可以归因于其惊人的大量的参数拟合能力(虽然这种能力目前还不可以完全解释),以至于它可以对从未“见过”的数据进行准确的预测。但是网络的这种能力并非唾手可得,你需要“喂”给网络和其参数数量同等量级的数据来得到所谓的“泛化性”。如果你花费了好几日仅从网络上收集到 5K 多张图片,那么你将面临无法过拟合你的小数据集的挑战。

也许你可以使用“迁移学习”来抢救一下。迁移学习的动机在于使用在某一项任务上训练出来的模型来解决另一项任务(译者注:这两种任务通常具有一定的相似性。例如用人脸检测的网络进行面部属性的识别)。这是因为网络的层次结构表明这两个模型倾向于在网络的第一个“特征提取”层中执行相似的操作。 这表明了“借用”在其他任务上训练的网络参数的想法的可行性。

现有的大量的预训练模型使得迁移学习在计算机视觉这样的任务中是非常易行(译者注:根据我的经验,迁移学习在医疗图像上似乎效果并不明显)。在其他领域也可以采用相同的原则。 实际上是从你训练的另一个网络进行迁移学习。 一般来说,如果你的预测任务非常特殊,且相关数据很少(例如,预测癌症患者的心率),请尝试提出另一个类似但更为常见的任务(例如,预测一般人群的心率) ,数据更容易收集。 首先训练一般模型,然后用原始数据微调网络。

2. 将你的输入数据规范化

输入规范化是一个重要的课题,并且在技术上,它对于保证稳定的学习过程以及更快地收敛到局部最小值至关重要。你需要牢记于心的是,输入规范化要比应用你喜欢的数据缩放变换要多得多。为了不至于对你的数据太陌生,你可以尝试使用这个机会来对你的数据进行适当的探索性分析。这个过程虽然简单,但是它对提高任意一个模型的性能都非常有效。你可以通过查看你的数据中的统计信息来对数据有更深入的见解。你的数据中有异常值吗?你的数据中有错误的标签吗?你数据的类别平衡吗?等等。

3. 网络结构的设置应与你的任务匹配

大多数用于分类任务的 DL 教程适用于单标签的情况(互斥标签 - 只有一个标签可以是真实的),这些教程中的网络大都使用 softmax categorical cross entropy 的配置。这样的配置是如此常见,以至许多人多忽略了这样一个事实,即每个网络都不必以 softmax 层结束。让我们回想一下 softmax 函数的作用,正如它的名字所表示的含义一样,用一种类似平滑最大值的方式处理数值。这也就意味着在大多数情况下,它会将单个类别“标记”为具有最高概率的类别。在两种常见情况下,这种行为可能很糟糕:多标签分类(你希望允许多个类获得高概率),当你将预测的数据不一定属于之前的任何一个类别(在这种情况下,softmax 将给出很高的概率,因为它只查看带预测类与其他类别相比的可能性)。在这些情况下的替代方案是使用 sigmoid(按单独的类别计算)以获得最终层的激活函数,同时使用二元交叉熵作为损失函数。

4. 逐渐提升模型的容量

微调网络超参数这一不可避免的过程可能会让你后悔选择深度学习作为你项目的解决方案。。 “超参数”是用于控制学习算法行为的一组设置的通用术语。在 DL 中,超参数包括模型的深度和宽度,正则化的量,学习率以及许多其他用于训练网络的参数。 超参数的问题在于它们是参数,你无法从训练集中学习它们(译者注:目前 AutoML 之类的研究就是为了解决超参数的调参问题)。 这通常使训练过程变得繁琐,因为最佳值的搜索空间可能很大,并且每次迭代都需要很长时间。 我可以给出的一个策略,使这种超参数的搜索不那么可怕。从最小的合理网络(深度和宽度都很小)开始,只有在需要时才逐渐提升模型的容量。根据经验,对于每个架构,我首先尝试适应我的数据的一小部分(比如说 10%),然后是我的整个数据。如果我无法将数据与我的网络匹配(即,在给定足够的训练时间的情况下达到零训练误差),则意味着我必须增加容量 - 我使用一些启发式选择来扩大网络的宽度或深度,然后重复。这种方法背后的想法是 Occam 的剃刀原则,这对你以后任务中的过拟合问题很有帮助。

5. 使用正确的数据增强类型

许多人错误地认为数据增加是“获取更多数据”的一种手段。实际上,数据增加应该被认为是规则化的一种形式 ,一种向模型引入正确类型的不变性的方法。 让我们这样想:当你使用大量的 epoch 训练模型时,你本质上就是在多次遍历整个训练集。 执行数据增强意味着每次向模型展示训练数据时,都会以略微增强的方式显示它。 你应该使用此方法来告诉网络你不关心的各种排列,例如,那些可能会大大改变图像的像素表示但不影响标签的排列。 如果图像模糊,您是否希望网络识别图像? 如果它们顺时针旋转 90 度? 如果它们是镜像的?根据你对任务的了解来选择数据增强的类型。

6. 回归或是分类

分类和回归任务间的区别非常明确:如果输出变量采用类别标签,那么你应该解决分类任务,如果需要得到连续的值,则应该解决回归任务。对吗?好吧,这这么说不能算错。事实上,许多人报告称,在连续数值的预测任务中,通过先执行分类任务(例如,将[0,10]分成10个不同的类:[0,1),[1,2),……),再使用回归模型进行微调预测连续值可以获得的更好结果。这本身并不是一个问题,而是一个重要的提醒:DL 仍然是一个经验主义比固有的理论主义更有效的领域。这意味着,只要有多种方法可以解决你的任务(大多数情况下,请考虑一下),你绝对应该考虑尝试多个选项。你可能会感到惊喜,即使训练结果糟糕,你仍可以获得更多经验。

7. 考虑正确的损失函数

你是否考虑过,为什么你想要使用“非标准”损失函数?它实际上比你想象的要常见得多,尽管它在教程中经常被忽略。一个经典的例子是当你处理一个不平衡的类别场景时(如果你在第二步进行了探索性的数据分析你就会发现类别的不平衡),比如有的类别它的标签数目特别多,这会出现问题。如果你没有考虑到类别不平衡问题,你可能会发现自己的网络适合大多数类,但对少数类的表现非常糟糕。解决这个问题的一个简单方法是明确地“告诉”网络更加重视少数群体中的训练数据,加大该类数据训练时错误权重。这基本上相当于对少数群体进行过度抽样。 这种做法在 ML 中的很常见,同样在 DL 中也非常有用,而且说实话,我总是惊讶于它能够提高实际应用程序的准确性。更高级的程序员可以通过将不同的权重不仅放在不同的类别上,还可以放在不同类型的错误上,将加权损失函数传递到到下一个层级,以平衡目标的召回精度。有时候我们需要创造力。

8. 模型评估

另一件经常被忽视的事情是,评估指标和用于优化过程的损失函数不同。 “正确”的业务流程应该是首先考虑最合适的评价标准来评估算法的性能。例如,这是将用于选择最佳超参数集的度量标准,然后才会弄清楚最合适的损失函数是什么。在许多场景下,出于数字或计算上的原因,你最终会使用不同的损失函数。 例如,你可能正在进行时间序列预测任务,你选择的度量标准是您的预测与实际标签间的皮尔森相关性,但是使用 MSE 作为代替,因为针对小批量的皮尔森优化是一致的。 因此,记住这一点:使用(甚至非常推荐!)不同的指标来训练和评估模型。

9. 阅读文献

是否有一些问题是正在着手处理而我还未提及的?你极有可能不是第一个遇到这个问题的人,不要尝试去造轮子!即使是一个简单的实验也会耗费你的时间,你应该去借鉴其他人解决该问题的方案。我的建议就是不要害怕实践,并在网上(或 arxiv)搜索与你正在考虑的问题相关的文献。从长远来看,这将节省你的时间,即使你不混迹在学术界,也可以对新的 idea 开放包容。

10. 得到乐趣

开个玩笑啦~其实我只有 9 件事要告诉你,10 只是为了和《10 Things I Hate About You (1999)》这部喜剧呼应一下(译者注:Gal Yona这位小哥还蛮有幽默感的)。欢迎大家在留言区踊跃发言,分享你的想法。

与作者交流

代码语言:javascript复制
github:https://github.com/keloli
blog:https://www.jianshu.com/u/d055ee434e59

0 人点赞