【问题标题】:How to interpret model.summary() output in CNN?如何解释 CNN 中的 model.summary() 输出?
【发布时间】:2020-07-18 12:09:21
【问题描述】:

我是深度学习和 CNN 的新手。如果已经创建了一个 CNN,如屏幕截图所示,那么如何解释 model.summary() 描述的输出。我无法理解不同层的输出形状。

模型总结:

Model: "sequential_3"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_14 (Conv2D)           (None, 29, 29, 32)        1568      
_________________________________________________________________
max_pooling2d_6 (MaxPooling2 (None, 14, 14, 32)        0         
_________________________________________________________________
conv2d_15 (Conv2D)           (None, 11, 11, 32)        16416     
_________________________________________________________________
max_pooling2d_7 (MaxPooling2 (None, 5, 5, 32)          0         
_________________________________________________________________
flatten_3 (Flatten)          (None, 800)               0         
_________________________________________________________________
dense_6 (Dense)              (None, 32)                25632     
_________________________________________________________________
dense_7 (Dense)              (None, 10)                330       
=================================================================
Total params: 43,946
Trainable params: 43,946
Non-trainable params: 0

【问题讨论】:

    标签: tensorflow keras deep-learning google-colaboratory conv-neural-network


    【解决方案1】:

    假设每个图像的大小为(32, 32, 3),根据问题。

    Keras 然后附加一个额外的维度来处理多个批次,即在单个 epoch 的每个步骤中训练多个图像。由于批量大小可以变化,其大小由无表示。因此,输入形状变为(None, 32, 32, 3)

    (32, 32) 图像与(4, 4) 过滤器进行卷积,步幅和膨胀率为1,并使用“有效”填充,得到大小为(32 - 4 + 1, 32 - 4 + 1) = (29, 29) 的输出。由于您有 32 个这样的过滤器,因此输出形状变为 (29, 29, 32)

    默认 MaxPooling 内核的形状为 (2, 2),步幅为 (2, 2)。将其应用于(29, 29) 图像会生成形状为(((29 - 2)//2) + 1, ((29 - 2)//2) + 1)) = (14, 14) 的图像。

    这种模式可以扩展到所有 Conv2D 和 MaxPooling 层。

    Flatten 层沿所有通道获取所有像素并创建一维向量(不考虑批量大小)。因此,(5, 5, 32) 的输入被展平为(5 * 5 * 32) = 800 值。

    参数计数

    Conv2D 层的参数数量由下式给出:

    (kernel_height * kernel_width * input_channels * output_channels) + (output_channels 如果使用偏差)。

    所以,对于第一个具有 3 个输入通道、32 个输出通道和内核大小为(4, 4) 的 Conv2D 层,参数数量为(4 * 4 * 3 * 32) + 32 = 1568

    【讨论】:

    • 这意味着如果padding被明确定义为“相同”,那么第一个卷积层的输出将是(32,32,32)?
    • 是的,它的形状是(32, 32, 32)
    【解决方案2】:

    你的第一层是一个卷积,它采用未知的输入形状(你知道它,你用input_shape=....在某个地方定义了它。

    第一个卷积有一个形状为(None, 29, 29, 32)的输出,其中:

    • None 是批量大小
    • 29 和 29 是生成图像的大小
    • 32 是这个卷积的滤波器数量,也是其输出中的通道数

    然后你有一个最大池化层,它将卷积的输出作为输入。池化的输出形状为(None, 14, 14, 32),因此它将图像的大小除以二,其余部分保持原样。

    然后你有另一个卷积,将池化的输出作为输入,这个新卷积的输出形状是(None, 11, 11, 32)。您在这里也使用了 32 个过滤器。

    .... .....

    ....

    然后你有一个Flatten 层,它获取图像并将它们转换为单个向量,输出形状为(None, 800),其中None 仍然是未触及的批量大小,800 是你拥有的所有元素输入张量,现在在单个向量中,批次中每个样本一个向量。

    然后Dense 层,第一个有 32 个单元,第二个有 10 个单元。

    模型的最终输出形状是(None, 10)。它在批次中为每个样本输出 10 个值。


    每一层都有许多参数(通常是权重)。可训练的参数将通过反向传播进行更新。不可训练的参数将保持静态或使用不同的方法更新(只有少数层如BatchNormalization 具有使用不同方法更新的参数)

    您的模型共有 43946 个权重,全部可训练。

    【讨论】:

      【解决方案3】:

      对于 Conv2d, 如您所见,输出形状为 (None, 10, 10, 64)。第一个维度表示批量大小,目前为 None。因为网络事先并不知道批量大小。拟合数据后,None 将被您在拟合数据时提供的批量大小替换。

      Input shape
      
      4D tensor with shape: (batch, channels, rows, cols) if data_format is "channels_first" 
      or 4D tensor with shape: (batch, rows, cols, channels) if data_format is 
      "channels_last".
      
      Output shape
      
      4D tensor with shape: (batch, filters, new_rows, new_cols) if data_format is 
      "channels_first" or 4D tensor with shape: (batch, new_rows, new_cols, filters) if 
      data_format is "channels_last". rows and cols values might have changed due to 
      padding.
      

      ma​​xpool2d层的值与上面相同,略有变化如下。

      **Input**
      
      If data_format='channels_last': 4D tensor with shape: (batch_size, rows, cols, channels)
      If data_format='channels_first': 4D tensor with shape: (batch_size, channels, rows, cols)
      
      **Output**
      
      If data_format='channels_last': 4D tensor with shape: (batch_size, pooled_rows, pooled_cols, channels)
      If data_format='channels_first': 4D tensor with shape: (batch_size, channels, pooled_rows, pooled_cols)
      

      现在,我们可以简单地在另一个卷积层的顶部添加一个卷积层,因为卷积的输出维度与输入维度相同。 我们通常在卷积层的顶部添加密集层来对图像进行分类。然而,将数据输入到形状(batch_size,单位)的密集层二维数组。而卷积层的输出是一个4D数组。因此,我们必须将从卷积层接收到的输出的维度更改为二维数组。

      我们可以通过在卷积层顶部插入一个 Flatten 层来实现。 Flatten layer 将图像的 3 个维度压缩为一个维度。现在我们只有一个形状为(batch_size, squashed_size), 的二维数组,这对于密集层来说是可以接受的。

      希望这会对你有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-09
        • 2021-06-01
        • 2014-02-03
        • 2018-09-16
        • 2018-09-09
        • 1970-01-01
        • 1970-01-01
        • 2022-06-23
        相关资源
        最近更新 更多