PyTorch实战-实现神经网络图像分类基础Tensor最全操作详解(一)

news2024/11/22 22:29:07

目录

前言

一、PyTorch数据结构-Tensor

1.什么是Tensor

2.数据Tensor使用场景

3.张量形态

标量(0D 张量)

 向量(1D 张量)

矩阵(2D张量)

3D 张量与高维张量

二、Tensor的创建

1. 从列表或NumPy数组创建

 2. 使用特定的初始化方法

 3. 从已有的Tensor创建

 三、Tensor的形状操作

1.查看大小和维度

2. 改变 Tensor 的形状

3. 移除和增加Tensor 的维度

 4.交换Tensor 维度

 5.拼接和堆叠Tensor

  6.拆分Tensor

 四、Tensor索引和切片

1.索引

 2.切片

3.通过索引和切片修改 Tensor

(1).修改单个元素的值

 (2).修改整行或整列

4.高级索引

(1).使用列表作为索引

 (2).使用布尔值作为索引(掩码)

 (3).使用 torch 的索引函数

点关注,防走丢,如有纰漏之处,请留言指教,非常感谢


前言

PyTorch可以说是三大主流框架中最适合初学者学习的了,相较于其他主流框架,PyTorch的简单易用性使其成为初学者们的首选。这样我想要强调的一点是,框架可以类比为编程语言,仅为我们实现项目效果的工具,也就是我们造车使用的轮子,我们重点需要的是理解如何使用Torch去实现功能而不要过度在意轮子是要怎么做出来的,那样会牵扯我们太多学习时间。以后就出一系列专门细解深度学习框架的文章,但是那是较后期我们对深度学习的理论知识和实践操作都比较熟悉才好开始学习,现阶段我们最需要的是学会如何使用这些工具。

深度学习的内容不是那么好掌握的,包含大量的数学理论知识以及大量的计算公式原理需要推理。且如果不进行实际操作很难够理解我们写的代码究极在神经网络计算框架中代表什么作用。不过我会尽可能将知识简化,转换为我们比较熟悉的内容,我将尽力让大家了解并熟悉神经网络框架,保证能够理解通畅以及推演顺利的条件之下,尽量不使用过多的数学公式和专业理论知识。以一篇文章快速了解并实现该算法,以效率最高的方式熟练这些知识。


博主专注数据建模四年,参与过大大小小数十来次数学建模,理解各类模型原理以及每种模型的建模流程和各类题目分析方法。此专栏的目的就是为了让零基础快速使用各类数学模型、机器学习和深度学习以及代码,每一篇文章都包含实战项目以及可运行代码。博主紧跟各类数模比赛,每场数模竞赛博主都会将最新的思路和代码写进此专栏以及详细思路和完全代码。希望有需求的小伙伴不要错过笔者精心打造的专栏。

一文速学-数学建模常用模型


 


一、PyTorch数据结构-Tensor

1.什么是Tensor

Tensor是PyTorch中最基本的数据结构,可以看作是一个多维数组(矩阵的扩展)。与NumPy中的数组类似,与其不同的是ndarrays不能使用GPU加速计算但Tensor可以在GPU上运行,这使得它在深度学习领域特别强大,归根结底还是得依赖庞大的算力支持我们才能尽可能得到更加精准的数据,通常我们叫它张量。

2.数据Tensor使用场景

没有引入张量这个概念之前,大家其实就在很多场景接触到了这些数据。了解到张量以后大家自然而然的就会明白了。张量这一概念的核心在于,它是一个数据容器。它包含的数据几乎总是数值数据,因此它是数字的容器。你可能对矩阵很熟悉,它是二维张量。张量是矩阵向任意维度的推广[注意,张量的维度(dimension)通常叫作轴(axis)]。

以下是一些常见的使用场景:

  • 神经网络的构建和训练:神经网络的输入、权重、输出、梯度等都是以Tensor的形式表示。PyTorch、TensorFlow等深度学习框架都是基于Tensor进行运算的。
  • 图像处理:图像通常以多维数组的形式表示,例如RGB图像可以表示为高度、宽度和3个颜色通道的Tensor。
  • 自然语言处理:在处理文本数据时,可以将文本编码成Tensor,每个单词可以映射为一个数字或一个词向量。
  • 时间序列分析:例如股票价格、天气数据等,可以表示成时间、特征维度的Tensor。
  • 推荐系统:用户-物品交互矩阵可以表示为一个二维的Tensor。
  • 强化学习:在Q-learning等算法中,状态、动作、奖励等信息都可以用Tensor表示。
  • 计算机视觉任务:如目标检测、分割、人脸识别等任务,输入图像、特征图、目标框坐标等都可以用Tensor表示。视频为5D张量,形状为 (samples, frames, height, width, channels) 或 (samples,frames, channels, height, width) ,图片4D张量形状为 (samples, height, width, channels) 或 (samples, channels,height, width) 。
  • 自动驾驶和机器人控制:传感器数据(如摄像头、激光雷达等)可以表示成Tensor,用于训练和实时控制。
  • 生成对抗网络(GAN):GAN中的生成器和判别器都是基于神经网络和Tensor进行训练和推断的。
  • 聚类和降维:在数据挖掘和特征工程中,Tensor可以用于聚类、主成分分析(PCA)等算法。

总的来说,Tensor作为多维数组,适用于几乎所有涉及到大规模数值计算和深度学习的领域。

这里借助numpy给大家更加直观的认识张量。

3.张量形态

标量(0D 张量)

一个只包含单个数字的张量被称为标量(scalar),也叫做标量张量、零维张量或0D张量。在NumPy中,一个float32或float64类型的数字就是一个标量张量(或标量数组)。你可以通过查看一个NumPy张量的ndim属性来了解它的轴数。标量张量具有0个轴(ndim == 0)。轴的数量也被称为阶数(rank)。以下是一个NumPy标量的例子。

import numpy as np
x = np.array(1)
print("数组中轴的个数:{}".format(x.ndim))
print(x)

数组中轴的个数:0
1

 向量(1D 张量)

  数字组成的数组叫作向量(vector)或一维张量(1D 张量)。一维张量只有一个轴。下面是一个 Numpy 向量。

x = np.array([1, 4, 7, 10, 13])
print("数组中轴的个数:{}".format(x.ndim))
print(x)

数组中轴的个数:1
[ 1  4  7 10 13]

这里需要注意一下,这个数组成为5D向量但不是5D张量,前者是数量上的数量,后者是轴的数量,大家不要搞混。

矩阵(2D张量)

 向量组成的数组叫作矩阵(matrix)或二维张量(2D 张量)。矩阵有 2 个轴(通常叫作行和列)。你可以将矩阵直观地理解为数字组成的矩形网格。下面是一个 Numpy 矩阵。

x = np.array([[1, 8, 21, 3, 78],
              [8, 12, 13, 32, 11],
              [7, 3, 5, 6, 2]])
print("数组中轴的个数:{}".format(x.ndim))
print(x)

数组中轴的个数:2
[[ 1  8 21  3 78]
 [ 8 12 13 32 11]
 [ 7  3  5  6  2]]

3D 张量与高维张量

将多个矩阵组合成一个新的数组,可以得到一个 3D 张量,你可以将其直观地理解为数字组成的立方体。下面是一个 Numpy 的 3D 张量。

x = np.array([[[5, 78, 2, 34, 0],
               [6, 79, 3, 35, 1],
               [7, 80, 4, 36, 2]],
              
              [[5, 78, 2, 34, 0],
               [6, 79, 3, 35, 1],
               [7, 80, 4, 36, 2]],
        
              [[5, 78, 2, 34, 0],
               [6, 79, 3, 35, 1],
               [7, 80, 4, 36, 2]]])
print(x.ndim)
print(x)

3
[[[ 5 78  2 34  0]
  [ 6 79  3 35  1]
  [ 7 80  4 36  2]]

 [[ 5 78  2 34  0]
  [ 6 79  3 35  1]
  [ 7 80  4 36  2]]

 [[ 5 78  2 34  0]
  [ 6 79  3 35  1]
  [ 7 80  4 36  2]]]

 以后我们接触到相应的数据进行张量转换的时候大家会了解的更为清晰,那么我们现在知道张量的基础概念和形式了,可以尝试着用Torch进行创建。

二、Tensor的创建

在PyTorch中,我们可以通过多种方式创建Tensor:

1. 从列表或NumPy数组创建

import torch
import numpy as np

# 从列表创建
tensor_from_list = torch.Tensor([1, 2, 3, 4])

# 从NumPy数组创建
numpy_array = np.array([1, 2, 3, 4])
tensor_from_numpy = torch.Tensor(numpy_array)
tensor_from_numpy

tensor([1., 2., 3., 4.])

 2. 使用特定的初始化方法

# 创建一个形状为(3, 2)的随机Tensor
random_tensor = torch.randn(3, 2)

# 创建一个全零的Tensor
zero_tensor = torch.zeros(3, 2)

# 创建一个全1的Tensor
ones_tensor = torch.ones(3, 2)
# 创建一个从 0 到 9 的等差数列
tensor5 = torch.arange(0, 10, 1)
# 创建一个从 0 到 1 的 5 个数的均匀间隔的数列
tensor6 = torch.linspace(0, 1, 5)
print(tensor6)
print(random_tensor)
print(zero_tensor)
print(ones_tensor)
print(tensor5)
print(tensor6)

tensor([0.0000, 0.2500, 0.5000, 0.7500, 1.0000])
tensor([[ 0.9255,  1.3031],
        [-1.2245, -0.5758],
        [-1.2821, -0.3471]])
tensor([[0., 0.],
        [0., 0.],
        [0., 0.]])
tensor([[1., 1.],
        [1., 1.],
        [1., 1.]])
tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
tensor([0.0000, 0.2500, 0.5000, 0.7500, 1.0000])

 3. 从已有的Tensor创建

# 从已有的Tensor创建新的Tensor(共享内存)
new_tensor = torch.Tensor(random_tensor.size())
print(new_tensor)

tensor([[0., 0.],
        [0., 0.],
        [0., 1.]])

 三、Tensor的形状操作

1.查看大小和维度

有两个函数size()和shape都可以查看:

random_tensor.size()
#random_tensor.shape 二者结果一致

torch.Size([3, 2])

2. 改变 Tensor 的形状

# 创建一个大小为 (2, 3) 的 Tensor
tensor = torch.arange(6).view(2, 3)
# 或者使用 reshape
# tensor = torch.arange(6).reshape(2, 3)
print(tensor)

tensor([[0, 1, 2],
        [3, 4, 5]])

3. 移除和增加Tensor 的维度

# squeeze 用于移除大小为 1 的维度
tensor = torch.arange(6).view(1, 2, 3)
squeezed_tensor = tensor.squeeze()
print(squeezed_tensor)

# unsqueeze 用于增加维度
tensor = torch.arange(6).view(2, 3)
unsqueeze_tensor = tensor.unsqueeze(0)
print(unsqueeze_tensor)

tensor([[0, 1, 2],
        [3, 4, 5]])
tensor([[[0, 1, 2],
         [3, 4, 5]]])

 4.交换Tensor 维度

# 交换维度
tensor = torch.arange(6).view(2, 3)
transposed_tensor = tensor.transpose(0, 1)  # 交换维度 0 和 1
print(transposed_tensor)

tensor([[0, 3],
        [1, 4],
        [2, 5]])

 5.拼接和堆叠Tensor

# cat 用于在指定维度上连接多个 Tensor
tensor1 = torch.arange(3)
tensor2 = torch.arange(3, 6)
concatenated_tensor = torch.cat((tensor1, tensor2), dim=0)
print(concatenated_tensor)

# stack 用于在新的维度上堆叠多个 Tensor
stacked_tensor = torch.stack((tensor1, tensor2), dim=0)
print(stacked_tensor)

  6.拆分Tensor

原Tensor:

tensor = torch.arange(10).view(2, 5)
print(tensor)

 拆分结果

# split 用于在指定维度上拆分 Tensor
tensor = torch.arange(10).view(2, 5)
split_tensors = torch.split(tensor, 2, dim=1)
print(split_tensors)

# chunk 用于在指定维度上将 Tensor 拆分成相等的几块
chunked_tensors = torch.chunk(tensor, 2, dim=0)
print(chunked_tensors)

 

(tensor([[0, 1],
        [5, 6]]), tensor([[2, 3],
        [7, 8]]), tensor([[4],
        [9]]))
(tensor([[0, 1, 2, 3, 4]]), tensor([[5, 6, 7, 8, 9]]))

 四、Tensor索引和切片

1.索引

import torch

# 创建一个二维 Tensor
tensor = torch.Tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

# 访问单个元素
print(tensor[0, 0])  # 输出 1

# 访问某一行
print(tensor[1])  # 输出 [4, 5, 6]

# 访问某一列
print(tensor[:, 1])  # 输出 [2, 5, 8]

# 使用逗号分隔访问多个不连续的元素
print(tensor[0, 0], tensor[1, 1], tensor[2, 2])  # 输出 1, 5, 9

 

tensor(1.)
tensor([4., 5., 6.])
tensor([2., 5., 8.])
tensor(1.) tensor(5.) tensor(9.)

 2.切片

# 使用切片获取子张量
print(tensor[0:2, 1:3])  # 输出 [[2, 3], [5, 6]]

# 使用步长获取间隔元素
print(tensor[::2])  # 输出 [[1, 2, 3], [7, 8, 9]]

# 使用负数索引倒序访问
print(tensor[-1])  # 输出 [7, 8, 9]

 

tensor([[2., 3.],
        [5., 6.]])
tensor([[1., 2., 3.],
        [7., 8., 9.]])
tensor([7., 8., 9.])

3.通过索引和切片修改 Tensor

(1).修改单个元素的值

# 创建一个二维 Tensor
tensor = torch.Tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 修改单个元素的值
tensor[0, 0] = 0
tensor

 

tensor([[0., 2., 3.],
        [4., 5., 6.],
        [7., 8., 9.]])

 (2).修改整行或整列

整行修改:

# 创建一个二维 Tensor
tensor = torch.Tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 修改整行或整列
tensor[1] = torch.Tensor([10, 11, 12])
tensor

 整列修改:

# 创建一个二维 Tensor
tensor = torch.Tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 修改整行或整列
tensor[:, 2] = torch.Tensor([30, 31, 32])
tensor

 

tensor([[ 1.,  2., 30.],
        [ 4.,  5., 31.],
        [ 7.,  8., 32.]])

4.高级索引

(1).使用列表作为索引

idx = [0, 2]
print(tensor[idx])  # 输出第 0 和第 2 行

 

tensor([[ 1.,  2., 30.],
        [ 7.,  8., 32.]])

 (2).使用布尔值作为索引(掩码)

mask = tensor > 5
print(tensor[mask])  # 输出所有大于 5 的元素

 

tensor([30., 31.,  7.,  8., 32.])

 (3).使用 torch 的索引函数

# 使用 torch 的索引函数
idx = torch.LongTensor([0, 2])
print(torch.index_select(tensor, 0, idx))  # 输出第 0 和第 2 行

 

tensor([[ 1.,  2., 30.],
        [ 7.,  8., 32.]])

点关注,防走丢,如有纰漏之处,请留言指教,非常感谢

以上就是本期全部内容。我是fanstuck ,有问题大家随时留言讨论 ,我们下期见。


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

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

相关文章

PCL 计算字符型ply文件的法向量

文章目录 ply格式计算法向量意义具体代码 ply格式 PLY(Polygon File Format)是一种用于存储三维模型数据的文件格式。在PLY文件中,法向量是指每个顶点或面片的法向量,用于描述表面的朝向和光照计算。 在PLY文件中,法…

springboot导出(POI)

POI官方文档 引入依赖 <!--POI--><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.poi</groupId&…

Spring Cloud Alibaba:Nacos服务治理平台

文章目录 什么是Nacos&#xff1f;使用Nacos进行服务注册与发现服务注册服务发现 负载均衡分析与拓展安全性性能监控日志记录 &#x1f389;欢迎来到架构设计专栏~Spring Cloud Alibaba&#xff1a;Nacos服务治理平台 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&…

学习笔记|矩阵按键控制原理|数值转化为键码|密码锁|STC32G单片机视频开发教程(冲哥)|第十四集:矩阵按键原理及实践

文章目录 1.矩阵按键是什么2.矩阵按键的控制原理3.矩阵按键程序的编写将数值转化为键码完整代码&#xff1a;demo.c&#xff1a;key.c:key.h: 密码锁&#xff08;简易版&#xff09;需求分析&#xff1a; 总结课后练习&#xff1a; 1.矩阵按键是什么 这个矩阵按键也是我们这个…

网上管理系统的分析及设计---应用UML建模

目 录 第1章 系统需求 第2章 需求分析 2.1 识别参与者 2.2 识别用例 2.3 用例的事件流描述 第3章 静态结构模型 3.1 定义系统对象 3.2 定义用户界面类 3.3 建立类图 第4章 动态行为模型 4.1 创建系统顺序图&#xff08;协作图&#xff09; 4.2 创建系统…

网络爬虫-----初识爬虫

目录 1. 什么是爬虫&#xff1f; 1.1 初识网络爬虫 1.1.1 百度新闻案例说明 1.1.2 网站排名&#xff08;访问权重pv&#xff09; 2. 爬虫的领域&#xff08;为什么学习爬虫 ?&#xff09; 2.1 数据的来源 2.2 爬虫等于黑客吗&#xff1f; 2.3 大数据和爬虫又有啥关系&…

Java低代码:jvs-list (子列表)表单回显及触发逻辑引擎配置说明

一、子列表【新增】表单默认回显主列表关联字段 子列表新增表单可使用表单回显配置&#xff0c;在新增表单中默认回显&#xff0c;如图效果 1、子列表中进入新增页面配置 2、切换到表单设置&#xff0c;选择回显设置&#xff0c;进入回显逻辑引擎。 3、在画布中拖入【对象变量…

记录一次对登录接口的性能测试

测试环境 客户端: win10 这里可以用linux,但没用,因为想直观查看结果。 被测环境:linux X86 4核CPU16G内存 被测接口:登录接口,没有做数据驱动。 场景设计 设置线程数19,持续时间5分钟,并用后端监听器监听结果,使用grafana+prometheus监控服务器资源。 测试执行 …

fabic如何将绘图原点移到画布中心

情况说明&#xff1a; fabic默认绘图原点为left&#xff1a;0&#xff0c;top&#xff1a;0 后端给我的内容是按照x&#xff0c;y返回的&#xff0c;需要将坐标系移到fabic画布的中心位置&#xff0c;找了下网上合适的砖&#xff0c;想一句命令直接设置&#xff0c;结果没有。…

二叉排序树(BST)的算法分析以及基本操作(结点的查询,插入,删除)

1.二叉排序树的定义 二叉排序树&#xff0c;又称二叉查找树&#xff08;BST&#xff0c;Binary Search Tree) 默认不允许两个结点的关键字相同。 1.二叉排序树的性质: 任意一棵二叉排序树的子树的结点大小都满足“左小右大”。 左子树上所有结点的关键字均小于根结点的关键…

廉价的全闪存雷电 NAS 折腾笔记:NUC9 操作系统踩坑

上一篇文章中&#xff0c;分享了关于低成本全闪存 NAS 的个人方案选择。 本篇文章&#xff0c;来聊聊硬件相关部分&#xff0c;以及软件的基础配置部分&#xff0c;也聊聊雷电组网的踩坑之旅。 写在前面 我使用的设备是 NUC9i5QNX&#xff0c;这台设备的硬件基础规格&#x…

【软件测试】selenium3

自动化测试的概念 自动化测试指软件测试的自动化&#xff0c;在预设状态下运行应用程序或者系统&#xff0c;预设条件包括正常和异常&#xff0c;最 后评估运行结果。将人为驱动的测试行为转化为机器执行的过程。 自动化测试就相当于将人工测试手段进行转换&#xff0c;让代码…

国产视觉检测设备崛起,以AI机器视觉及自研算法破解智造难题

机器视觉作为人工智能的前沿分支之一&#xff0c;被称为智能制造的“智慧之眼”&#xff0c;在工业领域中&#xff0c;能够代替人工完成识别、测量、定位、检测等工作&#xff0c;以实现对设备精密控制及产线智能化、自动化升级。 同时&#xff0c;深度学习和3D视觉的技术升级…

Java本地开发环境搭建

概述 Java语言是企业级应用软件开发语言&#xff0c;本文主要描述Java开发环境的搭建。 如上所示&#xff0c;TIOBE提供2023年9月份全球开发语言的排行榜&#xff0c;其中&#xff0c;Java排名第四&#xff0c;而Python已经跃升到第一位&#xff0c;因为&#xff0c;Python是人…

芯科蓝牙BG27开发笔记6-精简第一个程序

1. 这些IO的控制代码在哪里&#xff1f; 还是蓝牙点灯程序&#xff1a; 首先需要对pinout做一些精简&#xff1a; 为了简化工程&#xff0c;去掉了不必要的IO。 至于PTI接口是什么&#xff0c;怎么用&#xff0c;不知道&#xff0c;现在不考虑&#xff1a; 但是提出以下问题…

第6章_freeRTOS入门与工程实践之创建FreeRTOS工程

本教程基于韦东山百问网出的 DShanMCU-F103开发板 进行编写&#xff0c;需要的同学可以在这里获取&#xff1a; https://item.taobao.com/item.htm?id724601559592 配套资料获取&#xff1a;https://rtos.100ask.net/zh/freeRTOS/DShanMCU-F103 freeRTOS系列教程之freeRTOS入…

应该下那个 ActiveMQ

最近在搞 ActiveMQ 的时候&#xff0c;发现有 2 个 ActiveMQ 可以下载。 应该下那个呢&#xff1f; JMS 即Java Message Service&#xff0c;是JavaEE的消息服务接口。 JMS主要有两个版本&#xff1a;1.1和2.0。 2.0和1.1相比&#xff0c;主要是简化了收发消息的代码。 所谓…

Redis——其他数据类型介绍

概要介绍 Redis中有10种不同的数据类型。之前的blog中介绍了Redis中常见的五大数据类型&#xff1a;String&#xff0c;List&#xff0c;Hash&#xff0c;Set&#xff0c;ZSet。而Redis中还有许多其他的数据类型&#xff0c;一般在特定的场景中使用 Stream 首先介绍一下什么…

笔记本多拓展出一个屏幕

一、首先要知道&#xff0c;自己的电脑有没有Type-c接口&#xff0c;支持不支持VGA 推荐&#xff1a; 自己不清楚&#xff0c;问客服&#xff0c;勤问。 二、显示屏与笔记本相连&#xff0c;通过VGA 三、连接好了&#xff0c;需要去配置 网址&#xff1a;凑合着看&#xff…

代码随想录算法训练营Day42 | 动态规划(4/17) 0-1背包问题理论基础 LeetCode 416.分割等和子集

开始背包问题的练习&#xff01; 1. 背包问题的理论基础 对于面试的话&#xff0c;其实掌握01背包&#xff0c;和完全背包&#xff0c;就够用了&#xff0c;最多可以再来一个多重背包。这里附上代码随想录的图&#xff0c;可以对背包问题进行一个分类。 1.1 十分重要的基础&a…