在François Chollet(Keras的创建者)的《Python深度学习》一书的第5.3节(见Jupyter笔记本)中,我不清楚以下内容:
让我们通过使用在ImageNet上训练的VGG16网络的卷积基础,从我们的猫和狗图像中提取有趣的特征,然后在这些特征之上训练猫对狗分类器来实现这一点。
[…]
我们可以采取两种方式:
- 在我们的数据集上运行卷积库,记录其输出到磁盘上的Numpy数组,然后使用此数据作为独立的密集连接分类器,类似于您所看到的那些在本书的第一章。此解决方案非常快速且运行成本低,因为它只需要运行卷积库每个输入图像一次,卷积基础是管道中最昂贵的部分但是原因是,这种技术不允许我们利用数据完全增强
- 通过添加在顶部密集分层,并在输入数据。这使我们能够使用数据扩充,因为输入图像每次都经过卷积基模型所见。然而,出于同样的原因,这种技术比第一个贵得多
为什么我们不能增强我们的数据(从现有数据生成更多图像),在增强的数据集上运行卷积库(一次),记录其输出,然后将这些数据用作独立的全连接分类器的输入?
它不是会给出与第二种选择类似的结果,但速度更快吗?
我错过了什么?
它不是会给出与第二种选择类似的结果,但速度更快吗?
类似的结果是的,但它真的会更快吗?
Chollet在这里的主要观点是,第二种方法更昂贵,这仅仅是因为扩增过程本身导致大量图像;而第一个接近
只需要为每个输入图像运行一次卷积库
在第二个中
每次模型看到每个输入图像时,它都会经过卷积库[…]出于同样的原因,这种技术比第一种要昂贵得多
自以来
卷积基是迄今为止流水线中最昂贵的部分
其中"每次被模型看到"必须理解为"在扩增程序产生的每个版本中"(同意,这里的措辞可以而且应该更清楚…)。
使用您提出的方法无法对此进行演练。当然,这是第二种方法的有效替代版本,但考虑到整个端到端过程(CNN+FC),在这两种情况下,没有理由相信它实际上会更快。。。
更新(评论后):
也许你是对的,但我仍然有一种错过的感觉,因为作者明确写道,第一种方法"根本不允许我们利用数据增强"。
我认为你只是过度阅读了这里的内容——尽管同样,作者可以而且应该更清楚;正如所写的,Chollet的论点在某种程度上是循环的(这可能发生在我们最好的人身上):由于我们"对每个输入图像只运行一次卷积基",因此根据定义,我们不使用任何增强。。。有趣的是,书中的短语(第146页)略有不同(不那么引人注目):
但出于同样的原因,这种技术不允许使用数据扩充。
原因是什么?但当然,我们只将每个图像馈送到卷积基一次。。。
换句话说,事实上并不是我们不被"允许",而是我们选择了不增强(为了更快,也就是说)。。。
看看VGG16的论文并解释一下,我相信区别基本上在于你的基础网络将看到输入图像的次数,以及它将如何处理它们。
根据本文,在训练期间对输入图像执行随机缩放(缩放抖动)。如果你把新的密集层放在冻结的基础网络上,然后通过训练程序运行整个堆栈(第二种方法),我想假设你不会禁用基础网络中的比例抖动机制;因此,每次通过训练集(每个历元),您都会看到每个输入图像的(不同的)随机缩放版本。
如果您通过基础网络运行输入图像一次(第一种方法),则基础基本上是在评估模式下运行的,因此它根本不会缩放输入图像,也不会进行任何其他类型的图像增强类型的转换。您可以自己这样做,基本上将增强的输入图像添加到新转换的数据集中。我想这本书是假设你不会这么做的。
无论哪种方式,您都可能最终在多个历元上进行训练(通过数据集多次),因此第二种方法将承担为每个历元的每个训练样本执行整个基础网络的额外负载,而第一种方法只需要为每个样本离线执行一次基础网络,然后只在预转换的样本上进行训练。