返回顶部

[学习经验] 空洞卷积的概念及其代码实现

[复制链接]
迪迦奥特曼Lv.7 显示全部楼层 发表于 2023-9-21 10:28:15 |阅读模式 打印 上一主题 下一主题

马上注册,享用更多功能,让你轻松玩转AIHIA梦工厂!

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 迪迦奥特曼 于 2023-9-21 10:31 AM 编辑

当我们谈论卷积操作时,通常是一个卷积核(也可以叫做滤波器)在输入图像上滑动并计算一些特定区域的值,然后将这些值合并以生成输出图像。通常情况下,卷积核中的每个元素都与输入图像中的相应元素相乘,然后将它们相加以得到一个输出值。

现在,来谈谈"空洞卷积"。在空洞卷积中,我们引入了一个概念叫做"""空洞"。这些""实际上是卷积核中的一些位置不与输入的每个像素点一一对应,而是跳过一些像素点,以便扩大感受野(也就是卷积核所能看到的输入图像的区域)。

以一个直观的例子来解释:假设你有一块巧克力,正常情况下你可以将它分成4x4块来吃。但是如果你想一口吃掉它,你可以在巧克力上钻几个洞,这样你的嘴巴就可以同时触及到更多的巧克力,但巧克力还是一块。

在卷积中,通过引入洞,卷积核可以"看到"更多距离自己更远的像素,而不需要增加卷积核的大小。这对于捕捉图像中的长距离特征非常有用,比如在语义分割任务中,可以同时捕捉到物体的局部和全局信息。

所以,空洞卷积就是通过在卷积核中引入一些跳过像素的"洞"来扩大感受野,以便更好地理解图像中的特征。这就好像巧克力上的洞让你更容易一口吃掉一整块一样,但卷积核并没有变大。

所以用专业角度解释空洞卷积就是:
空洞卷积(也称为膨胀卷积或孔卷积)是卷积神经网络中的一种特殊卷积操作,它允许在保持参数数量较少的情况下增大感受野( receptive field)。空洞卷积通过在卷积核之间引入空洞(或孔),以增加感受野的大小,而不需要增加参数数量。这对于处理具有大范围上下文信息的图像数据非常有用,例如图像分割或语义分割任务。

以下是一些关于空洞卷积的重要概念:
膨胀率(Dilation Rate):膨胀率定义了卷积核中间的空洞之间的距离。通常,一个膨胀率为1的卷积核与普通卷积相同。增加膨胀率会使卷积核在输入上跳过更多的像素,从而增大感受野。

感受野(Receptive Field):感受野是指卷积神经网络中每个神经元的输入区域。较大的感受野可以捕获更广泛的上下文信息。

空洞卷积前后特征图尺寸计算
设输入特征图的尺寸为H_in × W_in,卷积核的大小为K,空洞率为d,则输出特征图的尺寸计算公式如下:
H_out = (H_in + 2 * padding - dilation * (K - 1) - 1) / stride + 1
W_out = (W_in + 2 * padding - dilation * (K - 1) - 1) / stride + 1
其中,padding是填充大小,stride是步长。
例如:输入特征图尺寸为:64x64,填充大小padding=0,步长stride=1,卷积核大小K=3x3,空洞率d=2,则:
H_out = (H_in + 2 * padding - dilation * (K - 1) - 1) / stride + 1
  =(64+2*0-2(3-1)-1)/1+1=60
W_out = (H_in + 2 * padding - dilation * (K - 1) - 1) / stride + 1
  =(64+2*0-2(3-1)-1)/1+1=60
即输出的特征图尺寸为60*60

需要注意的是,空洞卷积相较于普通卷积,可以在不增加模型参数和计算量的情况下,增大感受野,捕捉更多的上下文信息。但同时,它可能会导致特征图的尺寸减小,因此可能需要进一步处理特征图的尺寸变化,如通过填充或池化操作来保持尺寸一致性。

以下是一个简单的Python代码示例,使用PyTorch来实现一个带有空洞卷积的网络层:

import torch

import torch.nn as nn

# 定义一个包含空洞卷积的神经网络层

class DilatedConvolutionalLayer(nn.Module):

    def __init__(self, in_channels, out_channels, kernel_size, dilation):

        super(DilatedConvolutionalLayer, self).__init__()

        self.conv = nn.Conv2d(in_channels, out_channels, kernel_size, dilation=dilation)

    def forward(self, x):

        return self.conv(x)

# 创建一个输入张量

input_tensor = torch.randn(1, 3, 64, 64)  # 1个样本,3个通道,64x64的输入图像

# 创建一个具有空洞卷积的神经网络层

dilated_layer = DilatedConvolutionalLayer(in_channels=3, out_channels=64, kernel_size=3, dilation=2)

# 将输入传递给空洞卷积层

output_tensor = dilated_layer(input_tensor)

# 输出张量的形状

print("输入张量形状:", input_tensor.shape)

print("输出张量形状:", output_tensor.shape)



输出结果:
输入张量形状: torch.Size([1, 3, 64, 64])
输出张量形状: torch.Size([1, 64, 60, 60])
跟我们上面的计算是一样的!


AIHIA梦工厂,共建AI人脉圈,共享AI时代美好生活!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

AIHIA梦工厂旨在建立涵盖广泛人工智能行业,包括AI芯片、AI工业应用、AI电商、AI自动驾驶、AI智慧城市、智慧农业等人工智能应用领域。梦工厂为每位AI人提供技术交流、需求对接、行业资源、招聘求职、人脉拓展等多个方面交流学习平台促进人工智能的发展和应用。
  • 官方手机版

  • 联盟公众号

  • 商务合作

  • Powered by Discuz! X3.5 | Copyright © 2023, AIHIA梦工厂
  • 苏ICP备2023025400号-1 | 苏公网安备32021402002407 | 电信增值许可证:苏B2-20231396 | 无锡腾云驾数技术服务有限公司 QQ