Pytorch进阶训练技巧

Pytorch 进阶训练技巧

注:本文为阅读开源教程《深入浅出 Pytorch》所做笔记,仅记录部分笔者认为有价值且较少用到的技巧及知识点

一、自定义损失函数

​ Pytorch 支持实现并调用自定义损失函数,自定义损失函数一般以类的形式定义,继承自 nn.Module,实现构造函数与 forward 函数,在调用时直接实例化并调用计算 loss 即可,例如下文计算 DiceLoss:

class DiceLoss(nn.Module):
    # 继承自 nn.Module
    def __init__(self,weight=None,size_average=True):
        # 构造函数
        super(DiceLoss,self).__init__()
        
    def forward(self,inputs,targets,smooth=1):
        # 定义损失的计算过程
        inputs = F.sigmoid(inputs)       
        inputs = inputs.view(-1)
        targets = targets.view(-1)
        intersection = (inputs * targets).sum()                   
        dice = (2.*intersection + smooth)/(inputs.sum() + targets.sum() + smooth)  
        return 1 - dice

# 使用方法    
criterion = DiceLoss()
loss = criterion(input,targets)

二、动态调整学习率

​ Pytorch 也支持在训练过程中动态调整学习率,通过 torch.optim.lr_scheduler 类实现,该类封装了多种动态学习率调度对象,可以通过以下代码使用:

from torch.optim.lr_scheduler import LambdaLR

net_1 = model()
optimizer_1 = torch.optim.Adam(net_1.parameters(), lr = initial_lr)
scheduler_1 = LambdaLR(optimizer_1, lr_lambda=lambda epoch: 1/(epoch+1))

for epoch in range(epoches):
    # train
    optimizer_1.zero_grad()
    optimizer_1.step()
    scheduler_1.step()

常用的动态调整策略包括:

·StepLR(optimizer, step_size, gamma=0.1, last_epoch=-1):
n e w l r = i n i t i a l l r × γ e p o c h / s t e p s i z e newlr=initiallr × γ^ {epoch/step_{size}} newlr=initiallr×γepoch/stepsize
·ExponentialLR(optimizer, gamma, last_epoch=-1):
n e w l r = i n i t i a l l r × γ e p o c h newlr=initiallr×γ^{epoch} newlr=initiallr×γepoch
·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):给定一个 metric,当 metric 停止优化时减少学习率

​ 也可以通过类似于以下写法的函数自定义动态学习率:

def adjust_learning_rate(optimizer, epoch):
    lr = args.lr * (0.1 ** (epoch // 30))
    for param_group in optimizer.param_groups:
        param_group['lr'] = lr
 
# 使用时
for epoch in range(10):
    train(...)
    validate(...)
    adjust_learning_rate(optimizer,epoch)

三、使用预训练模型

​ 预训练模型是目前深度学习极为热门的模型应用,Pytorch 提供了一些经典预训练模型供使用,也可从其他网站下载其他预训练模型使用,Pytorch 提供了修改对接本地任务的接口:① 加载一个保留参数的预训练模型;② 通过函数冻结所有层的梯度更新;③ 将输出层改写对接本地任务。

# 定义冻结参数更新函数
def set_parameter_requires_grad(model, feature_extracting):
    if feature_extracting:
        for param in model.parameters():
            param.requires_grad = False
          
# 修改该模型
import torchvision.models as models
# 冻结参数的梯度
feature_extract = True
model = models.resnet18(pretrained=True)
set_parameter_requires_grad(model, feature_extract)
# 修改模型
num_ftrs = model.fc.in_features
model.fc = nn.Linear(in_features=num_ftrs, out_features=4, bias=True)

四、半精度训练

​ 在显存不足的情况下,可以通过半精度训练来减少显存占用,半精度训练需要修改以下三个地方:

  1. 导入 autocast:

    from torch.cuda.amp import autocast
    
  2. 模型 forward 函数使用 autocast 修饰:

    @autocast()   
    def forward(self, x):
        ...
        return x
    
  3. 训练时使用 with autocast():

     for x in train_loader:
    	x = x.cuda()
    	with autocast():
            output = model(x)
            ...
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值