深度学习之计算机视觉

神经网络简介

全连接层和卷积层的根本区别在于权重在中间层中彼此连接的方式。图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示例中的架构并略微修改。一旦训练好了模型,我们将评估模型,以了解架构表现的优异程度。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

中文分词词云图

目录 一、分词1、分词方式方法2、分词优缺点 二、jieba使用示例1、引入库2、切分模式3、加载自定义字典 三、词的可视化1、读取数据2、数据处理3、统计词频4、去除停用词5、词云图1、pyecharts绘图2、WordCloud绘图 一、分词 1、分词方式方法 以构词规则为出发点的规则分词 全…

平安养老险黄山中支开展“反洗钱电影送下乡”活动

为不断增强反洗钱教育宣传的精准性和有效性,提升乡村群众的洗钱风险防范意识,6月18日,在中国人民银行黄山市分行的部署和指导下,平安养老保险股份有限公司(以下简称“平安养老险”)黄山中心支公司、平安人寿…

服务器主机托管服务内容科普

在现代信息技术快速发展的背景下,服务器主机托管服务已成为众多企业、机构和个人不可或缺的一部分。本文将为您详细科普服务器主机托管服务的内容,帮助您更好地理解和选择适合自己的托管方案。 一、硬件与基础设施 服务器主机托管服务首先提供了硬件和网…

HTML静态网页成品作业(HTML+CSS)—— 家乡成都介绍网页(4个页面)

🎉不定期分享源码,关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 🏷️本套采用HTMLCSS,未使用Javacsript代码,共有4个页面。 二、作品演示 三、代…

数据库异常恢复2-备份文件恢复(快速恢复的手动启动方式)

(四) 备份文件备份恢复的概念 本次所说的数据恢复有异于数据的导入导出 1. 备份工具 gbase8s数据库提供了两种工具进行完成系统物理备份、逻辑日志备份和系统恢复:ontape和onbar ontape:提供了基本的系统物理备份、日志备份和恢复能力,其…

多目标跟踪中用到的求解线性分配问题(Linear Assignment Problem,LAP)Python

多目标跟踪中用到的求解线性分配问题(Linear Assignment Problem,LAP)Python flyfish 如果想看 C版本的,请点这里。 线性分配问题(LAP,Linear Assignment Problem)是一个经典的优化问题&…

java实现分类下拉树,点击时对应搜索---后端逻辑

一直想做分类下拉,然后选择后搜索的页面,正好做项目有了明确的需求,查找后发现el-tree的构件可满足需求,数据要求为:{ id:1, label:name, childer:[……] }形式的,于是乎,开搞! 一…

如何下载DVS Gesture数据集?解决tonic.datasets.DVSGesture错误HTTP Error 403: Forbidden

1 问题 DVSGesture数据集是一个专注于动态视觉传感(Dynamic Vision Sensor, DVS)技术的数据集,它包含了基于事件的图像记录,用于手势识别任务。DVSGesture数据集由一系列动态图像组成,这些图像是通过动态视觉传感器捕…

免费分享:GIS插件-ARCGIS一键拓扑(模型构建器)(附下载方法)

工具详情 ARCGIS一键拓扑(模型构建器),可直接在ArcGIS中安装使用。 可试用本工具进行数据拓扑检查。 下载方法 下载地址:https://open.geovisearth.com/service/resource/150下载流程:点击上面的下载地址,打开数字地球开放平台…

数据结构-绪论

目录 前言一、从问题到程序二、数据结构的研究内容三、理解数据结构3.1 数据3.2 结构3.2.1 逻辑结构的分类3.2.2 存储结构的分类 3.3 数据结构 四、数据类型和抽象数据类型4.1 抽象数据类型的定义格式4.2 抽象数据类型的实现 总结 前言 本篇文章先介绍数据结构的研究内容&…

php反序列化的一些知识

问题 <?php $raw O:1:"A":1:{s:1:"a";s:1:"b";}; echo serialize(unserialize($raw)); //O:1:"A":1:{s:1:"a";s:1:"b";}?> php反序列化的时按理说找不到A这个类&#xff0c;但是他没有报错&#xff0c;…

SAR动目标检测系列:【4】动目标二维速度估计

在三大类杂波抑制技术(ATI、DPCA和STAP)中&#xff0c;STAP技术利用杂波与动目标在二维空时谱的差异&#xff0c;以信噪比最优为准则&#xff0c;对地杂波抑制的同时有效保留动目标后向散射能量&#xff0c;有效提高运动目标的检测概率和动目标信号输出信杂比&#xff0c;提供理…

C++学习(23)

#学习自用# union 共用体和结构体相似&#xff0c;但是共用体一次只能占用一个成员的内存&#xff0c;所有成员共用同一地址。 #include<iostream> using namespace std; union A {int int_val;float float_val; }a; int main() {a.float_val 2.0f;cout << a.f…

【AWS SMB 能力最佳实践】利用 MGN 解决方案实现跨AWS账号迁移Amazon EC2 实例、弹性IP地址等资源

文章目录 一、实验情景二、实验关键服务概述2.1 MGN解决方案2.2 VPC对等连接 三、实验架构示意图四、实验具体操作步骤4.0 创建访问密钥4.1 创建VPC资源4.1.1 在源账号上创建VPC4.1.2 在目标账号上创建VPC 4.2 创建对等连接✨4.2.1 发起对等连接请求4.2.2 接受对等连接请求4.2.…

【内含优惠码】重磅发售!《2023年度中国量化投资白皮书》(纸质版)

这是可以公开了解量化行业图景的&#xff0c;为数不多资料。 简介 《2023年度中国量化投资白皮书》由宽邦科技、华泰证券、金融阶、华锐技术、AMD、阿里云、英迈中国等多家机构联合发起编写&#xff0c;并于2024年6月15日正式发布&#xff0c;全书公17万字6大章节勾勒最新量化…

torch.optim 之 Algorithms (Implementation: for-loop, foreach, fused)

torch.optim的官方文档 官方文档中文版 一、Implementation torch.optim的官方文档在介绍一些optimizer Algorithms时提及它们的implementation共有如下三个类别&#xff1a;for-loop, foreach (multi-tensor), and fused。 Chat-GPT对这三个implementation的解释是&#xf…

算法设计与分析 实验4 动态规划法求扔鸡蛋问题

目录 一、实验目的 二、问题描述 三、实验要求 四、实验内容 动态规划法 算法描述 算法伪代码描述 算法复杂度分析 数据测试 二分优化的动态规划法 算法描述 二分优化&#xff1a; 算法伪代码 算法复杂度分析 数据测试 单调决策优化的动态规划法 算法描述 算…

【Ardiuno】实验使用ESP32接收电脑发送的串口数据(图文)

使用ESP32可以非常方便的与电脑进行串口通讯&#xff0c;一般我们可以用串口接收ESP32的输出作为调试使用&#xff0c;今天我们再来实验一下从电脑端向ESP32单片机发送数据。 发送数据程序代码&#xff1a; void setup() {Serial.begin(9600); }void loop() { if(Serial.ava…

股票核心因子解读以及如何从接口获取股票数据信息

目录 1 股票基础信息1.1 股票核心因子1.2 获取股票信息 2 如何从接口获取股票数据2.1 yfinance2.2 finnhub-python2.3 alpha_vantage2.4 efinance2.4 Tushare 3 如何从各大金融平台获取咨询信息3.1 国外3.2 国内 1 股票基础信息 1.1 股票核心因子 基本面因子 因子名称计算公…

前缀和+双指针,CF 131F - Present to Mom

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 131F - Present to Mom 二、解题报告 1、思路分析 很经典的一种把列看作cell 来进行双指针/递推的题型 我们考虑&#xff0c;可以预处理出原矩阵中的所有star 然后我们去枚举矩形的上下边界&#xff0c;把…