不包括顶层调用 Keras 预训练模型的区别

Nhq*_*azi 1 keras tensorflow keras-layer keras-2

调用包含或不包含模型顶层的 VGG16 模型有什么区别?我想知道,为什么在不包括顶层的情况下调用模型时,模型摘要中没有显示层的输入参数。我通过以下两种方式使用了 VGG16 模型:

from keras.applications import vgg16
model = vgg16.VGG16(weights='imagenet', include_top=False)
print(model.summary)
Run Code Online (Sandbox Code Playgroud)

模型中层的形状不显示任何输入即(无,无,无,64),请参见下文

Layer (type)                 Output Shape              Param 
===================================================================   
block1_conv1 (Conv2D)        (None, None, None, 64)    1792      
block1_conv2 (Conv2D)        (None, None, None, 64)    36928     
block1_pool (MaxPooling2D)   (None, None, None, 64)    0         
Run Code Online (Sandbox Code Playgroud)

但是,以下代码返回输入参数

from keras.applications import vgg16
model = vgg16.VGG16()
print(model.summary)
Run Code Online (Sandbox Code Playgroud)

层的形状,在这种情况下,返回输入参数

Layer (type)                 Output Shape              Param   
==================================================================   
block1_conv1 (Conv2D)        (None, 224, 224, 64)      1792      
block1_conv2 (Conv2D)        (None, 224, 224, 64)      36928     
block1_pool (MaxPooling2D)   (None, 112, 112, 64)       0    
Run Code Online (Sandbox Code Playgroud)

我试图理解为什么会这样,请发表评论

sdc*_*cbr 5

VGG 的顶层是全连接层,它们连接到卷积基的输出。这些包含固定数量的节点,可以选择使用在 imagenet 上预训练的权重来实例化它们。当实例化包含顶层的 VGG 模型时,架构的大小因此是固定的,并且模型将只接受具有固定输入大小(224,224,3)的图像。用其他尺寸的图像馈送网络将改变密集分类层中的权重数量

但是,当您省略顶级分类器时,您将能够将不同大小的图像提供给网络,并且卷积堆栈的输出将相应地改变。通过这种方式,您可以将 VGG 架构应用于您选择的大小的图像,并在其上粘贴您自己的密集连接分类器。与密集层相比,卷积层中的权重数量保持不变,只是其输出的形状发生了变化。

当您实例化一个没有顶层但具有特定输入形状的 VGG 模型时,您会注意到所有这些:

from keras.applications import vgg16
model = vgg16.VGG16(include_top=False, input_shape=(100,100,3))
model.summary()
Run Code Online (Sandbox Code Playgroud)

将产生:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_4 (InputLayer)         (None, 100, 100, 3)       0         
_________________________________________________________________
block1_conv1 (Conv2D)        (None, 100, 100, 64)      1792      
_________________________________________________________________
block1_conv2 (Conv2D)        (None, 100, 100, 64)      36928     
_________________________________________________________________
block1_pool (MaxPooling2D)   (None, 50, 50, 64)        0         
_____________________________________________________________
etc.
Run Code Online (Sandbox Code Playgroud)

有趣的是,当您调用具有不同输入形状的架构时,卷积层的输出形状如何变化。对于上面的例子,我们得到:

block5_conv3 (Conv2D)        (None, 6, 6, 512)         2359808   
_________________________________________________________________
block5_pool (MaxPooling2D)   (None, 3, 3, 512)         0         
=================================================================
Total params: 14,714,688
Trainable params: 14,714,688
Non-trainable params: 0
Run Code Online (Sandbox Code Playgroud)

如果您使用形状为 (400,400,3) 的图像实例化架构,则会得到以下输出:

_________________________________________________________________
block5_conv3 (Conv2D)        (None, 25, 25, 512)       2359808   
_________________________________________________________________
block5_pool (MaxPooling2D)   (None, 12, 12, 512)       0         
=================================================================
Total params: 14,714,688
Trainable params: 14,714,688
Non-trainable params: 0
Run Code Online (Sandbox Code Playgroud)

请注意在两种情况下权重的数量如何保持不变。