日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > pytorch >内容正文

pytorch

动手学深度学习(二十七)——微调(fine turning)

發(fā)布時間:2023/12/18 pytorch 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 动手学深度学习(二十七)——微调(fine turning) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

    • 一、微調(diào)(fine tuning)
      • 1. 微調(diào)的四個步驟:
      • 2. 微調(diào)的訓練過程
      • 3. 常用的微調(diào)技術
      • 4. 總結
    • 二、動手實現(xiàn)和測試微調(diào)
      • 1. 數(shù)據(jù)準備
      • 2. 模型微調(diào)
      • 3. 對比不使用微調(diào)和不同的微調(diào)參數(shù)
      • 4. 凍結層進行微調(diào)

一、微調(diào)(fine tuning)

1. 微調(diào)的四個步驟:

  • 在源數(shù)據(jù)集(如ImageNet數(shù)據(jù)集)上預訓練一個神經(jīng)網(wǎng)絡模型,即源模型。
  • 創(chuàng)建一個新的神經(jīng)網(wǎng)絡模型,即目標模型。它復制了源模型上除了輸出層外的所有模型設計及其參數(shù)。我們假設這些模型參數(shù)包含了源數(shù)據(jù)集上學習到的知識,且這些知識同樣適用于目標數(shù)據(jù)集。我們還假設源模型的輸出層與源數(shù)據(jù)集的標簽緊密相關,因此在目標模型中不予采用。
  • 為目標模型添加一個輸出大小為目標數(shù)據(jù)集類別個數(shù)的輸出層,并隨機初始化該層的模型參數(shù)。
  • 在目標數(shù)據(jù)集(如椅子數(shù)據(jù)集)上訓練目標模型。我們將從頭訓練輸出層,而其余層的參數(shù)都是基于源模型的參數(shù)微調(diào)得到的。
  • 2. 微調(diào)的訓練過程

  • 是一個目標數(shù)據(jù)集上的正常訓練任務
  • 使用了更強的正則化:
    • 更小的學習率(大stride在初始模型中已走過了,相當于已經(jīng)有一個比較好的模型了)
    • 更少的迭代次數(shù)
      3.源數(shù)據(jù)集遠復雜于目標數(shù)據(jù),通常得到的微調(diào)效果更好
  • 3. 常用的微調(diào)技術

  • 重用分類器權重(對最后的分類層進行的處理哦!!!)
    • 源數(shù)據(jù)可能也有目標數(shù)據(jù)中的部分標號
    • 可以使用預訓練好的模型分類器中對應標號對應的向量作初始化值
  • 固定一些層
    • 神經(jīng)網(wǎng)絡通常學習有層次的特征表示(底層描述的特征更加通用,而高層的特征和數(shù)據(jù)集相關性更強)
    • 可以固定相對底部的層,不參與參數(shù)更新(應用了更強的正則化)
  • 4. 總結

  • 微調(diào)通過使用在大數(shù)據(jù)上得到的預訓練模型來初始化權重來提高精度
  • 預訓練模型質(zhì)量非常重要
  • 微調(diào)通常速度更快、精度更高
  • 二、動手實現(xiàn)和測試微調(diào)

    %matplotlib inline import os import torch import torchvision from torch import nn from d2l import torch as d2l

    1. 數(shù)據(jù)準備

    # 下載熱狗數(shù)據(jù)集 d2l.DATA_HUB['hotdog'] = (d2l.DATA_URL+'hotdog.zip','fba480ffa8aa7e0febbb511d181409f899b9baa5') data_dir = d2l.download_extract('hotdog') # 加載數(shù)據(jù) train_imgs = torchvision.datasets.ImageFolder(os.path.join(data_dir, 'train')) test_imgs = torchvision.datasets.ImageFolder(os.path.join(data_dir, 'test')) # 查看數(shù)據(jù) '''展示了8張熱狗數(shù)據(jù)和非熱狗的數(shù)據(jù),圖像的大小和橫縱比例都不盡相同''' hotdogs = [train_imgs[i][0] for i in range(8)] # hotdogs not_hotdogs = [train_imgs[-i-1][0] for i in range(8)] # not hotdogs d2l.show_images(hotdogs + not_hotdogs, 2, 8, scale=1.4); # 數(shù)據(jù)增廣使數(shù)據(jù)規(guī)整變多 ''' 在訓練期間,我們首先從圖像中裁切隨機大小和隨機長寬比的區(qū)域,然后將該區(qū)域縮放為 224x224 輸入圖像。 在測試過程中,我們將圖像的高度和寬度都縮放到 256 像素,然后裁剪中央 224 x 224 區(qū)域作為輸入。 此外,對于三個 RGB(紅、綠和藍)顏色通道,我們標準化每個通道。 具體而言,通道的平均值將從該通道的每個值中減去,然后將結果除以該通道的標準差。 ''' # 在Imagenet上使用的Normalize直接搬過來,參數(shù)第一個是mean,第二個是std;image = (image-mean)/std;這里是三通道 normalize = torchvision.transforms.Normalize([0.485, 0.456, 0.406],[0.229, 0.224, 0.225]) train_augs = torchvision.transforms.Compose([torchvision.transforms.RandomResizedCrop(224),torchvision.transforms.RandomHorizontalFlip(),torchvision.transforms.ToTensor(),normalize, ])test_augs = torchvision.transforms.Compose([torchvision.transforms.Resize(256),torchvision.transforms.CenterCrop(224),torchvision.transforms.ToTensor(), normalize])

    2. 模型微調(diào)

    定義和初始化模型

    # 定義和初始化模型 ''' 使用ImageNet數(shù)據(jù)集預訓練的ResNet-18作為源模型; 指pretrained =True,以保存模型參數(shù) ''' pretrained_net = torchvision.models.resnet18(pretrained=True)

    Check原始模型參數(shù)

    # 源模型包含多個要素圖層和一個輸出圖層,對除了輸出圖層之外的層進行微調(diào) '''查看源模型的輸出圖層參數(shù)''' pretrained_net.fc Linear(in_features=512, out_features=1000, bias=True) # 初始化微調(diào)圖層 finetune_net = torchvision.models.resnet18(pretrained=True) finetune_net.fc = nn.Linear(finetune_net.fc.in_features, 2) nn.init.xavier_uniform_(finetune_net.fc.weight);

    定義訓練函數(shù),便于更多參數(shù)的調(diào)整

    # 如果 `param_group=True`,輸出層中的模型參數(shù)將使用十倍的學習率 def train_fine_tuning(net, learning_rate, batch_size=128, num_epochs=5,param_group=True):train_iter = torch.utils.data.DataLoader(torchvision.datasets.ImageFolder(os.path.join(data_dir, 'train'),transform=train_augs),batch_size=batch_size, shuffle=True)test_iter = torch.utils.data.DataLoader(torchvision.datasets.ImageFolder(os.path.join(data_dir, 'test'),transform=test_augs),batch_size=batch_size)devices = d2l.try_all_gpus()loss = nn.CrossEntropyLoss(reduction="none")if param_group:'''將所有層的參數(shù)都拿出來進行訓練,最后一層的學習率是前面層的10倍'''params_1x = [param for name, param in net.named_parameters()if name not in ["fc.weight", "fc.bias"]]trainer = torch.optim.SGD([{'params': params_1x}, {'params': net.fc.parameters(),'lr': learning_rate * 10}], lr=learning_rate,weight_decay=0.001)else:'''全部參數(shù)一樣地訓練'''trainer = torch.optim.SGD(net.parameters(), lr=learning_rate,weight_decay=0.001)d2l.train_ch13(net, train_iter, test_iter, loss, trainer, num_epochs,devices) # 使用較小的學習率,通過微調(diào)預訓練獲得的模型參數(shù) train_fine_tuning(finetune_net, 5e-5) loss 0.181, train acc 0.932, test acc 0.935 228.9 examples/sec on [device(type='cuda', index=0)]

    3. 對比不使用微調(diào)和不同的微調(diào)參數(shù)

    如果不使用微調(diào),直接從零開始訓練:不使用微調(diào)的結果精度遠遠低于微調(diào)的結果

    # 對比不使用微調(diào) scratch_net = torchvision.models.resnet18() scratch_net.fc = nn.Linear(scratch_net.fc.in_features, 2) train_fine_tuning(scratch_net, 5e-4, param_group=False) loss 0.384, train acc 0.831, test acc 0.814 229.5 examples/sec on [device(type='cuda', index=0)]

    調(diào)整fine turning 的學習率發(fā)現(xiàn):學習率變太高會降低訓練的精度

    # 調(diào)高fine turning 的學習率 finetune_net = torchvision.models.resnet18(pretrained=True) finetune_net.fc = nn.Linear(finetune_net.fc.in_features, 2) nn.init.xavier_uniform_(finetune_net.fc.weight); train_fine_tuning(finetune_net, 4e-5) loss 0.203, train acc 0.921, test acc 0.930 229.4 examples/sec on [device(type='cuda', index=0)]

    4. 凍結層進行微調(diào)

    凍結一部分的層進行訓練:凍結層訓練可以減少訓練的時間,但是具體要凍結哪些層需要調(diào)整,我這里使用的方法也不確定是否正確,因為使用requires_grad沒有使用成功,就找了個笨方法

    # 如果不更新輸出層之前的層的參數(shù)(凍結一些層) # 我這里沒有使用requires_grad = False,沒有仔細探究是否真的凍結住了。是否需要將不計算梯度放到train函數(shù)之中 def train_fine_tuning_freeze(net, learning_rate, batch_size=128, num_epochs=5):train_iter = torch.utils.data.DataLoader(torchvision.datasets.ImageFolder(os.path.join(data_dir, 'train'),transform=train_augs),batch_size=batch_size, shuffle=True)test_iter = torch.utils.data.DataLoader(torchvision.datasets.ImageFolder(os.path.join(data_dir, 'test'),transform=test_augs),batch_size=batch_size)devices = d2l.try_all_gpus()loss = nn.CrossEntropyLoss(reduction="none")'''凍結一些層(只更新最后層的參數(shù))'''trainer = torch.optim.SGD(net.fc.parameters(), lr=learning_rate,weight_decay=0.001)d2l.train_ch13(net, train_iter, test_iter, loss, trainer, num_epochs,devices)finetune_net = torchvision.models.resnet18(pretrained=True) finetune_net.fc = nn.Linear(finetune_net.fc.in_features, 2) nn.init.xavier_uniform_(finetune_net.fc.weight); train_fine_tuning_freeze(finetune_net, 5e-5,num_epochs=10) loss 0.299, train acc 0.878, test acc 0.887 231.1 examples/sec on [device(type='cuda', index=0)]

    如果有什么存在疑惑的地方可以在評論區(qū)提出,大家一起討論!

    總結

    以上是生活随笔為你收集整理的动手学深度学习(二十七)——微调(fine turning)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。