Pytorch基础知识(二)
1.Tensor
torch.Tensor是一种包含单一数据类型元素的多维矩阵
Torch定义了10种CPU tensor类型和GPU tensor类型:
Data type | dtype | CPU tensor | GPU tensor |
---|---|---|---|
32-bit floating point | torch.float32 or torch.float | torch.FloatTensor | torch.cuda.FloatTensor |
64-bit floating point | torch.float64 or torch.double | torch.DoubleTensor | torch.cuda.DoubleTensor |
16-bit floating point [1] | torch.float16 or torch.half | torch.HalfTensor | torch.cuda.HalfTensor |
16-bit floating point [2] | torch.bfloat16 | torch.BFloat16Tensor | torch.cuda.BFloat16Tensor |
32-bit complex | torch.complex32 or torch.chalf | ||
64-bit complex | torch.complex64 or torch.cfloat | ||
128-bit complex | torch.complex128 or torch.cdouble | ||
8-bit integer (unsigned) | torch.uint8 | torch.ByteTensor | torch.cuda.ByteTensor |
8-bit integer (signed) | torch.int8 | torch.CharTensor | torch.cuda.CharTensor |
16-bit integer (signed) | torch.int16 or torch.short | torch.ShortTensor | torch.cuda.ShortTensor |
32-bit integer (signed) | torch.int32 or torch.int | torch.IntTensor | torch.cuda.IntTensor |
64-bit integer (signed) | torch.int64 or torch.long | torch.LongTensor | torch.cuda.LongTensor |
Boolean | torch.bool | torch.BoolTensor | torch.cuda.BoolTensor |
quantized 8-bit integer (unsigned) | torch.quint8 | torch.ByteTensor | / |
quantized 8-bit integer (signed) | torch.qint8 | torch.CharTensor | / |
quantized 32-bit integer (signed) | torch.qint32 | torch.IntTensor | / |
quantized 4-bit integer (unsigned) [3] | torch.quint4x2 | torch.ByteTensor | / |
创建
一个张量tensor可以从Python的list或序列构建:
1 | torch.FloatTensor([[1, 2, 3], [4, 5, 6]]) |
根据可选择的大小和数据新建一个tensor。 如果没有提供参数,将会返回一个空的零维张量。如果提供了numpy.ndarray,torch.Tensor或torch.Storage,将会返回一个有同样参数的tensor.如果提供了python序列,将会从序列的副本创建一个tensor
1 | 接口 一个空张量tensor可以通过规定其大小来构建 |
可以用python的索引和切片来获取和修改一个张量tensor中的内容
1 | x = torch.FloatTensor([[1, 2, 3], [4, 5, 6]]) |
每一个张量tensor都有一个相应的torch.Storage用来保存其数据。类tensor提供了一个存储的多维的、横向视图,并且定义了在数值运算会改变tensor的函数操作会用一个下划线后缀来标示。比如,**torch.FloatTensor.abs_()会在原地计算绝对值,并返回改变后的tensor,而tensor.FloatTensor.abs()**将会在一个新的tensor中计算结果
2.storage
pytorch中一个tensor对象分为头信息区(Tensor)和存储区(Storage)两部分
头信息区主要保存tensor的形状(size)、步长(stride)、数据类型(type)等信息;而真正的data(数据)则以连续一维数组的形式放在存储区,由torch.Storage实例管理着
注意:storage永远是一维数组,任何维度的tensor的实际数据都存储在一维的storage中
获取tensor的storage
1 | a = torch.tensor([[1.0, 4.0],[2.0, 1.0],[3.0, 5.0]]) |
3.Pytorch加载数据
Pytorch中加载数据需要Dataset、Dataloader。
- Dataset提供一种方式去获取每个数据及其对应的label,告诉我们总共有多少个数据。
- Dataloader为后面的网络提供不同的数据形式,它将一批一批数据进行一个打包。
4.Tensorboard
1 | import torchvision |
4.transforms
① Transforms当成工具箱的话,里面的class就是不同的工具。例如像totensor、resize这些工具。
② Transforms拿一些特定格式的图片,经过Transforms里面的工具,获得我们想要的结果。
1 | from torchvision import transforms |
5.torchvision数据集
① torchvision中有很多数据集,当我们写代码时指定相应的数据集指定一些参数,它就可以自行下载。
② CIFAR-10数据集包含60000张32×32的彩色图片,一共10个类别,其中50000张训练图片,10000张测试图片。
1 | import torchvision |
6.损失函数
① Loss损失函数一方面计算实际输出和目标之间的差距。
② Loss损失函数另一方面为我们更新输出提供一定的依据
L1loss损失函数
1 | import torch |
MSE损失函数
1 | import torch |
交叉熵损失函数
1 | import torch |
7.优化器
① 损失函数调用backward方法,就可以调用损失函数的反向传播方法,就可以求出我们需要调节的梯度,我们就可以利用我们的优化器就可以根据梯度对参数进行调整,达到整体误差降低的目的。
② 梯度要清零,如果梯度不清零会导致梯度累加
1 | loss = nn.CrossEntropyLoss() # 交叉熵 |
神经网络学习率优化
1 | import torch |
8.网络模型使用及修改
网络模型添加
1 | import torchvision |
网络模型修改
1 | import torchvision |
9.网络模型保存与读取
模型结构 + 模型参数
1 | import torchvision |
模型参数(官方推荐),不保存网络模型结构
1 | import torchvision |
10.固定模型参数
在训练过程中可能需要固定一部分模型的参数,只更新另一部分参数,有两种思路实现这个目标
- 1.一个是设置不要更新参数的网络层为false
- 2.另一个就是在定义优化器时只传入要更新的参数
当然最优的做法是,优化器中只传入requires_grad=True的参数,这样占用的内存会更小一点,效率也会更高
1 | import torch |
11.训练流程
DataLoader加载数据集
1 | import torchvision |
测试网络正确
1 | import torch |
网络训练数据
① model.train()和model.eval()的区别主要在于Batch Normalization和Dropout两层。
② 如果模型中有BN层(Batch Normalization)和 Dropout,需要在训练时添加model.train()。model.train()是保证BN层能够用到每一批数据的均值和方差。对于Dropout,model.train()是随机取一部分网络连接来训练更新参数。
③ 不启用 Batch Normalization 和 Dropout。 如果模型中有BN层(Batch Normalization)和Dropout,在测试时添加model.eval()。model.eval()是保证BN层能够用全部训练数据的均值和方差,即测试过程中要保证BN层的均值和方差不变。对于Dropout,model.eval()是利用到了所有网络连接,即不进行随机舍弃神经元。
④ 训练完train样本后,生成的模型model要用来测试样本。在model(test)之前,需要加上model.eval(),否则的话,有输入数据,即使不训练,它也会改变权值。这是model中含有BN层和Dropout所带来的性质。
⑤ 在做one classification的时候,训练集和测试集的样本分布是不一样的,尤其需要注意这一点
1 | import torchvision |
12.模型|参数查看
1 | import torch |
查看参数
1 | for layer in net.modules(): |
13.模型保存|加载
1 | 1、加载模型+参数 |
14.网络的修改
1 | from torch import nn |
修改网络结构
1 | 1、-----删除网络的最后一层----- |
15.参数冻结
1 | 任务一∶ |