【从零开始学习深度学习】21. 卷积神经网络(CNN)之二维卷积层原理介绍、如何用卷积层检测物体边缘

简介: 【从零开始学习深度学习】21. 卷积神经网络(CNN)之二维卷积层原理介绍、如何用卷积层检测物体边缘

卷积神经网络(convolutional neural network)是含有卷积层(convolutional layer)的神经网络。最常见的卷积神经网络均使用二维卷积层。它有高和宽两个空间维度,常用来处理图像数据。本文将介绍简单形式的二维卷积层工作原理。

1. 二维互相关运算

虽然卷积层得名于卷积(convolution)运算,但我们通常在卷积层中使用更加直观的互相关(cross-correlation)运算。在二维卷积层中,一个二维输入数组和一个二维核(kernel)数组通过互相关运算输出一个二维数组。

我们用一个具体例子来解释二维互相关运算的含义。如下图所示,输入是一个高和宽均为3的二维数组。我们将该数组的形状记为3 × 3 3 \times 33×3或(3,3)。核数组的高和宽分别为2。该数组在卷积计算中又称卷积核或过滤器(filter)。卷积核窗口(又称卷积窗口)的形状取决于卷积核的高和宽,即2 × 2 2 \times 22×2。图中的阴影部分为第一个输出元素及其计算所使用的输入和核数组元素:0 × 0 + 1 × 1 + 3 × 2 + 4 × 3 = 19 0\times0+1\times1+3\times2+4\times3=190×0+1×1+3×2+4×3=19

在二维互相关运算中,卷积窗口从输入数组的最左上方开始,按从左往右、从上往下的顺序,依次在输入数组上滑动。当卷积窗口滑动到某一位置时,窗口中的输入子数组与核数组按对应元素相乘并求和,得到输出数组中相应位置的元素。图中的输出数组高和宽分别为2,其中的4个元素由二维互相关运算得出,计算如下:

image.png

下面我们将上述过程实现在corr2d函数里。它接受输入数组X与核数组K,并输出数组Y

import torch 
from torch import nn
def corr2d(X, K): 
    # K为卷积核
    h, w = K.shape
    # Y为卷积计算后的输出,形状为X.shape[0] - h + 1, X.shape[1] - w + 1
    Y = torch.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1))
    for i in range(Y.shape[0]):
        for j in range(Y.shape[1]):
            Y[i, j] = (X[i: i + h, j: j + w] * K).sum()
    return Y

我们可以构造上图1中的输入数组X、核数组K来验证二维互相关运算的输出。

X = torch.tensor([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
K = torch.tensor([[0, 1], [2, 3]])
corr2d(X, K)

输出:

tensor([[19., 25.],
        [37., 43.]])

2. 自定义二维卷积

二维卷积层将输入和卷积核做互相关运算,并加上一个标量偏差来得到输出。卷积层的模型参数包括了卷积核标量偏差在训练模型的时候,通常我们先对卷积核随机初始化,然后不断迭代卷积核和偏差

下面基于corr2d函数来实现一个自定义的二维卷积层。在构造函数__init__里我们声明weightbias这两个模型参数。前向计算函数forward则是直接调用corr2d函数再加上偏差。

class Conv2D(nn.Module):
    def __init__(self, kernel_size):
        super(Conv2D, self).__init__()
        self.weight = nn.Parameter(torch.randn(kernel_size))
        self.bias = nn.Parameter(torch.randn(1))
    def forward(self, x):
        return corr2d(x, self.weight) + self.bias

卷积窗口形状为p × q p \times qp×q的卷积层称为p × q p \times qp×q卷积层。同样,p × q p \times qp×q卷积或p × q p \times qp×q卷积核说明卷积核的高和宽分别为p ppq qq

3. 卷积层的应用----图像中物体边缘检测

下面我们来看一个卷积层的简单应用:检测图像中物体的边缘,即找到像素变化的位置。首先我们构造一张6 × 8 6\times 86×8的图像(即高和宽分别为6像素和8像素的图像)。它中间4列为黑(0),其余为白(1)。

X = torch.ones(6, 8)
X[:, 2:6] = 0
X

输出:

tensor([[1., 1., 0., 0., 0., 0., 1., 1.],
        [1., 1., 0., 0., 0., 0., 1., 1.],
        [1., 1., 0., 0., 0., 0., 1., 1.],
        [1., 1., 0., 0., 0., 0., 1., 1.],
        [1., 1., 0., 0., 0., 0., 1., 1.],
        [1., 1., 0., 0., 0., 0., 1., 1.]])

然后我们构造一个高和宽分别为1和2的卷积核K当它与输入做互相关运算时,如果横向相邻元素相同,输出为0;否则输出为非0

K = torch.tensor([[1, -1]])

下面将输入X和我们设计的卷积核K做互相关运算。可以看出,我们将从白到黑的边缘和从黑到白的边缘分别检测成了1和-1。其余部分的输出全是0。

Y = corr2d(X, K)
Y

输出:

tensor([[ 0.,  1.,  0.,  0.,  0., -1.,  0.],
        [ 0.,  1.,  0.,  0.,  0., -1.,  0.],
        [ 0.,  1.,  0.,  0.,  0., -1.,  0.],
        [ 0.,  1.,  0.,  0.,  0., -1.,  0.],
        [ 0.,  1.,  0.,  0.,  0., -1.,  0.],
        [ 0.,  1.,  0.,  0.,  0., -1.,  0.]])

由此,我们可以看出,卷积层可通过重复使用卷积核有效地表征局部空间

4. 通过数据学习核数组

我们使用上面物体边缘检测中的输入数据X和输出数据Y来学习我们构造的核数组K。我们首先构造一个卷积层,其卷积核将被初始化成随机数组。接下来在每一次迭代中,我们使用平方误差来比较Y和卷积层的输出,然后计算梯度来更新权重。

# 构造一个核数组形状是(1, 2)的二维卷积层
conv2d = Conv2D(kernel_size=(1, 2))
step = 20
lr = 0.01
for i in range(step):
    Y_hat = conv2d(X)
    l = ((Y_hat - Y) ** 2).sum()
    l.backward()
    
    # 梯度下降
    conv2d.weight.data -= lr * conv2d.weight.grad
    conv2d.bias.data -= lr * conv2d.bias.grad
    
    # 梯度清0
    conv2d.weight.grad.fill_(0)
    conv2d.bias.grad.fill_(0)
    if (i + 1) % 5 == 0:
        print('Step %d, loss %.3f' % (i + 1, l.item()))

输出:

Step 5, loss 1.844
Step 10, loss 0.206
Step 15, loss 0.023
Step 20, loss 0.003

可以看到,20次迭代后误差已经降到了一个比较小的值。现在来看一下学习到的卷积核的参数。

print("weight: ", conv2d.weight.data)
print("bias: ", conv2d.bias.data)

输出:

weight:  tensor([[ 0.9948, -1.0092]])
bias:  tensor([0.0080])

可以看到,学到的卷积核的权重参数与我们之前定义的核数组K较接近,而偏置参数接近0。

5. 互相关运算和卷积运算

实际上,卷积运算与互相关运算类似。为了得到卷积运算的输出,我们只需将核数组左右翻转并上下翻转,再与输入数组做互相关运算。可见,卷积运算和互相关运算虽然类似,但如果它们使用相同的核数组,对于同一个输入,输出往往并不相同。

那么,你也许会好奇卷积层为何能使用互相关运算替代卷积运算。其实,在深度学习中核数组都是学出来的:卷积层无论使用互相关运算或卷积运算都不影响模型预测时的输出。为了解释这一点,假设卷积层使用互相关运算学出图1中的核数组。设其他条件不变,使用卷积运算学出的核数组即图1中的核数组按上下、左右翻转。也就是说,图1中的输入与学出的已翻转的核数组再做卷积运算时,依然得到图1中的输出。为了与大多数深度学习文献一致,如无特别说明,本书中提到的卷积运算均指互相关运算

6. 特征图和感受野

二维卷积层输出的二维数组可以看作是输入在空间维度(宽和高)上某一级的表征,也叫特征图(feature map)。影响元素x xx的前向计算的所有可能输入区域(可能大于输入的实际尺寸)叫做x xx感受野(receptive field)。以图1为例,输入中阴影部分的四个元素是输出中阴影部分元素的感受野。我们将图1中形状为2×2的输出记为Y,并考虑一个更深的卷积神经网络:将Y与另一个形状为2×2的核数组做互相关运算,输出单个元素z。那么,zY上的感受野包括Y的全部四个元素,在输入上的感受野包括其中全部9个元素。可见,我们可以通过更深的卷积神经网络使特征图中单个元素的感受野变得更加广阔,从而捕捉输入上更大尺寸的特征

总结

  • 二维卷积层的核心计算是二维互相关运算。在最简单的形式下,它对二维输入数据和卷积核做互相关运算然后加上偏差。
  • 我们可以设计卷积核来检测图像中的边缘。
  • 我们可以通过数据来学习卷积核。

相关文章
|
18天前
|
机器学习/深度学习 计算机视觉 网络架构
【YOLO11改进 - C3k2融合】C3k2DWRSeg二次创新C3k2_DWR:扩张式残差分割网络,提高特征提取效率和多尺度信息获取能力,助力小目标检测
【YOLO11改进 - C3k2融合】C3k2DWRSeg二次创新C3k2_DWR:扩张式残差分割网络,提高特征提取效率和多尺度信息获取能力,助力小目DWRSeg是一种高效的实时语义分割网络,通过将多尺度特征提取分为区域残差化和语义残差化两步,提高了特征提取效率。它引入了Dilation-wise Residual (DWR) 和 Simple Inverted Residual (SIR) 模块,优化了不同网络阶段的感受野。在Cityscapes和CamVid数据集上的实验表明,DWRSeg在准确性和推理速度之间取得了最佳平衡,达到了72.7%的mIoU,每秒319.5帧。代码和模型已公开。
【YOLO11改进 - C3k2融合】C3k2DWRSeg二次创新C3k2_DWR:扩张式残差分割网络,提高特征提取效率和多尺度信息获取能力,助力小目标检测
|
5天前
|
安全 Linux 网络安全
nmap 是一款强大的开源网络扫描工具,能检测目标的开放端口、服务类型和操作系统等信息
nmap 是一款强大的开源网络扫描工具,能检测目标的开放端口、服务类型和操作系统等信息。本文分三部分介绍 nmap:基本原理、使用方法及技巧、实际应用及案例分析。通过学习 nmap,您可以更好地了解网络拓扑和安全状况,提升网络安全管理和渗透测试能力。
30 5
|
8天前
|
机器学习/深度学习 人工智能 算法框架/工具
深度学习中的卷积神经网络(CNN)及其在图像识别中的应用
【10月更文挑战第36天】探索卷积神经网络(CNN)的神秘面纱,揭示其在图像识别领域的威力。本文将带你了解CNN的核心概念,并通过实际代码示例,展示如何构建和训练一个简单的CNN模型。无论你是深度学习的初学者还是希望深化理解,这篇文章都将为你提供有价值的见解。
|
8天前
|
运维 物联网 网络虚拟化
网络功能虚拟化(NFV):定义、原理及应用前景
网络功能虚拟化(NFV):定义、原理及应用前景
23 3
|
9天前
|
机器学习/深度学习 人工智能 自动驾驶
深入解析深度学习中的卷积神经网络(CNN)
深入解析深度学习中的卷积神经网络(CNN)
26 0
|
12天前
|
机器学习/深度学习 人工智能 TensorFlow
深度学习中的卷积神经网络(CNN)及其在图像识别中的应用
【10月更文挑战第32天】本文将介绍深度学习中的一个重要分支——卷积神经网络(CNN),以及其在图像识别领域的应用。我们将通过一个简单的代码示例,展示如何使用Python和TensorFlow库构建一个基本的CNN模型,并对其进行训练和测试。
|
18天前
|
机器学习/深度学习 计算机视觉 网络架构
【YOLO11改进 - C3k2融合】C3k2融合DWRSeg二次创新C3k2_DWRSeg:扩张式残差分割网络,提高特征提取效率和多尺度信息获取能力,助力小目标检测
【YOLO11改进 - C3k2融合】C3k2融合DWRSDWRSeg是一种高效的实时语义分割网络,通过将多尺度特征提取方法分解为区域残差化和语义残差化两步,提高了多尺度信息获取的效率。网络设计了Dilation-wise Residual (DWR) 和 Simple Inverted Residual (SIR) 模块,分别用于高阶段和低阶段,以充分利用不同感受野的特征图。实验结果表明,DWRSeg在Cityscapes和CamVid数据集上表现出色,以每秒319.5帧的速度在NVIDIA GeForce GTX 1080 Ti上达到72.7%的mIoU,超越了现有方法。代码和模型已公开。
|
18天前
|
机器学习/深度学习 自然语言处理 TensorFlow
深度学习中的卷积神经网络(CNN)及其应用
【10月更文挑战第26天】在这篇文章中,我们将深入探讨卷积神经网络(CNN)的基本原理、结构和应用。CNN是深度学习领域的一个重要分支,广泛应用于图像识别、语音处理等领域。我们将通过代码示例和实际应用案例,帮助读者更好地理解CNN的概念和应用。
|
19天前
|
网络协议 安全 算法
网络空间安全之一个WH的超前沿全栈技术深入学习之路(9-2):WireShark 简介和抓包原理及实战过程一条龙全线分析——就怕你学成黑客啦!
实战:WireShark 抓包及快速定位数据包技巧、使用 WireShark 对常用协议抓包并分析原理 、WireShark 抓包解决服务器被黑上不了网等具体操作详解步骤;精典图示举例说明、注意点及常见报错问题所对应的解决方法IKUN和I原们你这要是学不会我直接退出江湖;好吧!!!
|
9天前
|
机器学习/深度学习 人工智能 测试技术
深度学习在图像识别中的应用与挑战
本文探讨了深度学习技术,尤其是卷积神经网络(CNN)在图像识别任务中的最新进展和面临的主要挑战。通过分析不同的网络架构、训练技巧以及优化策略,文章旨在提供一个全面的概览,帮助研究人员和实践者更好地理解和应用这些技术。
40 9