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

embedded/2024/10/18 2:34:05/

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/embedded/6959.html

相关文章

Scala的函数至简原则

对于scala语言来说&#xff0c;函数的至简原则是它的一大特色。下面让我们一起来看看分别有什么吧&#xff01; 函数至简原则&#xff1a;能省则省&#xff01; 初始函数 def test(name:String):String{return name }1、return可以省略&#xff0c;Scala会使用函数体的最后一…

Spark面试整理-Spark部署和集群管理

Apache Spark的部署和集群管理是Spark应用的关键组成部分,它决定了如何在分布式环境中运行和管理Spark作业。Spark支持多种部署模式和集群管理器,以适应不同的需求和环境。以下是Spark部署和集群管理的主要方面: 部署模式 本地模式:在单个机器上运行Spark。适用于开发和测试…

vue3推荐算法

Vue 3 推荐算法主要指的是在 Vue 3 框架中实现的或者适用于 Vue 3 的算法库或组件库。Vue 3 由于其优秀的设计和性能&#xff0c;被广泛应用于构建各种类型的应用程序&#xff0c;包括需要复杂算法支持的项目。以下是一些在 Vue 3 中可能会用到的推荐算法资源&#xff1a; Vue-…

airtest-ios真机搭建实践

首先阅读4 ios connection - Airtest Project Docs 在Windows环境下搭建Airtest对iOS真机进行自动化测试的过程相对复杂&#xff0c;因为iOS的自动化测试通常需要依赖Mac OS系统&#xff0c;但理论上借助一些工具和服务&#xff0c;Windows用户也可以间接完成部分工作。下面是…

论文笔记:Does Writing with Language Models Reduce Content Diversity?

iclr 2024 reviewer评分 566 1 intro 大模型正在迅速改变人们创造内容的方式 虽然基于LLM的写作助手有可能提高写作质量并增加作者的生产力&#xff0c;但它们也引入了算法单一文化——>论文旨在评估与LLM一起写作是否无意中降低了内容的多样性论文设计了一个控制实验&…

urlparse()函数介绍

概述 urlparse()函数是Python标准库中的函数&#xff0c;用于解析URL字符串。它将URL字符串分解为各个组成部分&#xff0c;并返回一个包含这些部分的元组。 功能 urlparse()函数的功能是将URL字符串分解为以下六个部分&#xff1a; scheme&#xff1a;URL的协议&#xff0…

【OpenHarmony-NDK技术】简单将cJson移植到OpenHarmony中,并在c层修改参数值再返回json

1、cJson的简单介绍 cJson - github网址 概述 一般使用cJson是&#xff0c;需要将json文本转化为json对象–编码&#xff0c;将json对象转化为json文本–解析。 git clone https://github.com/DaveGamble/cJSON.git 后留意cJSON.h和cJSON.h两个文件。 1、cJson的介绍 cJso…

什么是显卡服务器?

显卡服务器又叫做GPU服务器,是基于GPU的应用于视频编解码、深度学习和科学计算等多种场景的快速、稳定、弹性的计算服务&#xff0c;显卡服务器是一种用于计算机科学技术领域的计算机以及配套设备&#xff0c;有着出色的图形处理能力和高性能计算能力提供极致计算性能&#xff…