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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

PyTorch-训练

發(fā)布時間:2024/4/11 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PyTorch-训练 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

簡介

在之前專欄的兩篇文章中我主要介紹了數(shù)據(jù)的準備以及模型的構(gòu)建,模型構(gòu)建完成的下一步就是模型的訓(xùn)練優(yōu)化,訓(xùn)練完成的模型用于實際應(yīng)用中。

損失函數(shù)

損失函數(shù)用于衡量預(yù)測值與目標值之間的誤差,通過最小化損失函數(shù)達到模型的優(yōu)化目標。不同的損失函數(shù)其衡量效果不同,未必都是出于最好的精度而設(shè)計的。PyTorch對于很多常用的損失函數(shù)進行了封裝,均在torch.nn模塊下,它們的使用方法類似,實例化損失計算對象,然后用實例化的對象對預(yù)測值和目標值進行損失計算即可。

  • L1損失
    • nn.L1Loss(reduction)
    • 計算L1損失即絕對值誤差。
    • reduce參數(shù)表示是否返回標量,默認返回標量,否則返回同維張量。
    • size_average參數(shù)表示是否返回的標量為均值,默認為均值,否則為求和結(jié)果。
    • reduction參數(shù)取代了上述兩個參數(shù),mean、sum和None的取值對應(yīng)上面的結(jié)果。
    • 下面代碼可以演示損失的計算流程。import torch from torch import nn pred = torch.ones(100, 1) * 0.5 label = torch.ones(100, 1)l1_mean = nn.L1Loss() l1_sum = nn.L1Loss(reduction='sum')print(l1_mean(pred, label)) print(l1_sum(pred, label))
  • MSE損失
    • nn.MSELoss(reduction='mean')
    • 計算均方誤差,常用于回歸問題。
    • 參數(shù)同上。
  • CE損失
    • nn.CrossEntropyLoss(weight=None, ignore_index=-100, reduction='mean')
    • 計算交叉熵損失,常用于分類問題。并非標準的交叉熵,而是結(jié)合了Softmax的結(jié)果,也就是說會將結(jié)果先進行softmax計算為概率分布。
    • weight參數(shù)是每個類別的權(quán)重,用于解決樣本不均衡問題。
    • reduction參數(shù)類似上面的損失函數(shù)。
    • ignore_index參數(shù)表示忽略某個類別,不計算其損失。
  • KL散度
    • nn.KLDivLoss(reduction='mean')
    • 計算KL散度。
    • 參數(shù)同上。
  • 二分交叉熵
    • nn.BCELoss(reduction='mean')
    • 計算二分交叉熵損失,一般用于二分類問題。
  • 邏輯二分交叉熵
    • nn.BCEWithLogitsLoss()
    • 輸入先經(jīng)過sigmoid變換再計算損失,類似CE損失。

上述只是提到了幾個常用的簡單損失函數(shù),更加復(fù)雜的可以查看官方文檔,一共封裝了近20個損失,當然,也可以自定義損失函數(shù),返回一個張量或者標量即可(事實上這些損失函數(shù)就是這么干的)。

優(yōu)化器

數(shù)據(jù)、模型、損失函數(shù)都確定了,那這個深度模型任務(wù)其實已經(jīng)完成了大半,接下來就是選擇合適的優(yōu)化器對模型進行優(yōu)化訓(xùn)練。

首先,要了解PyTorch中優(yōu)化器的機制,其所有優(yōu)化器都是繼承自O(shè)ptimizer類,該類封裝了一套基礎(chǔ)的方法如state_dict()、load_state_dict()等。

參數(shù)組(param_groups)

任何優(yōu)化器都有一個屬性為param_groups,這是因為優(yōu)化器對參數(shù)的管理是基于組進行的,為每一組參數(shù)配置特定的學(xué)習(xí)率、動量比例、衰減率等等,該屬性為一個列表,里面多個字典,對應(yīng)不同的參數(shù)及其配置。

例如下面的代碼中只有一個組。

import torch import torch.optim as optimw1 = torch.randn(2, 2) w2 = torch.randn(2, 2)optimizer = optim.SGD([w1, w2], lr=0.1) print(optimizer.param_groups)

梯度清零

事實上,PyTorch不會在一次優(yōu)化完成后清零之前計算得到的梯度,所以需要每次優(yōu)化完成后手動清零,即調(diào)用優(yōu)化器的zero_grad()方法。

參數(shù)組添加

通過調(diào)用優(yōu)化器的add_param_group()方法可以添加一組定制的參數(shù)。

常用優(yōu)化器

PyTorch將這些優(yōu)化算法均封裝于torch.optim模塊下,其實現(xiàn)時對原論文有所改動,具體參見源碼。

  • 隨機梯度下降
    • optim.SGD(params, lr, momentum, weight_decay)
    • 隨機梯度下降優(yōu)化器。
    • params參數(shù)表示需要管理的參數(shù)組。
    • lr參數(shù)表示初始學(xué)習(xí)率,可以按需調(diào)整學(xué)習(xí)率。
    • momentum參數(shù)表示動量SGD中的動量值,一般為0.9。
    • weight_decay參數(shù)表示權(quán)重衰減系數(shù),也是L2正則系數(shù)。
  • 隨機平均梯度下降
    • optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-8, weight_decay=0, amsgrad=False)
    • Adam優(yōu)化算法的實現(xiàn)。
    • 參數(shù)類似上面。

下圖演示了各種算法相同情境下的收斂效果。

學(xué)習(xí)率調(diào)整策略

合適的學(xué)習(xí)率可以使得模型迅速收斂,這也是Adam等算法的初衷,一般我們訓(xùn)練時會在開始給一個較大的學(xué)習(xí)率,隨著訓(xùn)練的進行逐漸下調(diào)這個學(xué)習(xí)率。那么何時下調(diào)、下調(diào)多少,相關(guān)的問題就是學(xué)習(xí)率調(diào)整策略,PyTorch提供了6中策略以供使用,它們都在torch.optim.lr_scheduler中,分為有序調(diào)整(較為死板)、自適應(yīng)調(diào)整(較為靈活)和自定義調(diào)整(適合各種情況)。

下面介紹最常用的自動學(xué)習(xí)率調(diào)整機制。它封裝為optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=10, verbose=False, threshold=0.0001,threshold_mode='rel', cooldown=0, min_lr=0, eps=1e-8)。

當指標不再變化時即調(diào)整學(xué)習(xí)率,這是一種非常實用的學(xué)習(xí)率調(diào)整策略。例如,當驗證集的損失不再下降即即將陷入過擬合,進行學(xué)習(xí)率調(diào)整。

  • mode參數(shù)由兩種為min和max,當指標不再變低或者變高時調(diào)整。
  • factor參數(shù)表示學(xué)習(xí)率調(diào)整比例。
  • patience參數(shù)表示等待耐心,當patience個step指標不變即調(diào)整學(xué)習(xí)率。
  • verbose參數(shù)表示調(diào)整學(xué)習(xí)率是否可見。
  • cooldown參數(shù)表示冷卻時間,調(diào)整后冷卻時間內(nèi)不再調(diào)整。
  • min_lr參數(shù)表示學(xué)習(xí)率下限。
  • eps參數(shù)表示學(xué)習(xí)率衰減最小值,學(xué)習(xí)率變化小于該值不調(diào)整。

訓(xùn)練流程實戰(zhàn)

下面的代碼演示了數(shù)據(jù)的導(dǎo)入、模型構(gòu)建、損失函數(shù)使用以及優(yōu)化器的優(yōu)化整個流程,大部分時候我們使用PyTorch進行模型訓(xùn)練都是這個思路

import torch from torch import nn import torch.nn.functional as F from torch import optimclass Net(nn.Module):def __init__(self):super(Net, self).__init__()self.conv1 = nn.Conv2d(in_channels=3, out_channels=32, kernel_size=(3, 3))self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)self.conv2 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3)self.pool2 = nn.MaxPool2d(2, 2)self.fc1 = nn.Linear(64*54*54, 256)self.fc2 = nn.Linear(256, 128)self.fc3 = nn.Linear(128, 101)def forward(self, x):x = self.pool1(F.relu(self.conv1(x)))x = self.pool2(F.relu(self.conv2(x)))x = x.view(-1, 64*54*54)x = F.relu(self.fc1(x))x = F.relu(self.fc2(x))x = self.fc3(x)return xnet = Net() x = torch.randn((32, 3, 224, 224)) y = torch.ones(32, ).long() criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9, dampening=0.1) scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=50, gamma=0.1)epochs = 10 losses = [] for epoch in range(epochs):correct = 0.0total = 0.0optimizer.zero_grad()outputs = net(x)loss = criterion(outputs, y)loss.backward()optimizer.step()scheduler.step()_, predicted = torch.max(outputs.data, 1)total += y.size(0)correct += (predicted == y).squeeze().sum().numpy()losses.append(loss.item())print("loss", loss.item(), "acc", correct / total)import matplotlib.pyplot as plt plt.plot(list(range(len(losses))), losses) plt.savefig('his.png') plt.show()

其訓(xùn)練損失變化圖如下,由于只是給出的demo數(shù)據(jù),訓(xùn)練很快收斂,準確率一輪達到100%。

補充說明

本文介紹了PyTorch中損失函數(shù)的使用以及優(yōu)化器的優(yōu)化流程,這也是深度模型訓(xùn)練的最后步驟,比較重要。本文的所有代碼均開源于我的Github,歡迎star或者fork。

總結(jié)

以上是生活随笔為你收集整理的PyTorch-训练的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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