keras 中的 Flatten() 层是否必要?

数据挖掘 神经网络 喀拉斯 美国有线电视新闻网 迁移学习 卷积神经网络
2021-10-07 02:51:57

在CNN迁移学习中,在应用卷积和池化之后,Flatten()层是必要的吗?
我见过一个例子,在移除 vgg16 的顶层之后第一个应用层是 GlobalAveragePooling2D(),然后是 Dense()。
这是迁移学习特有的吗?

这是没有 Flatten() 的例子。

base_model=MobileNet(weights='imagenet',include_top=False) #imports the mobilenet model and discards the last 1000 neuron layer.

x=base_model.output
x=GlobalAveragePooling2D()(x)
x=Dense(1024,activation='relu')(x) #we add dense layers so that the model can learn more complex functions and classify for better results.
x=Dense(1024,activation='relu')(x) #dense layer 2
x=Dense(512,activation='relu')(x) #dense layer 3
preds=Dense(3,activation='softmax')(x) #final layer with softmax activation

此示例使用 Flatten()。

vgg = VGG16(input_shape=IMAGE_SIZE + [3], weights='imagenet', include_top=False)

# don't train existing weights
for layer in vgg.layers:
  layer.trainable = False
  
  # useful for getting number of classes
folders = glob('Datasets/Train/*')
  
# our layers - you can add more if you want
x = Flatten()(vgg.output)
# x = Dense(1000, activation='relu')(x)
prediction = Dense(len(folders), activation='softmax')(x)

# create a model object
model = Model(inputs=vgg.input, outputs=prediction)

如果两者都可以应用,有什么区别?

2个回答

使用 GlobalAveragePooling2D,通过对特征图的每个元素进行平均,每个特征图只选择一个特征。
例如,如果您的全局平均池化层输入为 220 x 220 x 30,您将找到 1x1x30 输出
这意味着您正在从每个切片中找到一个全局代表性特征。那就是全球平均池化
不,这并不特定于迁移学习。它用于分类层中的特征图,与普通的全连接层相比,它更易于解释且不易过拟合。

另一方面,
Flattening 只是将多维特征图转换为单维,无需任何类型的特征选择。

虽然第一个答案已经解释了差异,但我会添加其他几点。

如果模型非常深(即很多池化),那么地图大小将变得非常小,例如从 300x300 到 5x5那么信息更有可能分散在不同的特征图上,并且一个特征图的不同元素不包含太多信息。
因此,当与 Dense 层连接时,您正在减少最终会减少参数数量的维度

Aurélien Géron
的 Hands-On Machine Learning 摘录,全局平均池化层输出每个特征图的平均值:这会丢弃任何剩余的空间信息,这很好,因为当时没有太多空间信息。事实上,GoogLeNet 输入图像通常预计为 224 × 224 像素,因此在 5 个最大池化层之后,每个池化层将高度和宽度除以 2,特征图下降到 7 × 7。此外,这是一个分类任务,而不是本地化,因此对象在哪里并不重要。由于这一层带来的降维,不需要在 CNN 的顶部有几个完全连接的层(就像在 AlexNet 中一样),这大大减少了网络中的参数数量并限制了过拟合的风险。

这是迁移学习特有的吗?

您也可以将此概念应用于您自己的模型,并针对不同情况(即小/大模型)测试结果/参数计数。
无论如何,迁移学习只是神经网络的一个特例,即你继续使用已经训练好的模型。


添加对方法差异的描述 在此处输入图像描述