新手小白的pytorch学习第三弹-------tensor的基本操作

news2024/12/23 17:33:23
  1. reshape, view, stacking, squeeze(), unsqueeze(),permute()
  2. torch.tensor 和 numpy 的 array
  3. 切片,张量里面获取元素值
  4. 随机种子

1 导入torch

import torch

2 reshape()

tensor_A = torch.arange(1, 11)
tensor_A

tensor_A.reshape(2, 5)

tensor_A.reshape(2, 5)

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

tensor_A.reshape(1, 10)

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

tensor_A.reshape(10, 1)

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

tensor_A.reshape(1, 9)

在这里插入图片描述##### 发现了吗? tensor_A 的每一个成功的reshape,括号中元素乘积都等于 tensor_A 中元素的个数(10)

而失败的 reshape 的乘积为 9 ,所以失败了
告诉我们元素要兼容,就是我可以将你这个 tensor 换个形状, 但你不能多元素也不能少元素, 就是说不能无中生有,也不能顺手牵羊

3 view

tensor_C = torch.arange(1, 10)
tensor_C

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

x = tensor_C.view(3, 3)
x

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

print(tensor_C, tensor_C.shape)
tensor_reshaped = tensor_C.reshape(3, 3)
tensor_viewed = tensor_C.view(3,3)
print(tensor_C, tensor_C.shape)
print(tensor_reshaped, tensor_reshaped.shape)
print(tensor_viewed, tensor_viewed.shape)

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

我刚开始还是没看出来 view和 reshape的区别,因为你看,是不是都将原来的张量的形状改变了
x = tensor_C.view(1, 9)
x

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

好,接下来我们改变 x 中的值,注意这里的 x 是 view 之后的值
x[:,8] = 500
x, tensor_C

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

发现了不, 我改变 view 之后的张量的值,原来的 tensor_C 张量的值也发生了改变,提问:这说明了什么?哎,这说明了什么?
答:这说明了我们俩改的就是同一个东西,即改的内容是内存中同一个地址单元的值
没错,这就是 view 和 reshape 在改变张量形状之间的区别,好,我们用 reshape 做个实验瞅瞅
tensor_D = torch.arange(1, 10)
tensor_D

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

y = tensor_D.reshape(3, 3)
y

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

ok, 咱么来改变一下 y 的值,看看原来的 tensor_D 有没有变化, 有变化说明什么?哎,对,说明和view一样
没有变化呢,对,没错,没有变化就说明他俩的区别,一个表示同一个内存里的值, 一个啥也不是,简单的改变一下形状
y[2:3] = 500
y, tensor_D
不是,怎么 reshape 和 view 一样啊
反正在这里看是一样的,等之后遇到问题再说吧,这里的数据都是连续的昂,注意注意

(tensor([[ 1, 2, 3],
[ 4, 5, 6],
[500, 500, 500]]),
tensor([ 1, 2, 3, 4, 5, 6, 500, 500, 500]))

4 stacking

让我们来学习一下张量的堆叠

先创建一个我们需要堆叠的张量
z = torch.arange(2, 50, step=10)
z

tensor([ 2, 12, 22, 32, 42])

这里要注意, torch.stack(), 第一个参数是一个 tuple, 要堆叠多少个张量就填几个该张量
tensor_stacked = torch.stack((z,z,z,z,z), dim=0)
tensor_stacked

tensor([[ 2, 12, 22, 32, 42],
[ 2, 12, 22, 32, 42],
[ 2, 12, 22, 32, 42],
[ 2, 12, 22, 32, 42],
[ 2, 12, 22, 32, 42]])

可以看出来, dim=0,表示是堆叠行
tensor_stacked = torch.stack((z, z, z, z), dim=1)
tensor_stacked

tensor([[ 2, 2, 2, 2],
[12, 12, 12, 12],
[22, 22, 22, 22],
[32, 32, 32, 32],
[42, 42, 42, 42]])

dim=1, 表示堆叠列
tensor_stacked = torch.stack((z, z, z, z), dim=2)
tensor_stacked

在这里插入图片描述

好,这里试验了一下,报错了,说是[-2,1]之间, 咱们试试看看
tensor_stacked = torch.stack((z, z, z, z), dim=-2)
tensor_stacked

tensor([[ 2, 12, 22, 32, 42],
[ 2, 12, 22, 32, 42],
[ 2, 12, 22, 32, 42],
[ 2, 12, 22, 32, 42]])

tensor_stacked = torch.stack((z, z, z, z), dim=-1)
tensor_stacked

tensor([[ 2, 2, 2, 2],
[12, 12, 12, 12],
[22, 22, 22, 22],
[32, 32, 32, 32],
[42, 42, 42, 42]])

从上面的代码和实验结果,咱们不难发现,dim = -2 和 dim = 0是一样的, dim = -1 和 dim = 1是一样的,好记好记得,两个1是列就可以啦

5 squeeze()

去掉单维,使得张量中只有高于一维的
a = torch.ones(1, 3, 3)
a, a.shape

(tensor([[[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]]]),
torch.Size([1, 3, 3]))

tensor_squeezed = a.squeeze()
tensor_squeezed, tensor_squeezed.shape

(tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]]),
torch.Size([3, 3]))

看见没,两个张量的 shape 中,是不是 squeeze 之后,单维的没了,就是为 1 的没了
咱们再试一个看看
b = torch.rand(1, 1, 1, 3, 4)
b, b.shape

(tensor([[[[[0.1872, 0.7857, 0.0147, 0.0184],
[0.7243, 0.0842, 0.8350, 0.3980],
[0.6132, 0.1699, 0.5776, 0.1239]]]]]),
torch.Size([1, 1, 1, 3, 4]))

tensor_squeezed = b.squeeze()
tensor_squeezed, tensor_squeezed.shape

(tensor([[0.1872, 0.7857, 0.0147, 0.0184],
[0.7243, 0.0842, 0.8350, 0.3980],
[0.6132, 0.1699, 0.5776, 0.1239]]),
torch.Size([3, 4]))

6 unsqueeze()

张量的扩张,咱们来看看咋扩张的呢
tensor_unsqueezed = tensor_squeezed.unsqueeze(dim=0)
tensor_unsqueezed, tensor_unsqueezed.shape

(tensor([[[0.1872, 0.7857, 0.0147, 0.0184]],

     [[0.7243, 0.0842, 0.8350, 0.3980]],

     [[0.6132, 0.1699, 0.5776, 0.1239]]]),

torch.Size([3, 1, 4]))

tensor_unsqueezed = tensor_squeezed.unsqueeze(dim=1)
tensor_unsqueezed, tensor_unsqueezed.shape

(tensor([[[0.1872, 0.7857, 0.0147, 0.0184]],
[[0.7243, 0.0842, 0.8350, 0.3980]],
[[0.6132, 0.1699, 0.5776, 0.1239]]]),
torch.Size([3, 1, 4]))

tensor_unsqueezed = tensor_squeezed.unsqueeze(dim=2)
tensor_unsqueezed, tensor_unsqueezed.shape

(tensor([[[0.1872],
[0.7857],
[0.0147],
[0.0184]],

[[0.7243],
[0.0842],
[0.8350],
[0.3980]],

[[0.6132],
[0.1699],
[0.5776],
[0.1239]]]),
torch.Size([3, 4, 1]))

tensor_unsqueezed = tensor_squeezed.unsqueeze(dim=3)
tensor_unsqueezed, tensor_unsqueezed.shape

在这里插入图片描述

好,相信通过实验都懂了,unsqueeze(dim = ) 这个函数中必须要有dim的值,同时注意 dim 的范围
这个范围也很好理解,看我们刚开始的张量形状是 torch.Size([3, 4]) 3的维度是0, 4的维度是1,
那我们选择一个地方插入一维向量,0就插入最左边, 1就插入中间,2就插入最右边,相信很好理解啊

7 torch.permute(input, dims)

作用是调换三个维度的值,看例子咱们就瞬间明白了
tensor = torch.rand(size=(224, 224, 3)) # weight, height, color_channel
tensor_permuted = torch.permute(tensor, (2, 0, 1))
print(f"tensor shape:{tensor.shape}")
print(f"tensor_permuted shape:{tensor_permuted.shape}")

tensor shape:torch.Size([224, 224, 3])
tensor_permuted shape:torch.Size([3, 224, 224])

看结果是不是调换顺序啦!对,torch.permute(input, dims) 就是这个意思
torch.tensor 和 numpy 的 array
torch.form_numpy(ndarry) numpy array-> tensor
torch.Tensor.numpy() tensor->array
OK, 接下来我们来学习一下, torch 里面的张量和 numpy 里面的array

8 先导入包numpy

import numpy as np
tensor = torch.arange(1., 10.)
array = np.arange(1., 10.)
print(f"tensor:\n{tensor},{tensor.dtype}")
print(f"\narray:\n{array},{array.dtype}")

tensor:
tensor([1., 2., 3., 4., 5., 6., 7., 8., 9.]),torch.float32

array:
[1. 2. 3. 4. 5. 6. 7. 8. 9.],float64

array 怎么转换为 torch 中的tensor呢

array_to_tensor = torch.from_numpy(array)
array_to_tensor

tensor([1., 2., 3., 4., 5., 6., 7., 8., 9.], dtype=torch.float64)

注意到这里的 dtype=torch.float64 是因为从上面可以看出 array 的默认数据类型是 float64, 不是张量的默认数据类型
我们可以修改数据类型
array_to_tensor = array_to_tensor.type(torch.float32)
array_to_tensor.dtype

torch.float32

tensor 转换为 array

tensor_to_array = torch.Tensor.numpy(tensor)
tensor_to_array

array([1., 2., 3., 4., 5., 6., 7., 8., 9.], dtype=float32)

array = array + 1
array, array_to_tensor

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

tensor = tensor + 1
tensor, tensor_to_array

(tensor([ 2., 3., 4., 5., 6., 7., 8., 9., 10.]),
array([1., 2., 3., 4., 5., 6., 7., 8., 9.], dtype=float32))

从上面我们可以看出,转换的数据与原来的数据不相关

9 切片,张量里面获取元素值

有时候,我们需要从张量中获取特定的元素,比如:第一列或者第二行,所以这个时候我们就需要进行切片操作了
创建一个tensor
x = torch.arange(1, 10).reshape(1, 3, 3)
x

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

切片顺序是从外部再到里面的
让我们一步一步的开始切片吧
print(f"first square bracket:\n{x[0]}")
print(f"second square bracket:\n{x[0][0]}")
print(f"third square bracket:\n{x[0][0][0]}")

first square bracket:
tensor([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
second square bracket:
tensor([1, 2, 3])
third square bracket:
1

我老是把它写成x[0:0:0],试一下好吧,好像不对
x[0:0:0]

在这里插入图片描述

这里还有一个步长
x[0:0:1]
反正引以为戒,不要学我老写错

tensor([], size=(0, 3, 3), dtype=torch.int64)

使用’:‘来特指这个维度的所有值,然后使用’,'来增加其它的维度
获得 第0维 和 第一维的索引0的值
x,x[:,0],x.shape
获得所有 第0维 和 第1维 但是只有 第2维 的索引为 1 的值
x[:,:,1] 

tensor([[2, 5, 8]])

获得 第0维 的值但只有 第一维 和 第二维 索引为 1 的值
x[:,1,1]

tensor([5])

获得第一维和第二维索引为0的值,然后所有第二维的值
x,x[0, 0, :]

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

10 结果的可复现性,随机种子

大家相比应该都知道,我们做实验的时候需要噪声数据来增加模型的泛化性
那如果我们需要复现结果时,随机数字不固定的话,是很难进行复现的
所以我们需要随机种子,这样它的结果就是固定的
tensor_E = torch.rand(3,4)
tensor_F = torch.rand(3,4)
print(tensor_E == tensor_F)

tensor([[False, False, False, False],
[False, False, False, False],
[False, False, False, False]])

使用随机种子

SEEDNUM = 42 #随便什么值都可以捏
torch.manual_seed(SEEDNUM)
tensor_E = torch.rand(3,4)
tensor_F = torch.rand(3,4)
print(tensor_E == tensor_F)

tensor([[False, False, False, False],
[False, False, False, False],
[False, False, False, False]])

怎么个事,怎么不一样, 好,原来是每使用一次都需要随机种子
SEEDNUM = 42 #随便什么值都可以捏
torch.manual_seed(SEEDNUM)
tensor_E = torch.rand(3,4)
torch.manual_seed(SEEDNUM)
tensor_F = torch.rand(3,4)
print(tensor_E == tensor_F)

tensor([[True, True, True, True],
[True, True, True, True],
[True, True, True, True]])

好,这一下是不是都相等啦!

11 总结一下

咱们学习了
(1) reshape, view, squeeze(), unsqueeze(), permute()
(2) array 和 tensor 的转化
(3) 切片, 随机种子

妈呀,今天我咋学了这么多呢,根本搞不完,明天搞咯,都没时间洗澡了,忙得很

今天被黄焖鸡那个服务员气炸了,不过,没关系,晚上咱们吃的锅包肉很好吃,毛血旺里面都没有什么肉肉,猪血还挺好吃的呢

下次吃小鸡炖蘑菇,肯定很好吃
BB,如果这里的学习内容对你有用的话,记得给俺点一个赞啊,点个赞赞

谢谢BB, 靴靴!

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

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

相关文章

C语言 ——— 实用调试技巧(Visual Studio)

目录 Debug 和 Release 的区别 F10 --- 逐过程调试 & F11 --- 逐语句调试 F9 --- 新建/切换断点 & F5 --- 开始调试 shift F5 & ctrl F5 Debug 和 Release 的区别 Debug:通常为调试版本,它包含调试信息,并且不作任何优化…

Unity ColorSpace 之 【颜色空间】相关说明,以及【Linear】颜色校正 【Gamma】的简单整理

Unity ColorSpace 之 【颜色空间】相关说明,以及【Linear】颜色校正 【Gamma】的简单整理 目录 Unity ColorSpace 之 【颜色空间】相关说明,以及【Linear】颜色校正 【Gamma】的简单整理 一、简单介绍 二、在Unity中设置颜色空间 三、Unity中的Gamma…

Vortex GPGPU的硬件代码分析(Cache篇2)

文章目录 前言一、VX_cache.sv代码部分解读2——buffering/initialize1.1 core response buffering与VX_elastic_buffer模块解读1.1.1 VX_pipe_buffer模块解读1.1.1.1 一种握手信号的解释1.1.1.2 世界线收束——VX_pipe_buffer的核心代码解释1.1.1.3 VX_pipe_register模块解读与…

算法015:串联所有单词的子串

串联所有单词的子串. - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/substring-with-concatenation-of-all-words/ 如果是第一次接触这个题目,接触滑动…

埋点系统如何统计用户的平均停留时长?

Hello,大家好,欢迎使用Webfunny前端监控和埋点系统。 今天,我们将介绍webfunny的埋点系统如何统计用户的平均停留时长 一、页面beforeLeave事件 当你页面离开的时候,会触发一个心跳检测,但是这个可能不是100%触发&am…

跳表的简单学习

跳表(SkipList)学习 1. 什么是跳表? 基于“空间换时间”思想,通过给链表建立索引,使得链表能够实现二分查找。 跳表是可以实现二分查找的有序链表。 2. 从单链表到跳表 对于一般的单链表,在其中进行查…

EasyCVR视频技术:城市电力抢险的“千里眼”,助力抢险可视化

随着城市化进程的加速和电力需求的不断增长,电力系统的稳定运行对于城市的正常运转至关重要。然而,自然灾害、设备故障等因素常常导致电力中断,给城市居民的生活和企业的生产带来严重影响。在这种情况下,快速、高效的电力抢险工作…

【PVE】新增2.5G网卡作为主网卡暨iperf测速流程

【PVE】新增2.5G网卡作为主网卡暨iperf测速流程 新增网卡 新增网卡的首先当然需要关闭PVE母机,把新网卡插上,我用淘宝遥现金搞了个红包,花了26元买了块SSU的2.5G网卡。说实话这个价位连散热片都没有,确实挺丐的。稍后测下速度看…

从零开始做题:segmentFlow

题目 解题 import string import binascii def Crack_4B(crc_list):print(-------------Start Crack CRC 4B-------------)#crc_list [0xc0a3a573, 0x3cb6ab1c, 0x85bb0ad4, 0xf4fde00b]#文件的CRC32值列表,注意顺序comment chars string.printableflag 0 for …

文心一言的流式接口数据进行处理 增加属性

需求:需要对文心一言的流式接口数据进行处理 增加属性 return ResponseEntity.ok().header("Access-Control-Allow-Origin", "*").contentType(org.springframework.http.MediaType.TEXT_EVENT_STREAM).cacheControl(org.springframework.http…

Leetcode3201. 找出有效子序列的最大长度 I

Every day a Leetcode 题目来源:3201. 找出有效子序列的最大长度 I 解法1:枚举 全奇数、全偶数、奇偶交替三种情况的最大值即为所求。 代码: /** lc appleetcode.cn id3201 langcpp** [3201] 找出有效子序列的最大长度 I*/// lc codesta…

imx6ull/linux应用编程学习(16)emqx ,mqtt创建连接mqtt.fx

在很多项目中都需要自己的私人服务器,以保证数据的隐私性,这里我用的是emqx。 1.进入emqx官网 EMQX:用于物联网、车联网和工业物联网的企业级 MQTT 平台 点击试用cloud 申请成功后可得:(右边的忽略) 进入…

【matlab】大数据基础与应用实例

目录 引言 线性回归模型 基本形式 最小二乘法 多元线性回归 线性回归的假设 模型评估 应用 独热编码 原理 应用场景 优点 缺点 数据收集 数据可视化 数据处理与分析 完整代码 引言 线性回归模型 线性回归模型是一种用于预测连续值输出(或称为因变…

「iOS」暑假第一周 —— ZARA的仿写

暑假第一周 ZARA的仿写 文章目录 暑假第一周 ZARA的仿写写在前面viewDidLoad 之中的优先级添加自定义字体下载想要的字体添加至info之中找到字体名字并应用 添加应用图标和启动页面 写在前面 暑假第一周留校学习,对于ZARA进行了仿写,在仿写的过程之中&a…

WPF学习(2) -- 样式基础

一、代码 <Window x:Class"学习.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expression/blend/2008&…

计算机网络之网络互连

1.什么是网络互连 1.1网络互连的目的 将两个或者两个以上具有独立自治能力的计算机网络连接起来&#xff0c;实现数据流通&#xff0c;扩大资源共享范围&#xff0c;或者容纳更多用户。 网络互连包括&#xff1a; 同构网络、异构网络的互连&#xff0c; 局域网与局域网&…

【操作系统】文件管理——文件管理基础、文件的逻辑结构和目录结构(个人笔记)

学习日期&#xff1a;2024.7.14 内容摘要&#xff1a;文件管理基础、文件的逻辑结构、文件目录 文件管理基础 引言 文件是一组有意义的信息/数据的集合&#xff0c;计算机中存放着各种各样的文件&#xff0c;一个文件有哪些属性&#xff1f; 操作系统应该向上层的应用程序提…

网络 闲聊

闲谈 闲话 网络安全——>网络空间安全 网络空间&#xff1a;一个由信息基础设备组成互相依赖的网络 继&#xff1a;海、陆、空、天、的第五大空间 信息安全的一个发展&#xff1a; 通信保密阶段---计算机安全---信息系统安全---网络空间安全 棱镜门事件 棱镜计划&…

leetcode日记(38)字母异位词分组

最开始的想法是创建vector<vector<string>> result&#xff0c;然后遍历strs中字符串&#xff0c;遍历result中vector&#xff0c;比较vector中第一个string和strs中string&#xff0c;若为字母异位词&#xff0c;则加入vector&#xff0c;若无&#xff0c;则创建新…

数学基础 三角函数、两条平行线截距

三角函数变化公式 已知两条平行线&#xff0c;其中一条的起始点p1&#xff0c;p2&#xff0c;其中一条直线 p3&#xff0c;p4计算两条直线之间的截距 在二维平面上&#xff0c;当我们说“两条直线之间的截距”时&#xff0c;这通常意味着我们需要找到一条与这两条直线都相交的…