【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.rhkb.cn/news/315689.html

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

相关文章

Java web应用性能分析之【sysbench基准测试】

Java web应用性能分析之【CPU飙高分析之MySQL】-CSDN博客 Java web应用性能分析之【Linux服务器性能监控分析概叙】-CSDN博客 Java web应用性能分析概叙-CSDN博客 Java web应用性能分析之【基准测试】-CSDN博客 上面基本科普了一下基准测试,这里我们将从sysbench…

【喜报】科大睿智为武汉博睿英特科技高质量通过CMMI3级评估咨询工作

武汉博睿英特科技有限公司是信息通信技术产品、建筑智慧工程服务提供商。其拥有专注于航空、政府、教育、金融等多行业领域的资深团队,及时掌握最新信息通信应用技术,深刻理解行业业务流程,擅于整合市场优质资源,积极保持与高校产…

苹果电脑如何轻松抹掉NTFS格式磁盘 如何将Mac系统下硬盘格式化为NTFS Mac硬盘格式化

在苹果电脑的操作系统下,对于磁盘格式的转换基本是每个电脑使用者都会进行的操作,一般是为了使磁盘更好地在电脑上存储文件。 NTFS(New Technology File System)是一种Windows系统常用的文件系统,而Mac电脑则默认使用…

java案例-服务端与客户端(传输对象)

需求 代码 SysUser 用户类Operation 操作类Client 客户端Server 服务端ServerReaderThread 服务端线程类 SysUser 用户类 需要实现Serializable 方便序列化,传输对象 public class SysUser implements Serializable {private String username;private String passwo…

小型架构实验模拟

一 实验需求 二 实验环境 22 机器: 做nginx 反向代理 做静态资源服务器 装 nginx keepalived filebeat 44机器: 做22 机器的备胎 装nginx keepalived 99机器:做mysql的主 装mysqld 装node 装filebeat 77机器:做mysq…

Git零基础

Git工作流程图 操作指令 分支 、 指令总结 远程仓库

ubuntu安装Anaconda安装及conda使用

一. 安装anaconda3详细教程 1、下载镜像 清华大学开源软件镜像站下载地址: https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ 下拉到最低端选择Linux,选择最新版(32/64位)下载。这里我下载的是版本Anaconda3-4.3.30-Linux…

python应用-socket网络编程(1)

目录 1 先简单回顾下客户端和服务端通信的知识 2 服务端常用函数 3 客户端常用函数 4 服务端和客户端都用的函数 5 示例介绍客户端和服务端通信过程 6 建立服务端套接制 7 创建服务端函数socket.create_server() 8 创建客户端套接字 9 客户端连接函数socket.create_co…

Asp .Net Core 系列:国际化多语言配置

文章目录 概述术语 本地化器IStringLocalizer在服务类中使用本地化 IStringLocalizerFactoryIHtmlLocalizerIViewLocalizer 资源文件区域性回退 配置 CultureProvider内置的 RequestCultureProvider实现自定义 RequestCultureProvider使用 Json 资源文件 设计原理IStringLocali…

MATLAB语音信号分析与合成——MATLAB语音信号分析学习资料汇总(图书、代码和视频)

教科书:MATLAB语音信号分析与合成(第2版) 链接(含配套源代码):https://pan.baidu.com/s/1pXMPD_9TRpJmubPGaRKANw?pwd32rf 提取码:32rf 基础入门视频: 视频链接: 清…

Eclipse C++ 无法debug 问题

环境: ubuntu20.04 Eclipse CDT(x86_64) 工程,使用的是默认的CMake Project 现象: 1. 使用Eclipse, 加了断点后,debug 无法停在断点;step over 执行后是从main 直接执行到exit &#xff…

七彩虹(Colorful)隐星P16 2023款笔记本电脑原装出厂Win11系统镜像下载 带建Recovery一键还原功能

七彩虹原厂Windows预装OEM专用系统,恢复出厂开箱状态一模一样 适用型号:隐星P16 23 链接:https://pan.baidu.com/s/1Ig5MQMiC8k4VSuCOZRQHUw?pwdak5l 提取码:ak5l 原厂W11系统自带所有驱动、出厂时自带的主题与专用壁纸、系…

分类预测 | Matlab实现POA-BP鹈鹕算法优化BP神经网络多特征分类预测

分类预测 | Matlab实现POA-BP鹈鹕算法优化BP神经网络多特征分类预测 目录 分类预测 | Matlab实现POA-BP鹈鹕算法优化BP神经网络多特征分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 1.Matlab实现POA-BP鹈鹕算法优化BP神经网络多特征分类预测(Matlab实…

31 OpenCV 距离变换和分水岭算法

文章目录 距离变换分水岭算法distanceTransform 距离变换watershed 分水岭算法示例 距离变换 分水岭算法 distanceTransform 距离变换 void cv::distanceTransform (InputArray src,OutputArray dst,int distanceType,int maskSize,int dstType CV_32F) src:输入图像&#xf…

Android 学习 鸿蒙HarmonyOS 4.0 第二天(项目结构认识)

项目结构认识 和 了解: 工程目录下的结构如下: 首先能看到有两个.开头的文件,分别是.hvigor 和 .idea。这两个文件夹都是与构建有关系的, 如果你开发过安卓app,构建完会生成一个apk安装包,鸿蒙则是生成hap…

maya blendshape

目录 shape编辑器 maya创建blendshape python 脚本 添加形变动画 查看顶点个数 shape编辑器 打开方式: 窗口-动画编辑器-形变编辑器 maya创建blendshape python 脚本 import maya.cmds as cmds# 创建基础网格 - 球体 baseMesh cmds.polySphere(name"bas…

一文讲解Android车载系统camera架构 - EVS

Android的camera开发中,使用最多的是camera2 以及现在Google主推的cameraX 架构,而这两个架构主要针对的是手机移动端上camera的流程。 而今天介绍的EVS(Exterior View System)架构是不同于camera2上的手机架构,针对Automotive的版本&#x…

ETL中双流合并和多流合并的区别

一、ETL工具 ETLCloud数据集成平台集实时数据集成和离线数据集成以及API发布为一体的数据集成平台。与其他开源数据集成工具相比,采用轻量化架构、具有更快的部署速度、更快的数据传输速度、更低的运维成本,同时支持多租户的团队协作能力,能…

opencv_17_翻转与旋转

一、图像翻转 1)void flip_test(Mat& image); 2)void ColorInvert::flip_test(Mat& image) { Mat dst; //flip(image, dst, 0); //上下翻转 flip(image, dst, 1); //左右翻转 // flip(image, dst, -1); //180度翻转 imsho…

JAVA读取从WPS在Excel中嵌入的图片资源

读取从WPS在Excel中嵌入的图片资源 引言 许多数据文件中可能包含嵌入式图片,这些图片对于数据分析和可视化非常重要。然而,从 WPS 在 Excel 中读取这些图片可能会有一些技术挑战。在本文中,我将展示如何从 WPS Excel 文件中读取嵌入的图片&am…