天天看點

資深入門者關于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           

繼續閱讀