一篇文章弄懂卷积神经网络基础概念

一篇文章弄懂卷积神经网络基础概念

卷积神经网络可以说是图像处理的天花板,也是当下图像处理在深度学习方面最热门的研究。接下来,从卷积核、池化、全连接等方面介绍卷积神经网络中的关键操作。

下采样和上采样

  • 下采样即由输入图像中提取特征。其中有两个作用,一是减少计算量,防止过拟合;二是增大感受野,使得后面的卷积核能够学到更加全局的信息。下采样常用的方式有两种:采用stride为2的池化层和采用stride为2的卷积层(下采样的过程是一个信息损失的过程)。
  • 上采样即将图像恢复到原来的尺寸(使图像由小分辨率映射到大分辨率)。其目的是为了进一步计算(图像补全、图像的语义分割),上采样常用的方式有三种:插值法、转置卷积以及Up-Pooling。

该文章中下采样主要为卷积(普通卷积、空洞卷积、池化)而上采样主要为转置卷积。

卷积

卷积操作的作用是提取图像中的局部信息。卷积核的大小通常比输入数据小,因此每次卷积计算得到的是输入数据的一个小的局部区域的特征。通过不同大小的卷积核和不同的卷积核数量,可以提取出不同尺度和不同方向的特征。
在这里插入图片描述

普通卷积

import torch
import torch.nn as nn
# 定义输入
input_data = torch.tensor([[[
                             [0.1 ,0.2,0.3,0.1,0.1,0.5],
                             [0.2,0.1,0.2,0.3,0.1,0.1],
                             [0.2,0.1,0.2,0.3,0.1,0.1],
                             [0.2,0.1,0.2,0.3,0.1,0.1],
                             [0.2,0.1,0.2,0.3,0.1,0.1],
                             [0.2,0.1,0.2,0.3,0.1,0.1]
                            ]]])
print(input_data)# 查看自定义张量input_data
# 定义标准卷积层
conv = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=3, stride=1, padding=0)
print(conv.state_dict())# 返回一个字典,其中包含了模型的所有参数
# 进行普通卷积操作
conv_result = conv(input_data)
print('Convolution result shape:', conv_result.shape)# 查看卷积操作后的形态
print('Convolution result:', conv_result)# 查看卷积操作后的结果

输出结果

tensor([[[[0.1000, 0.2000, 0.3000, 0.1000, 0.1000, 0.5000],
          [0.2000, 0.1000, 0.2000, 0.3000, 0.1000, 0.1000],
          [0.2000, 0.1000, 0.2000, 0.3000, 0.1000, 0.1000],
          [0.2000, 0.1000, 0.2000, 0.3000, 0.1000, 0.1000],
          [0.2000, 0.1000, 0.2000, 0.3000, 0.1000, 0.1000],
          [0.2000, 0.1000, 0.2000, 0.3000, 0.1000, 0.1000]]]])
OrderedDict([('weight', tensor([[[[-0.3229,  0.2283,  0.2123],
          [ 0.1449, -0.1590,  0.1524],
          [-0.2071, -0.0818,  0.2543]]]])), ('bias', tensor([-0.1603]))])
Convolution result shape: torch.Size([1, 1, 4, 4])
Convolution result: tensor([[[[-0.0384, -0.0675, -0.2571, -0.0657],
          [-0.1148, -0.0156, -0.1792, -0.2152],
          [-0.1148, -0.0156, -0.1792, -0.2152],
          [-0.1148, -0.0156, -0.1792, -0.2152]]]],
       grad_fn=<ConvolutionBackward0>)

空洞卷积

空洞卷积是卷积神经网络中的一种卷积方式,它的作用主要有以下几个方面:

  1. 扩大感受野:在传统卷积操作中,每个卷积核只能获取相邻的像素信息。而空洞卷积通过在卷积核内部增加跳跃的间隔(即空洞大小),可以让卷积核获取更远的像素信息,从而扩大感受野,提高图像识别的准确率。
  2. 减少参数量:在传统卷积操作中,每个卷积核的参数量取决于卷积核大小和通道数。而空洞卷积通过增加卷积核的空洞大小,可以在不增加参数量的情况下扩大感受野。
  3. 保持分辨率:在传统的卷积操作中,通过池化操作可以降低特征图的分辨率,从而减少计算量。而空洞卷积可以在不降低分辨率的情况下扩大感受野,从而保持特征图的分辨率。
  4. 改善边缘信息:在传统卷积操作中,由于卷积核只能获取相邻的像素信息,因此对于边缘信息的提取效果不佳。而空洞卷积通过扩大感受野,可以获取更远的像素信息,从而改善边缘信息的提取效果。

在这里插入图片描述

import torch
import torch.nn as nn
# 定义输入
input_data = torch.tensor([[[
                             [0.1 ,0.2,0.3,0.1,0.1,0.5],
                             [0.2,0.1,0.2,0.3,0.1,0.1],
                             [0.2,0.1,0.2,0.3,0.1,0.1],
                             [0.2,0.1,0.2,0.3,0.1,0.1],
                             [0.2,0.1,0.2,0.3,0.1,0.1],
                             [0.2,0.1,0.2,0.3,0.1,0.1]
                            ]]])
print(input_data)
# 定义标准卷积层和空洞卷积层
conv = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=3, stride=1, padding=0)
print(conv.state_dict())
# 空洞卷积输出结果
dilated_conv = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=3, stride=1, padding=2, dilation=2)
print(dilated_conv.state_dict())# 返回一个字典,其中包含了模型的所有参数
dilated_conv_result = dilated_conv(input_data)
print('Dilated convolution result shape:', dilated_conv_result.shape)# 查看卷积操作后的形态
print('Dilated convolution result:', dilated_conv_result)

输出结果


tensor([[[[0.1000, 0.2000, 0.3000, 0.1000, 0.1000, 0.5000],
          [0.2000, 0.1000, 0.2000, 0.3000, 0.1000, 0.1000],
          [0.2000, 0.1000, 0.2000, 0.3000, 0.1000, 0.1000],
          [0.2000, 0.1000, 0.2000, 0.3000, 0.1000, 0.1000],
          [0.2000, 0.1000, 0.2000, 0.3000, 0.1000, 0.1000],
          [0.2000, 0.1000, 0.2000, 0.3000, 0.1000, 0.1000]]]])
OrderedDict([('weight', tensor([[[[ 0.0818,  0.1001, -0.1972],
          [-0.0940, -0.2605,  0.1210],
          [ 0.1136,  0.2079,  0.0602]]]])), ('bias', tensor([-0.0697]))])
OrderedDict([('weight', tensor([[[[-0.2004, -0.2327, -0.1165],
          [-0.0940,  0.0574, -0.0417],
          [-0.0378, -0.2901,  0.3276]]]])), ('bias', tensor([0.3039]))])
Dilated convolution result shape: torch.Size([1, 1, 6, 6])
Dilated convolution result: tensor([[[[0.3047, 0.3805, 0.2748, 0.2120, 0.2449, 0.2829],
          [0.3146, 0.3664, 0.2596, 0.2495, 0.2543, 0.2411],
          [0.2563, 0.3082, 0.1581, 0.1279, 0.1709, 0.1047],
          [0.2447, 0.3082, 0.1613, 0.1480, 0.1909, 0.1577],
          [0.2372, 0.2389, 0.1941, 0.2060, 0.2275, 0.1980],
          [0.2372, 0.2389, 0.1941, 0.2060, 0.2275, 0.1980]]]],
       grad_fn=<ConvolutionBackward0>)

转置卷积

反卷积(Deconvolution)操作是卷积神经网络(CNN)中的一种常见操作,也称为转置卷积[2](Transposed Convolution)或分数步长卷积(Fractionally Strided Convolution)。在CNN中,卷积操作常用于提取输入图像的特征,反卷积操作则用于将特征图还原为原始图像或进行像素级别的分割。
在这里插入图片描述

import torch
import torch.nn as nn
# 定义输入和卷积核
t = torch.tensor([[
                   [ 0.1 , 0.2 ],
                   [ 0.2 , 0.1 ]]
                 ])
print(type(t),t)
# in_channels表示输入通道数,out_channels表示输出通道数,kernel_size表示卷积核大小
conv_transpose = nn.ConvTranspose2d(in_channels=1, out_channels=1, kernel_size=2, stride=1)
print(conv_transpose.state_dict())# 返回一个字典,其中包含了模型的所有参数
# 输出结果
conv_transpose_result = conv_transpose(t)
print('conv_transpose_result:', conv_transpose_result)

输出结果

<class 'torch.Tensor'> tensor([[[0.1000, 0.2000],
         [0.2000, 0.1000]]])
OrderedDict([('weight', tensor([[[[ 0.1511, -0.4327],
          [ 0.2216,  0.0240]]]])), ('bias', tensor([-0.4246]))])
tensor([[[-0.4095, -0.4377, -0.5112],
         [-0.3722, -0.4493, -0.4631],
         [-0.3803, -0.3976, -0.4222]]], grad_fn=<SqueezeBackward1>)

膨胀卷积和转置卷积的区别

转置卷积和膨胀卷积是两个不同的概念,它们之间的作用和区别如下所述:

  1. 转置卷积是一种反卷积操作,也称为反卷积或上采样(upsampling)操作。它的作用是将输入张量的大小扩大,通常用于图像分割、语义分割、图像生成等任务中。转置卷积的核函数可以看作是卷积核的转置,可以通过反向卷积来实现。在转置卷积中,卷积核的大小和步长是可调的,通过调整这些参数可以控制输出的大小和形状。
  2. 膨胀卷积是一种空洞卷积(dilated convolution)操作,它的作用是在不增加模型参数和计算量的情况下增加卷积层的感受野(receptive field)。膨胀卷积通过在卷积核中间插入一些空洞(dilation)来实现,这些空洞可以增加卷积核的有效大小。在膨胀卷积中,卷积核的大小和步长是固定的,但通过调整膨胀率可以控制卷积核的感受野。
  3. 两者的区别 转置卷积和膨胀卷积都是卷积神经网络中常用的操作,但它们的作用和使用场景是不同的。转置卷积用于对输入张量进行上采样操作,通常用于图像分割、图像生成等任务中。而膨胀卷积用于增加卷积层的感受野,可以提高模型对图像中局部特征的识别能力,通常用于语义分割、物体检测等任务中。此外,转置卷积的核函数大小和步长是可调的,而膨胀卷积的核函数大小和步长是固定的,但可以通过调整膨胀率来控制卷积核的感受野。

感受野:指卷积神经网络中每个输出特征图的每个像素点对应输入图像的区域大小。

池化

池化操作(Pooling)其主要作用是在卷积层之间减少特征图的维度,从而减少模型的参数数量和计算量,避免过拟合。常见的池化操作有最大池化(Max Pooling)和平均池化(Average Pooling)两种。

最大池化

最大池化计算简单而且能够更好的保留纹理特征,得到的图像颜色更亮。

import torch
import torch.nn as nn
# 创建一个最大池化层,池化窗口大小为3x3,步长为1
pool = nn.MaxPool2d(kernel_size=3, stride=1)
print(pool)
# 创建一个输入张量,大小为(1, 1, 4, 4)
x = torch.Tensor([[[
                    [ 1,  2,  3,  4], 
                    [ 5,  6,  7,  8], 
                    [ 9, 10, 11, 12], 
                    [13, 14, 15, 16]
                ]]])
# 将输入张量传递给池化层,并计算输出
output = pool(x)
# 打印输出张量
print(output)

输出结果

MaxPool2d(kernel_size=3, stride=1, padding=0, dilation=1, ceil_mode=False)
tensor([[[[11., 12.],
          [15., 16.]]]])

平均池化

import torch
import torch.nn as nn
# 创建一个最大池化层,池化窗口大小为3x3,步长为1
pool = nn.AvgPool2d(kernel_size=3, stride=1)
print(pool)
# 创建一个输入张量,大小为(1, 1, 4, 4)
x = torch.Tensor([[[
                    [ 1,  2,  3,  4], 
                    [ 5,  6,  7,  8], 
                    [ 9, 10, 11, 12], 
                    [13, 14, 15, 16]
                ]]])
# 将输入张量传递给池化层,并计算输出
output = pool(x)
# 打印输出张量
print(output)

输出结果

AvgPool2d(kernel_size=3, stride=1, padding=0)
tensor([[[[ 6.,  7.],
          [10., 11.]]]])

注:池化层是不可学习的,用stride为2的可学习卷积层来代替pooling可以得到更好的效果,当然同时也增加了一定的计算量。

全连接

全连接层(Fully Connected Layer)是卷积神经网络中的一种常用层,通常位于卷积层和输出层之间。全连接层的作用是将经过卷积层和池化层处理后的特征图进行展平(Flatten),然后连接一个或多个全连接层进行分类或回归。

import torch
import torch.nn as nn
# 创建一个全连接层,输入维度为4,输出维度为2
fc = nn.Linear(4, 2)
print(fc.state_dict())# 返回一个字典,其中包含了模型的所有参数
# 创建一个输入张量,大小为(1, 4)
x = torch.tensor([0.1,0.2,0.2,0.1])
# 将输入张量传递给全连接层,并计算输出
output = fc(x)
# 打印输出张量
print(output)# 第一个:-0.4654×0.1+0.0059 ×0.2+ 0.2813×0.2+0.1×(-0.2186)-0.3949 = -0.40586

输出结果

OrderedDict([('weight', tensor([[-0.4654,  0.0059,  0.2813, -0.2186],
        [ 0.4194,  0.0747,  0.2652,  0.0923]])), ('bias', tensor([-0.3949, -0.1806]))])
tensor([-0.4059, -0.0615], grad_fn=<AddBackward0>)
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
卷积神经网络(Convolutional Neural Network,CNN)是一种深度学习模型,主要用于图像识别和计算机视觉任务。它的基本概念包括以下几个方面: 1. 卷积层(Convolutional Layer):卷积层是CNN的核心组成部分,通过使用一系列可学习的滤波器(也称为卷积核)对输入图像进行卷积操作,提取图像的特征。每个滤波器会在输入图像上滑动,并计算出对应位置的卷积结果,生成一个特征图。 2. 池化层(Pooling Layer):池化层用于减小特征图的空间尺寸,同时保留重要的特征信息。常见的池化操作包括最大池化和平均池化,它们分别选取局部区域中的最大值或平均值作为池化结果。 3. 激活函数(Activation Function):激活函数引入非线性变换,增加模型的表达能力。在卷积神经网络中,常用的激活函数包括ReLU(Rectified Linear Unit)、Sigmoid和Tanh等。 4. 全连接层(Fully Connected Layer):全连接层将前面的卷积层和池化层的输出连接起来,并通过一系列的全连接操作进行分类或回归等任务。 5. 权重共享(Weight Sharing):卷积神经网络中的卷积操作具有权重共享的特性,即在不同位置使用相同的卷积核进行卷积计算。这样可以大大减少需要学习的参数数量,提高模型的效率和泛化能力。 6. 多层网络结构:卷积神经网络通常由多个卷积层、池化层和全连接层组成,通过堆叠多个层次来提取更高级别的特征表示。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值