python 在keras中,Flatten()和GlobalAveragePooling2D()有何区别

xcitsw88  于 2023-01-16  发布在  Python
关注(0)|答案(5)|浏览(142)

我想将ConvLSTM和Conv2D的输出传递到Keras中的密集层,使用全局平均池和平坦化之间的区别是什么?

model.add(ConvLSTM2D(filters=256,kernel_size=(3,3)))
model.add(Flatten())
# or model.add(GlobalAveragePooling2D())
model.add(Dense(256,activation='relu'))
6pp0gazn

6pp0gazn1#

两者似乎都有效并不意味着它们的效果相同。
“展平"将取任何形状的Tensor并将其转换为一维Tensor(加上样本维数),但保留Tensor中的所有值。例如,Tensor(样本,10,20,1)将被展平为(样本,10 * 20 * 1)。
GlobalAveragePooling2D的功能有所不同。它在空间维上应用平均池,直到每个空间维都是一个,并保持其他维不变。在这种情况下,值不会在平均时保留。例如,假设第二维和第三维是空间维(通道最后),则Tensor(samples,10,20,1)将输出为(samples,1,1,1)。

o75abkj4

o75abkj42#

展平层的作用

卷积运算后,tf.keras.layers.Flatten会将Tensor重新整形为(n_samples, height*width*channels),比如将(16, 28, 28, 3)变成(16, 2352),我们来试试看:

import tensorflow as tf

x = tf.random.uniform(shape=(100, 28, 28, 3), minval=0, maxval=256, dtype=tf.int32)

flat = tf.keras.layers.Flatten()

flat(x).shape
TensorShape([100, 2352])

GlobalAveragePooling图层的作用

卷积运算后,tf.keras.layers.GlobalAveragePooling层根据最后一个轴 * 对所有值 * 求平均值。这意味着最终形状将为(n_samples, last_axis)。例如,如果最后一个卷积层有64个滤波器,它将把(16, 7, 7, 64)转换为(16, 64)。让我们在几次卷积运算后进行测试:
一个二个一个一个

您应该使用哪一种?

Flatten层的参数总是至少与GlobalAveragePooling2D层的参数一样多。如果展平之前的最终Tensor形状仍然很大,例如(16, 240, 240, 128),则使用Flatten将产生大量参数:240*240*128 = 7,372,800。这个巨大的数字将乘以下一个密集层中的单元数!此时,GlobalAveragePooling2D在大多数情况下可能是首选。如果您使用MaxPooling2DConv2D太多,以至于展平前的Tensor形状类似于(16, 1, 1, 128),则不会有什么不同。如果您过度拟合,你可能想试试GlobalAveragePooling2D

uxh89sit

uxh89sit3#

展平是没有头脑,它只是转换多维对象到一维的重新安排的元素。
而GlobalAveragePooling是一种用于更好地表示向量的方法。它可以是1D/2D/3D。它使用一个解析器窗口,该窗口在对象中移动,并通过求平均值(GlobalAveragePooling)或选取最大值(GlobalMaxPooling)来池化数据。填充本质上是为了将极端情况考虑在内。
两者都用于以更简单的方式考虑排序的影响。

wqlqzqxt

wqlqzqxt4#

如果您更有信心,可以通过与numpy进行比较来测试**Flatten和GlobalPooling之间的差异
我们使用一批形状为(batch_dim, height, width, n_channel)的图像作为输入进行演示

import numpy as np
from tensorflow.keras.layers import *

batch_dim, H, W, n_channels = 32, 5, 5, 3
X = np.random.uniform(0,1, (batch_dim,H,W,n_channels)).astype('float32')
  • Flatten接受至少3D的输入Tensor。它使用(batch_dim, all the rest)对2D输入进行整形。在我们的4D情况下,它使用(batch_dim, H*W*n_channels)进行整形。
np_flatten = X.reshape(batch_dim, -1) # (batch_dim, H*W*n_channels)
tf_flatten = Flatten()(X).numpy() # (batch_dim, H*W*n_channels)

(tf_flatten == np_flatten).all() # True
  • GlobalAveragePooling2D接受4DTensor作为输入。它对所有通道的高度和宽度维度进行平均运算。所得维度为2D (batch_dim, n_channels)GlobalMaxPooling2D的结果相同,但具有最大值运算。
np_GlobalAvgPool2D = X.mean(axis=(1,2)) # (batch_dim, n_channels)
tf_GlobalAvgPool2D = GlobalAveragePooling2D()(X).numpy() # (batch_dim, n_channels)

(tf_GlobalAvgPool2D == np_GlobalAvgPool2D).all() # True
qacovj5a

qacovj5a5#

参数的压缩率在全局平均池化中呈指数级增长,平坦化只需将矩阵重新整形为一维,两者都可以馈送到完全连接的网络谢谢

相关问题