兩個重要的函數
-
dir(): 一個內置函數,用于列出對象的所有屬性和方法
-
help():一個內置函數,用于獲取關于Python對象、模塊、函數、類等的詳細信息
Dateset類
- Dataset:pytorch中的一個類,開發者在訓練和測試時,用一個子類去繼承Dataset類,繼承和重寫Dataset類中方法和屬性,以加載數據集。
class Dataset(object):"""An abstract class representing a Dataset.All other datasets should subclass it. All subclasses should override``__len__``, that provides the size of the dataset, and ``__getitem__``,supporting integer indexing in range from 0 to len(self) exclusive."""def __getitem__(self, index):raise NotImplementedErrordef __len__(self):raise NotImplementedErrordef __add__(self, other):return ConcatDataset([self, other])
- def getitem(self, index):必須重寫,用于以加載數據集。
- def len(self):可不重寫,用于計算數據集中樣本個數。
TensorBoard
- TensorBoard 是pytorch中一組用于數據可視化的工具,包含在TensorFlow庫。
- SummaryWriter類:用于在給定目錄中創建事件文件,在訓練時,將數據添加到文件中,用于顯示。使用SummaryWriter類創建對象時,若沒有給出事件文件名,則默認的事件文件名為run。
損失函數
- torch.nn.loss():PyTorch 中的一個類,用于計算L1 損失函數,即計算了預測值與實際值之間的L1范數(即絕對差值)。
- 在創建torch.nn.L1Loss(reduction)對象時,可以傳入一個可選的參數reduction,它決定了如何從每個樣本的損失中聚合得到最終的損失。
1. reduction=‘mean’:計算所有樣本損失的平均值作為最終損失。默認情況下,reduction參數的值為’mean’,即計算所有樣本損失的平均值作為最終損失。
2. reduction=‘none’:不進行任何聚合操作,直接返回每個樣本的損失。
3. reduction=‘sum’:計算所有樣本損失的總和作為最終損失。
4. reduction= ‘mean_none’: 計算所有樣本損失的平均值,但是不除以樣本數,即不進行歸一化。
5. reduction=‘sum_none’:計算所有樣本損失的總和,但是不乘以樣本數,即不進行歸一化。 - 在調用torch.nn.L1Loss()對象時,要傳入預測值和實際值。
- torch.nn.MSELoss():PyTorch庫中的一個類,用于計算均方誤差。MSE損失函數的計算方式是:對于每個樣本,計算預測值與真實值之間的平方差,然后取這些平方差的平均值。具體公式為:loss = 1/n Σ (y_pred - y_true)^2,其中n是樣本數量。
- torch.nn.CrossEntropyLoss:是PyTorch庫中的一個類,用于計算交叉熵損失。
- 在創建對象時,torch.nn.CrossEntropyLoss()參數:
- weight: 類別權重。這是一個一維的tensor,用于為每個類別指定不同的權重。默認值是None,這時所有的類別權重都相等。如果指定了類別權重,那么在計算損失時,每個類別的損失將會根據其對應的權重進行加權平均。
- reduction: 損失的歸約方式。這個參數決定了如何將交叉熵損失的值從樣本級別降低到批次級別。可能的值有:‘none’(不進行歸約,返回每個樣本的交叉熵損失),‘mean’(對所有樣本的交叉熵損失取平均),‘sum’(將所有樣本的交叉熵損失相加)。默認值是’mean’。
- ignore_index: 被忽略的類別索引。如果設置了該參數,那么在計算交叉熵損失時,該類別對應的損失將被忽略。這個參數主要用于處理數據集中的無效類別或不需要分類的類別。默認值是-100。
- 在調用torch.nn.CrossEntropyLoss的對象時,需要傳入兩個參數:
- input:這是一個一維或二維張量,表示模型的輸出。對于每個輸入樣本,輸出應該是一個長度為類別數量的向量,每個元素表示該類別與輸入樣本的相似度。
- target:這是一個一維張量,表示每個輸入樣本的正確類別標簽。
優化器(參數更新)
- torch.optim.SGD:PyTorch 中的一個類,它實現了隨機梯度下降(Stochastic Gradient Descent)算法。
- 創建類對象時,torch.optim.SGD(params,lr,momentum,dampening,weight_decay,nesterov)的參數:
- params:要優化的參數,通常是模型中的參數。
- lr:學習率。控制參數更新的步長。默認值是0.01。
- momentum:動量。這個參數會考慮之前梯度的方向,使得優化器具有一定的"慣性",有助于加速訓練。默認值是0。
- dampening:阻尼。這個參數可以防止動量過大導致震蕩。默認值是0。
- weight_decay:權重衰減。可以防止過擬合,通過對參數本身進行懲罰來控制模型的復雜度。默認值是0,表示不進行權重衰減。
- nesterov:是否使用 Nesterov 動量。如果為 True,會使用 Nesterov 動量,否則使用標準 momentum。默認值是False
- 創建優化器后,我們可以通過調用 optimizer.zero_grad() 清除之前的梯度,然后通過反向傳播計算新的梯度,最后使用 optimizer.step() 更新模型的參數。
import torch
from torch import nn
from torch.nn import Sequential,Conv2d,MaxPool2d,Flatten
from torch.nn import Linear
from torch.utils.tensorboard import SummaryWriter
import torchvision
import torchvision.transforms
from torch.utils.data import DataLoaderdataset = torchvision.datasets.CIFAR10("./dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)
dataloader = DataLoader(dataset, batch_size=64)class MY_Dodule(nn.Module):def __init__(self):super(MY_Dodule,self).__init__()self.model = Sequential(Conv2d(3, 32, kernel_size=5, padding=2),MaxPool2d(2),Conv2d(32, 32, kernel_size=5, padding=2),MaxPool2d(2),Conv2d(32, 64, kernel_size=5, padding=2),MaxPool2d(2),Flatten(),Linear(1024,64),Linear(64,10))def forward(self,input):output = self.model(input)return outputmy_module = MY_Dodule()
loss = nn.CrossEntropyLoss()
optim = torch.optim.SGD(my_module.parameters(),lr=0.1)
for epoch in range(20):running_loss = 0.0for data in dataloader:images,targets = datainput = imagesoutput = my_module(input) # 前向轉播result_loss = loss(output,targets) # 計算損失optim.zero_grad() # 清除之前的梯度result_loss.backward() # 反向轉播optim.step() #梯度更新running_loss += result_losspassprint(running_loss)pass
網絡模型的使用和修改
-
torchvision.models.vgg16(pretrained,progress):PyTorch 中的一個類,是用來加載預訓練的 VGG-16 模型的函數。
- pretrained:布爾型,決定是否從 PyTorch 的預訓練模型庫中加載訓練好的權重。如果設為 True,則返回的模型會包含在大規模圖像分類任務上訓練得到的權重。如果設為 False,則模型不包含預訓練的權重,你需要自己訓練模型。默認為False。
- progress:布爾型,決定是否顯示下載預訓練模型過程的進度條。如果設為 True,則在下載預訓練模型時會顯示進度條。默認為True。
-
在 VGG-16 模型中添加層:model是torchvision.models.vgg16()示例化對象,model.classifier.add_module(str,nn.Module)這個函數接受兩個參數。
- 模塊名稱(str):這是你想要添加的模塊的名稱。你可以自己定義一個有意義的名稱,以便在后續的代碼中引用這個模塊。
- 模塊對象(nn.Module):這是你想要添加的模塊本身。這個模塊可以是任何PyTorch定義的神經網絡層或者你自己定義的層。
-
在 VGG-16 模型中修改層:model是torchvision.models.vgg16()示例化對象,model.classifier[n] = nn.Module
- n:VGG-16 模型中修改層的層號
- nn.Module:修改后的模塊本身。這個模塊可以是任何PyTorch定義的神經網絡層或者你自己定義的層。
網絡模型的保存與讀取
- torch.save(model, ‘model.pth’):PyTorch 中的一個函數,模型model的權重和參數,保存在指定文件model.pth中。
- model = torch.load(‘model.pth’):PyTorch 中的一個函數,根據model.pth文件,加載保存的模型并返回給變量 model
- torch.save(model.state_dict(), ‘model.pth’): 將模型model參數(權重和偏置等,不包括模型的結構),以字典的形式保存到指定的文件 ‘model.pth’ 中。
- model.load_state_dict(torch.load(‘model.pth’)):torch.load()函數讀取文件中模型的參數信息,加載到model模型中。請注意,這種方式要求你在加載模型時已經知道模型model的結構。
模型訓練流程(以CIFAR10為例)
- 第一步:準備數據集,包括訓練集和測試集
import torchvision# 準備訓練集
train_data = torchvision.datasets.CIFAR10("dataset",train=True,transform=torchvision.transforms.ToTensor(),download=True)# 準備測試集
test_data = torchvision.datasets.CIFAR10("dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)
- 第二步:計算數據長度
# 計算數據集長度
train_data_size = len(train_data)
test_data_size = len(test_data)
print("訓練數據集的長度:{}".format(train_data_size))
print("測試數據集的長度:{}".format(test_data_size))
- 第三步:用dataloader()加載數據集,將數據集劃分為批量子集
# dataloader()加載數據集
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)
- 第四步:搭建神經網絡,一般用一個單獨python文件保存
import torch
from torch import nnclass My_Module(nn.Module):def __init__(self):super(My_Module,self).__init__()self.model = nn.Sequential(nn.Conv2d(3, 32, kernel_size=5, stride=1, padding=2),nn.MaxPool2d(2),nn.Conv2d(32 ,32, kernel_size=5, stride=1, padding=2),nn.MaxPool2d(2),nn.Conv2d(32,64,5,1,2),nn.MaxPool2d(2),nn.Flatten(),nn.Linear(64*4*4,64),nn.Linear(64,10),)def forward(self,input):output = self.model(input)return outputif __name__ == '__main__':my_module = My_Module()input = torch.ones((64, 3, 32, 32))output = my_module(input)print(output.shape)
- 第五步:創建網絡模型
# 創建網絡模型
my_module = My_Module()
- 第六步:定義損失函數
loss_f = nn.CrossEntropyLoss()
- 第七步:定義優化器,進行梯度下降
# 定義優化器,進行梯度下降
learning_rate = 0.01 # 學習效率
optimizer = torch.optim.SGD(my_module, lr=learning_rate)
- 第八步:設置訓練網絡模型的一些參數
# 設置訓練網絡模型的一些參數
total_train_step = 0 # 記錄訓練次數
total_test_step = 0 # 記錄測試次數
epoch = 10 # 訓練的輪次
writer = SummaryWriter("P27") # 添加tensorboard
- 第九步:訓練網絡模型
# 訓練網絡模型
for i in range(epoch):print("------第{}輪訓練開始------".format(i + 1))for data in train_dataloader:images ,targets = datainput = imagesoutput = my_module(input) # 前向傳播loss = loss_f(output, targets) # 計算損失loss.backward() # 反向轉播optimizer.zero_grad() #optimizer.step() # 梯度下降total_train_step = total_train_step + 1print("訓練次數:{},loss:{}".format(total_train_step, loss.item()))