• 卷积层的输出


    卷积层的输出

    flyfish

    在卷积神经网络中,卷积层的输出尺寸计算主要依赖于输入尺寸、卷积核尺寸、步幅(stride)和填充(padding)。

    经典的卷积神经网络模型 - AlexNet

    标准卷积

    以AlexNet第一个卷积层作为说明

    import torch
    import torch.nn as nn
    
    class AlexNet(nn.Module):
        def __init__(self, num_classes=1000):
            super(AlexNet, self).__init__()
            self.features = nn.Sequential(
                nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
                ......
    

    nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2)

    • 64核 :意味着卷积层有64个不同的卷积核,每个核都会生成一个特征图(feature map)。所以输出的深度是64。

    • 输出尺寸 :输出特征图的高度和宽度可以用以下公式计算:
      Output Size = ⌊ Input Size − Kernel Size + 2 × Padding Stride ⌋ + 1 \text{Output Size} = \left\lfloor \frac{\text{Input Size} - \text{Kernel Size} + 2 \times \text{Padding}}{\text{Stride}} \right\rfloor + 1 Output Size=StrideInput SizeKernel Size+2×Padding+1
      现在,我们应用这个公式来计算 AlexNet 模型中第一卷积层的输出尺寸。

    输入数据

    原始图片: 3 × 224 × 224 3 \times 224 \times 224 3×224×224 (3个通道,每个通道的大小为224x224)

    卷积层 1

    • 卷积核数量(输出通道数):64

    • 卷积核尺寸: 11 × 11 11 \times 11 11×11

    • 步幅(stride):4

    • 填充(padding):2

    计算输出尺寸

    我们需要计算输出特征图的宽度和高度:
    Output Height = ⌊ 224 − 11 + 2 × 2 4 ⌋ + 1 = ⌊ 224 − 11 + 4 4 ⌋ + 1 = ⌊ 217 4 ⌋ + 1 = 54 + 1 = 55 \text{Output Height} = \left\lfloor \frac{224 - 11 + 2 \times 2}{4} \right\rfloor + 1 = \left\lfloor \frac{224 - 11 + 4}{4} \right\rfloor + 1 = \left\lfloor \frac{217}{4} \right\rfloor + 1 = 54 + 1 = 55 Output Height=422411+2×2+1=422411+4+1=4217+1=54+1=55
    Output Width = ⌊ 224 − 11 + 2 × 2 4 ⌋ + 1 = ⌊ 224 − 11 + 4 4 ⌋ + 1 = ⌊ 217 4 ⌋ + 1 = 54 + 1 = 55 \text{Output Width} = \left\lfloor \frac{224 - 11 + 2 \times 2}{4} \right\rfloor + 1 = \left\lfloor \frac{224 - 11 + 4}{4} \right\rfloor + 1 = \left\lfloor \frac{217}{4} \right\rfloor + 1 = 54 + 1 = 55 Output Width=422411+2×2+1=422411+4+1=4217+1=54+1=55

    输出尺寸

    所以,卷积层1的输出特征图尺寸为: 64 × 55 × 55 64 \times 55 \times 55 64×55×55(64个特征图,每个特征图的大小为55x55)。
    卷积核的数量(filters)就是输出通道数(output channels)。在卷积神经网络中,每个卷积核会生成一个特征图,这些特征图共同组成了输出张量的深度(通道数)。

    • 输入通道数(input channels) :输入数据的通道数。例如,一个RGB图像有3个通道(红、绿、蓝)。

    • 输出通道数(output channels) :卷积层输出的通道数,也就是卷积核的数量。每个卷积核会生成一个特征图,所有特征图的数量就是输出通道数。

    import torch
    import torch.nn as nn
    
    # 定义输入张量,形状为 (batch_size, channels, height, width)
    input_data = torch.randn(1, 3, 224, 224)
    
    # 定义一个卷积层
    # 输入通道数 3,输出通道数 64,卷积核大小 11x11,步幅 4,填充 2
    conv_layer = nn.Conv2d(in_channels=3, out_channels=64, kernel_size=11, stride=4, padding=2)
    
    # 计算卷积层的输出
    output = conv_layer(input_data)
    
    print(f"输入张量的形状: {input_data.shape}")
    print(f"输出张量的形状: {output.shape}")
    
    输入张量的形状: torch.Size([1, 3, 224, 224])
    输出张量的形状: torch.Size([1, 64, 55, 55])
    

    有了dilation参数就是扩张卷积(dilated convolution)或者 膨胀卷积

    import torch
    import torch.nn as nn
    
    # 定义输入张量,形状为 (batch_size, channels, height, width)
    input_data = torch.randn(1, 3, 224, 224)
    
    # 定义一个卷积层,扩张率为2
    # 输入通道数 3,输出通道数 64,卷积核大小 11x11,步幅 4,填充 2,扩张率 2
    conv_layer = nn.Conv2d(in_channels=3, out_channels=64, kernel_size=11, stride=4, padding=2, dilation=2)
    
    # 计算卷积层的输出
    output = conv_layer(input_data)
    
    print(f"输入张量的形状: {input_data.shape}")
    print(f"输出张量的形状: {output.shape}")
    
    
    输入张量的形状: torch.Size([1, 3, 224, 224])
    输出张量的形状: torch.Size([1, 64, 52, 52])
    

    计算输出形状:
    H out = ⌊ H in + 2 P − D × ( K − 1 ) − 1 S ⌋ + 1 H_{\text{out}} = \left\lfloor \frac{H_{\text{in}} + 2P - D \times (K - 1) - 1}{S} \right\rfloor + 1 Hout=SHin+2PD×(K1)1+1
    W out = ⌊ W in + 2 P − D × ( K − 1 ) − 1 S ⌋ + 1 W_{\text{out}} = \left\lfloor \frac{W_{\text{in}} + 2P - D \times (K - 1) - 1}{S} \right\rfloor + 1 Wout=SWin+2PD×(K1)1+1

    给定参数

    • 输入尺寸 H in = 224 H_{\text{in}} = 224 Hin=224, W in = 224 W_{\text{in}} = 224 Win=224

    • 卷积核大小 K = 11 K = 11 K=11

    • 步幅 S = 4 S = 4 S=4

    • 填充 P = 2 P = 2 P=2

    • 扩张率 D = 2 D = 2 D=2

    计算感受野

    感受野的大小指的是在图像中一个特定位置的输出单元所覆盖的输入区域的大小。
    扩张卷积的实际感受野为:
    Effective Kernel Size = D × ( K − 1 ) + 1 = 2 × ( 11 − 1 ) + 1 = 21 \text{Effective Kernel Size} = D \times (K - 1) + 1 = 2 \times (11 - 1) + 1 = 21 Effective Kernel Size=D×(K1)+1=2×(111)+1=21

    计算输出高度和宽度

    给定参数的卷积层输出张量的形状

    关于扩张卷积(dilated convolution)或者 膨胀卷积输出的大小,上面的公式是PyTorch官网的,我则喜欢用下面的公式

    Effective Kernel Size = ( D × ( K − 1 ) + 1 ) \text{Effective Kernel Size} = (D \times (K - 1) + 1) Effective Kernel Size=(D×(K1)+1)

    L out = ⌊ L in + 2 P − Effective Kernel Size S ⌋ + 1 L_{\text{out}} = \left\lfloor \frac{L_{\text{in}} + 2P - \text{Effective Kernel Size}}{S} \right\rfloor + 1 Lout=SLin+2PEffective Kernel Size+1

    H out = ⌊ H in + 2 P − ( D × ( K − 1 ) + 1 ) S ⌋ + 1 H_{\text{out}} = \left\lfloor \frac{H_{\text{in}} + 2P - (D \times (K - 1) + 1)}{S} \right\rfloor + 1 Hout=SHin+2P(D×(K1)+1)+1
    W out = ⌊ W in + 2 P − ( D × ( K − 1 ) + 1 ) S ⌋ + 1 W_{\text{out}} = \left\lfloor \frac{W_{\text{in}} + 2P - (D \times (K - 1) + 1)}{S} \right\rfloor + 1 Wout=SWin+2P(D×(K1)+1)+1

    这个公式和PyTorch官网其实是一样的
    使用公式计算输出尺寸:
    H out = ⌊ 224 + 2 × 2 − 21 4 ⌋ + 1 H_{\text{out}} = \left\lfloor \frac{224 + 2 \times 2 - 21}{4} \right\rfloor + 1 Hout=4224+2×221+1
    = ⌊ 224 + 4 − 21 4 ⌋ + 1 = \left\lfloor \frac{224 + 4 - 21}{4} \right\rfloor + 1 =4224+421+1
    = ⌊ 207 4 ⌋ + 1 = \left\lfloor \frac{207}{4} \right\rfloor + 1 =4207+1
    = ⌊ 51.75 ⌋ + 1 = \left\lfloor 51.75 \right\rfloor + 1 =51.75+1
    = 51 + 1 = 51 + 1 =51+1
    = 52 = 52 =52
    感受野是卷积核在输入图像中覆盖的区域。 21 × 21 21 \times 21 21×21是感受野的大小 。 52 × 52 52 \times 52 52×52 是卷积操作之后输出特征图(feature map)的大小。

    卷积的扩张率

    扩张率 D D D 决定了卷积核元素之间插入零的数量。对于标准卷积(即扩张率 D = 1 D = 1 D=1),卷积核的元素是连续的,没有插入零。例如,一个 3 × 3 3 \times 3 3×3 的标准卷积核如下:

    | a | b | c |
    | d | e | f |
    | g | h | i |
    

    对于扩张率 D = 2 D = 2 D=2,在卷积核的每两个元素之间插入一个零:

    | a | 0 | b | 0 | c |
    | 0 | 0 | 0 | 0 | 0 |
    | d | 0 | e | 0 | f |
    | 0 | 0 | 0 | 0 | 0 |
    | g | 0 | h | 0 | i |
    

    可以看到,卷积核元素之间插入了 D − 1 = 1 D - 1 = 1 D1=1 个零。

    感受野的扩展

    扩张卷积的感受野计算公式为 D × ( K − 1 ) + 1 D \times (K - 1) + 1 D×(K1)+1,其中 K K K 是卷积核的尺寸。这个公式表示扩张卷积的实际感受野:

    • D D D :扩张率(dilation rate)。它决定了卷积核元素之间的距离。

    • K K K :卷积核的尺寸(即卷积核的边长,如果是 K × K K \times K K×K)。

    • K − 1 K - 1 K1 :表示卷积核中元素之间的间距数量。对于 K K K 长度的卷积核,有 K − 1 K - 1 K1 个间距。

    • D × ( K − 1 ) D \times (K - 1) D×(K1) :这是扩展后的卷积核覆盖的实际范围(即感受野)。

    • 最后的 + 1 +1 +1 :确保感受野包括卷积核的边界。假设 K = 3 K = 3 K=3,则卷积核有3个元素,需要考虑这3个元素的间距。公式 D × ( K − 1 ) D \times (K - 1) D×(K1)计算的是卷积核内部元素之间的距离,但这并不包括卷积核的边界元素。因此,感受野需要 +1 来包括卷积核的边界。

    例如,对于 3 × 3 3 \times 3 3×3 的卷积核和扩张率 D = 2 D = 2 D=2

    | a | 0 | b | 0 | c |
    | 0 | 0 | 0 | 0 | 0 |
    | d | 0 | e | 0 | f |
    | 0 | 0 | 0 | 0 | 0 |
    | g | 0 | h | 0 | i |
    

    这个扩张卷积的感受野是:
    2 × ( 3 − 1 ) + 1 = 2 × 2 + 1 = 5 2 \times (3 - 1) + 1 = 2 \times 2 + 1 = 5 2×(31)+1=2×2+1=5感受野从 3 × 3 3 \times 3 3×3 扩展到 5 × 5 5 \times 5 5×5

  • 相关阅读:
    h3c交换机配置教程命令(新手配置交换机详细教程)
    C——编译预处理
    Python爬虫——Selenium 浏览器交互与异常处理
    如何将 Python 运用到实际的测试工作中
    vue3(二)- - - - vite3.1 + vue3.2配置axios
    SpringMVC常用注解、参数传递、返回值
    python 在window对exe、注册表、bat、系统服务操作等实例讲解
    Linux网络应用层协议之http/https
    【单片机基础小知识-如何通过指针来读写寄存器】
    vue的由来、vue教程和M-V-VM架构思想、vue的使用、nodejs
  • 原文地址:https://blog.csdn.net/flyfish1986/article/details/140099883