今天要探讨的主题在模型从CNN Layer 转变成 Dense Layer 时,使用 GlobalAveragePooling (GAP) 与 Flatten 两者之前的差异。
我们假设最後一层CNN的宽高是W和H,通道数是C,那麽通过 GlobalAveragePooling 後,我们会得到W和H都变成1,通道数维持不变(11C),而又因为是GlobalAverage的关系,他是直接以通道为区分,直接装里面的权重值做平均。
相反的 Flatten 就简单很多,它直接宽乘高乘通道(HxWxC),再继续接上後面的 Dense Layer。了解以上两个概念後我们就可以来做实验。
实验一:GlobalAveragePooling
base = tf.keras.applications.MobileNetV2(input_shape=(224, 224, 3), include_top=False, weights='imagenet')
net = tf.keras.layers.GlobalAveragePooling2D()(base.output)
net = tf.keras.layers.Dense(NUM_OF_CLASS)(net)
model = tf.keras.Model(inputs=[base.input], outputs=[net])
model.summary()
model.compile(
optimizer=tf.keras.optimizers.SGD(LR),
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=[tf.keras.metrics.SparseCategoricalAccuracy()],
)
history = model.fit(
ds_train,
epochs=EPOCHS,
validation_data=ds_test,
verbose=True)
在 model.summary() 中,可以看到经过 GlobalAveragePooling,输出从 7x7x1280 变成 1x1x1280
out_relu (ReLU) (None, 7, 7, 1280) 0 Conv_1_bn[0][0]
__________________________
global_average_pooling2d_2 (Glo (None, 1280) 0 out_relu[0][0]
产出:
loss: 4.0428e-04 - sparse_categorical_accuracy: 1.0000 - val_loss: 0.4005 - val_sparse_categorical_accuracy: 0.9020
其实这模型前面训练很多遍了,但这次跑出了准确度90%。
实验二:Flatten
base = tf.keras.applications.MobileNetV2(input_shape=(224, 224, 3), include_top=False, weights='imagenet')
net = tf.keras.layers.Flatten()(base.output)
net = tf.keras.layers.Dense(NUM_OF_CLASS)(net)
model = tf.keras.Model(inputs=[base.input], outputs=[net])
model.summary()
model.compile(
optimizer=tf.keras.optimizers.SGD(LR),
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=[tf.keras.metrics.SparseCategoricalAccuracy()],
)
history = model.fit(
ds_train,
epochs=EPOCHS,
validation_data=ds_test,
verbose=True)
model.summary() 中,看到经过 Flatten,输出从 7x7x1280 变成 62720。
out_relu (ReLU) (None, 7, 7, 1280) 0 Conv_1_bn[0][0]
__________________________
flatten_1 (Flatten) (None, 62720) 0 out_relu[0][0]
产出
loss: 0.0063 - sparse_categorical_accuracy: 0.9990 - val_loss: 9.1377 - val_sparse_categorical_accuracy: 0.0833
效果不太理想,训练失败,由於看到 val_loss 有喷高的现象出现,故我将 LR 降低成0.01後,再次训练一次 Flatten 的实验三。
base = tf.keras.applications.MobileNetV2(input_shape=(224, 224, 3), include_top=False, weights='imagenet')
net = tf.keras.layers.Flatten()(base.output)
net = tf.keras.layers.Dense(NUM_OF_CLASS)(net)
model = tf.keras.Model(inputs=[base.input], outputs=[net])
model.compile(
optimizer=tf.keras.optimizers.SGD(0.01),
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=[tf.keras.metrics.SparseCategoricalAccuracy()],
)
history = model.fit(
ds_train,
epochs=EPOCHS,
validation_data=ds_test,
verbose=True)
产出:
loss: 1.4501e-04 - sparse_categorical_accuracy: 1.0000 - val_loss: 1.0266 - val_sparse_categorical_accuracy: 0.7500
降低 LR 後,模型有效成长,虽然最後准确度仍低於 GlobalAveragePooling,但至少是朝着收敛迈进,我自己在执行训练任务时,也是以 GlobalAveragePooling 为主。
<<: Android Studio初学笔记-Day17-ItemTouchHelper
先简单回顾一下,今天预计分析的题目: 如何利用两个 stack 完成 Queue 的概念? 逻辑很简...
ToggleButton为开关按钮,也就是说点一下就显示开启再点一下就显示关闭。 ToggleBut...
写在完赛之後 参赛动机与心得 在约莫两个月前与硕班的学长 Richard 的聊天当中,他邀请我参加这...
这也是很多输家最爱用的手段之一,进场时说是「成长型」投资,被套牢了,改口说是「价值型」投资,你真的懂...
useEffect - 副作用处理 useEffect:资料获取、订阅或手动方式修改 React C...