Keras如何在仍然没有维度的早期阶段计算参数的数量?



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

我问这个问题是因为我很难弄清楚我的"张量形状bug"。(我试图确定我的resnet50模型的C5块的输出尺寸,但我无法在模型中看到它们。

下面我给出了一个基于retanet中C5_reduced层的例子,该层由Resnet50的C5层提供。C5_reduced

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

基于模型。这个特定图层的摘要:

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

我猜C5是(None,1,1,2048),因为2048*256+256 = 524544(我不知道如何确认或削弱该假设)。既然已经知道了,为什么不在总结中展示呢?如果维度2和维度3不同,参数的数量也会不同,对吧?

如果您将确切的输入形状传递给网络上的第一层或输入层,您将得到您想要的输出。例如,我在这里使用输入层:

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中默认填充为validstrides也是1。那么输出的形状将是148 x 148。(你可以搜索公式)

那么None价值观?

  • 第一个没有值为批处理大小。在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 × 3 × 3 + 1) * 16 = 28 * 16 = 448

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

如果你想为以后的卷积计算参数,你需要考虑前一层的滤波器数量成为当前层通道的通道数量。

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

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

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

最新更新