Keras如何在还没有维度的情况下计算早期的参数个数?

Posted

技术标签:

【中文标题】Keras如何在还没有维度的情况下计算早期的参数个数?【英文标题】:How Keras can calculate the number of parameters at early stage when there are still None dimensions? 【发布时间】:2021-01-29 19:24:48 【问题描述】:

抱歉,这个非常基本的问题(我是 Keras 的新手)。我想知道 Keras 如何在早期(拟合之前)计算每一层的参数数量,尽管 model.summary 显示在这个阶段仍有一些维度具有 None 值。这些值是否已经以某种方式确定,如果是,为什么不在摘要中显示它们?

我问这个问题是因为我很难弄清楚我的“张量形状错误”(我试图确定我的 resnet50 模型的 C5 块的输出尺寸,但我在模型中看不到它们。即使我看到参数的数量也可以总结)。

我在下面给出一个基于 RetinaNet 中 C5_reduced 层的示例,该层由 Resnet50 的 C5 层馈送。 C5_reduced 是

Conv2D(256,kernel_size=1,strides=1,pad=1)

基于此特定层的 model.summary:

C5_reduced (Conv2D)    (None, None, None, 256)          524544 

我猜测 C5 是 (None,1,1,2048),因为 2048*256+256 = 524544(我不知道如何证实或证实该假设)。因此,如果它已经知道,为什么不在摘要中显示呢?如果维度 2 和维度 3 不同,那么参数的数量也会不同吧?

【问题讨论】:

您可以添加您的代码吗?举个例子很容易。 【参考方案1】:

如果您将准确的输入形状传递给网络上的第一层或输入层,您将获得所需的输出。例如我在这里使用了输入层:

input_1 (InputLayer)         [(None, 224, 224, 3)]     0         
_________________________________________________________________
block1_conv1 (Conv2D)        (None, 224, 224, 64)      1792      
_________________________________________________________________
block1_conv2 (Conv2D)        (None, 224, 224, 64)      36928     

将输入作为 (224,224,3) 传递。 3 代表这里的深度。注意卷积参数的计算不同于密集层的计算。

如果您执行以下操作:

tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(150, 150, 3))

你会看到:

conv2d (Conv2D) ---> (None, 148, 148, 16)    

尺寸减少到 148x148,在 Keras 中填充默认为valid。还有strides是1,那么输出的形状就是148 x 148。(可以搜索公式。)

那么值是什么?

第一个值是批量大小。在 Keras 中,第一个维度是批量大小。您可以传递它们并进行修复,也可以在拟合模型或预测时确定它们。 在2D卷积中,期望的输入是(batch_size, height, width, channels),也可以有(None, None, None, 3)等形状 >,这意味着允许使用不同的图像大小。

编辑:

tf.keras.layers.Input(shape = (None, None, 3)),
tf.keras.layers.Conv2D(16, (3,3), activation='relu')

生产:

conv2d_21 (Conv2D)           (None, None, None, 16)    448       

关于您的问题,即使我们将图像高度和宽度传递为,参数是如何计算的?

卷积参数计算依据:

(filter_height * filter_width * input_image_channels + 1) * number_of_filters

当我们将它们放入公式时,

filter_height = 3
filter_width = 3
input_image_channel = 3
number_of_filters = 16

参数 = (3 x 3 x 3 + 1) * 16 = 28 * 16 = 448

注意,我们只需要input_image的通道号为3,表示它是RGB图像。

如果要计算后面卷积的参数,则需要考虑上一层的过滤器数量变成当前层通道的通道数。

这就是您最终可以使用 None 参数而不是 batch_size 的方式。在这种情况下,Keras 需要知道您的图像是否为 RGB。或者您在创建模型时不会指定维度,并且可以在将模型与数据集拟合时传递它们。

【讨论】:

感谢 Frightera,但我的问题仍然存在:为什么不总结显示“宽度”和“高度”值(在上层,我知道这些不再是宽度和高度尺寸)?当我说这些值是已知的因为我们可以看到参数的数量时,我是否正确 或另有说明,当某些维度(批次维度除外)为无时,我们如何才能看到汇总的参数数量?可能是因为这些值是已知的,对吧?所以如果是这样,为什么不展示它们呢? 如果不是这样的话,怎么确定参数的数量,因为它取决于宽度和高度尺寸的具体值? 我编辑了我的答案,看看你的问题是否得到了回答。如果没有,请随时进一步询问:)【参考方案2】:

您需要为模型定义一个输入层。在您 a) 编译模型并为其提供数据之前,可训练参数的总数是未知的,此时模型会根据输入的维度制作图表,然后您将能够确定参数的数量,或者b) 你为模型定义一个输入层,输入维度,然后你可以用 model.summary() 找到参数的数量。

关键是模型无法知道输入和第一个隐藏层之间的参数数量,直到它被定义,或者你运行推理并给它输入的形状。

【讨论】:

感谢 devboydan。但我的问题仍然存在:如果它们是已知的,为什么不在 model.summary 中显示“真实”数字(并且它们是已知的,因为显示了参数的数量)。

以上是关于Keras如何在还没有维度的情况下计算早期的参数个数?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不限制其维度的情况下为函数参数指定类型?

Keras官方中文文档:包装器Wrapper

ValueError:检查输入时出错:预期 keras_layer_input 有 4 个维度,但得到了形状为 (10, 1) 的数组

Keras深度学习实战(24)——从零开始构建单词向量

Keras:如何在编译期间输入形状未知时创建带权重的自定义图层?

如何在 keras lambda 层中使用 tf.py_func 来包装 python 代码。 ValueError:应定义 Dense 输入的最后一个维度。没有找到