Pytorch简明教程01

文章目录

  • 01 Pytorch基础知识
    • 1.1 Tensor简介
    • 1.2 Tensor的创建
    • 1.3 张量的操作
      • 1. 运算操作
      • 2. 矩阵运算
      • 3. 维度变换
      • 4. 扩展和压缩维度
    • 1.4 广播机制
    • 1.5 梯度计算


01 Pytorch基础知识

主要介绍pytorch中的tensor,包括tensor的创建、基本操作、广播机制等

1.1 Tensor简介

tensor,即张量,是基于向量和矩阵的拓展:

  • 0D tensor:标量
  • 1D tensor:矢量
  • 2D tensor:矩阵
  • 3D tensor:时间序列,RGB图像
  • 4D tensor:多张RGB图像,一段视频
  • 5D tensor:多个视频(第一个维度是batchsize

1.2 Tensor的创建

# 直接通过torch.tensor(data)创建
torch.tensor([1,2,3,4])
# 随机初始化
torch.rand(4)
# 全0
torch.zeros(4)
# 全1
torch.ones(4)
# 规定范围和步长进行创建
torch.arange(0,10,2)
函数功能
Tensor(sizes)基础构造函数
tensor(data)类似于np.array,参数是一个list,[]
ones(sizes)全1
zeros(sizes)全0
eye(sizes)对角为1,其余为0
arange(s,e,step)从s到e,步长为step
linspace(s,e,steps)从s到e,均匀分成step份
rand/randn(sizes)rand是[0,1)均匀分布;randn是服从N(0,1)的正态分布
normal(mean,std)正态分布(均值为mean,标准差是std)
randperm(m)随机排列

在创建tensor的时候,可以通过参数dtype来指定tensor中的数据类型。

也可以基于numpy的array创建tensor,主要使用torch.from_numpy()方法

# 从NumPy ndarray转换为Tensor
import numpy as np
np_array = np.array([1, 2, 3])
tensor_from_np = torch.from_numpy(np_array)

通过size()或者shape可以查看tensor的形状。

1.3 张量的操作

1. 运算操作

运算包括普通的四则运算和矩阵运算

四则运算,都是进行逐个元素的运算

  • 加法

    torch.add(tensor1, tensor2)
    # 或者
    tensor1 + tensor2
    
  • 减法

    torch.sub(tensor1, tensor2)
    # 或者
    tensor1 - tensor2
    
  • 乘法(逐元素):

    torch.mul(tensor1, tensor2)
    # 或者
    tensor1 * tensor2
    
  • 除法(逐元素):

    torch.div(tensor1, tensor2)
    # 或者
    tensor1 / tensor2
    
import torch# 创建两个Tensor
tensor1 = torch.tensor([1, 2, 3], dtype=torch.float32)
tensor2 = torch.tensor([4, 5, 6], dtype=torch.float32)# 加法
add_result = tensor1 + tensor2# 减法
sub_result = tensor1 - tensor2# 乘法(逐元素)
mul_result = tensor1 * tensor2# 除法(逐元素)
div_result = tensor1 / tensor2print(f"Addition: {add_result}")
print(f"Subtraction: {sub_result}")
print(f"Multiplication: {mul_result}")
print(f"Division: {div_result}")
Addition: tensor([5., 7., 9.])
Subtraction: tensor([-3., -3., -3.])
Multiplication: tensor([ 4., 10., 18.])
Division: tensor([0.2500, 0.4000, 0.5000])

2. 矩阵运算

  • 矩阵乘法

    torch.matmul(tensor1, tensor2)
    # 或者使用 @ 符号
    tensor1 @ tensor2
    
  • 转置

    torch.transpose(tensor, 0, 1)
    # 对于2D tensor,也可以使用 tensor.t()
    
  • 逆矩阵

    torch.inverse(tensor)
    
# 创建两个矩阵
matrix1 = torch.tensor([[1, 2], [3, 4]], dtype=torch.float32)
matrix2 = torch.tensor([[5, 6], [7, 8]], dtype=torch.float32)# 矩阵乘法
matmul_result = torch.matmul(matrix1, matrix2)# 矩阵转置
transpose_result = matrix1.t()print(f"Matrix Multiplication:\n{matmul_result}")
print(f"Transpose of Matrix 1:\n{transpose_result}")
Matrix Multiplication:
tensor([[19., 22.],[43., 50.]])
Transpose of Matrix 1:
tensor([[1., 3.],[2., 4.]])

3. 维度变换

张量的维度变换常见的方法有torch.view()torch.reshape(),两个的区别:
torch.view()是直接在原tensor上进行变换,返回的tensor和原tensor共用一块地址;

torch.reshape() 返回的新tensor不是和原tensor共用一块地址。但是此函数并不能保证返回的是其拷贝值,所以官方不推荐使用。推荐的方法是我们先用 clone() 创造一个张量副本然后再使用 torch.view()进行函数维度变换 。

注:使用 clone() 还有一个好处是会被记录在计算图中,即梯度回传到副本时也会传到源 Tensor 。

view方法就是指定一个shape来改变tensor的形状;同时他还可以自动推断维度大小;

import torch# 创建一个1x4的Tensor
x = torch.randn(1, 4)
print(f"Original Tensor:\n{x}\n")# 使用view方法改变形状为2x2
y = x.view(2, 2)
print(f"Reshaped Tensor (2x2):\n{y}")
# 创建一个Tensor
x = torch.randn(3, 2)
print(f"Original Tensor (3x2):\n{x}\n")# 使用view改变形状,自动计算第二维度
y = x.view(6, -1)
print(f"Reshaped Tensor (6x1):\n{y}")

4. 扩展和压缩维度

用于指定增加或者减少特定维度。

unsqueeze方法用于增加Tensor的一个维度。你需要指定增加维度的位置。增加的这个新维度将有一个大小为1。这在某些操作中特别有用,例如,当你需要将一个一维的Tensor转换为二维的行或列向量时。

import torch# 创建一个一维Tensor
x = torch.tensor([1, 2, 3, 4])
print(f"Original Tensor: {x.size()}")# 在第0维增加一个维度
y = x.unsqueeze(0)
print(f"Tensor after unsqueeze at dim 0: {y.size()}")# 在第1维增加一个维度
z = x.unsqueeze(1)
print(f"Tensor after unsqueeze at dim 1: {z.size()}")
Original Tensor: torch.Size([4])
Tensor after unsqueeze at dim 0: torch.Size([1, 4])
Tensor after unsqueeze at dim 1: torch.Size([4, 1])

unsqueeze相反,squeeze方法用于移除Tensor中所有大小为1的维度。这在从某些操作中获取输出时非常有用,这些操作可能会引入大小为1的不必要维度。squeeze也可以指定移除特定的单一维度,但这个维度的大小必须为1,否则Tensor的形状不会改变。

# 使用之前示例中的y和z# 从y中移除所有大小为1的维度
y_squeezed = y.squeeze()
print(f"y after squeeze: {y_squeezed.size()}")# 从z中移除所有大小为1的维度
z_squeezed = z.squeeze()
print(f"z after squeeze: {z_squeezed.size()}")# 尝试从y中移除特定的维度,如果那个维度的大小不为1,则形状不变
y_squeezed_specific = y.squeeze(1)
print(f"y after trying to squeeze dim 1: {y_squeezed_specific.size()}")
y after squeeze: torch.Size([4])
z after squeeze: torch.Size([4])
y after trying to squeeze dim 1: torch.Size([1, 4])

小结:

  • unsqueeze 增加一个新的维度到Tensor中,通常用来创建额外的批处理维度或将一维Tensor转换为二维的行/列向量。
  • squeeze 移除Tensor中所有大小为1的维度,或者指定移除某个特定维度(如果该维度大小为1),常用于移除不必要的单一维度,简化Tensor的形状。

1.4 广播机制

当对两个形状不同的 Tensor 按元素运算时,可能会触发广播(broadcasting)机制:先适当复制元素使这两个 Tensor 形状相同后再按元素运算。

x = torch.arange(1, 3).view(1, 2)
print(x)
y = torch.arange(1, 4).view(3, 1)
print(y)
print(x + y)
tensor([[1, 2]])
tensor([[1],[2],[3]])
tensor([[2, 3],[3, 4],[4, 5]])

由于x和y分别是1行2列和3行1列的矩阵,如果要计算x+y,那么x中第一行的2个元素被广播 (复制)到了第二行和第三行,⽽y中第⼀列的3个元素被广播(复制)到了第二列。如此,就可以对2个3行2列的矩阵按元素相加。

1.5 梯度计算

torch.Tensor 是这个包的核心类。如果设置它的属性 .requires_gradTrue,那么它将会追踪对于该张量的所有操作。当完成计算后可以通过调用 .backward(),来自动计算所有的梯度。这个张量的所有梯度将会自动累加到.grad属性,通过.grad.data来查看梯度值。

注意:在 y.backward() 时,如果 y 是标量,则不需要为 backward() 传入任何参数;否则,需要传入一个与 y 同形的Tensor。

有时候,你可能不希望PyTorch跟踪计算图中的操作,例如在推理时不需要计算梯度。你可以使用torch.no_grad()来临时禁用梯度计算:在评估模型的时候可以用这个,防止内存爆炸。

with torch.no_grad():# 在这个block中,所有的Tensor操作都不会跟踪梯度y = x * 2print(y)

或者,你可以使用.detach()方法得到一个新Tensor,它与原Tensor共享数据但不需要梯度:

y = x.detach()
print(y)

在PyTorch中,当你创建一个新的Tensor时,requires_grad参数默认是False。这意味着,默认情况下,PyTorch不会跟踪该Tensor上的操作,也就是说,不会自动计算关于这个Tensor的梯度。这样做是为了优化性能,因为在很多情况下,尤其是在推理(inference)阶段,你不需要计算梯度。

如果你需要对一个Tensor计算梯度,你必须在创建Tensor时明确设置requires_grad=True,或者在创建后通过tensor.requires_grad_(True)来修改它的requires_grad属性。

只有在tensor进行backward()操作之后,计算图中的元素才会计算梯度,并且由于梯度是可以累加的,多次执行backward()操作,梯度是不断叠加的。

每次使用.backward()方法计算梯度后,通常需要手动将梯度清零。这是因为默认情况下,当.backward()被调用时,梯度会被累加到Tensor的.grad属性中,而不是被替换。这样设计的目的是为了方便在一些情况下(如RNN的训练)对梯度进行累积。但在大多数训练循环中,我们希望每一步的梯度是基于当前步的数据独立计算的,而不是累积之前所有步骤的梯度,因此需要在每次迭代之前清除之前累积的梯度。可以通过x.grad.data.zero_()手动清零,也可以在optimizer中自动清零。,通过调用.zero_grad()方法来实现这一点,通常是在优化器对象上调用此方法,例如:

optimizer.zero_grad()

这将遍历所有通过optimizer管理的参数(即所有设置了requires_grad=True的参数),并将它们的.grad属性重置为零。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/783578.shtml

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

相关文章

Windows安装Mysql8

新建Mysql配置文件 my.ini [mysql] # 设置mysql客户端默认字符集 default-character-setutf8 [mysqld] #设置3306端口 port 3306 # 设置mysql的安装目录 basedirD:\\KaiNeng\\mysql-8.0.26-winx64 # 设置mysql数据库的数据的存放目录 datadirD:\\KaiNeng\\m…

爬虫工作量由小到大的思维转变---<第六十四章 > Scrapy利用Bloom过滤器增强爬虫的页面去重效率

前言: 网络爬虫系统是信息时代获取和管理网络数据的重要工具,广泛应用于搜索引擎索引、数据聚合、在线研究等领域。随着网络信息的海量增长,爬虫系统不可避免地会面临重复内容的爬取问题。这不仅浪费了计算资源和网络带宽,而且还会…

24计算机考研调剂 | 中国航天科工集团第三研究所第八三五八研究所

中国航天科工集团第三研究院第八三五八研究所 2024年航天科工集团三院8358所调剂基本要求 一、8358所坐落天津,为定向招生(毕业后留所工作); 二、本年度拟调剂名额4-5人; 三、我所接收符合条件的调剂考生:…

代码第三十五天-子集Ⅱ

子集Ⅱ 题目要求 解题思路 回溯法 一般情况下,看到题目要求[所有可能的结果],而不是[结果的个数],我们就知道需要暴力搜索所有的可行解了,可以使用[回溯法] 回溯法是一种算法思想,而递归式一种编程方式,回…

Cesium实现渐变面

一、效果图 二、实现思路 使用着色器,通过纹理坐标和其他参数计算出材质的颜色和透明度。通过给定的颜色、漫反射强度和透明度,计算出最终的反射颜色和透明度,并且根据给定的中心点位置和当前像素的纹理坐标,计算出距离中心的距离…

C++未格式化的输入/输出操作,流随机访问

未格式化的输入/输出操作 到目前为止&#xff0c;我们的程序只使用过格式化IO操作。输入和输出运算符(<<和>>)根据读取或写入的数据类型来格式化它们。输入运算符忽略空白符&#xff0c;输出运算符应用补白、精度等规则。 标准库还提供了一组低层操作&#xff0c;…

(一)kafka实战——kafka源码编译启动

前言 本节内容是关于kafka消息中间键的源码编译&#xff0c;并通过idea工具实现kafka服务器的启动&#xff0c;使用的kafka源码版本是3.6.1&#xff0c;由于kafka源码是通过gradle编译的&#xff0c;以及服务器是通过scala语言实现&#xff0c;我们要预先安装好gradle编译工具…

[已解决]ModuleNotFoundError: No module named ‘triton‘

问题描述&#xff1a;ModuleNotFoundError: No module named triton window下难以编译&#xff0c;直接下载win版本已经编译的&#xff1a; https://huggingface.co/r4ziel/xformers_pre_built/blob/main/triton-2.0.0-cp310-cp310-win_amd64.wh

每日一练 找无重复字符的最长子串

我们来看下这个题目&#xff0c;我们要统计的是不重复的子串&#xff0c;我们可以使用“滑动窗口法”&#xff0c;其实我们很容易就能想到思路。 我们的左窗代表我们目前遍历的开始&#xff0c;即我们遍历的子串的开头&#xff0c;右窗从左窗开始进行遍历&#xff0c;每次遍历…

【C语言终章】预处理详解(上)

【C语言终章】预处理详解&#xff08;上&#xff09; 当你看到了这里时&#xff0c;首先要恭喜你&#xff01;因为这里就是C语言的最后一站了&#xff0c;你的编程大能旅途也将从此站开始&#xff0c;为坚持不懈的你鼓个掌吧&#xff01; &#x1f955;个人主页&#xff1a;开敲…

04-MySQL数据库-权限管理

一、查看权限 1&#xff0c;查看系统所有权限 mysql> show privileges; 权限字段介绍 privileges #权限名称 context #对象&#xff0c;表示可以对数据库&#xff0c;那些资源、进行哪些操作&#xff1b; comment #描述&#xff0c;备注解释说明&#xff1b; Grant…

Caddy之静态站点应用场景

一、背景与介绍 无意之中看到公司部门的软件介质下载站点不是使用Nginx部署&#xff0c;而是使用Caddy。就比较好奇了&#xff0c;这个Caddy是个什么东西? 为啥他们没用Nginx呢&#xff0c;带着好奇心搜索了一下相关资料。 官方解释: Caddy is a powerful, extensible platfo…

Redis 事务 与 管道

redis事务 谈到事务大家可能就会想起mysql中的事务 注意这里的事务不是指的是事务的四大特性acid 持久性 原子性 隔离性 一致性 事务的概念就是 一组命令,串行化执行而不被打断 这里redis的事务和mysql的事务就不太一样 传统关系型数据库的事务主要强调的是一个没有执行完成就…

neo4j使用详解(六、cypher常用函数语法——最全参考)

Neo4j系列导航&#xff1a; neo4j及简单实践 cypher语法基础 cypher插入语法 cypher插入语法 cypher查询语法 cypher通用语法 cypher函数语法 4.常用函数 主要包括谓词函数&#xff08;断言函数&#xff09;、标量函数、聚合函数、字符串函数以及集合函数 4.1.谓词函数&#…

数据结构--循环链表(C语言实现)

一.循环链表的设计 typedef struct CNode{ int data; struct CNode* next; }CNode ,*CList; 2.循环链表的示意图: 3.循环链表和单链表的区别: 唯一区别,没有空指针,尾节点的后继为头,为循环之意. 二.循环链表的实现 //初始化return true; }//返回key的前驱地址&#xff0c;如果…

Lazarus远控组件NukeSped分析

静态信息&#xff1a; 样本md5&#xff1a;9b656f5d7e679b94e7b91fc3c4f313e4 由此可见为假的Adobe Flash Player 的攻击样本 样本分析 通过五个函数&#xff0c;内部调用sub_40159D函数动态获取API函数 利用IDA python解密字符串。。 完整python代码 Python> idc.get_…

MongoDB副本集环境搭建(以单机Windows为例)

前言 近期有搭建MongoDB副本集的需求,简单记录一下搭建过程(以本地Windows环境为例)。 一、副本集选型 1 Primary节点、1 Secondary 节点、1 Arbiter节点模式副本集环境搭建。 二、搭建过程 1. 安装MongoDB服务 下载地址:https://www.mongodb.com,如下图所示: 选择…

android 13 相册和拍照问题

android 在13以下。拍照和从相册选取图片需要使用 存储权限&#xff0c;相机权限。 在使用时候 需要声申请 Manifest.permission.WRITE_EXTERNAL_STORAGEManifest.permission.CAMERA 这2个权限。 但是在android 13以及以上时候&#xff0c;不需要申请 Manifest.permission…

基于Springboot旅游网站管理系统设计和实现

基于Springboot旅游网站管理系统设计和实现 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末获取源码联系…

7.卷积神经网络与计算机视觉

计算机视觉是一门研究如何使计算机识别图片的学科&#xff0c;也是深度学习的主要应用领域之一。 在众多深度模型中&#xff0c;卷积神经网络“独领风骚”&#xff0c;已经被称为计算机视觉的主要研究根据之一。 一、卷积神经网络的基本思想 卷积神经网络最初由 Yann LeCun&a…