keras 中的 Flatten() 和 GlobalAveragePooling2D() 有什么区别
what is the difference between Flatten() and GlobalAveragePooling2D() in keras
我想将 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'))
两者似乎都有效并不意味着它们的作用相同。
Flatten 会将任意形状的张量转换为一维张量(加上样本维度),但将所有值保留在张量中。例如张量 (samples, 10, 20, 1) 将被展平为 (samples, 10 * 20 * 1).
GlobalAveragePooling2D 做了一些不同的事情。它在空间维度上应用平均池化,直到每个空间维度为一个,并保持其他维度不变。在这种情况下,值不会保留为平均值。例如,张量 (samples, 10, 20, 1) 将输出为 (samples, 1, 1, 1),假设第 2 和第 3 维是空间维度(通道最后)。
扁平化很简单,它只是通过 re-arranging 个元素将 multi-dimensional 对象转换为 one-dimensional。
虽然 GlobalAveragePooling 是一种用于更好地表示向量的方法。它可以是 1D/2D/3D。它使用一个解析器 window,它在对象上移动并通过平均 (GlobalAveragePooling) 或选择最大值 (GlobalMaxPooling) 来汇集数据。基本上需要填充才能将极端情况考虑在内。
两者都是为了更简单的考虑排序的影响。
你可以自己测试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 的输入张量。它使用这种格式 (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
接受 4D 张量作为输入。它对所有通道的高度和宽度维度进行平均操作。得到的维度是 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
展平层的作用
卷积运算后,tf.keras.layers.Flatten
会将张量重塑为(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)
。让我们做一下测试,经过一些卷积操作:
import tensorflow as tf
x = tf.cast(
tf.random.uniform(shape=(16, 28, 28, 3), minval=0, maxval=256, dtype=tf.int32),
tf.float32)
gap = tf.keras.layers.GlobalAveragePooling2D()
for i in range(5):
conv = tf.keras.layers.Conv2D(64, 3)
x = conv(x)
print(x.shape)
print(gap(x).shape)
(16, 24, 24, 64)
(16, 22, 22, 64)
(16, 20, 20, 64)
(16, 18, 18, 64)
(16, 16, 16, 64)
(16, 64)
你应该使用哪个?
Flatten
层的参数总是至少与 GlobalAveragePooling2D
层的参数一样多。如果展平前的最终张量形状仍然很大,例如 (16, 240, 240, 128)
,使用 Flatten
将产生大量参数:240*240*128 = 7,372,800
。这个巨大的数字将乘以下一个密集层中的单元数!在那一刻, GlobalAveragePooling2D
在大多数情况下可能是首选。如果你使用 MaxPooling2D
和 Conv2D
太多以至于你的张量形状在展平之前就像 (16, 1, 1, 128)
,它不会有什么不同。如果你过度拟合,你可能想尝试 GlobalAveragePooling2D
.
我想将 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'))
两者似乎都有效并不意味着它们的作用相同。
Flatten 会将任意形状的张量转换为一维张量(加上样本维度),但将所有值保留在张量中。例如张量 (samples, 10, 20, 1) 将被展平为 (samples, 10 * 20 * 1).
GlobalAveragePooling2D 做了一些不同的事情。它在空间维度上应用平均池化,直到每个空间维度为一个,并保持其他维度不变。在这种情况下,值不会保留为平均值。例如,张量 (samples, 10, 20, 1) 将输出为 (samples, 1, 1, 1),假设第 2 和第 3 维是空间维度(通道最后)。
扁平化很简单,它只是通过 re-arranging 个元素将 multi-dimensional 对象转换为 one-dimensional。
虽然 GlobalAveragePooling 是一种用于更好地表示向量的方法。它可以是 1D/2D/3D。它使用一个解析器 window,它在对象上移动并通过平均 (GlobalAveragePooling) 或选择最大值 (GlobalMaxPooling) 来汇集数据。基本上需要填充才能将极端情况考虑在内。
两者都是为了更简单的考虑排序的影响。
你可以自己测试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 的输入张量。它使用这种格式(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
接受 4D 张量作为输入。它对所有通道的高度和宽度维度进行平均操作。得到的维度是 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
展平层的作用
卷积运算后,tf.keras.layers.Flatten
会将张量重塑为(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)
。让我们做一下测试,经过一些卷积操作:
import tensorflow as tf
x = tf.cast(
tf.random.uniform(shape=(16, 28, 28, 3), minval=0, maxval=256, dtype=tf.int32),
tf.float32)
gap = tf.keras.layers.GlobalAveragePooling2D()
for i in range(5):
conv = tf.keras.layers.Conv2D(64, 3)
x = conv(x)
print(x.shape)
print(gap(x).shape)
(16, 24, 24, 64)
(16, 22, 22, 64)
(16, 20, 20, 64)
(16, 18, 18, 64)
(16, 16, 16, 64)
(16, 64)
你应该使用哪个?
Flatten
层的参数总是至少与 GlobalAveragePooling2D
层的参数一样多。如果展平前的最终张量形状仍然很大,例如 (16, 240, 240, 128)
,使用 Flatten
将产生大量参数:240*240*128 = 7,372,800
。这个巨大的数字将乘以下一个密集层中的单元数!在那一刻, GlobalAveragePooling2D
在大多数情况下可能是首选。如果你使用 MaxPooling2D
和 Conv2D
太多以至于你的张量形状在展平之前就像 (16, 1, 1, 128)
,它不会有什么不同。如果你过度拟合,你可能想尝试 GlobalAveragePooling2D
.