我想将ConvLSTM和Conv2D的输出传递给Keras中的密集层,使用全局平均池和扁平化两者之间的区别在我的情况下都有效。
python prettyprint-override">model.add(ConvLSTM2D(filters=256,kernel_size=(3,3)))
model.add(Flatten())
# or model.add(GlobalAveragePooling2D())
model.add(Dense(256,activation='relu'))
扁平化是无需动脑筋的,它只需通过重新排列元素将多维对象转换为一维。
而GlobalAveragePoling是一种用于更好地表示向量的方法论。它可以是1D/2D/3D。它使用一个解析器窗口,该窗口在对象之间移动,并通过对其进行平均(GlobalAveragePoing)或选择最大值(GlobalMaxPoing)来汇集数据。将角落情况带入帐户基本上需要填充。
两者都用于以更简单的方式考虑排序的效果。
在卷积运算之后,tf。凯拉斯。图层。展平将张量重塑为(n\u个样本,高度*宽度*通道)
,例如将(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])
在卷积操作之后,tf.keras.layers.GlobalAveragePoling
层根据最后一个轴对所有值进行平均。这意味着生成的形状将是(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
。
这两者似乎都起作用,但并不意味着它们的作用相同。
展平将采用任何形状的张量,并将其转换为一维张量(加上样本维度),但保留张量中的所有值。例如,张量(样本,10,20,1)将展平为(样本,10*20*1)。
GlobalAveragePoolig2D做了一些不同的事情。它在空间维度上应用平均池,直到每个空间维度都是一个,而其他维度保持不变。在这种情况下,值不会保持为平均值。例如,假设第二维度和第三维度是空间维度(最后一个通道),则张量(样本10、20、1)将输出为(样本1、1、1)。
我对Keras中的和感到困惑。他们之间有什么区别?我认为第一个是一个层,第二个是一个后端函数,但这意味着什么?在Conv2D中,我们发送过滤器的数量、过滤器的大小和跨步(但是在Conv2D中,我们使用内核是什么(64,3,3),我们把过滤器的数量和大小放在一起?我应该在哪里输入内核数?你能帮我解决这个问题吗?非常感谢。 pytorch中的代码 Keras中已更改的代码 但当我执行代码时,它会产生以
问题内容: 我一直认为Java 中的运算符用于验证其两个布尔操作数是否均为,并且该&运算符用于对两种整数类型进行按位运算。 最近我知道,也可以使用运算符来验证其两个布尔操作数是否均为,唯一的区别是即使LHS操作数为false,它也会检查RHS操作数。 Java中的运算符是否在内部重载?还是在这背后有其他概念? 问题答案: <-验证两个操作数 <-停止评估第一个操作数是否为false,因为结果为fa
问题内容: JavaScript中的&和&&有什么区别? 示例代码: 似乎&&是一个逻辑上的“和”,如果两个都为true,则总是为我提供第二个值。 但是什么是&? (顺便说一下,&&在Python中似乎是“ and”;&在Python中似乎是&。) 问题答案: 是按位AND 该运算符期望 两个数字 并重新调整一个 数字。 如果它们不是数字,则将其强制转换为数字。 注意: 在Javascript中,
问题内容: 我正在从Spring 2.5迁移到Spring 3。 他们介绍了一些黑魔法。预期仅在servlet配置文件中声明。 在Spring 2.5中,我刚刚使用,并且在分发服务器servlet配置XML中声明了标记,并使用了要扫描的基本包。 所以,我不知道是什么样的区别,并在servlet配置标签和我有什么可以消除在Spring3配置文件? 问题答案: 声明一般注释,比如支持,等等。 声明了注
问题内容: 我是Go编程语言的新手。 我注意到Go中有一些奇怪的地方:我认为它在Python中使用并替代了,但是当我在Go中使用时,它也是可行的。 和之间有什么区别? 问题答案: 是分配。有关Go中分配的更多信息:分配 和在变量声明中使用时的细微差别。 Go中变量声明的一般形式是: 上面的声明创建一个特定类型的变量,为其添加名称,并设置其初始值。 无论是或可以省略,但不能同时使用。 例如: 被称为
问题内容: 。*是零个或多个次数的任何字符。我试图找到以元音开头的单词,我用过 它给了我所有以元音开头的单词。当我这样做时,也会得到相同的结果。 现在,我正在寻找以元音结尾的单词。我做了 它没有给出任何结果,但是当我这样做时却给出了有效的结果。请解释两者含义上的差异。谢谢 问题答案: 看起来,在Oracle11中,和模式(之前没有任何内容)会生成零宽度的匹配项。所以与被捕获组包含零宽度的图案或分别