【PyTorch与深度学习】2、PyTorch张量的运算API(上)

课程地址
最近做实验发现自己还是基础框架上掌握得不好,于是开始重学一遍PyTorch框架,这个是课程笔记,这个课还是讲的简略,我半小时的课听了一个半小时。

1. 张量

1.1 张量操作

(1)chunk:将一个张量分割为特定数目的张量,每个块都是输入张量的视图。

  • 按维度0分割:
import torchb = torch.rand([3, 2])  # 随机生成3x2维度的张量
print("b=", b)
c, d = torch.chunk(b, chunks=2)  # 将b分割为c和d两个张量,默认沿着维度0去分割(按行分割)
print("c=", c)
print("d=", d)  # 最后一个张量维度会稍微小一点,因为3不能被2整除

运行结果:
b= tensor([[0.7704, 0.8685],
[0.0165, 0.5076],
[0.2730, 0.2270]])
c= tensor([[0.7704, 0.8685],
[0.0165, 0.5076]])
d= tensor([[0.2730, 0.2270]])

  • 按维度1分割:
import torchb = torch.rand([3, 2])  # 随机生成3x2维度的张量
print("b=", b)
c, d = torch.chunk(b, chunks=2, dim=1)  # 将b分割为c和d两个张量,默认沿着维度1去分割(按列分割)
print("c=", c)
print("d=", d)  # 最后一个张量维度会稍微小一点,因为3不能被2整除

运行结果:
b= tensor([[0.1275, 0.9670],
[0.5189, 0.0748],
[0.6840, 0.7675]])
c= tensor([[0.1275],
[0.5189],
[0.6840]])
d= tensor([[0.9670],
[0.0748],
[0.7675]])
(2)dsplit:将具有三个或更多维度的张量按深度拆分为多个张量。

import torch# 按深度划分(按最后一个维度划分),看打印结果
a = torch.arange(16.0).reshape(2, 2, 4)
print(a)
b = torch.dsplit(a, 2)  # 均分两份
print(b)
c = torch.dsplit(a, [3, 6])  # 第一份是按最后一个维度取前三个值,第二份是6个
print(c)
d = torch.dsplit(a, [2, 4])  # 第一份是1个,第二份是4个
print(d)
e = torch.dsplit(a, [1, 1, 2])  # 第一份是1个,第二份是1个,第三分是2个
print(e)

运行结果:
tensor([[[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.]],
[[ 8., 9., 10., 11.],
[12., 13., 14., 15.]]])
(tensor([[[ 0., 1.],
[ 4., 5.]],
[[ 8., 9.],
[12., 13.]]]), tensor([[[ 2., 3.],
[ 6., 7.]],
[[10., 11.],
[14., 15.]]]))
(tensor([[[ 0., 1., 2.],
[ 4., 5., 6.]],
[[ 8., 9., 10.],
[12., 13., 14.]]]), tensor([[[ 3.],
[ 7.]],
[[11.],
[15.]]]), tensor([], size=(2, 2, 0)))
(tensor([[[ 0., 1.],
[ 4., 5.]],
[[ 8., 9.],
[12., 13.]]]), tensor([[[ 2., 3.],
[ 6., 7.]],
[[10., 11.],
[14., 15.]]]), tensor([], size=(2, 2, 0)))
(tensor([[[ 0.],
[ 4.]],
[[ 8.],
[12.]]]), tensor([], size=(2, 2, 0)), tensor([[[ 1.],
[ 5.]],
[[ 9.],
[13.]]]), tensor([[[ 2., 3.],
[ 6., 7.]],
[[10., 11.],
[14., 15.]]]))

(3)dstack:按深度顺序(沿第三轴)堆叠张量。

import torcha = torch.tensor([1, 2, 3])  # 行向量
b = torch.tensor([4, 5, 6])
print(torch.dstack((a,b)))
a = torch.tensor([[1],[2],[3]])  # 列向量
b = torch.tensor([[4],[5],[6]])
print(torch.dstack((a,b)))

运行结果:
tensor([[[1, 4],
[2, 5],
[3, 6]]])
tensor([[[1, 4]],
[[2, 5]],
[[3, 6]]])

(4)hstack:按水平顺序堆叠张量(按列)

import torcha = torch.tensor([1, 2, 3])  # 行向量
b = torch.tensor([4, 5, 6])
print(torch.hstack((a,b)))
a = torch.tensor([[1],[2],[3]])  # 列向量
b = torch.tensor([[4],[5],[6]])
print(torch.hstack((a,b)))

运行结果:
tensor([1, 2, 3, 4, 5, 6])
tensor([[1, 4],
[2, 5],
[3, 6]])

(5)gather:沿着某一个维度取变量(根据索引取变量,这个一看就晕,但是我找到了一篇比较好的文章讲解这个)
torch.gather() 和torch.sactter_()的用法简析,这个讲的最好,我就是按照这个学的

import torcht = torch.tensor([[1, 2], [3, 4]])
a = torch.gather(t, 1, torch.tensor([[0, 0], [1, 0]]))  # 按维度1和[[0, 0], [1, 0]]的下标取张量t的元素
# out[i,j] = t[i][a[i, j]]
# out[0,0] = t[0][a[0, 0]]=t[0][0]=1
# out[0,1] = t[0][a[0, 1]]=t[0][0]=1
# 所以out[0]=[1, 1]
# out[1,0] = t[1][a[1, 0]]=t[1][1]=4
# out[1,1] = t[1][a[1, 1]]=t[1][0]=3
# 所以out[1]=[4, 5]
# 所以out=[[1, 1], [4, 3]]
print(a)
a = torch.gather(t, 0, torch.tensor([[0, 0], [1, 0]]))  # 按维度0和[[0, 0], [1, 0]]的下标取张量t的元素
# out[i,j] = t[a[i, j]][j]
# out[0,0] = t[a[0, 0]][0]=t[0][0]=1
# out[0,1] = t[a[0, 1]][1]=t[0][1]=2
# 所以out[0]=[1, 2]
# out[1,0] = t[a[1, 0]][0]=t[1][0]=3
# out[1,1] = t[a[1, 1]][1]=t[0][1]=2
# 所以out[1]=[3, 2]
# 所以out=[[1, 2], [3, 2]]
print(a)

运行结果:
tensor([[1, 1],
[4, 3]])
tensor([[1, 2],
[3, 2]])

(6)reshape:返回一个张量,其数据和元素数量与输入相同,但具有指定的形状,改变形状,不改变顺序,比如原来是从左到右,然后改成多行后,是按从左到右从上到下顺序重新改变形状。

import torcha = torch.arange(4.)  # 生成从0到3的一维张量
print(torch.reshape(a, (2, 2)))  # 改成2X2张量
b = torch.tensor([[0, 1], [2, 3]])
print(torch.reshape(b, (-1,)))  # -1,自动推断变成一维

运行结果:
tensor([[0., 1.],
[2., 3.]])
tensor([0, 1, 2, 3])
【注】一般在方法名后面加下划线的都是原地操作,内存位置不会发生改变
(7)scatter_: torch.gather() 和torch.sactter_()的用法简析,按索引张量更新元素。

import torchsrc = torch.arange(1, 11).reshape((2, 5))
print(src)
index = torch.tensor([[0, 1, 2, 0]])
a = torch.zeros(3, 5, dtype=src.dtype)  # 初始化一个和src张量数据类型一样的3X5的0张量,
# 这样方便观察,非0的部分就是修改过的
z = a.scatter_(0, index, src)  # 按索引张量将src中的元素写入到z中,按维度0写入
# z[index[i][j],j]=src[i][j],index中i只有0,j从0到3
# z[index[0][0],0]=z[0,0]=src[0][0]=1
# z[index[0][1],1]=z[1,1]=src[1][1]=6
# z[index[0][2],2]=z[2,2]=src[2][2](i越界1个,相当于又变回0,索引只有(0,1),则2对应的应该是0,1,0的0,以此类推循环)=src[0][2]=3
# z[index[0][3],3]=z[0,3]=src[0][3]=4
print(z)
a = torch.zeros(3, 5, dtype=src.dtype)
z = a.scatter_(1, index, src)  # 按索引张量将src中的元素写入到z中,按维度1写入
# z[i,index[i][j]]=src[i][j],index中只有0,j从0到3
# z[0,index[0][0]]=z[0,0]=src[0][0]=1
# z[0,index[0][1]]=z[0,1]=src[0][1]=2
# z[0,index[0][2]]=z[0,2]=src[0][2]=3
# z[0,index[0][3]]=z[0,0]=src[0][3]=4(被覆盖,最终z[0,0]=4)
print(z)

运行结果:
tensor([[ 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10]])
tensor([[1, 0, 0, 4, 0],
[0, 2, 0, 0, 0],
[0, 0, 3, 0, 0]])
tensor([[4, 2, 3, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]])

(8)scatter_add_:以与 scatter_() 类似的方式,将张量 src 中的所有值添加到索引张量中指定的索引处的 self 中。

import torchsrc = torch.ones((2, 5))
print(src)
index = torch.tensor([[0, 1, 2, 0, 0]])
z = torch.zeros(3, 5, dtype=src.dtype).scatter_add_(0, index, src)  # 按维度0进行相加
print(z)
# z[index[i][j], j]=src[i][j],i只能为0,j从0到4
# z[index[0][0], 0]=z[0,0]=src[0][0]=1
# z[index[0][1], 1]=z[1,1]=src[0][1]=1
# z[index[0][2], 2]=z[2,2]=src[0][2]=1
# z[index[0][3], 3]=z[0,3]=src[0][3]=1
# z[index[0][4], 4]=z[0,4]=src[0][4]=1

运行结果:
tensor([[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.]])
tensor([[1., 0., 0., 1., 1.],
[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.]])
(9)split:将张量划分为多块,每块都是原来张量的一部分。

import torcha = torch.arange(10).reshape(5, 2)
print(a)
print(torch.split(a, 2))  # 分成两份,最后一份可能会少一点,要保证前面均分
print(torch.split(a, [1, 4]))  # 按1:4比例划分,不指定参数默认按0维度(行)划分

运行结果:
tensor([[0, 1],
[2, 3],
[4, 5],
[6, 7],
[8, 9]])
(tensor([[0, 1],
[2, 3]]), tensor([[4, 5],
[6, 7]]), tensor([[8, 9]]))
(tensor([[0, 1]]), tensor([[2, 3],
[4, 5],
[6, 7],
[8, 9]]))

chunk和split的区别:【GPT回答】chunk 函数将张量均匀分成几块,每块大小相等。split 函数可以根据指定的大小或部分来分割张量,每个块的大小可以不相等。总的来说,如果您需要将张量均匀地分成几块,可以使用 chunk 函数。如果您需要更灵活地指定每个块的大小或部分,可以使用 split 函数。

(10)squeeze:将张量中所有维度为1的那个维度移除掉

import torcha = torch.tensor([[[1, 2, 3], [1, 2, 3]]])  # 2x3x1张量
a = torch.squeeze(a)  # 压缩维度为1的维度,变成2维张量,2X3
print(a)a = torch.tensor([[[[1, 2, 3], [1, 2, 3]]]])  # 2x3x1x1张量
a = torch.squeeze(a)  # 压缩维度为1的维度,变成2维张量,2X3
print(a)# 压缩指定的维度为1的维度(PyTorch低于2.0版本,指定的维度不能是list(就是相当于用list的元素多次指定要压缩的维度为1的维度的索引),所以这里写dim = 2)
a = torch.tensor([[[[1, 2, 3], [1, 2, 3]]]])  # 2x3x1x1张量
a = torch.squeeze(a, dim=2)  # 压缩维度为1的维度,且索引为2,变成3维张量,2X3x1
print(a)

运行结果:
tensor([[1, 2, 3],
[1, 2, 3]])
tensor([[1, 2, 3],
[1, 2, 3]])
tensor([[[[1, 2, 3],
[1, 2, 3]]]])
(11)stack:沿着某一个新的维度将一系列张量拼接起来。

import torcha = torch.ones(3, 2)  # 3x2 全是1的张量
b = torch.zeros(3, 2)  # 3x3 全是0的张量
c = torch.stack([a, b])  # dim 默认为0,它们合并到新的张量的第0维,新的张量的元素分别是a, b,相当于最后是一个三维张量
print(c)c = torch.stack([a, b], dim=1)  # 按行拼接
print(c)

运行结果:
tensor([[[1., 1.],
[1., 1.],
[1., 1.]],
[[0., 0.],
[0., 0.],
[0., 0.]]])
tensor([[[1., 1.],
[0., 0.]],
[[1., 1.],
[0., 0.]],
[[1., 1.],
[0., 0.]]])

进程已结束,退出代码0

它们是这样的张量(接下来的看法可能不对):

如果按维度0进行拼接,

(后面全是1),按0维度这样看就是
tensor([[[1., 1.],
[1., 1.],
[1., 1.]],
[[0., 0.],
[0., 0.],
[0., 0.]]])
如果按维度1拼接,

按1维度这样看就是
tensor([[[1., 1.],
[0., 0.]],
[[1., 1.],
[0., 0.]],
[[1., 1.],
[0., 0.]]])

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

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

相关文章

蓝桥杯ctf2024 部分wp

数据分析 1. packet 密码破解 1. cc 逆向分析 1. 欢乐时光 XXTEA #include<stdio.h> #include<stdint.h> #define DELTA 0x9e3779b9 #define MX (((z>>5^y<<2)(y>>3^z<<4))^((sum^y)(key[(p&3)^e]^z))) void btea(unsigned int* v…

Linux软件包管理器——yum

文章目录 1.什么是软件包1.1安装与删除命令1.2注意事项1.3查看软件包1.3.1注意事项&#xff1a; 2.关于rzsz3.有趣的Linux下的指令 -sl 1.什么是软件包 在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序. 但是这样太麻烦了, 于是有些人把一…

335GB,台北地区倾斜摄影OSGB数据V0.2版介绍!

前几天发布了台北地区倾斜摄影OSGB数据第一个版本(139GB,台北倾斜摄影OSGB数据V0.1版),虽然数据还是一个半成品&#xff0c;完全没想到热度很高&#xff0c;很多读者对这份数据都有比较浓厚的兴趣&#xff0c;在这里首先感谢各位读者的大力支持与鼓励&#xff0c;给了我持续更新…

单路双电源三态控制的电平转换总线收发器AiP74LVC1T45

AiP74LVC1T45框图 AiP74LVC1T45引脚定义 AiP74LVC1T45丝印 概述 AiP74LVCH1T45是一个双电源带三态控制的总线收发器&#xff0c;具有3状态输出&#xff0c;可实现双向电平转换。它们具有两个1位输入输出端口(A和B)&#xff0c;一个方向控制输入(DIR)和双电源引脚(VCC(A)和VCC(…

C语言 | Leetcode C语言题解之第55题跳跃游戏

题目&#xff1a; 题解&#xff1a; #define max(a, b) (((a) > (b)) ? (a) : (b))bool canJump(int* nums, int numsSize){int cover 0;int i;// 只可能获取cover范围中的步数&#xff0c;所以i<coverfor(i 0; i < cover; i) {// 更新cover为从i出发能到达的最大…

idea No versioned directories to update were found

idea如何配置svn以及svn安装时需要注意什么 下载地址&#xff1a;https://112-28-188-82.pd1.123pan.cn:30443/download-cdn.123pan.cn/batch-download/123-820/3ec9445a/1626635-0/3ec9445a25ba365a23fc433ce0c16f34?v5&t1714358478&s171435847804276f7d9249382ba512…

Linux:浏览器访问网站的基本流程(优先级从先到后)

浏览器访问网站的基本流程&#xff08;优先级从先到后&#xff09; 首先查找浏览器是否存在该网站的访问缓存 其次查找本机的域名解析服务器 windows&#xff1a;C:\Windows\System32\drivers\etc\hostsLinux&#xff1a;/etc/hosts 使用外部的域名解析服务器解析&#xff…

LMDeploy 量化部署 LLM-VLM 实践 学习笔记

视频链接 https://www.bilibili.com/video/BV1tr421x75B/?vd_sourcea1ce254b4a97f9f687a83e661793cb2c 什么是模型部署 部署指的是已经开发好的大模型投入使用&#xff0c;要把模型部署到服务器或者移动端里&#xff0c;如何在有限的资源里加载大模型&#xff1f; 比如你好不…

网络安全 SQLmap-tamper的使用

目录 使用SQLmap Tamper脚本 1. 选择合适的Tamper脚本 2. 在命令行中使用Tamper脚本 3. 组合使用Tamper脚本 4. 注意和考虑 黑客零基础入门学习路线&规划 网络安全学习路线&学习资源 SQLmap是一款强大的自动化SQL注入和数据库取证工具。它用于检测和利用SQL注入漏…

计算机网络之传输层TCP\UDP协议

UDP协议 用户数据报协议UDP概述 UDP只在IP数据报服务之上增加了很少功能&#xff0c;即复用分用和差错检测功能 UDP的主要特点&#xff1a; UDP是无连接的&#xff0c;减少开销和发送数据之前的时延 UDP使用最大努力交付&#xff0c;即不保证可靠交付&#xff0c;可靠性由U…

关于google search console工具提交sitemap.xml无法抓取的问题解决办法

其实这个问题很好解决。 第一种情况&#xff1a;利用工具为我们的网站自动生成静态的sitemap.xml文件。这种可以检查下是否完整&#xff0c;然后上传到根目录下去&#xff0c;再去google search console提交我们的网站地图。 第二种情况&#xff1a;同样利用工具自动生成动态s…

AI图书推荐:AI驱动增长—ChatGPT和Bard 用于企业流程自动化

这本书《AI驱动增长—ChatGPT和Bard 用于企业流程自动化》&#xff08;ChatGPT and Bard for Business Automation: Achieving AI-Driven Growth&#xff09;由Tom Taulli撰写&#xff0c;主要探讨了ChatGPT和Bard两种人工智能技术在商业自动化中的应用&#xff0c;以及如何通过…

逆向案例三十——webpack登录某游戏

网址&#xff1a;aHR0cHM6Ly93d3cuZ205OS5jb20v 步骤&#xff1a; 进行抓包分析&#xff0c;找到登录接口&#xff0c;发现密码有加密 跟栈分析&#xff0c;从第三个栈进入&#xff0c;打上断点&#xff0c;再次点击登录 明显找到password,它由o赋值&#xff0c;o由a.encode(…

格瑞威特 | 邀您参加2024全国水科技大会暨技术装备成果展览会

—— 展位号&#xff1a;A13 —— 企业介绍 北京格瑞威特环保设备有限公司成立于2009年&#xff0c;是专业从事设计、研发、销售智能加药计量泵、在线水质分析仪表、便携式水质分析仪表、流量计、液位计、阀门、搅拌机、烟气报警仪、加药装置等各类水处理设备及配件的OEM供服…

ZISUOJ 高级语言程序设计实训-基础C(部分题)

说明&#xff1a; 有几个题是不会讲的&#xff0c;我只能保证大家拿保底分。 题目列表&#xff1a; 问题 A: 求平均数1 思路&#xff1a; 送分题…… 参考题解&#xff1a; #include <iostream> #include <iomanip> using std::cin; using std::cout;int main(…

leetcode-包含min函数的栈-93

题目要求 题目思路 1.设计上两个栈&#xff0c;第一个栈s1里面正常存储插入进来的数据&#xff0c;s2里面只存储s1里面最小的那个数据。 2.对于push函数&#xff0c;所有新来的value都需要在s1中插入&#xff0c;s2中&#xff0c;如果s2为空&#xff0c;那么也直接插入&#x…

动手学大模型LLM应用开发之个人知识库助手项目

目录 一、前言二、项目架构三、项目搭建运行四、RAG过程五、参考资料 一、前言 本项目由datawhale成员开发&#xff0c;主要实现了基于 Datawhale 的现有项目 README 的知识问答&#xff0c;使用户可以快速了解 Datawhale 现有项目情况。 项目地址 二、项目架构 ① LLM 层主要…

《面向云计算的零信任体系第1部分:总体架构》行业标准正式发布

中华人民共和国工业和信息化部公告2024年第4号文件正式发布行业标准&#xff1a;YD/T 4598.1-2024《面向云计算的零信任体系 第1部分&#xff1a;总体架构》&#xff08;后简称“总体架构”&#xff09;&#xff0c;并于2024年7月1日正式施行。 该标准由中国信通院牵头&#xf…

【汇编】#6 80x86指令系统其二(串处理与控制转移与子函数)

文章目录 一、串处理指令1. 与 REP 协作的 MOVS / STOS / LODS的指令1.1 重复前缀指令REP1.2 字符串传送指令&#xff08;Move String Instruction&#xff09;1.2 存串指令&#xff08;Store String Instruction&#xff09;1.3 取字符串指令&#xff08;Load String Instruct…

word启动缓慢之Baidu Netdisk Word Addin

word启动足足花了7秒钟&#xff0c;你知道我这7秒是怎么过来的吗&#xff1f; 原因就是我们可爱的百度网盘等APP&#xff0c;在我们安装客户端时&#xff0c;默认安装了Office加载项&#xff0c;不仅在菜单栏上加上了一个丑陋的字眼&#xff0c;也拖慢了word启动速度........ 解…