天天看点

资深入门者关于PyTorch和深度学习的碎碎念——训练方法总结

<<< (●′◡′●)点赞<(−●′◡′●)(●′◡′●)点赞<(−●′◡′●)

/\\       //>>>> 
   /__\\     //        关注加RP,AC更容易!
  /    \\   //>>>>>
           

<<< (●′◡′●)收藏<(−●′◡′●)(●′◡′●)收藏<(−●′◡′●)

使用GPU训练

使用GPU训练。只考虑单卡训练的模式。使用device可以选择训练的显卡。

首先在系统上通过nvidia-smi确认显卡信息。通过CUDA_VISUABLE_DEVICES控制当前终端下可见的显卡。

pytorch.device模块控制是否使用GPU,nn.model.to, tensor.to方法控制数据或模型存储的设备(GPU/CPU)。

device = pytorch.device('cuda:0') // GPU 第一张显卡
device = pytorch.device('cpu') // CPU

net = torch.nn.Model()
net.to(device) // 指定设备上训练
           

multitask训练

多个模型共用一个backbone时,可以多个任务联合训练

backbone = BackBoneModel()
head1 = Task1Model()
head2 = Task2Model()
loss1 = Loss1()
loss2 = Loss2()
opt1 = optim.SomeMethod(head1.parameters(), ...)
opt2 = optim.SomeMethod(head2.parameters(), ...)
opt_backbone = optim.SomeMethod(backbone.parameters(), ..)
for X, y in data:
   feature = backbone(X)
   y1 = head1(feature)
   y2 = head2(feature)
   loss_a = loss1(y1, y)
   loss_b = loss2(y1, y)
   tot_loss = loss_a + loss_b
   head1.zero_grad()
   head2.zero_grad()
   back_bone.zero_grad()
   tot_loss.backward()
   opt1.step()
   opt2.step()
   opt_backbone.step()
           

也可以将两个head合进backbone,用同样的opt优化;

预训练,微调,冻结训练

【预训练】指的是在开源数据已经训练好的模型,利用其中提取特征的结构直接提取特征;

这样在目标任务数据集较小的时候可以不必从头训练,用较小的数据量达到较好的效果。

如果不希望backbone的参数改变,可以采用【冻结训练】。

载入预训练参数代码:

model_dict = model.state_dict()
pretrained_dict = torch.load(model_path, map_location = device)
pretrained_dict = {k: v for k, v in pretrained_dict.items() if np.shape(model_dict[k]) == np.shape(v)}
model_dict.update(pretrained_dict)
model.load_state_dict(model_dict)
           

冻结训练时可以利用parameters的requires_grad = false属性,停止后向传播;

for param in model.named_parameters():
    if param[0] in need_frozen_list:
        param[1].requires_grad = False
optimizer = torch.optim.SGD(filter(lambda p: p.requires_grad, model.parameters()), lr=args.lr,momentum=args.momentum, weight_decay=args.weight_decay)
           

也可以用with torch.no_grad()API, 在模型定义中包住backbone的代码。

class xxnet(nn.Module):
    def __init__():
        ....
        self.layer1 = xx
        self.layer2 = xx
        self.fc = xx

    def forward(self.x):
        with torch.no_grad():
            x = self.layer1(x)
            x = self.layer2(x)
        x = self.fc(x)
        return x           

继续阅读