PyTorch如何通过 torch.unbind 和torch.stack动态调整张量的维度顺序
笔者一篇博客PyTorch 的 torch.unbind 函数详解与进阶应用:中英双语中有一个例子如下:
# 创建一个 3x2x2 的三维张量
x = torch.tensor([[[1, 2], [3, 4]],[[5, 6], [7, 8]],[[9, 10], [11, 12]]])# 第一步:沿第 0 维分解为 3 个 2x2 张量
unbind_result = torch.unbind(x, dim=0)# 第二步:沿第 2 维重新堆叠
stack_result = torch.stack(unbind_result, dim=2)
print("最终结果:", stack_result)
结果
最终结果:
tensor([[[ 1, 5, 9],[ 3, 7, 11]],[[ 2, 6, 10],[ 4, 8, 12]]])
- 使用 torch.unbind 沿第 0 维分解。
- 使用 torch.stack 沿第 2 维重新组合,从而完成了维度转换。
张量的形状在每一步的变化如下:
- 原始张量形状为 [3, 2, 2]。
- 分解后,得到 3 个形状为 [2, 2] 的张量。
- 堆叠时,将这些张量沿新的维度 dim=2 组合,最终形状变为 [2, 2, 3]。
通过这种分解和堆叠方式,我们可以灵活地操作张量的维度和数据布局。
具体是怎么变的,这里记录一下。
这个例子展示了如何通过 torch.unbind 和 torch.stack 动态调整张量的维度顺序。以下是对这个例子的详细解释,包括每一步的操作和张量形状变化:
1. 初始张量
我们先创建一个形状为 [3, 2, 2] 的张量 x:
x = torch.tensor([[[1, 2], [3, 4]],[[5, 6], [7, 8]],[[9, 10], [11, 12]]])
张量的内容:
x = [[[1, 2], [3, 4]], # 第一个“平面”[[5, 6], [7, 8]], # 第二个“平面”[[9, 10], [11, 12]] # 第三个“平面”]
形状:[3, 2, 2]
这里的含义:
- 第一维度(dim=0,大小为3):有3个“平面”(或者块)。
- 第二维度(dim=1,大小为2):每个“平面”有两行。
- 第三维度(dim=2,大小为2):每行有两个元素。
2. 使用 torch.unbind 沿 dim=0 分解
unbind_result = torch.unbind(x, dim=0)
torch.unbind 的作用是沿着指定的维度(这里是 dim=0)移除这一维度,并返回一个元组,元组中的每个元素都是输入张量在该维度上的切片。
对于我们的例子:
x沿着dim=0分解,相当于把张量按“平面”切开。- 原始的 3×2×2 张量被分成了 3 个形状为
[2, 2]的子张量。
unbind_result 的内容:
unbind_result = (tensor([[1, 2], [3, 4]]), # 第一个平面tensor([[5, 6], [7, 8]]), # 第二个平面tensor([[9, 10], [11, 12]]) # 第三个平面
)
每个切片都是一个形状为 [2, 2] 的二维张量。
这里的维度变化:
- 原始张量形状
[3, 2, 2]→ 切片形状[2, 2]。
3. 使用 torch.stack 沿 dim=2 重新组合
stack_result = torch.stack(unbind_result, dim=2)
torch.stack 的作用是把一组张量沿着新的维度拼接起来。这里:
unbind_result是一个包含 3 个[2, 2]张量的元组。- 我们指定
dim=2,意思是在原始张量的最后一维(第三维)增加一个新的维度来进行拼接。
拼接过程:
- 第一个子张量的每个位置与第二个、第三个子张量的对应位置对齐,按列方向拼接。
- 拼接后,原来
[2, 2]的子张量变成了[2, 3]的子张量。
举例说明:
- 原始三个
[2, 2]的张量:tensor([[1, 2], [3, 4]]) tensor([[5, 6], [7, 8]]) tensor([[9, 10], [11, 12]]) - 沿
dim=2进行拼接后:[[[1, 5, 9], [3, 7, 11]], # 第一行拼接[[2, 6, 10], [4, 8, 12]] # 第二行拼接 ]
最终结果:
stack_result = tensor([[[ 1, 5, 9], [ 3, 7, 11]],[[ 2, 6, 10], [ 4, 8, 12]]
])
形状变化:
- 原始张量
[3, 2, 2]→ 分解后的切片[2, 2]→ 拼接后的结果[2, 2, 3]。
4. 形状变化总结
| 操作 | 张量内容 | 张量形状 |
|---|---|---|
| 初始张量 | x | [3, 2, 2] |
使用 torch.unbind(dim=0) | 3 个 [2, 2] 的子张量 | [2, 2] |
使用 torch.stack(dim=2) | 拼接为一个新的张量 | [2, 2, 3] |
5. 为什么维度顺序调整了?
通过 torch.unbind 和 torch.stack 的组合,实际上我们重新定义了张量的组织方式:
torch.unbind将dim=0的维度移除,分解成多个子张量。torch.stack指定新的维度(这里是dim=2),将这些子张量拼接为一个新维度,从而实现了维度的重新排列。
最终,我们将原来的“平面”维度(dim=0)转移到了列方向(dim=2),实现了动态调整维度顺序的效果。
6. 总结
torch.unbind用于移除一个维度并分解张量。torch.stack用于沿指定的新维度拼接张量。- 两者结合可以灵活调整张量的维度顺序。
这个例子展示了如何从 [3, 2, 2] 变换到 [2, 2, 3],过程中分解和拼接操作相辅相成,适用于需要动态调整张量维度的高级场景。
后记
2024年12月12日22点28分于上海,基于GPT4o大模型生成。
相关文章:
PyTorch如何通过 torch.unbind 和torch.stack动态调整张量的维度顺序
笔者一篇博客PyTorch 的 torch.unbind 函数详解与进阶应用:中英双语中有一个例子如下: # 创建一个 3x2x2 的三维张量 x torch.tensor([[[1, 2], [3, 4]],[[5, 6], [7, 8]],[[9, 10], [11, 12]]])# 第一步:沿第 0 维分解为 3 个 2x2 张量 un…...
【Unity3D】报错libil2cpp.so找不到问题
mainTemplate.gradle文件末尾添加: **IL_CPP_BUILD_SETUP** 此报错发生在低版本的Unity升级到高版本后,例如Unity2019升级到Unity2021,而Unity2019默认创建的mainTemplate.gradle文件是不包含**IL_CPP_BUILD_SETUP** 因此会导致libil2cpp.so…...
事件冒泡机制详解
一、事件传播的三个阶段 1. 捕获阶段 事件从最外层元素(如document)开始,沿着 DOM 树向目标元素传播。这个阶段就像是事件的“下行通道”,在这个过程中,事件会经过目标元素的祖先元素。不过,在捕获阶段&a…...
红米Note 9 Pro5G刷LineageOS
LineageOS介绍 LineageOS 是一个基于 Android 的开源操作系统,是面向智能手机和平板电脑等设备的替代性操作系统。它是 CyanogenMod 的继承者,而 CyanogenMod 是曾经非常受欢迎的一个第三方 Android 定制 ROM。 在 2016 年,CyanogenMod 项目因…...
6.3.1 MR实战:计算总分与平均分
在本次实战中,我们的目标是利用Apache Hadoop的MapReduce框架来处理和分析学生成绩数据。具体来说,我们将计算一个包含五名学生五门科目成绩的数据集的总分和平均分。这个过程包括在云主机上准备数据,将成绩数据存储为文本文件,并…...
ARM循环程序和子程序设计
1、计算下列两组数据的累加和并存入到sum1和 sum2 单元中。datal:0x12,0x935,0x17,0x100,0x95,0x345。 data2:0x357,0x778,0x129,0x188,0x190,0x155,0x167。 1.定义数据段 ;定义数据段,类型为data(表示为数据段),权限为可读可写(程序可以读取和修改这…...
静态路由、RIP、OSPF、BGP的区别
静态路由:是管理员手动将路由写入到路由器中,配置简单开销小,但不能适应网络变化,只用于小型的网络 RIP,路由信息协议,属于距离矢量路由协议的一种,根据跳数来判断最优路由,如果跳数…...
知识分享第二十八天-数学篇一
组合.二项式定理.常见导数 组合 让我们通过一个具体的例子来理解组合(Combinations)的概念 假设你有一个装有5个不同颜色球的袋子:红、蓝、绿、黄和紫。你想从中随机抽取3个球, 不考虑顺序,那么你可以有多少种不同的…...
BigDecimal在进行除法运算时需要注意四舍五入的位置
我们在进行A除B的时候,需要将四舍五入的逻辑放入除法的过程中就定义,不要等到A/B结果出来了再去进行四舍五入,这样会出现问题。下面举例 10%3 我们拿10除3为例,很明显,结果是一个除不尽的小数3.3333… 直接除 publi…...
第二部分:进阶主题 14 . 性能优化 --[MySQL轻松入门教程]
MySQL性能优化是一个广泛的话题,它涉及到数据库设计、查询语句的编写、索引的使用、服务器配置等多个方面。下面是一些常见的MySQL性能优化策略: 1. 数据库和表结构优化 下面是三个关于MySQL数据库和表结构优化的具体示例: 示例 1: 合理选…...
Mac电脑设置鼠标的滚轮方向
Mac电脑使用鼠标时,上下滚动,方向与Windows相反,如果要保持与Windows一致,则下载MOS这个软件,然后在MOS中进行配置,就可以让鼠标操作方式与Windows一致。 软件下载地址: https://mos.caldis.me…...
【LDAP】LDAP概念和原理介绍
目录 一、前言 二、什么是LDAP? 2.1 什么是目录服务? 2.2 LDAP的介绍 2.3 为什么要使用LDAP 三、LDAP的主要产品线 四、LDAP的基本模型 4.1 目录树概念 4.2 LDAP常用关键字列表 4.3 objectClass介绍 五、JXplorer工具使用 一、前言 对于许多的…...
Android系统(android app和系统架构)
文章目录 AndroidAndroid Apps四大组件 Android系统Platform API之下:一个微笑内核adb(Android Debug Bridge) Android包管理机制Android的Intent机制参考 Android LinuxFrameworkJVM 在Linux/Java上做了个二次开发?并不完全是:Android定义…...
Android HandlerThread、Looper、MessageQueue 源码分析
Android HandlerThread、Looper、MessageQueue 源码分析 简介 在 Android 开发中,大家应该对 HandlerThread 有一定了解。顾名思义,HandlerThread 是 Thread 的一个子类。与普通的 Thread 不同,Thread 通常一次只能执行一个后台任务&#x…...
HTML知识点详解教程
文章目录 HTML知识点详解教程1. HTML基本语法2. HTML标签详解2.1 分区标签 <div>2.2 标题标签 <h1> ~ <h6>2.3 段落标签 <p>2.4 图片标签 <img>2.5 列表标签 <ul> 和 <ol>无序列表 <ul>有序列表 <ol> 2.6 超链接标签 &l…...
[数据结构#1] 并查集 | FindRoot | Union | 优化 | 应用
目录 1. 并查集原理 问题背景 名称与编号映射 数据结构设计 2. 并查集基本操作 (1) 初始化 (2) 查询根节点 (FindRoot) (3) 合并集合 (Union) (4) 集合操作总结 并查集优化 (1) 路径压缩 (2) 按秩合并 3. 并查集的应用 (1) 统计省份数量 (2) 判断等式方程是否成…...
科研绘图系列:R语言绘制网络图和密度分布图(network density plot)
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据下载图1图2图3图4图5图6图7图8系统信息参考介绍 R语言绘制网络图和密度分布图(network & density plot) 加载R包 library(magrittr) library(dplyr) library(…...
Linux中输入和输出基本过程
1.文件内核级缓冲区 前面在如何理解Linux一切皆文件的特点中提到为了保证在Linux中所有进程访问文件时的方式趋近相 同,在f ile 结构体中存在一个 files_operations 结构体指针,对应的结构体保存所有文件操作的函 数指针(这个结构体也被称为…...
使用 acme.sh 签发和自动续期 ssl https 证书
acme.sh 是一个热度非常高的签发和自动续期 https 证书的工具,虽然官网上提供了充分的操作说明,但是不够简洁,本文以在 nginx 中签发和配置http 为例,列出必要的几个简单步骤。 安装 因为网络原因,github 大部分人是…...
spring重点面试题总结
bean的生命周期 在 Spring 中,BeanDefinition、Bean 实例化、依赖注入、Aware 接口的处理、以及 BeanPostProcessor 的前置和后置处理等,都是 Spring 容器管理 Bean 生命周期的关键部分。下面我将详细解释这些过程。 1. 通过 BeanDefinition 获取 Bean…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...
