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

news2024/9/21 14:38:50

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

1. 张量

1.1 张量操作

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

  • 按维度0分割:
import torch

b = 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 torch

b = 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 torch

a = 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 torch

a = 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 torch

t = 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 torch

a = 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 torch

src = 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 torch

src = 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 torch

a = 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 torch

a = 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 torch

a = 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.coloradmin.cn/o/1631226.html

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

相关文章

1.Neo4j图数据库介绍

背景 1.社交、电商、金融、零售、物联网行业,现实社会组织起了一张庞大复杂的关系网。 2.传统数据库很难处理关系运算。 3.需要一种支持海量复杂数据关系运算的数据库。 图数据库是以图数据结构存储和查询数据,是一种NoSQL数据库,存储更多…

冯唐成事心法笔记 —— 知己

系列文章目录 冯唐成事心法笔记 —— 知己 冯唐成事心法笔记 —— 知人 冯唐成事心法笔记 —— 知世 冯唐成事心法笔记 —— 知智慧 文章目录 系列文章目录卷首语 管理是一生的日常,成事是一生的修行PART 1 知己 用好自己的天赋如何管理自我第一,如何…

沉浸式翻译 chrome 插件 Immersive Translate - Translate Website PDF

免费翻译网站,翻译PDF和Epub电子书,双语翻译视频字幕 📣 网络上口碑爆炸的网站翻译扩展工具【沉浸式翻译】⭐⭐⭐⭐⭐ 💻 功能特点如下: 📰 网站翻译 🚀 提供双语网站翻译,智能识…

数据库常考理论

1 笛卡尔积X与自然连接∞的区别 2 求候选键 3 无损连接及函数依赖 4 范式判断 笛卡尔积:S1*S2,产生的结果包括S1和S2的所有属性列,并且S1中每条记录依次和S2中所有记录 组合成一条记录,最终属性列为S1S2属性列,记录数为S1*S2记…

k8s pod使用sriov

之前的文章中讲了k8s multus的使用,本章节来讲述下如何使用multus来实现sriov的使用。 一、sriov 简介 SR-IOV在2010年左右由Intel提出,但是随着容器技术的推广,intel官方也给出了SR-IOV技术在容器中使用的开源组件,例如&#…

Java集合框架-Collection-queue

目录 一、Deque二、ArrayDequeArrayDeque层次结构图ArrayDeque概述ArrayDeque底层数据结构ArrayDeque常用方法(简略) 三、PriorityQueuePriorityQueue层次结构图PriorityQueue概述PriorityQueue 底层数据结构PriorityQueue常用方法(详细) Java里有一个叫做Stack的类&#xff0c…

Qt | 标准、复选、单选、工具、命令按钮大全

01、QPushButton QPushButton 类(标准按钮) 示例 3:默认按钮与自动默认按钮 02、QCheckBox QCheckBox 类(复选按钮) 1、复选按钮的第三状态(见右图 Qt5.10.1 的选中状态):是指除了选中 和未选中状态之外的第三种状态,这种状态用来指示“不变”,表 示用户既不选中也不取…

go语言实现简单认证样例

目录 1、代码实现样例 2、postman调用 1、代码实现样例 package mainimport ("net/http""strings""github.com/dgrijalva/jwt-go""github.com/gin-gonic/gin" )var (// 密钥,用于验证 JWT 令牌signingKey []byte("…

09 配置文件日志多线程

配置文件 配置文件 在企业开发过程中,我们习惯把一些需要灵活配置的数据放在一些文本文件中,而不是在Java代码写死我们把这种存放程序配置信息的文件,统称为配置文件 配置文件一般要求有明确的格式,以方便读写操作!!! Properti…

【已解决】VMware虚拟机中出现无法将“iso文件”当做CD-ROM映像进行连接:找不到该文件的错误

报错 在VMware上运行虚拟机时报错:VMware虚拟机中出现无法将“iso文件”当做CD-ROM映像进行连接:找不到该文件的错误 原因分析 找不到这个iso文件了,检查文件位置 解决方案 找到iso文件,然后在VM中编辑虚拟机中这个文件的位置…

双塔模型在召回和粗排的区别

答案参考:推荐系统中,双塔模型用于粗排和用于召回的区别有哪些? - 知乎 召回和粗排在不同阶段面临样本不一样,对双塔来说样本分布差异会使召回和粗排采取不一样的方式。召回打分空间是全部item空间,曝光只有很少一部分&#xff0…

IDEA上文件换行符、分隔符(Line Separator)LF,CR,CRLF错乱影响Git上传Github或Gitee代码

IDEA上文件换行符、分隔符(Line Separator)LF,CR,CRLF错乱影响Git上传Github或Gitee代码 指定目录 然后就可以上传了 OK 一定注意更改Line Separator的文件目录 如果是target目录下的文件,是不能修改为LF的,把target文件删除,再重载一次main文件,就…

安装JAVA和java IDEA并汉化过程

1.安装java: 打开java的下载链接: Java Downloads | Oracle 然后选择对应的版本下载即可,我这里是windows 所以下载这个 然后正常一步步安装即可。 2.配置java环境: 在桌面右键此电脑然后点击属性——高级系统设置——环境变量——然后…

揭秘工业大模型:从人工智能小白到技术先锋

工业大模型的五个基本问题 信息化时代,数字化转型成为企业提升营运效率、应对经营风险和提升核心竞争力的重要途径。在此过程中,数据作为一种客观存在的资源,所产生的价值日益凸显。党的十九届四中全会从国家治理体系和治理能力现代化的高度将…

【启扬方案】启扬RK3568核心板助力酒店智能化入住与服务新体验!

近年来,随着人们对于便利和效率的需求不断提升,酒店行业也开始追求智能化的管理方式。酒店无人自助机系统整合了人机交互、人脸识别、智能化控制、语音识别等技术,结合软件应用,房客可以自助完成身份识别、选房、支付、自动发放房…

Hot100-哈希法

1. 两数之和 - 力扣&#xff08;LeetCode&#xff09; 在做面试题目的时候遇到需要判断一个元素是否出现过的场景应该第一时间想到哈希法 class Solution {public int[] twoSum(int[] nums, int target) {int[] result new int[2];for (int i 0; i < nums.length;i){for…

风险防不胜防?看YashanDB如何守护你的数据库安全(下篇)

前言 上一篇文章&#xff0c;咱们主要讲了数据库安全机制中的访问管理~今天继续深入聊聊威胁监测以及数据保护&#x1f9d0; &#xff08;文末可回顾上篇文章噢&#x1f4d6;&#xff09; 02 威胁监测 安全审计 YashanDB语法上支持权限审计、行为审计和角色审计&#xff0c;…

开发规范:API安全

开发规范&#xff1a;API安全 API是现代移动、SaaS和web应用程序的关键组成部分&#xff0c;可以应用在面向客户、合作伙伴和内部应用程序中。API可以暴露应用程序逻辑和敏感数据。不安全的API很容易成为黑客攻击的目标&#xff0c;使他们能够访问安全的服务器或网络。攻击者可…

甘特图是什么?利用甘特图来优化项目管理流程

在现代项目管理中,图表是一种强大而直观的工具,可以帮助项目经理和团队成员清晰地了解并掌控整个项目进程。其中,甘特图是最常用和最有效的图表之一。 甘特图是一种条形图,可以用来直观地展示项目中各个任务的进度、持续时间和相互关系。它由一个横轴和一个纵轴组成。横轴代表时…

Docker搭建LNMP+Wordpress的实验

目录 一、项目的介绍 1、项目需求 2、服务器环境 3、任务需求 二、Linux系统基础镜像 三、部署Nginx 1、建立工作目录 2、编写Dockerfile 3、准备nginx.conf配置文件 4、设置自定义网段和创建镜像和容器 5、启动镜像容器 6、验证nginx 三、Mysql 1、建立工作目录…