您现在的位置是:首页 >其他 >Pytorch学习之路(2)网站首页其他
Pytorch学习之路(2)
(PS:请先阅读Pytorch学习之路(1)开篇注释)
【因为我也是小菜鸟】
Pytorch基础知识
1.张量
(1)简介
0维张量——标量(数字)
1维张量——向量
2维张量——矩阵
3维张量——时间序列数据 股价 文本数据 单张彩色图片(RGB)
4维张量——图像
5维张量——视频
张量的核心是一个数据容器
(2)创建tensor
1).随机初始化矩阵[torch.rand()]
import torch
x = torch.rand(4, 3)
print(x)
tensor([[0.7569, 0.4281, 0.4722],
[0.9513, 0.5168, 0.1659],
[0.4493, 0.2846, 0.4363],
[0.5043, 0.9637, 0.1469]])
2).全0矩阵的构建 我们可以通过torch.zeros()
构造一个矩阵全为 0,并且通过dtype
设置数据类型为 long。除此以外,我们还可以通过torch.zero_()和torch.zeros_like()将现有矩阵转换为全0矩阵。
import torch
x = torch.zeros(4, 3, dtype=torch.long)
print(x)
tensor([[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
3).张量的构建 我们可以通过torch.tensor()
直接使用数据,构造一个张量
import torch
x = torch.tensor([5.5, 3])
print(x)
tensor([5.5000, 3.0000])
4).
基于已经存在的 tensor,创建一个 tensor
x = x.new_ones(4, 3, dtype=torch.double)
# 创建一个新的全1矩阵tensor,返回的tensor默认具有相同的torch.dtype和torch.device
# 也可以像之前的写法 x = torch.ones(4, 3, dtype=torch.double)
print(x)
x = torch.randn_like(x, dtype=torch.float)
# 重置数据类型
print(x)
# 结果会有一样的size
# 获取它的维度信息
print(x.size())
print(x.shape)
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
tensor([[ 2.7311, -0.0720, 0.2497],
[-2.3141, 0.0666, -0.5934],
[ 1.5253, 1.0336, 1.3859],
[ 1.3806, -0.6965, -1.2255]])
torch.Size([4, 3])
torch.Size([4, 3])
返回的torch.Size其实是一个tuple,⽀持所有tuple的操作。我们可以使用索引操作取得张量的长、宽等数据维度。
注:
常见的构造Tensor的方法:
函数 | 功能 |
---|---|
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) | 随机排列 |
(3)张量操作
1).加法
import torch
# 方式1
y = torch.rand(4, 3)
print(x + y)
# 方式2
print(torch.add(x, y))
# 方式3 in-place,原值修改
y.add_(x)
print(y)
2).索引
(注:索引出来的结果与原数据共享内存,修改一个,另一个会跟着修改。如果不想修改,可以考虑使用copy()等方法)
import torch
x = torch.rand(4,3)
# 取第二列
print(x[:, 1])
tensor([-0.0720, 0.0666, 1.0336, -0.6965])
y = x[0,:]
y += 1
print(y)
print(x[0, :]) # 源tensor也被改了了
tensor([3.7311, 0.9280, 1.2497])
tensor([3.7311, 0.9280, 1.2497])
3).维度变换(torch.view()
和torch.reshape()
)
4).取值
如果我们有一个元素 tensor
,我们可以使用 .item()
来获得这个 value
,而不获得其他性质:
import torch
x = torch.randn(1)
print(type(x))
print(type(x.item()))
<class 'torch.Tensor'>
<class 'float'>
(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]])
2.自动求导
(1)autograd包
PyTorch 中,所有神经网络的核心是 autograd
包。它是一个在运行时定义 ( define-by-run )的框架,这意味着反向传播是根据代码如何运行来决定的,并且每次迭代可以是不同的。
(2)梯度
现在开始进行反向传播,因为 out
是一个标量,因此out.backward()
和 out.backward(torch.tensor(1.))
等价。
3.并行计算
注:你需要至少安装了一个NVIDIA GPU并安装了相关的驱动。
(1)解释
PyTorch的并行计算就是PyTorch可以在编写完模型之后,让多个GPU来参与训练,减少训练时间。你可以在命令行使用nvidia-smi
命令来查看你的GPU信息和使用情况。
CUDA
是NVIDIA提供的一种GPU并行计算框架。对于GPU本身的编程,使用的是CUDA
语言来实现的。但是,在我们使用PyTorch编写深度学习代码时,使用的CUDA
又是另一个意思。在编写程序中,当我们使用了 .cuda()
时,其功能是让我们的模型或者数据从CPU迁移到GPU上(默认是0号GPU)当中,通过GPU开始计算。
(2)常见并行计算方法
1).网络结构分布到不同的设备中(Network partitioning)
2).同一层的任务分布到不同数据中(Layer-wise partitioning)
3).不同的数据分布到不同的设备中,执行相同的任务(Data parallelism)
(3)使用CUDA加速训练
1).单卡训练
在PyTorch框架下,CUDA的使用变得非常简单,我们只需要显式的将数据和模型通过.cuda()
方法转移到GPU上就可加速我们的训练。如下:
model = Net()
model.cuda() # 模型显示转移到CUDA上
for image,label in dataloader:
# 图像和标签显示转移到CUDA上
image = image.cuda()
label = label.cuda()
2).多卡训练
PyTorch提供了两种多卡训练的方式,分别为DataParallel
和DistributedDataParallel
(以下我们分别简称为DP和DDP)。这两种方法中官方更推荐我们使用DDP
,因为它的性能更好。但是DDP
的使用比较复杂,而DP
经需要改变几行代码既可以实现,所以先介绍DP
,再介绍DDP
。
写在最后:由于很多部分还没看懂,这篇文章将不断更新,再次感谢大佬的教程Datawhale/thorough-pytorch带我开始了ai的学习,如果有错误的地方希望大家多多包含指正喵。