用卷积神经网络实现图像分类的数据增强



我正在用Daniel Nouri的noccn模块用cudaconvnet进行图像分类,并希望通过对原始图像进行大量补丁(并翻转它)来实现数据增强。什么时候最好?

我已经确定了训练过程中的三个阶段:
a)根据数据创建批次
b)获得下一个要训练的批次
c)给定批次,获得下一张要输入网络的图像

在我看来,a)的优点是我可以将增强的数据分散在所有批次中。但它将占用1000倍以上的磁盘空间。原始数据集已经是1TB,因此完全不可行。

b) 和c)不涉及将新数据存储在磁盘上,但我可以将数据分散到多个批次中吗?如果我没有,那么假设我有batch_size==128,并且我可以将我的数据增加1000x,那么接下来的8个批次都将包含来自同一类的图像。因为每个训练样本根本不会被随机分配,这对训练网络来说不是很糟糕吗?

此外,如果我选择b)或c),并从k个训练示例中创建一个新的批,那么数据增加n倍将使批大小为n*k,而不是给我n倍多的批。

例如,在我的例子中,我的batchsize==128,并且可以预期1000x的数据增加。因此,每个批次的大小实际上是128*1000,我得到的只是更准确的偏导数估计(这在很大程度上是无用的,因为批次大小==128k是毫无意义的高)。

那么我该怎么办呢?

好吧,您希望在其余数据中尽可能随机地穿插增强样本。否则,正如您所提到的,您肯定会遇到问题,因为批次不会正确采样,并且您的梯度下降步骤会过于偏向。我对cudaconnet不太熟悉,因为我主要使用Torch,但在使用人工增强数据时,我经常遇到与您相同的情况。

你最好的选择是(c)。

对我来说,当你的教练的内环加载了一个样本时,增加数据的最佳位置就是——在那一刻,对单个数据样本应用随机失真、翻转、裁剪(或者你增加样本的其他方式)。这将实现的是,每次培训师尝试加载样本时,它实际上都会收到一个修改后的版本,该版本可能与它在上一次迭代中看到的任何其他图像都不同。

然后,当然,你需要调整其他东西才能仍然获得1000倍的数据大小因子

  1. 理想情况下,在内部循环完成处理第一个集合后,每个epoch加载更多批。如果你的扩增仪设置正确,每一批都会继续获得随机样本,所以一切都会很好。Torch允许这样做,但这有点棘手,我不确定你是否能在cudaconnet中做到这一点
  2. 否则,只需让训练器再运行1000个训练周期。虽然没有那么优雅,但最终的结果是一样的。如果你以后需要报告你实际训练的时期数量,只需将实际计数除以1000,就可以根据你的1000倍增强数据集得到更合适的估计

这样,您的目标类将始终像原始数据一样随机分布在整个数据集中,而不会消耗任何额外的磁盘空间来缓存增强样本。当然,这是以额外的计算能力为代价的,因为在这一过程中的每一步,你都会根据需要生成样本,但你已经知道。。。

此外,也许更重要的是,您的批次将保持原来的128大小,因此迷你批次处理过程将保持不变,您学习的参数更新将继续以您预期的频率出现。同样的过程也适用于SGD培训(批量=1),因为培训师永远不会看到两次"相同"的图像。

希望能有所帮助。

最新更新