pytorch-learning
Pytorch学习
加载数据
Dataset 和 DataLoader
- Dataset:获取数据,label,数量
- DataLoader:加载数据,同时可以进行数据预处理
Dataset
Dataset 是一个抽象类,所有子类都应该重写 __getitem__
方法; 可以选择性重写 __len__
方法
__getitem__
: 返回数据及其label__len__
: 返回数据数量
简单示例
下面是一个简单获取图像数据集的示例(label为文件夹的名字,如果label是在txt中,那么获取到名字之后找到相应的 txt 文件拿到 label 即可)
关键代码:
1 | class MyData(Dataset): |
Jupyter演示:
DataLoader
后面单独讲
训练可视化
有时候需要根据模型的loss来挑选合适的模型,或者查看模型训练结果,使用下面几个方式可以直观的做出可视化
Tensorboard
Pytorch1.1之后加入了Tensorboard
安装:
1 | pip install tensorboard |
pytorch导入包
1 | from torch.utils.tensorboard import SummaryWriter |
读取标量
1 | add_scalar(tag, scalar_value, global_step=None, walltime=None, new_style=False, double_precision=False) |
1 | writer = SummaryWriter("logs") #指定文件夹路径 |
然后会在指定位置生成目录(这里是logs)及文件,可以在命令行输入:tensorboard --logdir=logs
也可以指定端口:tensorboard --logdir=logs --port=6007
读取图像
1 | add_image(tag, img_tensor, global_step=None, walltime=None, dataformats='CHW') |
能读入的图像只能是以下几种类型:img_tensor (torch.Tensor, numpy.ndarray, or string/blobname): Image data
如何读取numpy型图像,可以利用opencv读取
也直接用numpy读取
导入numpy
1 | import numpy as np |
1 | img_path = "train/ants_image/0013035.jpg" |
使用Tensorboard
1 | writer = SummaryWriter("logs") #指定文件夹路径 |
有时候图片shape不匹配(默认是CHW格式,chanel,height,width)会报错,在使用Tensorboard之前记得看一看图片shape,避免报错,比如我这张图片是HWC格式(通道Chanel在最后)
1 | print(img_array.shape) #(512, 768, 3) H W C |
那么就要指定格式
1 | writer = SummaryWriter("logs") #指定文件夹路径 |
然后可以在命令行输入tensorboard --logdir=logs
然后点击链接查看
transforms
简单使用示例:
ToTensor
1 | from torchvision import transforms |
结合Tensorboard
1 | from torch.utils.tensorboard import SummaryWriter |
Normalize
1 | trans_norm = transforms.Normalize([0.5,0.5,0.5], [0.5,0.5,0.5]) # 输入均值,标准差 |
Resize
1 | print(img.size) |
Resize输入两个参数时,输出的图片按照给定参数变化,如果只输入一个数字,比如Resize(512), 代表指定最短边的像素数量
Compose
参数是一个transform实例列表
1 | trans_compose = transforms.Compose([trans_resize, trans_totensor]) |
前一个的输出是后一个的输入
数据集
torchvision里的数据集的使用
以CIFAR10为例
1 | # 数据集使用 |
1 | from PIL import Image |
数据集默认为PIL图片,可以结合transforms转化为Tensor
1 | import torchvision |
结合tensorboard可视化前十张图片
1 | from torch.utils.tensorboard import SummaryWriter |
DataLoader
torch.utils.data — PyTorch 2.1 documentation
1 | import torchvision |
1 | # 从DataLoader里面取数据, 发现每一个data融合了四张图片的数据 |
搭建神经网络
torch.nn.Module
所有torch定义的网络都必须继承这个类
一个示例:
1 | import torch.nn as nn |
卷积
torch.nn.functional.conv2d — PyTorch 2.1 documentation
以function.conv2d为例,注意这里的输入和kernel都是四维的,第一个表示batch数
1 | import torch |
1 | input = torch.tensor([[1,2,0,3,1], |
1 | output = F.conv2d(input, kernel, stride=1, padding=0) |
卷积层
卷积层在nn.Conv2d里面
Conv2d — PyTorch 2.1 documentation
1 | torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros') |
这个kernel只需要设置大小,不需要设置具体值(由训练得到)
1 | import torchvision |
1 | dataset = torchvision.datasets.CIFAR10("./dataset", train=False, transform=torchvision.transforms.ToTensor(), |
优化器
在torch.optim里面
注意每一次反向传播之前,先清零梯度
略一下,可以看李沐的课程或者官网
使用torch的预训练模型
以VGG16为例
1 | import torchvision |
1 | train_data = torchvision.datasets.CIFAR10("./dataset", |
1 | # 未预训练 |
将VGG16更改为可以应用CIFAR10数据集模型
1 | vgg16_true.add_module("add_linear", nn.Linear(1000, 10)) |
当然也可以更改未预训练的模型
1 | vgg16_false.add_module("add_linear", nn.Linear(1000, 10)) |
模型的加载和保存
1 | import torchvision |
保存方式1
既保存网络模型结构,也保存网络模型参数
1 | torch.save(vgg16, "./models/vgg16_1.pth") |
加载
1 | model = torch.load("./models/vgg16_1.pth") |
保存方式二(官方推荐)
只保存模型参数(状态),保存为字典
1 | # 只保存模型参数(状态) |
加载
1 | model = torch.load("./models/vgg16_2.pth") |
注意的问题
在自己定义模型时(使用继承nn.Module)
方式一虽然会保存模型结构,但是仍然需要代码中有这个模型class类(相当于任然需要访问模型定义的代码)
Transformer
【18、深入剖析PyTorch中的Transformer API源码】https://www.bilibili.com/video/BV1o44y1Y7cp?vd_source=c2c8a4fe07a11ba495278ab92632a245
论文:[Attention is all you need]([1706.03762] Attention Is All You Need (arxiv.org))
Self-attention
自注意力机制vsCNN
vsRNN
Transformer
本质就是一个Seq2Seq模型