百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

PyTorch 张量入门:第二篇 —— Tensors 快速

itomcoil 2025-08-06 20:24 7 浏览

PyTorch 张量入门:第二篇 —— Tensors 快速教程

导语

张量(Tensor)是 PyTorch 的核心数据结构,类似于多维数组,但支持 GPU 加速和自动求导。掌握张量的创建、属性、运算及与 NumPy 的互操作,是深入学习深度学习模型的基础。本章将带你一步步了解张量的方方面面,让你能够灵活地构建和操作数据,为后续模型开发做好准备。


一、张量的创建

概念讲解

PyTorch 提供多种方式来创建张量:

  • o 从数据:直接用 Python 列表或元组;
  • o 随机初始化torch.randtorch.randn 等;
  • o 常量初始化torch.zerostorch.ones
  • o 从 NumPytorch.from_numpy,与 NumPy 共享内存;
  • o 根据已有张量torch.zeros_liketorch.ones_liketorch.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. 1. torch.tensor(data)torch.from_numpy(np_array) 在内存使用上有何区别?
    答案torch.tensor 会复制数据,将数据从源(Python 列表或 NumPy 数组)拷贝到新张量;而 torch.from_numpy 则与原始 NumPy 数组共享内存,不会复制数据,因此对其中一方的修改会反映到另一方。
  2. 2. 如果想创建一个 5×5 的单位矩阵(对角线为 1,其余为 0),应该如何操作?
    答案:可以使用 torch.eye(5),该函数会返回一个 5×5 的单位矩阵。

二、张量属性

概念讲解

每个张量都有三个核心属性:

  1. 1. 形状(shape):张量的维度,例如 (2, 3)
  2. 2. 数据类型(dtype):元素类型,如 float32int64
  3. 3. 存储设备(device):位于 CPU 还是 GPU(如 cpucuda: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. 1. 如何将一个已有张量从 GPU 转回 CPU?
    答案:调用 tensor.to("cpu")tensor.cpu() 即可将张量移动到 CPU。
  2. 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. 1. torch.cattorch.stack 的区别是什么?
    答案torch.cat 沿指定维度拼接已有张量,要求所有张量在拼接维度之外的形状相同;torch.stack 会在新维度上堆叠张量,结果张量的维度会增加 1,所有原张量的形状必须完全相同。
  2. 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. 1. 如果张量在 GPU 上,调用 .numpy() 会发生什么?
    答案:GPU 张量没有与 CPU 上 NumPy 数组共享的内存,因此调用 .numpy() 会报错。需要先使用 tensor.cpu() 将张量移动到 CPU,然后才能调用 .numpy()
  2. 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,可以像右图那样做。用数学式来表示感知机:上面这个数学式子可以被改写:...