深度学习 - 张量的广播机制和复杂运算

2024-06-05 22:04

本文主要是介绍深度学习 - 张量的广播机制和复杂运算,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

张量的广播机制(Broadcasting)是一种处理不同形状张量进行数学运算的方式。通过广播机制,PyTorch可以自动扩展较小的张量,使其与较大的张量形状兼容,从而进行元素级的运算。广播机制遵循以下规则:

  1. 如果张量维度不相同,在较小张量的形状前面加上1,直到两个张量的维度相同。
  2. 如果两个张量在某个维度的长度不相同,但其中一个张量在该维度的长度为1,那么在该维度上,较小长度的张量会被扩展为较大长度。
  3. 如果两个张量在任何维度上长度不同且均不为1,则无法进行广播,会引发错误。

广播机制的规则示例

规则1:在较小张量的形状前面加1
a = torch.tensor([1, 2, 3])
b = torch.tensor([[1], [2], [3]])
c = a + b
print(c)

运行结果

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

解释a的形状是(3,), b的形状是(3,1)。在较小的张量前面加1变成(1,3)和(3,1),然后在第0维度上广播。

规则2:在某个维度的长度为1
a = torch.tensor([[1, 2, 3]])
b = torch.tensor([[4], [5], [6]])
c = a + b
print(c)

运行结果

tensor([[5, 6, 7],[6, 7, 8],[7, 8, 9]])

解释a的形状是(1,3), b的形状是(3,1)。a被广播到(3,3),b也被广播到(3,3)。

规则3:无法广播的情况
a = torch.tensor([1, 2, 3])
b = torch.tensor([[1, 2], [3, 4]])
try:c = a + b
except RuntimeError as e:print(e)

运行结果

The size of tensor a (3) must match the size of tensor b (2) at non-singleton dimension 1

解释a的形状是(3,), b的形状是(2,2),它们的形状不兼容,无法进行广播。

广播机制的详细示例

示例1:标量与多维张量相加
a = torch.tensor(5)
b = torch.tensor([[1, 2, 3], [4, 5, 6]])
c = a + b
print(c)

运行结果

tensor([[ 6,  7,  8],[ 9, 10, 11]])

解释:标量a被广播到与b形状匹配,变成(2,3)。

示例2:形状不一致但能广播
a = torch.tensor([1, 2, 3])
b = torch.tensor([[1], [2], [3]])
c = a + b
print(c)

运行结果

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

解释a的形状是(3,), b的形状是(3,1)。a被广播到(3,3),b被广播到(3,3)。

示例3:不同维度的广播
a = torch.tensor([1, 2, 3])
b = torch.tensor([[[1]], [[2]], [[3]]])
c = a + b
print(c)

运行结果

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

解释a的形状是(3,),b的形状是(3,1,1)。a被广播到(3,1,3),b被广播到(3,1,3)。

示例4:标量与高维张量的广播
a = torch.tensor(10)
b = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
c = a * b
print(c)

运行结果

tensor([[[10, 20],[30, 40]],[[50, 60],[70, 80]]])

解释:标量a被广播到与b的形状匹配。

示例5:不同形状的广播加法
a = torch.tensor([[1, 2], [3, 4], [5, 6]])
b = torch.tensor([10, 20])
c = a + b
print(c)

运行结果

tensor([[11, 22],[13, 24],[15, 26]])

解释a的形状是(3,2),b的形状是(2,)。b被广播到(3,2)。

张量的基本操作

示例1:基本运算
a = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
b = torch.tensor([[[2, 2], [2, 2]], [[2, 2], [2, 2]]])
c = a * b
print(c)

运行结果

tensor([[[ 2,  4],[ 6,  8]],[[10, 12],[14, 16]]])

解释:对ab中的每个元素进行乘法运算。

示例2:列表索引
a = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
b = a[0]
print(b)

运行结果

tensor([[1, 2],[3, 4]])

解释:选择张量a的第0个二维子张量。

示例3:范围索引
a = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
b = a[:, 0, :]
print(b)

运行结果

tensor([[1, 2],[5, 6]])

解释:选择张量a中所有的第0个二维子张量的所有元素。

示例4:布尔索引
a = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
b = a > 4
c = a[b]
print(c)

运行结果

tensor([5, 6, 7, 8])

解释:选择张量a中所有大于4的元素。

示例5:多维索引
a = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
b = a[1, 1, 1]
print(b)

运行结果

tensor(8)

解释:选择张量a的第二个三维子张量中的第二个二维子张量中的第二个元素。

示例6:形状操作(reshape)
a = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
b = a.reshape(4, 2)
print(b)

运行结果

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

解释:将张量a重塑为形状为(4, 2)的张量。

示例7:形状操作(squeeze)
a = torch.tensor([[[1, 2]], [[3, 4]], [[5, 6]]])
b = a.squeeze()
print(b)

运行结果

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

解释:删除张量a中所有为1的维度。

示例8:形状操作(unsqueeze)
a = torch.tensor([[1, 2], [3, 4], [5, 6]])
b = a.unsqueeze(1)
print(b)

运行结果

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

解释:在张量a的第一维度增加一个维度。

示例9:形状操作(transpose)
a = torch.tensor([[[1, 2, 3], [4, 5, 6]]])
b = a.transpose(1, 2)
print(b)

运行结果

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

解释:交换张量a的第1维和第2维。

示例10:形状操作(permute)
a = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
b = a.permute(2, 0, 1)
print(b)

运行结果

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

解释:根据指定的顺序重新排列张量a的维度。

这篇关于深度学习 - 张量的广播机制和复杂运算的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1034294

相关文章

深度解析Python中递归下降解析器的原理与实现

《深度解析Python中递归下降解析器的原理与实现》在编译器设计、配置文件处理和数据转换领域,递归下降解析器是最常用且最直观的解析技术,本文将详细介绍递归下降解析器的原理与实现,感兴趣的小伙伴可以跟随... 目录引言:解析器的核心价值一、递归下降解析器基础1.1 核心概念解析1.2 基本架构二、简单算术表达

深度解析Java @Serial 注解及常见错误案例

《深度解析Java@Serial注解及常见错误案例》Java14引入@Serial注解,用于编译时校验序列化成员,替代传统方式解决运行时错误,适用于Serializable类的方法/字段,需注意签... 目录Java @Serial 注解深度解析1. 注解本质2. 核心作用(1) 主要用途(2) 适用位置3

Java MCP 的鉴权深度解析

《JavaMCP的鉴权深度解析》文章介绍JavaMCP鉴权的实现方式,指出客户端可通过queryString、header或env传递鉴权信息,服务器端支持工具单独鉴权、过滤器集中鉴权及启动时鉴权... 目录一、MCP Client 侧(负责传递,比较简单)(1)常见的 mcpServers json 配置

Maven中生命周期深度解析与实战指南

《Maven中生命周期深度解析与实战指南》这篇文章主要为大家详细介绍了Maven生命周期实战指南,包含核心概念、阶段详解、SpringBoot特化场景及企业级实践建议,希望对大家有一定的帮助... 目录一、Maven 生命周期哲学二、default生命周期核心阶段详解(高频使用)三、clean生命周期核心阶

Java实现复杂查询优化的7个技巧小结

《Java实现复杂查询优化的7个技巧小结》在Java项目中,复杂查询是开发者面临的“硬骨头”,本文将通过7个实战技巧,结合代码示例和性能对比,手把手教你如何让复杂查询变得优雅,大家可以根据需求进行选择... 目录一、复杂查询的痛点:为何你的代码“又臭又长”1.1冗余变量与中间状态1.2重复查询与性能陷阱1.

深度剖析SpringBoot日志性能提升的原因与解决

《深度剖析SpringBoot日志性能提升的原因与解决》日志记录本该是辅助工具,却为何成了性能瓶颈,SpringBoot如何用代码彻底破解日志导致的高延迟问题,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言第一章:日志性能陷阱的底层原理1.1 日志级别的“双刃剑”效应1.2 同步日志的“吞吐量杀手”

基于Redis自动过期的流处理暂停机制

《基于Redis自动过期的流处理暂停机制》基于Redis自动过期的流处理暂停机制是一种高效、可靠且易于实现的解决方案,防止延时过大的数据影响实时处理自动恢复处理,以避免积压的数据影响实时性,下面就来详... 目录核心思路代码实现1. 初始化Redis连接和键前缀2. 接收数据时检查暂停状态3. 检测到延时过

Redis中哨兵机制和集群的区别及说明

《Redis中哨兵机制和集群的区别及说明》Redis哨兵通过主从复制实现高可用,适用于中小规模数据;集群采用分布式分片,支持动态扩展,适合大规模数据,哨兵管理简单但扩展性弱,集群性能更强但架构复杂,根... 目录一、架构设计与节点角色1. 哨兵机制(Sentinel)2. 集群(Cluster)二、数据分片

Unity新手入门学习殿堂级知识详细讲解(图文)

《Unity新手入门学习殿堂级知识详细讲解(图文)》Unity是一款跨平台游戏引擎,支持2D/3D及VR/AR开发,核心功能模块包括图形、音频、物理等,通过可视化编辑器与脚本扩展实现开发,项目结构含A... 目录入门概述什么是 UnityUnity引擎基础认知编辑器核心操作Unity 编辑器项目模式分类工程

深度解析Python yfinance的核心功能和高级用法

《深度解析Pythonyfinance的核心功能和高级用法》yfinance是一个功能强大且易于使用的Python库,用于从YahooFinance获取金融数据,本教程将深入探讨yfinance的核... 目录yfinance 深度解析教程 (python)1. 简介与安装1.1 什么是 yfinance?