卷积神经网络CNN原理+代码(pytorch实现MNIST集手写数字分类任务)

这篇具有很好参考价值的文章主要介绍了卷积神经网络CNN原理+代码(pytorch实现MNIST集手写数字分类任务)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

卷积神经网络

前言

若将图像数据输入全连接层,可能会导致丧失一些位置信息

卷积神经网络将图像按照原有的空间结构保存,不会丧失位置信息。

卷积运算:

1.以单通道为例:

将将input中选中的部分与kernel进行数乘 :
卷积神经网络CNN原理+代码(pytorch实现MNIST集手写数字分类任务)

以上图为例对应元素相乘结果为211,并将结果填入output矩阵的左上角
卷积神经网络CNN原理+代码(pytorch实现MNIST集手写数字分类任务)

得到:
卷积神经网络CNN原理+代码(pytorch实现MNIST集手写数字分类任务)

最终得到的结果为:
卷积神经网络CNN原理+代码(pytorch实现MNIST集手写数字分类任务)

2.三通道卷积

卷积神经网络CNN原理+代码(pytorch实现MNIST集手写数字分类任务)

三个通道分别利用三个卷积核进行计算,并将结果相加得到最终定格结果。

那么我们可以得到n个通道的卷积过程
卷积神经网络CNN原理+代码(pytorch实现MNIST集手写数字分类任务)

若希望得到的卷积后结果通道数为m,则需要m个卷积核同时对原始数据进行处理,得到m个结果,并将其拼接起来,也得到了m个通道
卷积神经网络CNN原理+代码(pytorch实现MNIST集手写数字分类任务)

注意:

1.每一个卷积核的通道数量和输入的通道数量是相同的

2.卷积核的总数与输出的通道数量相等

所以我们要构建一个卷积层,其权重的维度为:
卷积神经网络CNN原理+代码(pytorch实现MNIST集手写数字分类任务)

代码演示:
**

torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)

卷积神经网络CNN原理+代码(pytorch实现MNIST集手写数字分类任务)

import torch

in_channels, out_channels = 5, 10
width, height = 100, 100
kernel_size = 3  #卷积核的大小
batch_size = 1

input = torch.randn(  #正态分布随机采样
    batch_size,
    in_channels,#这个参数一定要前后对应,否则无法正常运行,其余参数无所谓
    width,
    height
)

#生成一个卷积对象   至少需要三个参数
conv_layer = torch.nn.Conv2d(in_channels,  #输入通道的数量
                             out_channels, #输出通道的数量
                             kernel_size=kernel_size) #卷积核尺寸

output = conv_layer(input)

print(input.shape)
#torch.Size([1, 5, 100, 100])
print(output.shape)
#torch.Size([1, 10, 98, 98])
#相比于100减去了2,是因为采用了3*3的卷积核,将宽度为2边框去除了
print(conv_layer.weight.shape)
#torch.Size([10, 5, 3, 3])
#10为m输出的通道数  5为n输入的通道数  3*3为卷积核的尺寸
卷积运算中几个常用的参数
1.padding

不想改变输出矩阵的大小,可以向外填充,默认是填充零
卷积神经网络CNN原理+代码(pytorch实现MNIST集手写数字分类任务)

代码演示:

import torch

input = [3, 4, 6, 5, 7,
         2, 4, 6, 8, 2,
         1, 6, 7, 8, 4,
         9, 7, 4, 6, 2,
         3, 7, 5, 4, 1]
input = torch.Tensor(input).view(1, 1, 5, 5)  #四个参数分别为B C W H
conv_layer = torch.nn.Conv2d(1, 1, kernel_size=3, padding=1, bias=False)

#构造卷积核
kernel = torch.Tensor([1, 2, 3, 4, 5, 6, 7, 8, 9]).view(1, 1, 3, 3) #参数为 输出通道数, 输入通道数, W, H
conv_layer.weight.data = kernel.data  #将构造的卷积核赋值给卷积层的权重  记得要加.data

output = conv_layer(input)
print(output)
#卷积计算的结果如下
#tensor([[[[ 91., 168., 224., 215., 127.],
#          [114., 211., 295., 262., 149.],
#          [192., 259., 282., 214., 122.],
#          [194., 251., 253., 169.,  86.],
#          [ 96., 112., 110.,  68.,  31.]]]], grad_fn=<ThnnConv2DBackward0>)
2.stride

W*H框运动的步长,可以有效降低图像的宽度和高度

例如,当stride=2时,通过3*3卷积核计算得到的输出维度为2 * 2
卷积神经网络CNN原理+代码(pytorch实现MNIST集手写数字分类任务)

代码演示:

#在上一小节的代码中做如下修改即可
conv_layer = torch.nn.Conv2d(1, 1, kernel_size=3, stride=2, bias=False)
3.Max Pooling Layer

最大池化层:将图像分成2*2的小块,在每一块中寻找最大值,返回给输出,如下图所示,将4 * 4的图像经过池化后变为了2 * 2的图像

作用:减少数据量,降低运算需求

注意:池化层操作只针对同一通道,对通道的数量等其他参数无影响
卷积神经网络CNN原理+代码(pytorch实现MNIST集手写数字分类任务)

代码演示:

import torch

input = [3, 4, 6, 5,
         2, 4, 6, 8,
         1, 6, 7, 8,
         9, 7, 4, 6]
input = torch.Tensor(input).view(1, 1, 4, 4)  #输出输入通道都为1,卷积核尺寸为4*4

maxpooling_layer = torch.nn.MaxPool2d(kernel_size=2)  #相当于stride=2,取2*2为一组

output = maxpooling_layer(input)
print(output)
#tensor([[[[4., 8.],
#          [9., 8.]]]])
实战演练

数据采用MNIST,进行分类任务(懂得都懂)

设计一个卷积神经网络

卷积神经网络CNN原理+代码(pytorch实现MNIST集手写数字分类任务)

如上图所示,将一个(1, 28, 28)的图像张量输入进卷积网络中

1.首先经过一个卷积核大小为(5, 5) 输出通道数为10的卷积层

2.经过一个(2, 2)的最大池化层(取出2*2范围内的最大值返回给输出)

3.再经过一个卷积核大小为(5, 5) 输出通道数为20的卷积层,在这里通道数由10变为20

4.又经过一个(2, 2)的最大池化层

5.最终通过一个输入为320维输出为10为的全连接层(作为分类器),得到10个概率值对应于10种类型 320由上一层的参数总数计算而来(20 * 4 * 4)

注:运算过程中,池化层不关注输入输出的维度,但是卷积层和全连接层的输入和输出维度一定要和前后层相对应。

由此,我们得到每一步的核心函数:
卷积神经网络CNN原理+代码(pytorch实现MNIST集手写数字分类任务)

代码实现:

import torch
import torch.nn.functional as F #使用functional中的ReLu激活函数

#CNN模型
class Net(torch.nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        #两个卷积层
        self.conv1 = torch.nn.Conv2d(1, 10, kernel_size=5)  #1为in_channels 10为out_channels
        self.conv2 = torch.nn.Conv2d(10, 20, kernel_size=5)
        #池化层
        self.pooling = torch.nn.MaxPool2d(2)  #2为分组大小2*2
        #全连接层 320 = 20 * 4 * 4
        self.fc = torch.nn.Linear(320, 10)

    def forward(self, x):
        #先从x数据维度中得到batch_size
        batch_size = x.size(0)
        #卷积层->池化层->激活函数
        x = F.relu(self.pooling(self.conv1(x)))
        x = F.relu(self.pooling(self.conv2(x)))
        x = x.view(batch_size, -1)  #将数据展开,为输入全连接层做准备
        x = self.fc(x)
        return x
model = Net()
GPU的使用

1.将模型迁移到GPU

#在model = Net()后加入如下代码
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)  #将模型的所有内容放入cuda中

2.训练中将数据迁入GPU,包括inputs和target

#inputs, target = data后加入.to(device)
def train(epoch):
    running_loss = 0.0
    for batch_idx, data in enumerate(train_loader, 0):   #在这里data返回输入:inputs、输出target
        inputs, target = data
        #在这里加入一行代码,将数据送入GPU中计算!!!
        inputs, target = inputs.to(device), target.to(device)
        optimizer.zero_grad()

        #前向 + 反向 + 更新
        outputs = model(inputs)
        loss = criterion(outputs, target)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()
        if batch_idx % 300 == 299:
            print('[%d, %5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss / 300))

3.测试中同样也需要将数据送入GPU中,代码同上

整体代码:
import torch
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import  DataLoader
import torch.nn.functional as F #使用functional中的ReLu激活函数
import torch.optim as optim

#数据的准备
batch_size = 64
#神经网络希望输入的数值较小,最好在0-1之间,所以需要先将原始图像(0-255的灰度值)转化为图像张量(值为0-1)
#仅有灰度值->单通道   RGB -> 三通道 读入的图像张量一般为W*H*C (宽、高、通道数) 在pytorch中要转化为C*W*H
transform = transforms.Compose([
    #将数据转化为图像张量
    transforms.ToTensor(),
    #进行归一化处理,切换到0-1分布 (均值, 标准差)
    transforms.Normalize((0.1307, ), (0.3081, ))
])

train_dataset = datasets.MNIST(root='../dataset/mnist/',
                               train=True,
                               download=True,
                               transform=transform
                               )
train_loader = DataLoader(train_dataset,
                          shuffle=True,
                          batch_size=batch_size
                          )
test_dataset = datasets.MNIST(root='../dataset/mnist/',
                               train=False,
                               download=True,
                               transform=transform
                               )
test_loader = DataLoader(test_dataset,
                          shuffle=False,
                          batch_size=batch_size
                          )


#CNN模型
class Net(torch.nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        #两个卷积层
        self.conv1 = torch.nn.Conv2d(1, 10, kernel_size=5)  #1为in_channels 10为out_channels
        self.conv2 = torch.nn.Conv2d(10, 20, kernel_size=5)
        #池化层
        self.pooling = torch.nn.MaxPool2d(2)  #2为分组大小2*2
        #全连接层 320 = 20 * 4 * 4
        self.fc = torch.nn.Linear(320, 10)

    def forward(self, x):
        #先从x数据维度中得到batch_size
        batch_size = x.size(0)
        #卷积层->池化层->激活函数
        x = F.relu(self.pooling(self.conv1(x)))
        x = F.relu(self.pooling(self.conv2(x)))
        x = x.view(batch_size, -1)  #将数据展开,为输入全连接层做准备
        x = self.fc(x)
        return x
model = Net()
#在这里加入两行代码,将数据送入GPU中计算!!!
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)  #将模型的所有内容放入cuda中

#设置损失函数和优化器
criterion = torch.nn.CrossEntropyLoss()
#神经网络已经逐渐变大,需要设置冲量momentum=0.5
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)

#训练
#将一次迭代封装入函数中
def train(epoch):
    running_loss = 0.0
    for batch_idx, data in enumerate(train_loader, 0):   #在这里data返回输入:inputs、输出target
        inputs, target = data
        #在这里加入一行代码,将数据送入GPU中计算!!!
        inputs, target = inputs.to(device), target.to(device)

        optimizer.zero_grad()

        #前向 + 反向 + 更新
        outputs = model(inputs)
        loss = criterion(outputs, target)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()
        if batch_idx % 300 == 299:
            print('[%d, %5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss / 300))

def test():
    correct = 0
    total = 0
    with torch.no_grad():  #不需要计算梯度
        for data in test_loader:   #遍历数据集中的每一个batch
            images, labels = data  #保存测试的输入和输出
            #在这里加入一行代码将数据送入GPU
            images, labels = images.to(device), labels.to(device)
            outputs = model(images)#得到预测输出
            _, predicted = torch.max(outputs.data, dim=1)#dim=1沿着索引为1的维度(行)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()
    print('Accuracy on test set:%d %%' % (100 * correct / total))

if __name__ == '__main__':
    for epoch in range(10):
        train(epoch)
        test()
运行结果

我只进行了10轮迭代,准确率最终达到了98%,与单纯使用多层的全连接神经网络准确率97%相比提高了一个百分点,错误率降低了1/3,性能有了显著地提升

另外本次在GPU上运行十轮迭代的时间约为1-2分钟,请大家放心跑,无压力。

卷积神经网络CNN原理+代码(pytorch实现MNIST集手写数字分类任务)文章来源地址https://www.toymoban.com/news/detail-439442.html

到了这里,关于卷积神经网络CNN原理+代码(pytorch实现MNIST集手写数字分类任务)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Pytorch】计算机视觉项目——卷积神经网络CNN模型识别图像分类

    在上一篇笔记《【Pytorch】整体工作流程代码详解(新手入门)》中介绍了Pytorch的整体工作流程,本文继续说明如何使用Pytorch搭建卷积神经网络(CNN模型)来给图像分类。 其他相关文章: 深度学习入门笔记:总结了一些神经网络的基础概念。 TensorFlow专栏:《计算机视觉入门

    2024年02月05日
    浏览(57)
  • 机器学习算法之——卷积神经网络(CNN)原理讲解

            我们知道神经网络的结构是这样的: 那卷积神经网络跟它是什么关系呢? 其实卷积神经网络依旧是层级网络,只是层的功能和形式做了变化,可以说是传统神经网络的一个改进。比如下图中就多了许多传统神经网络没有的层次。 简而言之,卷积神经网络(Convo

    2024年02月04日
    浏览(51)
  • 深度学习入门——卷积神经网络CNN基本原理+实战

    ​ 卷积神经网络(Convolutional Neural Network,CNN)是深度学习技术中最基础的网络结构,模拟人脑工作,具备强大的特征学习能力。CNN结构主要由两部分组成:特征提取部分和分类部分color{blue}{特征提取部分和分类部分}特征提取部分和分类部分。特征提取部分网络将执行一系列

    2024年01月21日
    浏览(49)
  • Python基于PyTorch实现卷积神经网络回归模型(CNN回归算法)项目实战

    说明:这是一个机器学习实战项目(附带 数据+代码+文档+视频讲解 ),如需 数据+代码+文档+视频讲解 可以直接到文章最后获取。 卷积神经网络,简称为卷积网络,与普通神经网络的区别是它的卷积层内的神经元只覆盖输入特征局部范围的单元,具有稀疏连接(sparse connec

    2024年02月15日
    浏览(50)
  • Python基于PyTorch实现卷积神经网络分类模型(CNN分类算法)项目实战

    说明:这是一个机器学习实战项目(附带 数据+代码+文档+视频讲解 ),如需 数据+代码+文档+视频讲解 可以直接到文章最后获取。 卷积神经网络,简称为卷积网络,与普通神经网络的区别是它的卷积层内的神经元只覆盖输入特征局部范围的单元,具有稀疏连接(sparse connec

    2024年02月15日
    浏览(51)
  • 基于卷积神经网络CNN的图片分类实现——附代码

    目录 摘要: 1.卷积神经网络介绍: 2.卷积神经网络(CNN)构建与训练: 2.1 CNN的输入图像 2.2 构建CNN网络 2.3 训练CNN网络 3.卷积神经网络(CNN)的实际分类测试: 4.本文Matlab实验代码: 使用Matlab自带的深度学习工具箱构建卷积神经网络(CNN)进行图片分类,以识别并分类手写

    2024年02月02日
    浏览(49)
  • 边写代码边学习之卷积神经网络CNN

    卷积神经网络(Convolutional Neural Network,CNN)是一种深度学习神经网络的架构,主要用于图像识别、图像分类和计算机视觉等任务。它是由多层神经元组成的神经网络,其中包含卷积层、池化层和全连接层等组件。 CNN的设计受到了生物视觉系统的启发,其中最重要的组件是卷

    2024年02月15日
    浏览(43)
  • Pytorch 与 Tensorflow对比学习 第3周:进阶主题 Day 15-16: 卷积神经网络(CNN)

    第3周:进阶主题 Day 15-16: 卷积神经网络(CNN) 在这两天中,我专注于学习卷积神经网络(CNN)的基础知识,包括卷积层和池化层的工作原理以及它们在图像处理中的应用。 卷积神经网络基础: 卷积层:学习了卷积层如何通过滤波器(或称为核)提取图像的特征。每个滤波器

    2024年01月20日
    浏览(45)
  • matlab实现卷积神经网络CNN(二)——代码实现与解析

            基于上一篇文章对于CNN网络结构的整理,我们将用matlab实现一维数据的CNN网络单多输入和单多输出。         文中字母含义详情可见上一篇文章。         data数据格式应为 M×SN ;M为一维数据的长度(即一个样本有多少个点),由于是一维数据,所以宽度

    2024年02月05日
    浏览(48)
  • 【使用 k 折叠交叉验证的卷积神经网络(CNN)】基于卷积神经网络的无特征EMG模式识别研究(Matlab代码实现)

    💥💥💞💞 欢迎来到本博客 ❤️❤️💥💥 🏆博主优势: 🌞🌞🌞 博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️ 座右铭: 行百里者,半于九十。 📋📋📋 本文目录如下: 🎁🎁🎁 目录 💥1 概述 📚2 运行结果 🎉3 参考文献 🌈4 Matlab代码实现 文献来源

    2024年02月11日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包