【现代深度学习技术】卷积神经网络 | 图像卷积

news/2025/2/25 9:06:23

在这里插入图片描述

【作者主页】Francek Chen
【专栏介绍】 ⌈ ⌈ PyTorch深度学习 ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上,结合当代大数据和大算力的发展而发展出来的。深度学习最重要的技术特征是具有自动提取特征的能力。神经网络算法、算力和数据是开展深度学习的三要素。深度学习在计算机视觉、自然语言处理、多模态数据分析、科学探索等领域都取得了很多成果。本专栏介绍基于PyTorch的深度学习算法实现。
【GitCode】专栏资源保存在我的GitCode仓库:https://gitcode.com/Morse_Chen/PyTorch_deep_learning。

文章目录

    • 一、互相关运算
    • 二、卷积层
    • 三、图像中目标的边缘检测
    • 四、学习卷积核
    • 五、互相关和卷积
    • 六、特征映射和感受野
    • 小结


  上节我们解析了卷积层的原理,现在我们看看它的实际应用。由于卷积神经网络的设计是用于探索图像数据,本节我们将以图像为例。

一、互相关运算

  严格来说,卷积层是个错误的叫法,因为它所表达的运算其实是互相关运算(cross-correlation),而不是卷积运算。根据【现代深度学习技术】卷积神经网络 | 从全连接层到卷积 中的描述,在卷积层中,输入张量和核张量通过互相关运算产生输出张量。

  首先,我们暂时忽略通道(第三维)这一情况,看看如何处理二维图像数据和隐藏表示。在图1中,输入是高度为 3 3 3、宽度为 3 3 3的二维张量(即形状为 3 × 3 3 \times 3 3×3)。卷积核的高度和宽度都是 2 2 2,而卷积核窗口(或卷积窗口)的形状由内核的高度和宽度决定(即 2 × 2 2 \times 2 2×2)。

在这里插入图片描述

图1 二维互相关运算。阴影部分是第一个输出元素,以及用于计算输出的输入张量元素和核张量元素:0×0+1×1+3×2+4×3=19

  在二维互相关运算中,卷积窗口从输入张量的左上角开始,从左到右、从上到下滑动。当卷积窗口滑动到新一个位置时,包含在该窗口中的部分张量与卷积核张量进行按元素相乘,得到的张量再求和得到一个单一的标量值,由此我们得出了这一位置的输出张量值。在如上例子中,输出张量的四个元素由二维互相关运算得到,这个输出高度为 2 2 2、宽度为 2 2 2,如下所示:
0 × 0 + 1 × 1 + 3 × 2 + 4 × 3 = 19 1 × 0 + 2 × 1 + 4 × 2 + 5 × 3 = 25 3 × 0 + 4 × 1 + 6 × 2 + 7 × 3 = 37 4 × 0 + 5 × 1 + 7 × 2 + 8 × 3 = 43 (1) \begin{aligned} 0\times0+1\times1+3\times2+4\times3=19\\ 1\times0+2\times1+4\times2+5\times3=25\\ 3\times0+4\times1+6\times2+7\times3=37\\ 4\times0+5\times1+7\times2+8\times3=43 \end{aligned} \tag{1} 0×0+1×1+3×2+4×3=191×0+2×1+4×2+5×3=253×0+4×1+6×2+7×3=374×0+5×1+7×2+8×3=43(1)

  注意,输出大小略小于输入大小。这是因为卷积核的宽度和高度大于1,而卷积核只与图像中每个大小完全适合的位置进行互相关运算。所以,输出大小等于输入大小 n h × n w n_h \times n_w nh×nw减去卷积核大小 k h × k w k_h \times k_w kh×kw,即:
( n h − k h + 1 ) × ( n w − k w + 1 ) (2) (n_h-k_h+1) \times (n_w-k_w+1) \tag{2} (nhkh+1)×(nwkw+1)(2) 这是因为我们需要足够的空间在图像上“移动”卷积核。稍后,我们将看到如何通过在图像边界周围填充零来保证有足够的空间移动卷积核,从而保持输出大小不变。接下来,我们在corr2d函数中实现如上过程,该函数接受输入张量X和卷积核张量K,并返回输出张量Y

import torch
from torch import nn
from d2l import torch as d2l
def corr2d(X, K):  #@save
    """计算二维互相关运算"""
    h, w = K.shape
    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.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]])
K = torch.tensor([[0.0, 1.0], [2.0, 3.0]])
corr2d(X, K)

在这里插入图片描述

二、卷积层

  卷积层对输入和卷积核权重进行互相关运算,并在添加标量偏置之后产生输出。所以,卷积层中的两个被训练的参数是卷积核权重和标量偏置。就像我们之前随机初始化全连接层一样,在训练基于卷积层的模型时,我们也随机初始化卷积核权重。

  基于上面定义的corr2d函数实现二维卷积层。在__init__构造函数中,将weightbias声明为两个模型参数。前向传播函数调用corr2d函数并添加偏置。

class Conv2D(nn.Module):
    def __init__(self, kernel_size):
        super().__init__()
        self.weight = nn.Parameter(torch.rand(kernel_size))
        self.bias = nn.Parameter(torch.zeros(1))

    def forward(self, x):
        return corr2d(x, self.weight) + self.bias

  高度和宽度分别为 h h h w w w的卷积核可以被称为 h × w h \times w h×w卷积或 h × w h \times w h×w卷积核。我们也将带有 h × w h \times w h×w卷积核的卷积层称为 h × w h \times w h×w卷积层。

三、图像中目标的边缘检测

  如下是卷积层的一个简单应用:通过找到像素变化的位置,来检测图像中不同颜色的边缘。首先,我们构造一个 6 × 8 6\times 8 6×8像素的黑白图像。中间四列为黑色( 0 0 0),其余像素为白色( 1 1 1)。

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

在这里插入图片描述

  接下来,我们构造一个高度为 1 1 1、宽度为 2 2 2的卷积核K。当进行互相关运算时,如果水平相邻的两元素相同,则输出为零,否则输出为非零。

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

  然后,我们对参数X(输入)和K(卷积核)执行互相关运算。如下所示,输出Y中的1代表从白色到黑色的边缘,-1代表从黑色到白色的边缘,其他情况的输出为 0 0 0

Y = corr2d(X, K)
Y

在这里插入图片描述

  现在我们将输入的二维图像转置,再进行如上的互相关运算。其输出如下,之前检测到的垂直边缘消失了。不出所料,这个卷积核K只可以检测垂直边缘,无法检测水平边缘。

corr2d(X.t(), K)

在这里插入图片描述

四、学习卷积核

  如果我们只需寻找黑白边缘,那么以上[1, -1]的边缘检测器足以。然而,当有了更复杂数值的卷积核,或者连续的卷积层时,我们不可能手动设计滤波器。那么我们是否可以学习由X生成Y的卷积核呢?

  现在让我们看看是否可以通过仅查看“输入-输出”对来学习由X生成Y的卷积核。我们先构造一个卷积层,并将其卷积核初始化为随机张量。接下来,在每次迭代中,我们比较Y与卷积层输出的平方误差,然后计算梯度来更新卷积核。为了简单起见,我们在此使用内置的二维卷积层,并忽略偏置。

# 构造一个二维卷积层,它具有1个输出通道和形状为(1,2)的卷积核
conv2d = nn.Conv2d(1,1, kernel_size=(1, 2), bias=False)

# 这个二维卷积层使用四维输入和输出格式(批量大小、通道、高度、宽度),
# 其中批量大小和通道数都为1
X = X.reshape((1, 1, 6, 8))
Y = Y.reshape((1, 1, 6, 7))
lr = 3e-2  # 学习率

for i in range(10):
    Y_hat = conv2d(X)
    l = (Y_hat - Y) ** 2
    conv2d.zero_grad()
    l.sum().backward()
    # 迭代卷积核
    conv2d.weight.data[:] -= lr * conv2d.weight.grad
    if (i + 1) % 2 == 0:
        print(f'epoch {i+1}, loss {l.sum():.3f}')

在这里插入图片描述

  在 10 10 10次迭代之后,误差已经降到足够低。现在我们来看看我们所学的卷积核的权重张量。

conv2d.weight.data.reshape((1, 2))

在这里插入图片描述

  细心的读者一定会发现,我们学习到的卷积核权重非常接近我们之前定义的卷积核K

五、互相关和卷积

  回想一下我们在【现代深度学习技术】卷积神经网络 | 从全连接层到卷积 中观察到的互相关和卷积运算之间的对应关系。为了得到正式的卷积运算输出,我们需要执行式(6)中定义的严格卷积运算,而不是互相关运算。幸运的是,它们差别不大,我们只需水平和垂直翻转二维卷积核张量,然后对输入张量执行互相关运算。

  值得注意的是,由于卷积核是从数据中学习到的,因此无论这些层执行严格的卷积运算还是互相关运算,卷积层的输出都不会受到影响。为了说明这一点,假设卷积层执行互相关运算并学习图1中的卷积核,该卷积核在这里由矩阵 K \mathbf{K} K表示。假设其他条件不变,当这个层执行严格的卷积时,学习的卷积核 K ′ \mathbf{K}' K在水平和垂直翻转之后将与 K \mathbf{K} K相同。也就是说,当卷积层对图1中的输入和 K ′ \mathbf{K}' K执行严格卷积运算时,将得到与互相关运算相同的输出。

  为了与深度学习文献中的标准术语保持一致,我们将继续把“互相关运算”称为卷积运算,尽管严格地说,它们略有不同。此外,对于卷积核张量上的权重,我们称其为元素

六、特征映射和感受野

  如在【现代深度学习技术】卷积神经网络 | 从全连接层到卷积 中所述,图1中输出的卷积层有时被称为特征映射(feature map),因为它可以被视为一个输入映射到下一层的空间维度的转换器。在卷积神经网络中,对于某一层的任意元素 x x x,其感受野(receptive field)是指在前向传播期间可能影响 x x x计算的所有元素(来自所有先前层)。

  请注意,感受野可能大于输入的实际大小。让我们用图1为例来解释感受野:给定 2 × 2 2 \times 2 2×2卷积核,阴影输出元素值 19 19 19的感受野是输入阴影部分的四个元素。假设之前输出为 Y \mathbf{Y} Y,其大小为 2 × 2 2 \times 2 2×2,现在我们在其后附加一个卷积层,该卷积层以 Y \mathbf{Y} Y为输入,输出单个元素 z z z。在这种情况下, Y \mathbf{Y} Y上的 z z z的感受野包括 Y \mathbf{Y} Y的所有四个元素,而输入的感受野包括最初所有九个输入元素。因此,当一个特征图中的任意元素需要检测更广区域的输入特征时,我们可以构建一个更深的网络。

小结

  • 二维卷积层的核心计算是二维互相关运算。最简单的形式是,对二维输入数据和卷积核执行互相关操作,然后添加一个偏置。
  • 我们可以设计一个卷积核来检测图像的边缘。
  • 我们可以从数据中学习卷积核的参数。
  • 学习卷积核时,无论用严格卷积运算或互相关运算,卷积层的输出不会受太大影响。
  • 当需要检测输入特征中更广区域时,我们可以构建一个更深的卷积网络。

http://www.niftyadmin.cn/n/5865295.html

相关文章

vue框架后遗症∶被遗忘的dom操作

用多了vue、react等前端框架,不得不说用数据驱动视图来开发真的很香,但是也免不了会有不用这些框架的项目,dom操作还是很有必要的,一开始学习网页设计的时候就教过,后面一直开发项目基本上用框架。虽然有些想不起来了&…

VantUI官网更新2025,移动端前端开发

Vant 2 - Mobile UI Components built on Vue https://vant-ui.github.io/vant/v2/#/zh-CN/quickstart Vant 4 - A lightweight, customizable Vue UI library for mobile web apps. https://vant-ui.github.io/vant/#/zh-CN Vant Weapp - 轻量、可靠的小程序 UI 组件库,微…

同质化?生态壁垒?分析2025年宠物智能硬件行业主要竞品的技术布局

一、宠物智能硬件市场:从百亿蓝海到千亿生态的跨越 2023年全球宠物智能硬件市场规模已突破70亿美元,预计2025年将超过100亿美元,年复合增长率达25%以上。这一增长背后,是三大核心驱动力: 情感消费升级:全球…

计算机毕业设计Hadoop+Spark+DeepSeek-R1大模型民宿推荐系统 hive民宿可视化 民宿爬虫 大数据毕业设计(源码+文档+PPT+讲解)

温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…

常见的Linux面试题

以下是一些常见的Linux面试题: 基础操作类 如何远程连接Linux服务器:常用的工具如Xshell、CRT、FinalShell等,通过SSH协议连接,默认端口是22。 如何查看当前目录下的所有文件(包括隐藏文件):使…

stm32week4

stm32学习 二.外设 12.DMA DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设和存储器或者存储器之间的高速数据传输,无须CPU干预,节省了CPU的资源 12个独立可配置的通道:DMA1(7个通道),DMA2(5个通道) 每个通道都支持软…

Linux提权之sudo提权(十四)

sudo 是一种权限管理机制,管理员可以授权于一些普通用户去执行一些 root 执行的操作,而不需要知道 root 的密码。 首先通过信息收集,查看是否存在sudo配置不当的可能。如果存在,寻找低权限sudo用户的密码,进而提权。 …

开源项目austin学习day01

尝试本地运行项目,遇到如下几个报错: 1.om.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up. 问题:jdbc版本与数据库版本不…