你想开始做图像分类,却无从下手。您应该使用哪个预训练网络?您应该如何修改网络以满足您的需要?您的网络应该包含20层还是100层?哪些是最快和最准确的?这些是你在为图像分类选择最好的CNN时会寻找的许多问题。在选择CNN进行图像分类时,有3个非常重要的指标需要优化:准确性、速度和内存消耗。这些指标的性能取决于您对CNN的选择以及您对其所做的任何修改。不同的网络(如VGG、Inception和ResNet等)在这些指标上有不同的权衡。此外,您还可以修改这些网络结构,例如通过削减一些层、添加一些层、在网络内部使用扩张卷积或不同的网络训练技术。本文可作为设计指南,指导针对特定分类任务的CNN设计。特别是,我们将关注3个主要指标:准确性、速度和内存消耗。我们将研究许多不同的分类CNN,并根据这3个指标探索它们的相应属性。我们还研究了对这些基本CNN的可能修改以及它们如何影响这些指标。最后,我们研究了如何针对特定图像分类任务优化设计CNN。网络类型网络类型和这3个指标之间存在明显的权衡。首先,您肯定希望使用Inception或ResNet类型的设计。它们比VGGNet和AlexNet更新,并且在速度和准确性之间提供了更好的权衡(如上图所示)。斯坦福大学的JustinJohnson对其中一些做了很好的基准测试(https://github.com/jcjohnson/cnn-benchmarks)。Inception和ResNet的选择确实是速度和准确率的权衡:为了准确率,使用超深的ResNet;为了提高速度,请使用Inception。使用巧妙的卷积设计来减少运行时间和内存消耗CNN总体设计的最新进展提出了一些很好的替代方案,可以在不损失太多准确性的情况下加速CNN,并减少内存消耗。所有这些方法都可以很容易地集成到上述任何一类卷积神经网络中。MobileNets(https://arxiv.org/pdf/1801.04381??.pdf)使用深度分离卷积大大减少了计算和内存消耗,同时只牺牲了1%到5%的准确率,具体取决于准确率的高低节省的计算量你想得到。XNOR-Net(https://arxiv.org/pdf/1603.05279.pdf)使用二进制卷积,即卷积运算只涉及两个可能的值:0或1。通过这种设计,网络可以具有高度稀疏且易于压缩而不会消耗太多内存。ShuffleNet(https://arxiv.org/pdf/1707.01083.pdf)使用点组卷积和通道随机化来大大降低计算成本,同时保持比MobileNets更高的精度。事实上,他们可以以10倍以上的计算速度达到早期最先进分类CNN的准确性。网络修剪(https://arxiv.org/pdf/1605.06431.pdf)是一种去除CNN的一些权重以减少运行时间和内存消耗的技术,并且希望不会降低准确性。为了保持准确性,移除的部分不应对最终结果产生太大影响。链接的论文显示了使用ResNets可以多么容易地做到这一点。网络的深度更容易:通常添加更多层会以牺牲一些速度和内存为代价来提高准确性。然而,我们已经意识到,这种权衡会受到边际效应的影响,即我们添加的层数越多,添加每一层所带来的准确度增益就越小。激活函数最近关于激活函数的争论很多。然而,一个好的经验法则是从ReLU开始。使用ReLU通常会立即产生一些好的结果。不像ELU、PReLU或LeakyReLU,它们需要一些繁琐的调整。当你确定你的设计使用ReLU可以取得很好的效果时,那么你可以调整其他部分,调整它们的参数,尝试在精度上做最后的提升。内核大小您可能认为使用更大的内核总是会以速度和内存为代价获得最高的精度。然而,情况并非总是如此,因为在研究中多次发现使用更大的内核会使网络难以发散。最好使用较小的内核(例如3×3)。ResNet和VGGNet都非常全面地说明了这一点。正如这两篇论文所示,您还可以使用1×1内核来减少特征数量。DilatedConvolution为了能够使用远离中心的像素,DilatedConvolution在卷积核的权重之间使用空间。这允许网络在不增加参数数量的情况下以指数方式扩展感受野,这意味着根本不会增加内存消耗。空洞卷积已被证明可以提高网络准确性,同时在速度上有一个小的折衷。数据扩充您应该始终进行数据扩充。使用更多数据已被证明可以持续提高性能,甚至达到极限(https://arxiv.org/pdf/1707.02968.pdf)。通过数据扩充,您可以免费获得更多数据。增强的类型取决于您的应用程序。例如,如果你在做一个自动驾驶汽车应用,你可能会在路上遇到汽车、树木和建筑物,所以垂直翻转你的图像是没有意义的。但是,由于天气变化或场景变化,您必然会遇到光照变化,通过光照变化和电平翻转来扩充数据是有意义的。你可以看看这个数据增强库(https://github.com/aleju/imgaug)。训练优化器当你最终想要训练网络时,有几种优化算法可供选择。许多人说SGD在准确性方面会给出最好的结果,根据我的经验,这是事实。然而,调整学习率设置和参数是乏味且具有挑战性的。另一方面,尽管使用自适应学习率(例如Adam、Adagrad或Adadelta)更容易和更快,但您可能无法获得与SGD相同的最佳精度。最好的做法是让优化器遵循与激活函数相同的“风格”:先使用最简单的,看看是否有效,然后再使用更复杂的进行调优。我个人建议从Adam开始,因为根据我的经验,它是最容易使用的:设置一个不太高的学习率,默认情况下通常为0.0001,通常你会得到一些不错的结果。然后,您可以从头开始使用SGD,甚至可以从Adam开始,然后使用SGD进行微调。事实上,本文发现使用Adam,中间切换到SGD,以最简单的方式达到最佳精度。看看论文中的这张图:ClassBalance很多时候你会遇到不平衡的数据,尤其是在现实世界的应用程序中。这是一个简单的真实示例:出于安全原因,您正在训练一个深度网络来预测输入视频中的某人是否持有致命武器。但是在你的训练数据中,你只有50个人拿着武器的视频,和1000个没有拿武器的人的视频!如果你立即使用这些数据来训练你的网络,你的模型肯定会偏向于预测某人没有高偏见。类别不平衡问题可以通过以下方式解决:在损失函数中使用类别权重。本质上,样本数量不足的类在损失函数中获得更高的权重,因此对特定类的错误分类会导致损失函数中出现更高的错误。过采样:对训练样本中不足的类别进行重复采样,有助于均衡样本分布。当可用数据较少时,此方法效果最佳。下采样:您也可以简单地从包含太多样本的类中跳过一些训练样本。当有大量可用数据时,此方法最有效。DataAugmentation:对少数类数据进行数据扩充。优化迁移学习对于大多数应用程序,使用迁移学习比从头开始训练网络更合适。但是,选择是:要丢弃哪些层以及保留哪些层。这在很大程度上取决于您的数据。您的数据与用于预训练网络(通常在ImageNet上训练)的数据越相似,您需要重新训练的层数就越少,反之亦然。例如,假设你想训练网络区分图像中是否包含葡萄,那么你有大量包含葡萄和不包含葡萄的图像。这些图像与ImageNet中使用的图像非常相似,因此您只需要重新训练最后几层,也许只需要完全连接的层。但是,如果要对一张外太空图像是否包含行星进行分类,这种数据与ImageNet中的数据有很大的不同,因此还需要重新训练后续的卷积层。简而言之,应遵循以下原则:结论本文为设计用于图像分类应用的CNN提供了全面的指南。我希望您喜欢阅读本文并学到一些新的有用的东西。原文链接:https://hackernoon.com/a-comprehensive-design-guide-for-image-classification-cnns-46091260fb92(id:almosthuman2014)》]点此阅读作者更多好文
