深度学习之计算机视觉

news2024/11/28 10:39:11

神经网络简介

全连接层和卷积层的根本区别在于权重在中间层中彼此连接的方式。图5.1描述了全连接层或线性层是如何工作的。

         在计算机视觉中使用线性层或全连接层的最大挑战之一是它们丢失了所有空间信息,并且就全连接层使用的权重数量而言复杂度太高。例如,当将224像素的图像表示为平面阵列时,我们最终得到的数组长度是150,528(224x224x3通道)。当图像扁平化后,我们失去了所有的空间信息。让我们来看看CNN的化版本是什么样子的,如图5.2 所示。

所有卷积层所做的是在图像上施加一个称为滤波器的权重窗口。在详细理解卷积和其他构建模块之前,先为 MNIST 数据集构建一个简单但功能强大的图像分类器。一旦构建了这个分类器,我们将遍历网络的每个组件。构建图像分类器可分为以下步骤。

  • 获取数据
  • 创建验证数据集
  • 从零开始构建CNN模型
  • 训练和验证模型

MNIST——获取数据

MNIST数据集包含60,000个用于训练的0~9的手写数字图片,以及用于测试集的10,000张图片。PyTorch的torchvision库提供了一个MNIST数据集,它下载并以易于使用的格式提供数据。让我们用MNIST函数把数据集下载到本机,并封装成DataLoader。我们将使用torchvision变换将数据转换成PyTorch张量并进行归一化。下面的代码负责下载数据、把数据封装成 DataLoader以及数据的归一化处理(归一化处理的原因:加快模型的收敛速度、提高模型的精度、增强模型泛化能力):

# transforms.Normalize((0.1307,), (0.3081)),其中均值(mean)为0.1307,标准差(std)为0.3081。
# 这些参数是在MNIST数据集上的统计结果,用于将图像数据归一化到[0, 1]范围内。
transformation = 
transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081))])
train_dataset = 
datasets.MNIST ('data/', train=True, transform=transformation, download=True)
test_dataset = 
datasets.MNIST('data/', train=False, transform=transformation, download=True)
train_loader =  
torch.utils.data.Dataloader(train_dataset, batch_size=32, shuffle=True)
test_loader = 
torch.utils.data.Dataloader(test_dataset, batch_size=32, shuffle=True)

从零开始构建CNN模型

Conv2d

        Conv2d负责在MNIST图像上应用卷积滤波器。让我们试着理解如何在一维数组上应用卷积,然后转向如何将二维卷积应用于图像。我们查看图5.5,将大小为3的滤波器(或内核)conv1d应用于长度为7的张量:

        底部框表示7个值的输入张量,连接框表示应用3个卷积滤波器后的输出。在图像的右上角,3个框表示Conv1d 层的权重和参数。卷积滤波器像窗口一样应用,并通过跳过一个值移动到下一个值。要跳过的值称为步幅,并默认设置为1。下面通过写下第一个和最后一个输出的计算来理解如何计算输出值:

Output1->(-0.5209x0.2286)+(-0.0147x2.4488)+(-0.4281x-0.9498)

Output5->(-0.5209x-0.6791)+(-0.0147x-0.6535)+(-0.4281x0.6437)

        所以,到目前为止,对卷积的作用应该比较清楚了。卷积基于移动步幅值在输入上应用滤波器,即一组权重。在前面的例子中,滤波器每次移动一格。如果步幅值是2,滤波器将每次移动2格。下面看看PyTorch的实现,来理解它是如何工作的:

conv = nn.Convld(l,l,3,bias=False)
sample = torch.randn(l,l,7)
conv(Variable(sample))
#检查卷积滤波器的权重
conv.weight

        还有另一个重要的参数,称为填充,它通常与卷积一起使用。如果仔细地观察前面的例子,大家可能会意识到,如果直到数据的最后才能应用滤波器,那么当数据没有足够的元素可以跨越时,它就会停止。填充则是通过在张量的两端添加0来防止这种情况。下面看一个关于如何填充一维数组的例子。

        在图5.6中,我们应用了填充为2步幅为1的Convld层。

        让我们看看Conv2d如何在图像上工作。

        在了解Conv2d的工作原理之前,强烈建议大家查看一个非常好的博客(http://setosa.io/ev/image-kernels/),其中包含一个关于卷积如何工作的现场演示。花几分钟看完演示之后,请阅读下文。
        我们来理解一下演示中发生的事情。在图像的中心框中,有两组不同的数字:一个在方框中表示;另一个在方框下方。在框中表示的那些是像素值,如左边照片上的白色框所突出显示的那样。在框下面表示的数字是用于对图像进行锐化的滤波器(或内核)值。这些数字是精心挑选的,以完成一项特定的工作。在本例中,它用于锐化图像。如前面的例子中一样,我们进行元素级的乘法运算并将所有值相加,生成右侧图像中像素的值。生成的值在图像右侧的白色框中高亮显示。
        虽然在这个例子中内核中的值是精心选择的,但是在CNN中我们不会去精选值而是随机地初始化它们,并让梯度下降和反向传播调整内核的值。学习的内核将负责识别不同的特征,如线条、曲线和眼睛。下面来看图5.7,我们把它看成是一个数字矩阵,看看卷积是如何工作的。

        在图5.7中,假设用6x6矩阵表示图像,并且应用大小为3x3的卷积滤波器,然后展示如何生成输出。简单起见,我们只计算矩阵的高亮部分。通过执行以下计算生成输出:

Output->0.86x0+-0.92x0+-0.61x1+-0.32x-1+-1.69x-1+……

        Conv2d函数中使用的另一个重要参数是kernel_size,它决定了内核的大小。常用的内核大小有为1、3、5和7。内核越大,滤波器可以覆盖的面积就越大,因此通常会观察到大小为7或9的滤波器应用于早期层中的输入数据。

池化

        通用的实践是在卷积层之后添加池化(pooling)层,因为它们会降低特征平面和卷积层输出的大小。
        池化提供两种不同的功能:一个是减小要处理的数据大小;另一个是强制算法不关注图像位置的微小变化。例如,面部检测算法应该能够检测图片中的面部,而不管照片中面部的位置。
        我们来看看 MaxPool2d的工作原理。它也同样具有内核大小和步幅的概念。它与卷积不同,因为它没有任何权重,只是对前一层中每个滤波器生成的数据起作用。如果内核大小为2x2,则它会考虑图像中2x2的区域并选择该区域的最大值。让我们看看图5.8,它清楚地说明了 MaxPool2d的工作原理。

        左侧的框包含特征平面的值。在应用最大池化之后,输出存储在框的右侧。我们写出输出第一行中值的计算代码,看看输出是如何计算的:

Output1 -> Maximum(3,7,2,8) -> 8
Output2 -> Maximum(-1,-8,9,2) -> 9

        另一种常用的池化技术是平均池化,需要把average函数替换成maxinum函数。图5.9说明了平均池化的工作原理。

        在这个例子中,我们取的是4个值的平均值,而不是4个值的最大值。让我们写出计算代码,以便更容易理解:

Output1 -> Average(3,7,2,8) -> 5
Output2 -> Average(-1,-8,9,2) -> 0.5

非线性激活——ReLU

        在最大池化之后或者在应用卷积之后使用非线性层是通用的最佳实践。大多数网络架构倾向于使用ReLu或不同风格的ReLu。无论选择什么非线性函数,它都作用于特征平面的每个元素。为了使其更直观,来看一个示例(见图5.10),其中把 ReLU 应用到应用过最大池化和平均池化的相同特征平面上:

视图

        对于图像分类问题,通用实践是在大多数网络的末端使用全连接层或线性层。我们使用一个以数字矩阵作为输入并输出另一个数字矩阵的二维卷积。为了应用线性层,需要将矩阵扁平化,将二维张量转变为一维的向量。图5.11所示为 view 方法的工作原理。

        让我们看看在网络中实现该功能的代码:

x.view(-1,320)

        可以看到,view方法将使n维张量扁平化为一维张量。在我们的网络中,第一个维度是每个图像。批处理后的输入数据维度是32x1x28x28,其中第一个数字32表示将有32个高度为28、宽度为28和通道为1的图像,因为图像是黑白的。当进行扁平化处理时,我们不想把不同图像的数据扁平化到一起或者混合数据,因此,传给view函数的第一个参数将指示PyTorch 避免在第一维上扁平化数据。来看看图5.12中的工作原理。

        在上面的例子中,我们有大小为2x1x2x2的数据;在应用view函数之后,它会转换成大小为2x1x4的张量。让我们再看一下没有使用参数-1的另一个例子(见图5.13)。

        如果忘了指明要扁平化哪一个维度的参数,可能会得到意想不到的结果。所以在这一步要格外小心。

        线性层

        在将数据从二维张量转换为一维张量之后,把数据传入非线性层,然后传入非线性的激活层。在我们的架构中,共有两个线性层,一个后面跟着ReLU,另一个后面跟着log_softmax,用于预测给定图片中包含的数字。

训练模型

        训练模型的过程与之前的狗猫图像分类问题相同。下面的代码片段在提供的数据集上对我们的模型进行训练:

def fit(epoch,model,data_loader,phase='training',volatile=False):
    if phase == 'training':
        model.train()
    if phase == 'validation':
        model.eval()
        volatile=True
    running_loss = 0.0
    running_correct = 0
    for batch_idx,(data,target) in enumerate(data loader):
        if is cuda:
            data,target =data.cuda(),target.cuda()
        data, target = Variable(data,volatile),Variable(target)
    if phase =='training':
        optimizer.zero grad()
    output = model(data)loss =F.nll loss(output,target)
    running loss +=
        F.nll loss(output,target,size average=False).data[0]
    preds = output.data.max(dim=l,keepdim=True)[1]
    running_correct += preds.eq(target.data.view_as(preds)).cpu().sum()
    if phase == 'training':
        loss.backward()
        optimizer.step()
    loss =running_loss/len(data_loader.dataset)
    accuracy =100. * running_correct/len(data_loader.dataset)
    print(f'{phase} loss is {loss:{5}.{2}} and {phase} accuracy is
        {running_correct}/{len(data_loader.dataset)}{accuracy:{10}.{4}}')
    return loss,accuracy

        该方法针对 training 和 validation 具有不同的逻辑。使用不同模式主要有两个原因:

  • 在 training 模式中,dropout 会删除一定百分比的值,这在验证或测试阶段不应发生。
  • 对于training 模式,计算梯度并改变模型的参数值,但是在测试或验证阶段不需要反向传播。

        上一个函数中的大多数代码都是不言自明的,就如前几章所述。在函数的末尾,我们返回特定轮数中模型的loss和accuracy。
        让我们通过前面的函数将模型运行20次迭代,并绘制出training和validation上的loss和 accuracy,以了解网络表现的好坏。以下代码将fit方法在training和validation数据集上运行20次迭代:

model = Net()
if is cuda:
    model.cuda()
optimizer=optim.SGD(model.parameters(),lr=0.01,momentum=0.5)
train_losses , train_accuracy = [],[]
val_losses , val_accuracy = [],[]
for epoch in range(1,20):
    epoch_loss,epoch_accuracy = fit(epoch,model,train_loader,phase='training')
    val_epoch_loss,val_epoch_accuracy = fit(epoch,model,test_loader,phase='validation')
train_losses.append(epoch_loss)
train_accuracy.append(epoch_accuracy)
val_losses.append(val_epoch_loss)
val_accuracy.append(val_epoch_accuracy)

以下代码绘制出了训练和测试的损失值:

plt.plot(range(1,len(train losses)+1),train_losses,'bo',label='training loss')
plt.plot(range(1,len(val losses)+1),val_losses,'r',label='validation loss')
plt.legend()

上述代码生成的图片如图5.14所示。

下面的代码绘制出了训练和测试的准确率:

plt.plot(range(1,len(train accuracy)+1),train accuracy,'bo',label = 'train accuracy')
plt.plot(range(1,len(val accuracy)+1),val accuracy,'r',label = 'val accuracy')
plt.legend()

        上述代码生成的图片如图5.15 所示。
        在 20轮训练后,我们达到了98.9%的测试准确率。我们使用简单的卷积模型,几乎达到了最先进的结果。让我们看看在之前使用的Dogs vs.Cats数据集上尝试相同的网络架构时会发生什么。我们将使用之前第2章中的数据和MNIST示例中的架构并略微修改。一旦训练好了模型,我们将评估模型,以了解架构表现的优异程度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1844858.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电商爬虫API的定制开发:满足个性化需求的解决方案

一、引言 随着电子商务的蓬勃发展,电商数据成为了企业决策的重要依据。然而,电商数据的获取并非易事,特别是对于拥有个性化需求的企业来说,更是面临诸多挑战。为了满足这些个性化需求,电商爬虫API的定制开发成为了解决…

Spring Boot集成tensorflow实现图片检测服务

1.什么是tensorflow? TensorFlow名字的由来就是张量(Tensor)在计算图(Computational Graph)里的流动(Flow),如图。它的基础就是前面介绍的基于计算图的自动微分,除了自动帮你求梯度之外,它也提供了各种常见的操作(op,…

使用 jQuery 选择器获取页面元素,然后利用 jQuery 对象的 css() 方法设置其 display 样式属性,从而实现显示和隐藏效果。

在页面中显示电影排行榜 当单击“(收起)”链接时,排行榜中后三项的电影名称隐藏而且链接的文本更改为“(展开) ” 当单击“(展开)”的链接时,后三项的电影名称重新显示且链接的文本…

基于微信共享充电桩小程序毕业设计作品成品(3)开发技术文档_充电桩小程序前端技术栈

后台管理系统文件 所在路径:后台源码ht目录是后台 绿色显示的是系统框架,不要动 位置程序名说明源码根目录login.php后台登录页面源码根目录check_u_login.php后台登录处理程序ht 后台根目录index.php后台首页left.php后台左侧菜单u_logout.php退出登…

2024广东省职业技能大赛云计算赛项实战——OpenStack搭建

OpenStack搭建 前言 搭建采用双节点安装,即controller控制节点和compute计算节点。 CentOS7 系统选择 2009 版本:CentOS-7-x86_64-DVD-2009.iso 可从阿里镜像站下载:https://mirrors.aliyun.com/centos/7/isos/x86_64/ OpenStack使用竞赛培…

【NCBI】SRA toolkit安装及使用-WindowsLinux版本

文章目录 Windows版本下载安装- 设置环境变量使用下载SRA Linux版本下载安装使用 由于市面上的文章介绍SRA toolkit基本上都是基于Linux,而在windows下运行SRA toolkit基本上可以达到相同的效果且更为方便,故本文将分别阐明在Windows和Linux环境下SRA to…

【DAO】DAOS在后傲腾时代的发展策略

视频:DAOS在后傲腾时代的发展策略_哔哩哔哩_bilibili 代替方案 WAL (write ahead log) 在架构上用DRAM 代替PMEM,如图 变化是: 傲腾方案: PMEM 数据写到内存就完成"落盘",是一个原…

10年265倍!动态展示全球第一股英伟达10年股价走势

英伟达在过去十年的股价走势展示了其在市场上的强劲表现和显著增长。自1999年上市以来,英伟达的股价经历了多次显著的涨幅,并在2024年达到了历史新高。 从2023年6月的数据来看,英伟达的股价为386.54美元/股,市值为9548亿美元。然…

探寻Scala的魅力:大数据开发语言的入门指南

大数据开发语言Scala入门 一、引言1.1 概念介绍1.2 Scala作为大数据开发语言的优势和应用场景1.2.1 强大的函数式编程支持1.2.2 可与Java无缝集成1.2.3 高性能和可扩展性1.2.4 大数据生态系统的支持 二、Scala基础知识2.1. Scala简介:2.1.1 Scala的起源和背景2.1.2 …

django学习入门系列之第三点《CSS基础样式介绍1》

文章目录 高度和宽度块级标签|行内标签的转换字体和颜色往期回顾 高度和宽度 如果在块级标签内,单独定义高度的话,宽度会默认拉满 使用百分比的时候 如果是块级标签,宽度可以用百分比,高度用不了(使用起来没效果&…

前后端分离的后台管理系统源码,快速开发OA、CMS网站后台管理、毕业设计项目

那有没有一款软件解-决这种现状呢?答案是肯定的。引入我们的软件——eladmin。 介绍 ELADMIN,一个简单且易上手的 Spring boot 后台管理框架,已发布 Mybatis-Plus 版本,为开发者提供了一个全-面、高-效的解-决方案。 特点 高-效率:前后端完全分离,项目简单可配,内置代码…

MySQL:表的增删查改

文章目录 1.Create(创建)2.Retrieve(读取、查询)2.1 SELECT 列2.2 WHERE 子句2.3 结果排序(order by)2.4 筛选分页结果(limit、offset)2.5 Update更新2.6 Delete删除2.7 去重 3.聚合函数3.1 聚合函数的基本使用3.2group by子句的使用(分组查询) 增删查改:: Create(创…

自动驾驶学习-车载摄像头ISP(2)

背景 智能驾驶ISP(Image Signal Processor,图像信号处理器)在自动驾驶和辅助驾驶系统中扮演着至关重要的角色。 典型的ISP通常会对摄像头输出的RAW数据先做黑电平矫正(BLC)、坏点矫正(DPC)、数…

社区团购多级分销流程:从入门到精通实践

随着电商平台和社交媒体的迅速发展,社区团购逐渐成为了一种新兴的购物模式。通过多级分销体系,社区团购有效地扩大了销售网络,提高了商品的流通速度和覆盖范围。本文将详细解析社区团购多级分销的流程,帮助你从入门到精通。 ### 一…

2748. 美丽下标对的数目(Rust暴力枚举)

题目 给你一个下标从 0 开始的整数数组 nums 。如果下标对 i、j 满足 0 ≤ i < j < nums.length &#xff0c;如果 nums[i] 的 第一个数字 和 nums[j] 的 最后一个数字 互质 &#xff0c;则认为 nums[i] 和 nums[j] 是一组 美丽下标对 。 返回 nums 中 美丽下标对 的总…

STM32单片机SPI通信详解

文章目录 1. SPI通信概述 2. 硬件电路 3. 移位示意图 4. SPI时序基本单元 5. SPI时序 6. Flash操作注意事项 7. SPI外设简介 8. SPI框图 9. SPI基本结构 10. 主模式全双工连续传输 11. 非连续传输 12. 软件/硬件波形对比 13. 代码示例 1. SPI通信概述 SPI&#x…

IOS逆向分析—终极详细(三)

IOS逆向分析—终极详细&#xff08;三&#xff09; 前言一、逆向分析是什么&#xff1f;二、IDA分析1.下载并安装IDA2.安装插件3.加载二进制4.代码分析5.其它 总结 前言 本文是个人完成对IOS上APP分析的整个过程&#xff0c;当然对于不同的机型还会遇到不同的情况&#xff0c;谨…

Jenkins+gitee流水线部署springboot项目

目录 前言 一、软件版本/仓库 二、准备工作 2.1 安装jdk 11 2.2 安装maven3.9.7 2.3 安装docker 2.4 docker部署jenkins容器 三、jenkins入门使用 3.1 新手入门 3.2 jenkins设置环境变量JDK、MAVEN、全局变量 3.2.1 jenkins页面 3.2.2 jenkins容器内部终端 3.2.3 全…

从零开始:使用ChatGPT快速创作引人入胜的博客内容

随着科技的飞速发展&#xff0c;人工智能逐渐渗透到我们生活的各个领域。无论是商业、教育还是娱乐&#xff0c;AI技术都在以惊人的速度改变着我们。特别是在内容创作领域&#xff0c;人工智能正发挥着越来越重要的作用。今天&#xff0c;我将和大家分享如何从零开始&#xff0…

Vue67-Vuex简介

因为vuex是插件&#xff0c;所以&#xff0c;使用的时候&#xff1a;vue.use(插件名) 一、Vuex的意义和使用场景 红色的箭头&#xff0c;都是读数据。 若是&#xff0c;B、C、D都想修改A组件中的x数据&#xff08;写&#xff09;&#xff1a;此时&#xff0c;A组件就是数据的接…