第6章
Tensor
原文链接:https://www.rethink.fun/chapter6/Tensor.html
PyTorch把对数据的存储和操作都封装在Tensor里。PyTorch里的模型训练的输入输出数据,模型的参数,都是用Tensor来表示的。Tensor在操作方面和NumPy的ndarray是非常类似的。不同的是Tensor还实现了像GPU计算加速,自动求导等PyTorch的核心功能。
Tensor是PyTorch里对多维数组的表示。可以用它来表示:
标量(0维):单个数,比如 torch.tensor(3.14)
向量(1维):一列数,比如 torch.tensor([1,2,3])
矩阵(2维):行列数据,比如 torch.tensor([[1,2],[3,4]])
高维张量(3维及以上):高维数据,比如torch.tensor([[[1,2],[3,4]],[[5,6],[7,8]]])
PyTorch里的数据类型,主要为:
整数型 torch.uint8、torch.int32、torch.int64。其中torch.int64为默认的整数类型。
浮点型 torch.float16、torch.bfloat16、 torch.float32、torch.float64,其中torch.float32为默认的浮点数据类型。
布尔型 torch.bool
在PyTorch里使用最广泛的就是浮点型tensor。其中torch.float32称为全精度,torch.float16/torch.bfloat16称为半精度。一般情况下模型的训练是在全精度下进行的。如果采用混合精度训练的话,会在某些计算过程中采用半精度计算。混合精度计算会节省显存占用以及提升训练速度。
广播机制
原则上来说,tensor的所有的逐元素运算都要求两个tensor的形状必须完全一致。
但在实际中,假如我们有一个tensor:t1。t1的shape为(3,2)。我们想给t1的每个元素都加上1。此时我们不必构造一个shape为(3,2),元素全为1的tensor再进行相加。我们可以直接写 t1 +1,PyTorch内部会虚拟扩展出一个形状为(3,2)的tensor,再和t1相加。这种机制,就是广播机制。需要注意的是,PyTorch 在进行广播计算时,并不会真的复制数据,而是通过调整张量的索引方式(Strided Memory Access)来实现逐元素计算。从而节省大量的存储,提高计算效率。
广播机制的一般原则是:
一. 维度对齐;二. 扩展维度;三. 进行按位计算
Tensor在不同设备上的计算原则
在 PyTorch 中,将 Tensor 和 Model 移动到 CUDA(GPU)设备的原则如下:
(1)Tensor 放入 CUDA
使用 tensor.to(‘cuda’) 或 tensor.cuda() 可以将一个张量(Tensor)移动到 GPU 上。此时,该张量的数据存储和计算都会在 GPU 上进行。
(2)Model 放入 CUDA
使用 model.to(‘cuda’) 或 model.cuda() 可以将一个模型移动到 GPU 上。这实际上是将模型内部的所有可学习参数(即 Parameter,本质上是 Tensor)移动到 GPU 上。
(3)计算设备一致性
Tensor进行计算时,参与计算的所有Tensor必须位于同一设备上。否则,PyTorch 会抛出错误。
(4)计算结果的设备归属
运算结果的Tensor会位于参与计算Tensor所在的设备上。
一般情况下,我们利用GPU训练模型,会把Input Tensor,Label Tenosr和Model移动到GPU上,则整个模型的训练期间的计算都会在GPU上。因为前向传播时,Input Tensor和模型内部参数Tensor进行计算,得到模型Output Tensor也在GPU上。Output Tensor和 LabelTensor 都在GPU上,计算得到的Loss,梯度也在GPU上。
一句话总结就是:模型和张量需要显式移动到目标设备上(如 GPU);所有参与同一计算的张量必须位于相同设备,计算结果也会保留在该设备上。
计算图与自动求梯度
PyTorch里的自动求梯度例子:
import torch
x = torch.tensor(1.0, requires_grad=True) #指定需要计算梯度
y = torch.tensor(1.0, requires_grad=True) #指定需要计算梯度
v = 3*x+4*y
u = torch.square(v)
z = torch.log(u)
z.backward() #反向传播求梯度
print("x grad:", x.grad)
print("y grad:", y.grad)
打印结果
x grad: tensor(0.8571)
y grad: tensor(1.1429)
仔细分析PyTorch的代码可以发现,我们定义了x,y需要计算梯度,然后定义了计算的流程。PyTorch内部会自动帮我们构建和维护计算图。我们只要调用结果z的反向传播方法,PyTorch内部会根据计算图反向传播,计算梯度。
用PyTorch实现线性回归
原文链接
Pytorch中的梯度累积

通过梯度累积,可在不显著增加内存占用的前提下,模拟更大batch_size的训练效果,特别适合资源受限的深度学习场景。
优美的loss曲线
重点介绍了TensorBoard库的使用,参考原文。
Normalization
参考原文
对特征进行标准化
实际上在深度学习里,更常用的是对特征进行标准化处理。也就是对每个feature减去自己的均值,再除以自己的标准差。这样就把这个feature转化为均值为0,标准差为1的分布了。
有一点要特别注意,假如你在训练时对数据做了归一化,那么你一定要记录你做归一化时的参数。在对数据进行预测时,首先需要先对feature用同样的参数进行归一化,然后再带入模型,得到预测值。
为什么归一化不会影响模型
归一化仅对参数空间进行了可逆的线性变换,模型的理论表达能力不变,不改变数据的本质关系。这一现象类似于“换单位不会影响物理规律”。 归一化不会影响深度学习模型的训练结果,因为它只是数据的线性变换,保留了所有必要的信息,模型可以通过权重调整完全补偿这种变换。

被折叠的 条评论
为什么被折叠?



