Pytorchは、ネットワーク指定のレイヤートレーニングのいくつかのパラメーターを修正しました

Pytorchは、ネットワーク指定のレイヤートレーニングのいくつかのパラメーターを修正しました


問題の説明

転移学習と同様に、モデルの重みをロードした後、指定されたレイヤーのパラメーターが固定され、残りのレイヤーのトレーニングが実行され、固定レイヤーのパラメーターは更新されず、トレーニング部分のみが更新されます。

実装

1.条件を設定し、条件を満たしたパラメータを更新しないように設定します。コードは次のとおりです。

for k,v in model2.named_parameters():
    if k in Layer1pre.keys():
        v.requires_grad = False

2.次に、フィルターを使用してパラメーターをフィルター処理することを忘れないでください。

params = filter(lambda p: p.requires_grad, model.parameters())
criterion = nn.CrossEntropyLoss()
# optimizer = torch.optim.Adam(model2.parameters(), lr=learning_rate)
optimizer = torch.optim.Adam(params, lr=learning_rate)

フィルタステップが欠落している場合、固定パラメータは固定されず、出力結果は図に示すように更新されます。
ここに画像の説明を挿入

3.設定が成功し、固定出力がFalseであり、非固定出力がTrueであるかどうかを確認します。

forname, value in model2.named_parameters():
    print(name, value.requires_grad)  # 打印所有参数requires_grad属性,True或False

図に示すように、フィルターの後、最初のレイヤーのパラメーターはrequires_grad = Falseに設定され、2番目のレイヤーのパラメーターのみが後続のトレーニングで更新されます。
ここに画像の説明を挿入
検査後:図に示すように、モデル2の最初のレイヤーのパラメーターは変更されていません。
ここに画像の説明を挿入
完全なコードは次のとおりです。

# 加载model,model是自己定义好的模型
Layer1pre = torch.load('./ResultData_earlystop/savemodel/checkpoint_model_layer1.pt')
model2 = CNNLayer2(num_classes=10, aux_logits=True)
if use_gpu:
    model = model2.cuda()

# 读取参数
model2.load_state_dict(Layer1pre, strict=False)

for k,v in model2.named_parameters():
    if k in Layer1pre.keys():
        v.requires_grad = False

params = filter(lambda p: p.requires_grad, model.parameters())
criterion = nn.CrossEntropyLoss()
# optimizer = torch.optim.Adam(model2.parameters(), lr=learning_rate)
optimizer = torch.optim.Adam(params, lr=learning_rate)

for name, value in model2.named_parameters():
   print(name, value.requires_grad)#打印参数requires_grad属性,True或False

#TrainLoss,TrainAcc,EvalLoss,EvalAcc
loss_train_epochs = []  # 里面包含epoch个训练loss值
acc_train_epochs = []

loss_eval_epoch_all = []
acc_eval_epoch_all = []

loss_train_avg = []  # [0 for epoch in range(num_epochs)]
accuracy_train_avg = []
loss_eval_avg = []
accuracy_eval_avg = []


early_stopping = EarlyStopping(patience=patience, verbose=True, layer=2)

for epoch in range(num_epochs):
    epoch_start = time.time()
    print('*' * 15, f'Epoch: {
      
      epoch + 1}', '*' * 15)
    # print(f'epoch {epoch+1}')
    running_loss = 0.0
    running_acc = 0.0
    preds_all = []
    targets_all = []
    model2.train()
    for i, data in enumerate(train_loader, batch_size):
        img, label = data
        if use_gpu:
            img = img.cuda()
            label = label.cuda()
        # 向前传播

        logits= model2(img)
        # print('logits.type:',logits.type)

        # loss
        loss = criterion(logits, label)

        running_loss += loss.item()
        # running_loss2 += loss2.item()
        # print('loss:', loss, running_loss)
        _, pred = torch.max(logits, 1)

        # print('Lab result:', label)
        running_acc += (pred == label).float().mean()
        # 向后传播
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

    TrainLoss = running_loss / len(train_loader)
    TrainAcc = running_acc / len(train_loader)

    loss_train_epochs.append(copy.deepcopy(TrainLoss))
    acc_train_epochs.append(copy.deepcopy(TrainAcc.numpy()))

    print(f'TrainLoss: {
      
      TrainLoss:.6f}')
    print(f'TrainAcc: {
      
      TrainAcc:.6f}')

    model2.eval()
    eval_loss = 0.
    eval_acc = 0.
    for data in eval_loader:
        img, label = data
        if use_gpu:
            img = img.cuda()
            label = label.cuda()

        with torch.no_grad():
            logits = model2(img)
            loss = criterion(logits, label)
        eval_loss += loss.item()
        _, pred = torch.max(logits, 1)
        eval_acc += (pred == label).float().mean()


    EvalLoss = eval_loss / len(eval_loader)
    EvalAcc = eval_acc / len(eval_loader)

    if best_acc2 < EvalAcc:
        best_acc2 = EvalAcc
        best_epoch = epoch + 1
        best_experiment = m + 1
        torch.save(model2.state_dict(), save_path)

    # bestacc = best_acc
    loss_eval_epoch_all.append(copy.deepcopy(EvalLoss))
    acc_eval_epoch_all.append(copy.deepcopy(EvalAcc.numpy()))

    # early_stopping needs the validation loss to check if it has decresed,
    # and if it has, it will make a checkpoint of the current model
    early_stopping(EvalLoss, model2,2)

    if early_stopping.early_stop:
        print("Early stopping")
        break
    # load the last checkpoint with the best model
    model2.load_state_dict(torch.load('./ResultData_earlystop/savemodel/checkpoint_model_layer2.pt'))
    
print("model.aux1.fc1.weight", model.aux1.fc1.weight)
print("model2.aux1.fc1.weight", model2.aux1.fc1.weight)
print("1-2", model2.aux1.fc1.weight-model2.aux1.fc1.weight)

おすすめ

転載: blog.csdn.net/qq_38703529/article/details/122208134