PyTorch 张量入门:第二篇 —— Tensors 快速
itomcoil 2025-08-06 20:24 7 浏览
PyTorch 张量入门:第二篇 —— Tensors 快速教程
导语
张量(Tensor)是 PyTorch 的核心数据结构,类似于多维数组,但支持 GPU 加速和自动求导。掌握张量的创建、属性、运算及与 NumPy 的互操作,是深入学习深度学习模型的基础。本章将带你一步步了解张量的方方面面,让你能够灵活地构建和操作数据,为后续模型开发做好准备。
一、张量的创建
概念讲解
PyTorch 提供多种方式来创建张量:
- o 从数据:直接用 Python 列表或元组;
- o 随机初始化:torch.rand、torch.randn 等;
- o 常量初始化:torch.zeros、torch.ones;
- o 从 NumPy:torch.from_numpy,与 NumPy 共享内存;
- o 根据已有张量:torch.zeros_like、torch.ones_like、torch.rand_like。
代码示例
import torch
import numpy as np
# 1. 从 Python 列表创建
x_data = torch.tensor([[1, 2, 3], [4, 5, 6]])
# 2. 随机初始化
x_rand = torch.rand(2, 3) # 均匀分布 [0,1)
x_randn = torch.randn(2, 3) # 正态分布
# 3. 常量初始化
x_zeros = torch.zeros(2, 3)
x_ones = torch.ones(2, 3)
# 4. 从 NumPy 数组创建(共享内存)
np_array = np.array([[7, 8, 9], [10, 11, 12]])
x_from_np = torch.from_numpy(np_array)
# 5. 根据已有张量创建
x_ones_like = torch.ones_like(x_data) # 与 x_data 同形状
x_rand_like = torch.rand_like(x_data, dtype=torch.float)
print("x_data:\n", x_data)
print("x_rand:\n", x_rand)
print("x_zeros:\n", x_zeros)
print("x_from_np:\n", x_from_np)
print("x_ones_like:\n", x_ones_like)
思考题
- 1. torch.tensor(data) 与 torch.from_numpy(np_array) 在内存使用上有何区别?
答案:torch.tensor 会复制数据,将数据从源(Python 列表或 NumPy 数组)拷贝到新张量;而 torch.from_numpy 则与原始 NumPy 数组共享内存,不会复制数据,因此对其中一方的修改会反映到另一方。 - 2. 如果想创建一个 5×5 的单位矩阵(对角线为 1,其余为 0),应该如何操作?
答案:可以使用 torch.eye(5),该函数会返回一个 5×5 的单位矩阵。
二、张量属性
概念讲解
每个张量都有三个核心属性:
- 1. 形状(shape):张量的维度,例如 (2, 3);
- 2. 数据类型(dtype):元素类型,如 float32、int64;
- 3. 存储设备(device):位于 CPU 还是 GPU(如 cpu 或 cuda:0)。
代码示例
import torch
# 创建一个随机张量
tensor = torch.randn(3, 4)
# 查看属性
print(f"Shape: {tensor.shape}") # torch.Size([3, 4])
print(f"Dtype: {tensor.dtype}") # torch.float32
print(f"Device: {tensor.device}") # cpu
# 将张量移动到 GPU(如可用)
if torch.cuda.is_available():
tensor_gpu = tensor.to("cuda:0")
print(f"Moved to device: {tensor_gpu.device}")
思考题
- 1. 如何将一个已有张量从 GPU 转回 CPU?
答案:调用 tensor.to("cpu") 或 tensor.cpu() 即可将张量移动到 CPU。 - 2. 在创建随机张量时,如何指定数据类型为 int64?
答案:可以在创建时通过 dtype=torch.int64 参数指定,例如 torch.randint(0, 10, (3, 3), dtype=torch.int64)。
三、张量运算
概念讲解
PyTorch 提供丰富的张量运算,主要包括:
- o 索引与切片:与 NumPy 类似;
- o 拼接与堆叠:torch.cat(拼接)、torch.stack(堆叠);
- o 算术运算:加减乘除、点积、矩阵乘法;
- o 汇总操作:求和、均值、最大/最小值;
- o 原地操作:带 _ 后缀的方法(如 add_),直接修改原张量。
代码示例
import torch
# 索引与切片
t = torch.arange(1, 10).reshape(3, 3)
print("Original:\n", t)
print("第一行:", t[0])
print("第二列:", t[:, 1])
# 拼接与堆叠
t1 = torch.ones(2, 3)
t2 = torch.zeros(2, 3)
cat = torch.cat([t1, t2], dim=0) # 纵向拼接,结果 4×3
stack = torch.stack([t1, t2], dim=0) # 结果 2×2×3
# 矩阵乘法
mat1 = torch.randn(2, 4)
mat2 = torch.randn(4, 3)
matmul = mat1 @ mat2 # 等价于 torch.matmul(mat1, mat2)
# 汇总操作
sum_val = t.sum() # 所有元素之和
mean_val = t.float().mean() # 转为浮点后取均值
# 原地操作
print("Before add_:\n", t1)
t1.add_(5) # 每个元素加 5
print("After add_:\n", t1)
思考题
- 1. torch.cat 与 torch.stack 的区别是什么?
答案:torch.cat 沿指定维度拼接已有张量,要求所有张量在拼接维度之外的形状相同;torch.stack 会在新维度上堆叠张量,结果张量的维度会增加 1,所有原张量的形状必须完全相同。 - 2. 在自动求导场景下,为什么要谨慎使用原地操作?
答案:原地操作会修改已有张量的内存,可能会破坏计算图中中间变量的记录,导致梯度计算错误或报错。
四、与 NumPy 互操作
概念讲解
- o 张量 → NumPy:调用 .numpy() 即可,但仅限于 CPU 张量;
- o NumPy → 张量:torch.from_numpy,与 NumPy 数组共享内存,修改任一方会影响另一方。
代码示例
import torch
import numpy as np
# 张量转 NumPy
tensor = torch.ones(4, 4)
arr = tensor.numpy()
print("NumPy array:", arr)
# NumPy 转张量(共享内存)
arr += 10
tensor2 = torch.from_numpy(arr)
print("Updated Tensor:", tensor2)
思考题
- 1. 如果张量在 GPU 上,调用 .numpy() 会发生什么?
答案:GPU 张量没有与 CPU 上 NumPy 数组共享的内存,因此调用 .numpy() 会报错。需要先使用 tensor.cpu() 将张量移动到 CPU,然后才能调用 .numpy()。 - 2. 为什么共享内存可以提高效率?
答案:因为不需要数据复制,避免了额外的内存分配和数据拷贝开销,提高了数据传输效率和运行性能。
知识小结
- o 张量是 PyTorch 的基本数据单元,支持 CPU/GPU 计算和自动求导;
- o 多种创建方式:从数据、随机、常量、NumPy、按现有张量;
- o 了解形状、数据类型和设备属性,有助于张量管理;
- o 支持丰富运算:索引切片、拼接堆叠、算术和原地操作;
- o 与 NumPy 之间可高效互操作,为数据预处理与模型开发提供便捷。
下一篇预告:深入探讨张量广播(Broadcasting)机制与高级索引,进一步提升数据操作效率,敬请期待!
相关推荐
- selenium(WEB自动化工具)
-
定义解释Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7,8,9,10,11),MozillaF...
- 开发利器丨如何使用ELK设计微服务中的日志收集方案?
-
【摘要】微服务各个组件的相关实践会涉及到工具,本文将会介绍微服务日常开发的一些利器,这些工具帮助我们构建更加健壮的微服务系统,并帮助排查解决微服务系统中的问题与性能瓶颈等。我们将重点介绍微服务架构中...
- 高并发系统设计:应对每秒数万QPS的架构策略
-
当面试官问及"如何应对每秒几万QPS(QueriesPerSecond)"时,大概率是想知道你对高并发系统设计的理解有多少。本文将深入探讨从基础设施到应用层面的解决方案。01、理解...
- 2025 年每个 JavaScript 开发者都应该了解的功能
-
大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发。1.Iteratorhelpers开发者...
- JavaScript Array 对象
-
Array对象Array对象用于在变量中存储多个值:varcars=["Saab","Volvo","BMW"];第一个数组元素的索引值为0,第二个索引值为1,以此类推。更多有...
- Gemini 2.5编程全球霸榜,谷歌重回AI王座,神秘模型曝光,奥特曼迎战
-
刚刚,Gemini2.5Pro编程登顶,6美元性价比碾压Claude3.7Sonnet。不仅如此,谷歌还暗藏着更强的编程模型Dragontail,这次是要彻底翻盘了。谷歌,彻底打了一场漂亮的翻...
- 动力节点最新JavaScript教程(高级篇),深入学习JavaScript
-
JavaScript是一种运行在浏览器中的解释型编程语言,它的解释器被称为JavaScript引擎,是浏览器的一部分,JavaScript广泛用于浏览器客户端编程,通常JavaScript脚本是通过嵌...
- 一文看懂Kiro,其 Spec工作流秒杀Cursor,可移植至Claude Code
-
当Cursor的“即兴编程”开始拖累项目质量,AWS新晋IDEKiro以Spec工作流打出“先规范后编码”的系统工程思维:需求-设计-任务三件套一次生成,文档与代码同步落地,复杂项目不...
- 「晚安·好梦」努力只能及格,拼命才能优秀
-
欢迎光临,浏览之前点击上面的音乐放松一下心情吧!喜欢的话给小编一个关注呀!Effortscanonlypass,anddesperatelycanbeexcellent.努力只能及格...
- JavaScript 中 some 与 every 方法的区别是什么?
-
大家好,很高兴又见面了,我是姜茶的编程笔记,我们一起学习前端相关领域技术,共同进步,也欢迎大家关注、点赞、收藏、转发,您的支持是我不断创作的动力在JavaScript中,Array.protot...
- 10个高效的Python爬虫框架,你用过几个?
-
小型爬虫需求,requests库+bs4库就能解决;大型爬虫数据,尤其涉及异步抓取、内容管理及后续扩展等功能时,就需要用到爬虫框架了。下面介绍了10个爬虫框架,大家可以学习使用!1.Scrapysc...
- 12个高效的Python爬虫框架,你用过几个?
-
实现爬虫技术的编程环境有很多种,Java、Python、C++等都可以用来爬虫。但很多人选择Python来写爬虫,为什么呢?因为Python确实很适合做爬虫,丰富的第三方库十分强大,简单几行代码便可实...
- pip3 install pyspider报错问题解决
-
运行如下命令报错:>>>pip3installpyspider观察上面的报错问题,需要安装pycurl。是到这个网址:http://www.lfd.uci.edu/~gohlke...
- PySpider框架的使用
-
PysiderPysider是一个国人用Python编写的、带有强大的WebUI的网络爬虫系统,它支持多种数据库、任务监控、项目管理、结果查看、URL去重等强大的功能。安装pip3inst...
- 「机器学习」神经网络的激活函数、并通过python实现激活函数
-
神经网络的激活函数、并通过python实现whatis激活函数感知机的网络结构如下:左图中,偏置b没有被画出来,如果要表示出b,可以像右图那样做。用数学式来表示感知机:上面这个数学式子可以被改写:...
- 一周热门
- 最近发表
- 标签列表
-
- ps图案在哪里 (33)
- super().__init__ (33)
- python 获取日期 (34)
- 0xa (36)
- super().__init__()详解 (33)
- python安装包在哪里找 (33)
- linux查看python版本信息 (35)
- python怎么改成中文 (35)
- php文件怎么在浏览器运行 (33)
- eval在python中的意思 (33)
- python安装opencv库 (35)
- python div (34)
- sticky css (33)
- python中random.randint()函数 (34)
- python去掉字符串中的指定字符 (33)
- python入门经典100题 (34)
- anaconda安装路径 (34)
- yield和return的区别 (33)
- 1到10的阶乘之和是多少 (35)
- python安装sklearn库 (33)
- dom和bom区别 (33)
- js 替换指定位置的字符 (33)
- python判断元素是否存在 (33)
- sorted key (33)
- shutil.copy() (33)