【PyTorch】1-基础知识(张量、导数、CUDA)

devtools/2024/9/22 14:58:22/

PyTorch:1-基础知识

注:所有资料来源且归属于thorough-pytorch(https://datawhalechina.github.io/thorough-pytorch/),下文仅为学习记录

1.1:张量

神经网络核心包:autograd(自动微分)

张量的核心:数据容器

张量维度几何含义
0标量
1向量
2矩阵
3时间序列
4图像
5视频

1个图像

(width, height, channel) = 3D

1个图像数据集

(batch_size, width, height, channel) = 4D

torch.Tensor

存储和变换数据

创建tensor

【1】随机矩阵

python">import torch
# row行数, col列数
x = torch.rand(row, col)

【2】全0矩阵

python">import torch
# row行数, col列数
x = torch.zeros(row, col, dtype=torch.long)

【3】张量构建

python">import torch
# x1为元素1,x2为元素2,默认转float
x = torch.tensor([x1, x2])

【4】输出张量维度

python">print(x.size())
# or
print(x.shape)

常见构造

函数功能
Tensor(sizes)基础构造函数
tensor(data)类似于np.array
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)随机排列

张量的操作

【1】加法

python">x = torch.rand(row, col)
y = torch.rand(row, col)# m1
x + y
# m2
torch.add(x,y)
# m3
y.add_(x)

【2】索引

取某一行/列

python">x = torch.rand(row, col)
print(x[: 1]) # 取第2列

ps:索引出来的结果与原数据共享内存。修改一个,另一个会跟着修改。如果不想修改,可以使用copy()

【3】维度变换

torch.view() 共享内存

python">import torch
x = torch.randn(4, 4)
y = x.view(16)
z = x.view(-1, 8) # -1是指这一维的维数由其他维度决定
print(x.size(), y.size(), z.size())# torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])

torch.reshape()不共享内存

python">import torch
x = torch.randn(4, 4)
y = x.reshape(16)
z = x.reshape(-1, 8) # -1是指这一维的维数由其他维度决定
print(x.size(), y.size(), z.size())# output is the same

推荐的方法:先用 clone() 创造一个张量副本,然后再使用 torch.view()进行函数维度变换

【4】取值

python">import torch
x = torch.randn(1) 
print(type(x)) 
print(type(x.item()))# <class 'torch.Tensor'> 表示x是张量
# <class 'float'> 表示x的元素是浮点数

广播机制

背景:对两个形状不同的 Tensor 按元素运算

python">import torch
x = torch.arange(1, 3).view(1, 2)
print(x)
y = torch.arange(1, 4).view(3, 1)
print(y)
print(x + y)
# 很明显此处讲x的row扩展为了3,y的col扩展为了2,然后再进行加法操作"""
tensor([[1, 2]])
tensor([[1],[2],[3]])
tensor([[2, 3],[3, 4],[4, 5]])
"""

1.2:自动求导

Autograd

记录张量操作

属性 .requires_gradTrue,则会追踪对于 Tensor 的所有操作。

完成计算后可以调用 .backward(),自动计算所有的梯度。

张量的所有梯度将会自动累加到.grad属性。

防止操作追踪

防止跟踪历史记录,可以将代码块包装在 with torch.no_grad(): 中,也就是evaluate模型时所用。

每个张量都有一个.grad_fn属性,该属性引用了创建 Tensor 自身的Function

若张量为用户手动创建,则.grad_fn = None

计算导数

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

Example

python">import torch
x = torch.ones(2, 2, requires_grad=True)
print(x)y = x**2
print(y)
print(y.grad_fn)"""
tensor([[1., 1.],[1., 1.]], requires_grad=True)
tensor([[1., 1.],[1., 1.]], grad_fn=<PowBackward0>)
<PowBackward0 object at 0x741131d598a0>
"""

梯度

因为 out 是一个标量,因此out.backward() out.backward(torch.tensor(1.)) 等价,求解的导数是 d(out)/dx

grad在反向传播过程中是累加的,所以一般在反向传播之前需把梯度清零 x.grad.data.zero_()

雅可比向量积的例子

python">import torch
x = torch.randn(3, requires_grad=True)
print(x)y = x * 2
i = 0
while y.data.norm() < 1000:y = y * 2i = i + 1
print(y)
print(i)# y不再是标量!
# torch.autograd无法直接计算完整的雅可比矩阵
# 想要雅可比向量积,需将这个向量作为参数传给 backward
v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(v)print(x.grad)"""
tensor([ 0.3718,  0.4511, -0.5233], requires_grad=True)tensor([  761.5394,   923.9069, -1071.7576], grad_fn=<MulBackward0>)10tensor([2.0480e+02, 2.0480e+03, 2.0480e-01])
"""

修改张量数值,但不被autograd记录/反向传播

可对 tensor.data 进行操作

python">import torch
x = torch.ones(1,requires_grad=True)print(x.data)               # 还是一个tensor
print(x.data.requires_grad) # 但是已经是独立于计算图之外y = 2 * x
x.data *= 100               # 只改变了值,不会记录在计算图,所以不会影响梯度传播y.backward()
print(x)                    # 更改data的值也会影响tensor的值 
print(x.grad)"""
tensor([1.])Falsetensor([100.], requires_grad=True)tensor([2.])
"""

并行计算

查看GPU情况

nvidia-smi
# windows下的cmd也可以用!

CUDA

CUDA是NVIDIA提供的一种GPU并行计算框架。

在PyTorch使用 CUDA,表示开始要求模型或者数据使用GPU。

当使用 .cuda() 时,其功能是让模型或者数据从CPU迁移到GPU上(默认是0号GPU)

设置训练所用的GPU

方法1:运行train.py时设置可用cuda

CUDA_VISBLE_DEVICE=0,1 python train.py 
# 使用0,1两块GPU

方法2:在train.py开头设置可用cuda

python">import os
os.environ["CUDA_VISIBLE_DEVICE"] = "2"

常见并行方法

【1】Network partitioning

网络结构分布到不同的设备中

【2】Layer-wise partitioning

同一层的任务分布到不同数据中

【3】Data parallelism

不同的数据分布到不同的设备中,执行相同的任务

cuda加速训练

【1】单卡

显式的将数据和模型通过.cuda()方法转移到GPU上

python">model = Net()
model.cuda() # 模型显示转移到CUDA上for image,label in dataloader:# 图像和标签显示转移到CUDA上image = image.cuda() label = label.cuda()

【2】多卡

DataParallelDistributedDataParallel

DP.png

DP数据并行

python">model = Net()
model.cuda() # 模型显示转移到CUDA上if torch.cuda.device_count() > 1: # 含有多张GPU的卡model = nn.DataParallel(model) # 单机多卡DP训练

指定GPU进行并行训练

python">model = nn.DataParallel(model, device_ids=[0,1]) # 使用第0和第1张卡进行并行训练

DDP多机多卡

AI硬件加速设备

TPU

Tensor Processing Unit,张量处理器。

NPU

存中…(img-6EdY2G6i-1713698392008)]

DP数据并行

python">model = Net()
model.cuda() # 模型显示转移到CUDA上if torch.cuda.device_count() > 1: # 含有多张GPU的卡model = nn.DataParallel(model) # 单机多卡DP训练

指定GPU进行并行训练

python">model = nn.DataParallel(model, device_ids=[0,1]) # 使用第0和第1张卡进行并行训练

DDP多机多卡

AI硬件加速设备

TPU

Tensor Processing Unit,张量处理器。

NPU

Neural-network Processing Unit,神经网络处理器。


http://www.ppmy.cn/devtools/7379.html

相关文章

在线拍卖系统,基于SpringBoot+Vue+MySql开发的在线拍卖系统设计和实现

目录 一. 系统介绍 二. 功能模块 2.1. 管理员功能模块 2.2. 用户功能模块 2.3. 前台首页功能模块 2.4. 部分代码实现 一. 系统介绍 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系…

electron项目打包慢、打包报错

项目使用了electron框架&#xff0c;在第一次打包或者网络条件不好的环境下进行打包时熟速度慢的出奇&#xff0c;甚至经常出现打包失败的情况&#xff08;如上面图片的报错&#xff09;。 这是因为&#xff0c;在electron打包的过程中&#xff0c;需要去官方源https://github.…

05集合-CollectionListSet

Collection体系的特点、使用场景总结 如果希望元素可以重复&#xff0c;又有索引&#xff0c;索引查询要快? 用ArrayList集合, 基于数组的。(用的最多) 如果希望元素可以重复&#xff0c;又有索引&#xff0c;增删首尾操作快? 用LinkedList集合, 基于链表的。 如果希望增…

【Ansible】02

【Ansible】01 Ansible playbook 剧本 ansible-playbook 常用于复杂任务的管理管理经常要完成的任务playbook也是通过模块和它的参数 , 在特定主机上执行任务playbook是一个文件 , 该文件中需要通过yaml格式进行书写将经常需要执行的任务写入一个文件剧本/文件中可以包换多…

什么是RAG?

RAG是“Retrieval-Augmented Generation”的缩写&#xff0c;这是一种自然语言处理&#xff08;NLP&#xff09;技术&#xff0c;用于增强生成式模型的性能&#xff0c;尤其是在问答、文本摘要、对话系统等任务中。RAG结合了检索&#xff08;Retrieval&#xff09;和生成&#…

【创建型模式】原型模式

一、原型模式概述 原型&#xff08;Prototype&#xff09;模式的定义&#xff1a;用一个已经创建的实例作为原型&#xff0c;通过复制该原型对象来创建一个和原型相同或相似的新对象。在这里&#xff0c;原型实例指定了要创建的对象的种类。用这种方式创建对象非常高效&#xf…

【JavaEE初阶】网络原理|认识协议|协议分层|TCP/IP模型|封装和分用

一、认识协议 1.概念 简单来说&#xff1a;就是一种通信双方&#xff0c;对于通信规则的约定&#xff08;标准&#xff09;&#xff0c;一定是通信双方都认可的 但是这个协议不一定是认可面非常广的&#xff0c;即使是两个人之间的也可叫做协议 就好⽐⻅⽹友&#xff0c;彼此…

c#数据储存栈(stack)和堆(heap)的方式

C#中&#xff0c;类的数据存储是通过堆&#xff08;Heap&#xff09;和栈&#xff08;Stack&#xff09;这两种内存结构来实现的。理解这两种数据结构的工作方式有助于更好地理解C#中的数据存储机制。 栈&#xff08;Stack&#xff09; 栈是一种后进先出&#xff08;Last In,…