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

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 * 2
    i = 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>)

10

tensor([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.])

False

tensor([100.], requires_grad=True)

tensor([2.])
"""

并行计算

查看GPU情况

bash 复制代码
nvidia-smi
# windows下的cmd也可以用!

CUDA

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

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

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

设置训练所用的GPU

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

bash 复制代码
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数据并行

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,神经网络处理器。

相关推荐
AngelPP16 小时前
OpenClaw 架构深度解析:如何把 AI 助手搬到你的个人设备上
人工智能
宅小年16 小时前
Claude Code 换成了Kimi K2.5后,我再也回不去了
人工智能·ai编程·claude
AI探索者17 小时前
LangGraph StateGraph 实战:状态机聊天机器人构建指南
python
AI探索者17 小时前
LangGraph 入门:构建带记忆功能的天气查询 Agent
python
九狼17 小时前
Flutter URL Scheme 跨平台跳转
人工智能·flutter·github
ZFSS17 小时前
Kimi Chat Completion API 申请及使用
前端·人工智能
天翼云开发者社区18 小时前
春节复工福利就位!天翼云息壤2500万Tokens免费送,全品类大模型一键畅玩!
人工智能·算力服务·息壤
知识浅谈18 小时前
教你如何用 Gemini 将课本图片一键转为精美 PPT
人工智能
FishCoderh18 小时前
Python自动化办公实战:批量重命名文件,告别手动操作
python
躺平大鹅18 小时前
Python函数入门详解(定义+调用+参数)
python