【keras模型查看】(卷积层、池化层、全连接层、Batchnorm层)参数个数、乘法次数

21 篇文章 2 订阅
3 篇文章 0 订阅

1. 卷积层

1.1 输入参数

  • 卷积的输入参数:指需要做卷积的输入图像/音频等,它要求是一个Tensor,具有[batch, in_height, in_width, in_channels]这样的shape,具体图片的含义是[训练时一个batch的图片数量, 图片高度, 图片宽度, 图像通道数],注意这是一个4维的Tensor,要求类型为float32和float64其中之一

源码说明:

Arguments:
    filters: Integer, the dimensionality of the output space
      (i.e. the number of output filters in the convolution).
    kernel_size: An integer or tuple/list of 2 integers, specifying the
      height and width of the 2D convolution window.
      Can be a single integer to specify the same value for
      all spatial dimensions.
    strides: An integer or tuple/list of 2 integers,
      specifying the strides of the convolution along the height and width.
      Can be a single integer to specify the same value for
      all spatial dimensions.
      Specifying any stride value != 1 is incompatible with specifying
      any `dilation_rate` value != 1.
    padding: one of `"valid"` or `"same"` (case-insensitive).
    
  • 第一个参数filters卷积核个数,也是输出通道数。Integer, the dimensionality of the output space (i.e. the number of output filters in the convolution).

  • 第二个参数kernel_size: 卷积核大小,指定二维卷积窗口的高和宽,(如果kernel_size只有一个整数,代表宽和高相等):An integer or tuple/list of 2 integers, specifying the height and width of the 2D convolution window. Can be a single integer to specify the same value for all spatial dimensions.

  • 第三个参数strides: 卷积步长,指定卷积窗沿高和宽方向的每次移动步长,An integer or tuple/list of 2 integers, (如果strides只有一个整数,代表沿着宽和高方向的步长相等) specifying the strides of the convolution along the height and width. Can be a single integer to specify the same value for all spatial dimensions. Specifying any stride value != 1 is incompatible with specifying any dilation_rate value != 1.

  • 第四个参数padding: 为valid或same中一种, one of "valid" or "same" (case-insensitive). 两种padding方式的区别如下:

    • same mode

      当filter的中心(K)与image的边角重合时,开始做卷积运算。注意:这里的same还有一个意思,卷积之后输出的feature map尺寸保持不变(相对于输入图片)。当然,same模式不代表完全输入输出尺寸一样,也跟卷积核的步长有关系。same模式也是最常见的模式,因为这种模式可以在前向传播的过程中让特征图的大小保持不变,调参师不需要精准计算其尺寸变化(因为尺寸根本就没变化)。
      same

    • valid mode

      当filter全部在image里面的时候,进行卷积运算,可见filter的移动范围较same更小了。
      在这里插入图片描述

1.2 输出维数

ref: https://www.cnblogs.com/sddai/p/10512784.html

由上一小节可知,卷积层的padding方式不同,其输出维数也会不同。在此,分为padding=valid和padding=same两种情况进行说明:

1.2.1 padding=valid

给定输入参数:

  • inputs=[batch_size, in_height, in_width, in_channels],
  • filters,
  • kernel_size=[k_h, k_w],
  • stride_size=[s_h, s_w]
  • padding=‘valid’

则输出参数为:

output = [batch_size, out_height, out_width, out_channels]

# 其中:
out_channels = filters
out_height = ceil((in_height - k_h + 1) / s_h)
out_width = ceil((in_width - k_w + 1) / s_w) 

示例1:

给定输入参数:

  • inputs=[batch_size, in_height, in_width, in_channels]=[1, 34, 13, 1]
  • filters=128
  • kernel_size=[k_h, k_w]=[10, 4]
  • stride_size=[s_h, s_w]=[3, 2]
  • padding=‘valid’

则输出参数为:

output = [batch_size, out_height, out_width, out_channels]

# 其中:
out_channels = filters = 128
out_height = ceil((in_height - k_h + 1) / s_h) = ceil(34-10+1/3)=ceil(8.3) = 9
out_width = ceil((in_width - k_w + 1) / s_w) = ceil(13-4+1/2) = ceil(5) = 5

# 即
output = [batch_size, out_height, out_width, out_channels] = [1, 9, 5, 128]

实际示例:
在这里插入图片描述


示例2:

给定输入参数:

  • inputs=[batch_size, in_height, in_width, in_channels]=[1, 9, 7, 128]
  • filters=128
  • kernel_size=[k_h, k_w]=[3, 3]
  • stride_size=[s_h, s_w]=[1, 1]
  • padding=‘valid’

则输出参数为:

output = [batch_size, out_height, out_width, out_channels]

# 其中:
out_channels = filters = 128
out_height = ceil((in_height - k_h + 1) / s_h) = ceil(9-3+1/1)=ceil(7) = 7
out_width = ceil((in_width - k_w + 1) / s_w) = ceil(7-3+1/1) = ceil(5) = 5

# 即
output = [batch_size, out_height, out_width, out_channels] = [1, 7, 5, 128]

实际示例:

在这里插入图片描述

1.2.2 padding=same

给定输入参数:

  • inputs=[batch_size, in_height, in_width, in_channels],
  • filters,
  • kernel_size=[k_h, k_w],
  • stride_size=[s_h, s_w]
  • padding=‘same’

则输出参数为:

output = [batch_size, out_height, out_width, out_channels]

# 其中:
out_channels = filters
out_height = ceil(in_height / s_h)
out_width = ceil(in_width / s_w) 

示例3:

给定输入参数:

  • inputs=[batch_size, in_height, in_width, in_channels]=[1, 34, 13, 1]
  • filters=128
  • kernel_size=[k_h, k_w]=[10, 4]
  • stride_size=[s_h, s_w]=[3, 2]
  • padding=‘valid’

则输出参数为:

output = [batch_size, out_height, out_width, out_channels]

# 其中:
out_channels = filters = 128
out_height = ceil(in_height / s_h) = ceil(34/3) = ceil(11.3) = 12
out_width = ceil(in_width / s_w) = ceil(13/2) = ceil(6.5) = 7

# 即
output = [batch_size, out_height, out_width, out_channels] = [1, 12, 7, 128]

1.3 参数个数

由上一篇博客(【keras模型查看】模型结构、模型参数、每层输入/输出:https://blog.csdn.net/u010637291/article/details/110677379)可知查看模型结构和参数的方式,即:

# 查看模型层及参数
model.summary()

可查看到每层模型的参数个数, 如最后一层的全连接层有3999个参数,模型总参数个数为85023:

在这里插入图片描述

但其实可根据每层的输入参数计算出具体的参数个数,如卷积层的参数个数(ref:CNN中卷积层的计算细节:https://zhuanlan.zhihu.com/p/29119239):

示例4.0:

普通二维卷积Conv2D,给定输入参数(同示例1):

  • inputs=[batch_size, in_height, in_width, in_channels]=[1, 34, 13, 1]
  • filters=128
  • kernel_size=[k_h, k_w]=[10, 4]
  • stride_size=[s_h, s_w]=[3, 2]
  • padding=‘valid’

参数个数:

  • 卷积核大小=k_h × \times × k_w × \times × in_channels = 10 * 4 * 1= 40
  • 卷积核个数 = filters = 128
  • 偏置项个数 = 卷积核个数 = filters = 128
  • 参数个数 = 卷积核个数 × \times × 卷积核大小 + 偏置项个数 = 128 * 40 + 128 = 5248

在这里插入图片描述

示例4.1:

DepthWiseConv2D,给定输入参数(同示例1):

  • inputs=[batch_size, in_height, in_width, in_channels]=[1, 7, 7, 128]
  • filters=128
  • kernel_size=[k_h, k_w]=[3, 3]
  • stride_size=[s_h, s_w]=[1, 1]
  • padding=‘valid’

参数个数:

  • 卷积核大小=k_h × \times × k_w × \times × in_channels = 3 * 3 * 1 = 9
  • 卷积核个数 = filters = 128
  • 偏置项个数 = 卷积核个数 = filters = 128
  • 参数个数 = 卷积核个数 × \times × 卷积核大小 + 偏置项个数 = 128 * 9 + 128 = 1280
    在这里插入图片描述

示例4.2:

PointWiseConv2D,给定输入参数(同示例1):

  • inputs=[batch_size, in_height, in_width, in_channels]=[1, 7, 7, 128]
  • filters=128
  • kernel_size=[k_h, k_w]=[1, 1]
  • stride_size=[s_h, s_w]=[1, 1]
  • padding=‘valid’

参数个数:

  • 卷积核大小=k_h × \times × k_w × \times × in_channels × \times × k_depth= 1 * 1 * 1 * 128 = 128
  • 卷积核个数 = filters = 128
  • 偏置项个数 = 卷积核个数 = filters = 128
  • 参数个数 = 卷积核个数 × \times × 卷积核大小 + 偏置项个数 = 128 * 128 + 128 = 16512

在这里插入图片描述

1.4 乘法次数

只考虑乘法计算量:

为了得到输出的特征图的某一个位置的像素值,需要如下次乘法操作:in_channels × \times × k_h × \times × k_w

而特征图总共有out_channels × \times × out_height × \times × out_width 个像素。

因此总计算量(乘法次数)为:

multiply_times = in_channels * k_h * k_w * (out_channels * out_height * out_width)

示例5:

给定输入参数(同示例1):

  • inputs=[batch_size, in_height, in_width, in_channels]=[1, 34, 13, 1]
  • filters=128
  • kernel_size=[k_h, k_w]=[10, 4]
  • stride_size=[s_h, s_w]=[3, 2]
  • padding=‘valid’

乘法次数:

  • in_channels = 1
  • k_h, k_w = 10, 4
  • out_channels = 128
  • out_height = ceil((in_height - k_h + 1) / s_h) = ceil(34-10+1/3) = 9
  • out_width = ceil((in_width - k_w + 1) / s_w) = ceil(13-4+1/2) = 5
  • multiply_times = in_channels * k_h * k_w * (out_channels * out_height * out_width) = 1 * 10 * 4 * (128 * 9 * 5) = 230,400

2. 池化层

可有最大池化层和平均池化层,目前最大池化层更常用。即在输入的池化大小里寻找最大或平均值作为输出。以最大池化层示例:

在这里插入图片描述

池化层即对输入的特征图进行压缩,一方面使特征图变小,简化网络计算复杂度;一方面进行特征压缩,提取主要特征。

2.1 输入参数

输入参数:一个4维Tensor,具有[batch, in_height, in_width, in_channels]这样的shape,类型为float32和float64其中之一。

源码说明:

"""Average pooling operation for spatial data.

  Arguments:
    pool_size: integer or tuple of 2 integers,
      factors by which to downscale (vertical, horizontal).
      `(2, 2)` will halve the input in both spatial dimension.
      If only one integer is specified, the same window length
      will be used for both dimensions.
    strides: Integer, tuple of 2 integers, or None.
      Strides values.
      If None, it will default to `pool_size`.
    padding: One of `"valid"` or `"same"` (case-insensitive).
  • 第一个参数pool_size:池化大小
  • 第二个参数strides:步长
  • 第三个参数padding:同卷积层padding。

2.2 输出维数

和卷积类似,但不需要做卷积运算,做取平均值和最大值统计:

示例6:

给定输入参数:

  • inputs=[batch_size, in_height, in_width, in_channels]=[1, 1, 5, 128]
  • pool_size=[p_h, p_w]=[1, 5]
  • strides=[s_h, s_w]=1
  • padding=‘valid’

输出维数:

  • output = [batch_size, out_height, out_width, out_channels], 其中:
  • out_height = ceil((in_height - p_h + 1) / s_h) = ceil((1-1+1)/1)=1
  • out_width = ceil((in_width - p_w + 1) / s_w) = ceil((5-5+1)/1) = 1
  • 即 output = [1, 1, 1, 128]

在这里插入图片描述

2.3 参数个数

无。如下图所示:
在这里插入图片描述

2.4 乘法次数

如果为最大池化层,则不需做乘法;
如果为平均池化层,则乘法次数=out_height × \times × out_width × \times × out_channels

示例7:

给定输入参数(同示例6):

  • inputs=[batch_size, in_height, in_width, in_channels]=[1, 1, 5, 128]
  • pool_size=[p_h, p_w]=[1, 5]
  • strides=[s_h, s_w]=1
  • padding=‘valid’

乘法次数 = 1 * 1 * 128 = 128

3. 全连接层

实际上,全连接层也可以被视为是一种极端情况的卷积层,其卷积核尺寸就是输入矩阵尺寸,因此输出矩阵的高度和宽度尺寸都是1。

不过区别在于,一维卷积是单个像素位置的全部通道进行线性加权,而全连接是先把所有输入平铺 (或者用池化层)成一维向量,即更偏向于对像素级别的线性加权。还有就是广义上的全连接网络还会带一个激活函数。

总之,一句话讲,两者的区别的就是,一维卷积是对图片通道级别的操作,全连接则更偏向于是像素级别的操作。

3.1 输入参数

输入参数:一个2维Tensor,具有[batch_size, in_channels]这样的shape,类型为float32和float64其中之一。

源码说明:

Arguments:
    units: Positive integer, dimensionality of the output space.
    activation: Activation function to use.
      If you don't specify anything, no activation is applied
      (ie. "linear" activation: `a(x) = x`).
    use_bias: Boolean, whether the layer uses a bias vector.
  • 第一个参数units:输出维数
  • 第二个参数activation:激活函数, 如softmax
  • 第三个参数use_bias:是否使用偏置项。

3.2 输出维数

由上可知,全连接层的[in_height, in_width] = [1, 1], [k_h, k_w]=[1, 1], [out_height, out_width]=[1, 1]。

输出即为:outputs: [batch_size, units]

示例8:

给定输入参数:

  • inputs = [batch_size, in_channels] = [1, 128]
  • units = 31
  • activation = softmax

输出维数 = [batch_size, units] = [1, 128]

在这里插入图片描述

3.3 参数个数

参数个数 = units × \times × in_channels + 偏置项个数

示例9:

给定输入参数(同示例8):

  • inputs = [batch_size, in_channels] = [1, 128]
  • units = 31
  • activation = softmax

参数个数= 31 * 128 + 128 = 3999
在这里插入图片描述

3.4 乘法次数

只考虑乘法计算量:

multiply_times = in_channels * k_h * k_w * (out_channels * out_height * out_width)

示例10:

给定输入参数(同示例8):

  • inputs=[batch_size, in_channels]=[1, 128]
  • units = 31
  • padding=‘valid’

乘法次数:

  • multiply_times = in_channels * k_h * k_w * (out_channels * out_height * out_width) = 128 * 1 * 1 * (31 * 1 * 1) = 3968

4. Batch normalization层

Batch Normalization,简称BatchNorm或BN,翻译为“批归一化”,是神经网络中一种特殊的层,如今已是各种流行网络的标配。

4.1 参数个数

针对输入bn_in,batchnorm层的计算为:

bn_out = gamma * (bn_in - mean) / sqrt(variance) + beta

共涉及到四个参数:gamma、mean、variance和beta。

如果batch size为m,则在前向传播过程中,网络中每个节点都有m个输出,所谓的Batch Normalization,就是对该层每个节点的这m个输出进行归一化再输出,具体计算方式如下:
在这里插入图片描述
所以batchnorm层的参数个数 = 4 × \times × batch_size

示例11:

给定输入inputs=[1, 9, 5, 128]

则输出为outputs=[1, 9, 5, 128]

参数个数=4*128=512

在这里插入图片描述

4.2 乘法次数

根据batchnorm层的计算,即:

bn_out = gamma * (bn_in - mean) / sqrt(variance) + beta

共有2次加法运算,2次乘法。

乘法次数 = 2 * batch_size

无参数层 (InputLayer, ZeroPadding, ReLU, AveragePooling, Reshape)

实际中,参数为0的层包括:InputLayer, ZeroPadding, ReLU, AveragePooling, Reshape

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在将CBAM添加到UNet中,通常可以将CBAM应用于UNet的编码器和解码器部分的每个卷积层之后。以下是一种常见的CBAM与卷积层池化层的位置分布示例: ```python import tensorflow as tf from keras.models import Model from keras.layers import Input, Conv2D, MaxPooling2D, concatenate, Activation def cbam_block(inputs, reduction_ratio=16): # Channel attention channels = inputs.shape[-1] avg_pool = tf.reduce_mean(inputs, axis=[1, 2], keepdims=True) fc1 = Conv2D(channels // reduction_ratio, kernel_size=(1, 1))(avg_pool) fc1 = Activation('relu')(fc1) fc2 = Conv2D(channels, kernel_size=(1, 1))(fc1) channel_attention = tf.sigmoid(fc2) * inputs # Spatial attention max_pool = tf.reduce_max(inputs, axis=3, keepdims=True) conv = Conv2D(1, kernel_size=(7, 7), padding='same')(max_pool) spatial_attention = tf.sigmoid(conv) * inputs # Combine channel and spatial attention outputs = tf.add(channel_attention, spatial_attention) return outputs def unet_cbam(input_shape): inputs = Input(input_shape) # Encoder conv1 = Conv2D(64, 3, activation='relu', padding='same')(inputs) conv1 = Conv2D(64, 3, activation='relu', padding='same')(conv1) conv1 = cbam_block(conv1) # CBAM block added pool1 = MaxPooling2D(pool_size=(2, 2))(conv1) # Decoder conv2 = Conv2D(128, 3, activation='relu', padding='same')(pool1) conv2 = Conv2D(128, 3, activation='relu', padding='same')(conv2) conv2 = cbam_block(conv2) # CBAM block added pool2 = MaxPooling2D(pool_size=(2, 2))(conv2) # Add more encoder and decoder layers with CBAM block # Output outputs = Conv2D(num_classes, 1, activation='softmax')(pool2) model = Model(inputs=inputs, outputs=outputs) return model ``` 在这个示例中,CBAM块被插入到了每个卷积层之后,以增强模型的注意力机制。你可以根据需要添加更多的编码器和解码器,并在每之后应用CBAM块。这里的示例代码仅供参考,你可以根据自己的具体需求进行修改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值