【深度学习实验】卷积神经网络(二):自定义简单的二维卷积神经网络

2024-07-30 08:33:17 浏览数 (2)

一、实验介绍

本实验实现了一个简单的二维卷积神经网络,包括二维互相关运算函数和自定义二维卷积层类,并对一个随机生成是二维张量进行了卷积操作。

二、实验环境

本系列实验使用了PyTorch深度学习框架,相关操作如下:

1. 配置虚拟环境

代码语言:javascript复制
conda create -n DL python=3.7 
代码语言:javascript复制
conda activate DL
代码语言:javascript复制
pip install torch==1.8.1 cu102 torchvision==0.9.1 cu102 torchaudio==0.8.1 -f https://download.pytorch.org/whl/torch_stable.html
代码语言:javascript复制
conda install matplotlib
代码语言:javascript复制
 conda install scikit-learn

2. 库版本介绍

软件包

本实验版本

目前最新版

matplotlib

3.5.3

3.8.0

numpy

1.21.6

1.26.0

python

3.7.16

scikit-learn

0.22.1

1.3.0

torch

1.8.1 cu102

2.0.1

torchaudio

0.8.1

2.0.2

torchvision

0.9.1 cu102

0.15.2

三、实验内容

ChatGPT:

卷积神经网络(Convolutional Neural Network,简称CNN)是一种深度学习模型,广泛应用于图像识别、计算机视觉和模式识别等领域。它的设计灵感来自于生物学中视觉皮层的工作原理。 卷积神经网络通过多个卷积层、池化层全连接层组成。

  • 卷积层主要用于提取图像的局部特征,通过卷积操作和激活函数的处理,可以学习到图像的特征表示。
  • 池化层则用于降低特征图的维度,减少参数数量,同时保留主要的特征信息。
  • 全连接层则用于将提取到的特征映射到不同类别的概率上,进行分类或回归任务。

卷积神经网络在图像处理方面具有很强的优势,它能够自动学习到具有层次结构的特征表示,并且对平移、缩放和旋转等图像变换具有一定的不变性。这些特点使得卷积神经网络成为图像分类、目标检测、语义分割等任务的首选模型。除了图像处理,卷积神经网络也可以应用于其他领域,如自然语言处理和时间序列分析。通过将文本或时间序列数据转换成二维形式,可以利用卷积神经网络进行相关任务的处理。

0. 导入必要的工具包

代码语言:javascript复制
import torch
from torch import nn
import torch.nn.functional as F
  • torch.nn:PyTorch中的神经网络模块,提供了各种神经网络层和函数。
  • torch.nn.functional:PyTorch中的函数形式的神经网络层,如激活函数和损失函数等。
代码语言:javascript复制

1. 二维互相关运算(corr2d)

【深度学习实验】卷积神经网络(一):卷积运算及其Pytorch实现(一维卷积:窄卷积、宽卷积、等宽卷积;二维卷积)_QomolangmaH的博客-CSDN博客

https://blog.csdn.net/m0_63834988/article/details/133278425?spm=1001.2014.3001.5501

如前文所示,在计算卷积的过程中,需要进行卷积核翻转.在具体实现上,一般会以互相关操作来代替卷积,从而会减少一些不必要的操作或开销。

  • 翻转指从两个维度(从 上到下、从左到右)颠倒次序,即旋转180度。
  • 互相关和卷积的区别仅仅在于卷积核是否进行翻转.因此互相关也可以称为不翻转卷积。

在神经网络中使用卷积是为了进行特征抽取卷积核是否进行翻转和其特征抽取的能力无关。特别是当卷积核是可学习的参数时,卷积和互相关在能力上是等价的.因此,为了实现上(或描述上)的方便起见,我们用互相关来代替卷积.事实上,很多深度学习工具中卷积操作其实都是互相关操作。

代码语言:javascript复制
def corr2d(X, K): 
    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
  • 输入:输入张量X和卷积核张量K。
  • 输出:互相关运算结果张量Y,形状为(X.shape[0] - K.shape[0] 1, X.shape[1] - K.shape[1] 1)。
  • 通过两个嵌套的循环遍历输出张量Y的每个元素,使用局部相乘和求和的方式计算互相关运算结果。

2. 二维卷积层类(Conv2D)

代码语言:javascript复制
class Conv2D(nn.Module):
    def __init__(self, kernel_size, weight=None):
        super().__init__()
        if weight is not None:
            self.weight = weight
        else:
            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
a. __init__(初始化)
  • 接受一个kernel_size参数作为卷积核的大小,并可选地接受一个weight参数作为卷积核的权重。
  • 如果没有提供weight参数,则会随机生成一个与kernel_size相同形状的权重,并将其设置为可训练的参数(nn.Parameter)。
  • 定义了一个偏置项bias,也将其设置为可训练的参数。
b. forward(前向传播函数)

调用之前的corr2d函数,对输入x和卷积核权重self.weight进行相关性计算,并将计算结果与偏置项self.bias相加,作为前向传播的输出。

3. 模型测试

代码语言:javascript复制
# 由于卷积层还未实现多通道,所以我们的图像也默认是单通道的
fake_image = torch.randn((5,5))
# 实例化卷积算子
conv = Conv2D(kernel_size=(3,3))
output = conv(fake_image)

创建了一个大小为(5, 5)的随机输入图像fake_image,然后实例化了Conv2D类,传入了卷积核大小为(3, 3)。接着调用conv对象的forward方法,对fake_image进行卷积操作,并将结果保存在output变量中。最后输出output的形状。

注意:本实验仅简单的实现了一个二维卷积层,只支持单通道的卷积操作,且不包含包含训练和优化等过程,欲知后事如何,请听下回分解。

0 人点赞