使用预训练卷积神经网络了解特征提取

时间:2018-08-09 17:48:11

标签: machine-learning neural-network keras deep-learning conv-neural-network

在FrançoisChollet(Keras的创建者)在书Deep Learning with Python中的第5.3节(请参阅companion Jupyter notebook)中,我不清楚以下内容:

  

让我们通过在ImageNet上训练的VGG16网络的卷积基础将其付诸实践,从我们的猫和狗图像中提取有趣的特征,然后在这些特征之上训练猫与狗的分类器。

     

[...]

     

我们可以通过两种方式进行操作:

     
      
  • 在我们的数据集上运行卷积基础,记录其输出   到磁盘上的Numpy数组,然后使用此数据作为   独立的密集连接分类器,类似于您所看到的   在本书的第一章中。该解决方案非常快速且   运行便宜,因为它只需要运行卷积基数   每个输入图像一次,而卷积基数到目前为止   管道中最昂贵的部分。 但是,完全一样   原因,这种技术将不允许我们利用数据   完全
  •   
  • 通过添加来扩展我们拥有的模型(conv_base)   顶层密集,并在   输入数据。这使我们可以使用数据增强,因为每个   输入图像每次都经过卷积基数   由模型看到。但是,出于同样的原因,这种技术是   比第一个贵得多。
  •   

为什么我们不能扩充我们的数据(从现有数据中生成更多图像),对扩充后的数据集运行一次卷积基础(一次),记录其输出,然后将此数据用作独立的完全连接的输入分类器?

它会不会提供与第二种选择相似的结果,但是会更快?

我想念什么?

2 个答案:

答案 0 :(得分:2)

  

它会不会提供与第二种选择相似的结果,但是会更快?

类似的结果,是的,但是真的会更快吗?

Chollet的要点在于,第二种方法更昂贵,这仅仅是由于增强程序本身导致的大量图片;而第一种方法

  

只需要对每个输入图像运行一次卷积基数

第二个

  

模型每次看到它时,每个输入图像都会经过卷积基数。[...] 出于同样的原因,该技术比第一个昂贵得多。

>

  

卷积基数是迄今为止管道中最昂贵的部分

“每次都能被模型看到的地方”必须理解为“在增强程序产生的每个版本中”(同意,措词可以而且应该在这里更清楚...)。

使用建议的方法无法解决此问题。当然,这是第二种方法的有效替代版本,但是考虑到整个端到端过程,没有理由相信它实际上会更快。 (CNN + FC)在这两种情况下...

更新(在评论后):

  

也许您是对的,但由于作者明确写道第一种方法“根本不允许我们利用数据扩充”,因此我仍然有失落的感觉。

我认为您只是在这里阅读过多的东西-尽管再次,作者可以并且应该更加清楚;如所写,Chollet在这里的论点有点圆形(对我们最好的人可能发生):由于我们对每个输入图像都只运行一次“卷积基数”,因此结果证明根据定义,我们不使用任何扩充...有趣的是,书中的短语(第146页)略有不同(不太生动):

  

但是出于同样的原因,该技术不允许您使用数据扩充。

那是什么原因?但是,当然,我们只将每张图像仅一次馈送到卷积基础 ...

换句话说,实际上并不是我们不是“被允许”,而是我们选择了进行增强(以求更快)。 / p>

答案 1 :(得分:0)

看看the VGG16 paper并作一些解释,我相信区别主要在于您的基本网络将看到输入图像的次数以及如何将其视为结果。

根据论文,在训练过程中对输入图像执行随机缩放(缩放抖动)。如果您将新的密集层放置在冻结的基础网络之上,然后通过训练过程(第二种方法)运行整个堆栈,那么我认为,前提是您不会在基础网络中禁用缩放抖动机制。这样,您每次通过训练集(每个历元)都会看到(输入不同的)每个输入图像的随机缩放版本。

如果您一次通过基本网络运行输入图像(第一种方法),则基本运行在评估模式下,因此它根本不会缩放输入图像,也不会进行任何其他形式的图像增强转换类型。您可以这样做,以便基本上将增强的输入图像添加到新转换的数据集中。我想这本书假设您不会这样做。

无论哪种方式,您都可能最终会在多个时期进行训练(通过数据集多次),因此第二种方法会承担执行每个时期的每个训练样本执行整个基础网络的额外负担,而第一种方法会只需对每个脱机样本执行一次基础网络,然后仅对经过预转换的样本进行训练即可。