pytorch 学习汇总(一):
编程中遇到的问题:
1. Model class
- 默认继承自nn.Module; 并需在构造函数:
__init__
中用super(ConvNet, self).__init__()
调用父类初始化 - Model class 中需define forward pass, 以前向传播的方式定义模型操作流程
- model建立完成后需move to device, 而device一般由
device= torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
来定义
2. data pipeline
- dataset构建
目前接触到两种:
第一种: 直接使用torchvision中的datasets,提供了各个datasets,每个有相应params:root='./datasets', train=True, transform=transforms.ToTensor(), download=True
,注意此方法pytorch中的data需在读取中完成transform(至少做.ToTensor()
),下面介绍的自定义datasets 类中同理。
第二种: 自定义dataset类
__init__
中定义需要做的transform,并拿到images和masks的路径lists;__getitem__
中做数据的读取,注意此时输入的参数idx
不是用来直接输入一个index,返回图片与label,而是配合torch.utils.data.DataLoader
做数据流(类似于Tensorflow中的tf.data.Dataset
)。另外在__getitem__
中需判断是否需要做transform,如
__getitem__
:
- dataset instantiation:
get_transform
:
- DataLoader
- 一般用法:
total_step = len(train_loader)
for epoch in range(num_epochs):
for i, (image, label) in enumerate(train_loader):
# 注意 .to(device)
image = image.to(device)
label = label.to(device)
- __init__中的几个重要的输入:
1、dataset,这个就是PyTorch已有的数据读取接口(比如torchvision.datasets.ImageFolder)或者自定义的数据接口的输出,该输出要么是torch.utils.data.Dataset类的对象,要么是继承自torch.utils.data.Dataset类的自定义类的对象。
2、batch_size,根据具体情况设置即可。
3、shuffle,一般在训练数据中会采用。
4、collate_fn,是用来处理不同情况下的输入dataset的封装,一般采用默认即可,除非你自定义的数据读取输出:例子。
5、batch_sampler,从注释可以看出,其和batch_size、shuffle等参数是互斥的,一般采用默认。
6、sampler,从代码可以看出,其和shuffle是互斥的,一般默认即可。
7、num_workers,从注释可以看出这个参数必须大于等于0,0的话表示数据导入在主进程中进行,其他大于0的数表示通过多个进程来导入数据,可以加快数据导入速度。
8、pin_memory,注释写得很清楚了: pin_memory (bool, optional): If True, the data loader will copy tensors into CUDA pinned memory before returning them. 也就是一个数据拷贝的问题。
9、timeout,是用来设置数据读取的超时时间的,但超过这个时间还没读取到数据的话就会报错。
在__init__中,RandomSampler类表示随机采样且不重复,所以起到的就是shuffle的作用。BatchSampler类则是把batch size个RandomSampler类对象封装成一个,这样就实现了随机选取一个batch的目的。这两个采样类都是定义在sampler.py脚本中,地址:https://github.com/pytorch/pytorch/blob/master/torch/utils/data/sampler.py
3. forward and backward
# Forward
out = model(image)
loss = criterion(out, label)
# BP
optimizer.zero_grad()
loss.backward()
optimizer.step()
源码:
def zero_grad(self):
r"""Clears the gradients of all optimized :class:`torch.Tensor` s."""
for group in self.param_groups:
for p in group['params']:
if p.grad is not None:
p.grad.detach_()
p.grad.zero_()
def step(self, closure):
r"""Performs a single optimization step (parameter update).
Arguments:
closure (callable): A closure that reevaluates the model and
returns the loss. Optional for most optimizers.
"""
raise NotImplementedError
Reference
https://blog.csdn.net/u014380165/article/details/79058479