Pytorch-tutorials-学习(二)

Pytorch 文件布局

要玩自己的深度学习,首先要布局好整个程序文件的组织结构。
暂且考虑以下文件组织结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
log/
checkpoint/
data/
dataset.py
get_data.py
model/
nn/
loss/
utils/
preprocess.py
visualize.py
metric.py
config.py
main.py

1:log/:是用来存储我们的用于tensorboardX的可视化文件
2.checkpoint/:用于存储模型参数
3.data/:用于存储我们的数据集和标签,在我们的dataset.py中是我们上一节的Dataset自定义数据集,而get_data.py就是上一节中讲的Dataloader
4.model/:里的nn/存储的是模型的网络,而loss/里存储的是我们可能用到的自定义loss函数
5.utils/:里面存放了我们预处理文件preprocess.py,这里的预处理是直接对data/里的数据进行的操作。另外还有visualize.py,可以进行一些tensorboardX不能可视化的函数,如t-SNE。最后还有metric.py文件,该文件里面存放了一些评判函数。
6.config.py:是配置文件,所有可配置的变量都集中在此,并提供默认值
7.main.py:主函数

tensorboardX

tensorboardX是仿照tensorflow中的tensorboard的,专门针对pytorch的可视化的库。要用这个库还需要安装tensorflow.(无奈..)

该软件包目前支持记录标量、图像、音频、直方图、文本、embedding、反向传播路径等。

流程

  • 创建summarywriter:在记录任何内容之前,我们需要创建一个记录各个量的编写器实例。可以通过以下方式来实现

    1
    2
    3
    4
    5
    6
    7
    from tensorboardX import SummaryWriter
    writer=SummaryWriter('/log')
    #creates writer object.The log will be saved in '/log'
    writer2=SummaryWriter()
    #creates writer2 object with auto generated file name, the dir will be something like 'runs/Aug20-17-20-33'
    writer3=SummaryWriter(comment='3x learning rate')
    #creates writer3 object with auto generated file name, the comment will be appended to the filename. The dir will be something like 'runs/Aug20-17-20-33-3xlearning rate'
  • 添加信息:通用API格式————add_something(tag name,object,iteration number).

    1
    2
    3
    4
    5
    6
    1. add_scalar:使用writer.add_scalar('myscalar',value,iteration).注意不要给程序喂tensor,可以根据x.item()提取标量。
    2. add_image:使用writer.add_image('imresult',x,iteration)。如果要展现一批量的images则用torchvision的make_grid函数来准备image array并将该结果输入到add_image(....)中(make_grid输入 4Dtensor 返回3D tensor)
    3.add_histogram:使用writer.add_histogram('hist',array,iteration)。存histogram是昂贵的。为了存histogram,需要转换array成numpy array。
    4.add_graph:神经网络的图绘制是基于autograd的backward tracing。为了绘制这张图,你需要一个模型m和一个满足模型m正确输入大小的输入tensor t。令r=m(t),那么可以用writer.add_graph(m,r)来存储这张图。默认该输入tensor不需要梯度,因此当back tracing的时候,它会被忽略。为了能绘制出输入结点,则需传入额外的参数requires_grad=True当创建输入tensor时。
    5.add_audio:输入到add_audio函里的是一个一维array.
    6.add_embedding:Embedding的高维数据能被可视化并且转换成人可见的3D数据通过tensorboard,tensorboard里提供了PCA和t-sne来投影数据到低维空间.tensorboard需要你提供给他一串数据点。该串数据点传递n×d大小的tensor,其中n是点的数量,d是特征维度。为了使可视化信息更充沛,你能传入可选的metadata或label_imgs给每个数据点。以该种方式可以看到相邻的点有相似的标签,远距离的点有不同的标签(语义上的或可视上的)。这里的metadata是一个label list.该list的长度应该等于n.该label_imgs是4D的tensor,大小位NCHW,其中N=n。
  • 关闭编写器。writer.close()

  • 浏览器下可视化:在命令行中输入命令tensorboard —logdir=(这一步与tensorflow是一样的)

以上就是我们在tensorboardX中可能用到的一些操作。

pytorch 数据集图片显示

pytorch载入的数据集是元组tuple形式,里面包括了数据及标签(train_data,label),torch.Tensor形式,以便后面计算使用。

首先载入数据集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import torch
from torch.autograd import Variable
import matplotlib.pyplot as plt
import torchvision.datasets as dset
import torchvision.transforms as transforms
from autoencoder import AutoEncoder
import torch.nn as nn
import torchvision
import numpy as np
dataset = dset.CIFAR10(root='../train/data', download=True,
transform=transforms.Compose([
transforms.Scale(200),
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
transforms.Gray()
]))

使用torch的接口

1
2
3
img=torchvision.utils.make_grid(dataset[1][0].numpy)
plt.imshow(np.transpose(img,(1,2,0)))
plt.show()

等价于下述方式:

1
2
3
b=dataset[1][0].numpy()#取数据,不取标签  形状为1×200×200
plt.imshow(b.reshape(200,200),cmap='gray')
plt.show()

torchvision.utils.make_grid(tensor,nrow=8,padding=2,normalize=False,range=None,scale_each=False)

这里的几个参数的意思是:

  • normalize=True,会将图片的像素值归一化处理
  • 如果range=(min,max),那么min,max用来规范化image
  • scale_each=True,每个图片独立规范化,而不是根据所有图片的像素最大最小值来规范化

该包里还有一个函数是用来将给定的Tensor保存成image文件。
torchvision.utils.save_image(tensor,filename,nrow=8,padding=2,normalize=False,range=None,scale_each=False)
如果给定的是mini-batch tensor,那就用marke-grid做成切分图,再保存。

LR_Schedule 学习率的设置

自定义根据epoch改变的学习率

1
2
3
4
5
6
7
8
9
10
11
def adjust_learning_rate(optimizer,epoch):
lr=args.lr*(0.1**(epoch//30))
for param_group in optimizer.param_groups:
param_group['lr']=lr
######
#主函数中
optimizer=torch.optim.SGD(model.parameters(),lr=args.lr,momentum=0.9)
for epoch in range(10):
adjust_learning_rate(optimizer,epoch)
train(...)
validate(...)

根据模型的不同层设置不同的学习率

当我们在使用预训练的模型时,需要对分类层进行单独修改并进行初始化,其他层的参数采用预训练的模型参数进行初始化,这个时候我们希望在进行训练过程中,除分类层以外的层只进行微调,不需要过多改变参数,因此需要设置较少的学习率。而改正后的分类层则需要以较大的步子去收敛,学习率往往要设置大一点。

1
2
3
4
5
6
model=torchvision.models.resnet101(pretrained=True)
large_lr_layers=list(map(id,model.fc.parameters()))
small_lr_layers=filter(lambda p:id(p) not in large_lr_layers,model.parameters())
optimizer=torch.optim.SGD([
{"params":large_lr_layers},
{"params":small_lr_layers,"lr":1e-4}],lr=1e-2,momenum=0.9)

注:large_lr_layers学习率为1e-2,small_lr_layers学习率为1e-4,两部分参数共用一个momenum

根据具体需要改变lr

我们常会用到的是ReduceLROnPlateau

1
class torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=10, verbose=False, threshold=0.0001, threshold_mode='rel', cooldown=0, min_lr=0, eps=1e-08)

如果以acc为例,当mode设置为”max”时,如果acc在给定patience内没有提升,则以factor的倍率降低lr。
示例:

1
2
3
4
5
6
7
optimizer=torch.optim.SGD(model.parameters(),lr=0.1,momentum=0.9)
scheduler=ReduceLROnPlateau(optimizer,'max',verbose=1,patience=3)

for epoch in range(10):
train(...)
val_acc=validate(....)
scheduler.step(val_acc)

其他lr_scheduler

  • 1.torch.optim.lr_scheduler.LambdaLR(optimizer,lr_lambda,last_epoch=-1)
    将每个参数组的学习率设置为初始lr的给定函数倍。当last_epoch=-1,设定为初始lr

这里lr_lambda可以是函数也可以是函数list——该函数在已知整数参数epoch的情况下会计算乘法因子。
示例

1
2
3
4
5
6
7
lambda1=lambda epoch: epoch //30
lambda2=lambda epoch: 0.95**epoch
scheduler = LambdaLR(optimizer, lr_lambda=[lambda1, lambda2])
for epoch in range(100):
scheduler.step()
train(...)
validate(...)

  • 2.torch.optim.lr_scheduler.StepLR(optimizer,step_size,gamma=0.1,last_epoch=1)
    将每个参数组的学习率设置为在每个step_size期间,lr衰减gamma倍。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # Assuming optimizer uses lr = 0.05 for all groups
    # lr = 0.05 if epoch < 30
    # lr = 0.005 if 30 <= epoch < 60
    # lr = 0.0005 if 60 <= epoch < 90
    # ...
    scheduler = StepLR(optimizer, step_size=30, gamma=0.1)
    for epoch in range(100):
    scheduler.step()
    train(...)
    validate(...)
  • 3.torch.optim.lr_scheduler.MultiStepLR(optimizer,milestones,gamma=0.1,last_epoch=-1)
    设置一旦epoch数达到其中一个milestones每个参数组的学习率就下降gamma.
    其中milestones是epoch指标的list,并且必须是上升的。

1
2
3
4
5
6
7
8
9
10
# Assuming optimizer uses lr = 0.05 for all groups
# lr = 0.05 if epoch < 30
# lr = 0.005 if 30 <= epoch < 60
# lr = 0.0005 if 60 <= epoch < 90
# ...
scheduler = StepLR(optimizer, step_size=30, gamma=0.1)
for epoch in range(100):
scheduler.step()
train(...)
validate(...)
  • 4.torch.optim.lr_scheduler.ExponentialLR(optimizer,gamma,last_epoch=-1)
    设置每个参数组的学习率在每个epoch是以gamma衰减。

  • 5.torch.optim.lr_scheduler.CosineAnnealingLR(optimizer,T_max,eta_min=0,last_epoch=-1)
    设置每个参数组的学习率用cos退火方法,其中$\eta_{min}+\frac{1}{2}(\eta_{max}-\eta_{min})(1+cos(\frac{T_{cur}}{T_{max}}\pi))$
    其中参数T_max(int)是迭代的最大数,eta_min(float)是学习率的最小值默认为0.

-------------本文结束感谢您的阅读-------------

本文标题:Pytorch-tutorials-学习(二)

文章作者:Yif Du

发布时间:2018年11月02日 - 19:11

最后更新:2018年11月21日 - 00:11

原始链接:http://yifdu.github.io/2018/11/02/Pytorch-tutorials-学习(二)/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。