[煉丹術]使用Pytorch搭建模型的步驟及教程


使用Pytorch搭建模型的步驟及教程

我們知道,模型有一個特定的生命周期,了解這個為數據集建模和理解 PyTorch API 提供了指導方向。我們可以根據生命周期的每一個步驟進行設計和優化,同時更加方便調整各種細節。

模型的生命周期的五個步驟如下:

  • 1.准備數據
  • 2.定義模型
  • 3.訓練模型
  • 4.評估模型
  • 5.進行預測

注意:使用 PyTorch API 有很多方法可以實現這些步驟中的每一個,下面是一些使用Pytorch API最簡單、最常見或最慣用的方法。

一、准備數據

第一步是加載和准備數據。

神經網絡模型需要數值輸入數據和數值輸出數據。

您可以使用標准 Python 庫來加載和准備表格數據,例如 CSV 文件。例如,Pandas 可用於加載 CSV 文件,scikit-learn 中的工具可用於編碼分類數據,例如類標簽。

PyTorch 提供了Dataset 類,您可以對其進行擴展和自定義以加載數據集。

例如,您的數據集對象的構造函數可以加載您的數據文件(例如 CSV 文件)。然后可以覆蓋__len __()可以被用於獲取數據集(行或樣本數)的長度函數和__getitem __() ,其用於獲得由索引的特定示例函數。

加載數據集時,您還可以執行任何所需的轉換,例如縮放或編碼。

下面提供了自定義數據集類的骨架。

# dataset definition
class CSVDataset(Dataset):
    # load the dataset
    def __init__(self, path):
        # store the inputs and outputs
        self.X = ...
        self.y = ...
 
    # number of rows in the dataset
    def __len__(self):
        return len(self.X)
 
    # get a row at an index
    def __getitem__(self, idx):
        return [self.X[idx], self.y[idx]]

加載后,PyTorch 提供DataLoader 類以在模型的訓練和評估期間導航Dataset實例。

可以為訓練數據集、測試數據集甚至驗證數據集創建一個DataLoader實例。

所述random_split()函數可以被用於將數據集分裂成訓練集和測試集。拆分后,可以將數據集中的行選擇提供給 DataLoader,同時提供批量大小以及是否應在每個 epoch 中對數據進行混洗。

random_split(dataset, lengths)

返回從原始數據集隨機拆分的 n 個非重疊數據集。lengths 參數指定每個拆分的長度。

例如,我們可以通過傳入數據集中的選定行樣本來定義DataLoader

DataLoader(dataset, batch_size=1, shuffle=False)

返回給定數據集的迭代,每批具有指定數量的樣本。該函數還有許多其他參數。
shuffle參數設置為“True”,以便在每個epoch之后對數據進行shuffled。這對於驗證和測試數據集是不必要的,因為我們將只對它們進行評估,而順序並不重要。

...
# create the dataset
dataset = CSVDataset(...)
# select rows from the dataset
train, test = random_split(dataset, [[...], [...]])
# create a data loader for train and test sets
train_dl = DataLoader(train, batch_size=32, shuffle=True)
test_dl = DataLoader(test, batch_size=1024, shuffle=False)

定義后,可以枚舉DataLoader,每次迭代產生一批樣本。

# train the model
for i, (inputs, targets) in enumerate(train_dl):
	...

二、定義模型

下一步是定義模型。

在 PyTorch 中定義模型的習慣用法涉及定義一個擴展Module 類的類

nn.Module 是為所有神經網絡模型擴展的基類。我們定義的模型有四個功能

1.__ init __(self)

該函數調用超類的構造函數。這是強制性的。

此處使用 torch.nn 庫定義了該模型的不同層。層的類型和數量特定於手頭的問題。它可以是單層線性模型,也可以是基於復雜數學模型的多層。

還聲明了每一層的輸入和輸出大小以及其他必需的參數。每層的大小和其他值可以作為構造函數中的參數進行檢索,從而允許模型實例具有可變架構或硬編碼。

2.forward(self, x)

此函數定義數據如何通過一次前向傳遞。可以從 torch.nn.functional 庫定義不同層的激活函數。

3.training_step(self,batch)

在這個函數中,我們定義了模型的一個訓練步驟,該步驟接收一批數據並返回損失。

對於給定的批次,我們將輸入和目標分開,這里是圖像及其標簽。輸入通過使用“ self ”關鍵字調用的 forward 函數傳遞,以獲得輸出。

將適當的損失函數應用於輸出和目標以計算損失。

4.validation_step(self,batch)

在這個函數中,我們定義了一個驗證步驟,即我們評估當前狀態的模型。

給定批次的損失是按照上面的 training_step() 函數中的描述計算的。除此之外,還可以評估其他幾個指標,例如准確度、auc、精確度、召回率等等。

這些指標的結果用於評估模型的性能,而不是用於訓練過程。因此,我們將.detach()應用於結果以將它們從梯度計算中排除。

對來自 DataLoader 對象的每批數據調用模型的 validation_step() 函數。輸出列表可以看作是一個二維數組,每一行對應一個批次,每一行按順序保存損失和 n 個度量的值。

它的轉置如下:

這使得使用 torch.mean() 函數更容易計算平均損失和其他指標。.item() 函數用於返回數值而不是單值張量。

fit擬合函數

fit 函數接受許多參數,其中一個是默認優化函數。創建了優化器的一個實例。在每個epoch:

  • 每一批訓練集都經過模型的training_step()函數得到loss。
  • 梯度是使用 .backward() 函數計算的。
  • 優化器根據梯度更新權重和偏差。
  • 梯度值被重置為 0,這樣它們就不會在 epoch 上累積。
  • 在訓練階段結束時,將評估驗證集並將結果附加到歷史記錄中。
    你的類的構造函數定義了模型的層,而 forward() 函數是定義如何通過模型的定義層向前傳播輸入的覆蓋。

此外,Pytorch Module還有許多網絡層級可用,例如Linear用於全連接層,Conv2d用於卷積層,MaxPool2d用於池化層。

激活函數也可以定義為層,例如ReLUSoftmaxSigmoid

下面是一個具有一層的簡單 MLP 模型的示例。

# model definition
class MLP(Module):
    # define model elements
    def __init__(self, n_inputs):
        super(MLP, self).__init__()
        self.layer = Linear(n_inputs, 1)
        self.activation = Sigmoid()
 
    # forward propagate input
    def forward(self, X):
        X = self.layer(X)
        X = self.activation(X)
        return X

給定層的權重也可以在構造函數中定義層后初始化。

常見示例包括XavierHe 權重初始化方案。例如:

...
xavier_uniform_(self.layer.weight)

三、訓練模型

訓練過程要求您定義損失函數和優化算法。

常見的損失函數包括:

有關損失函數的更多信息,請參閱教程:

使用隨機梯度下降進行優化,標准算法由SGD 類提供,盡管該算法的其他版本也可用,例如Adam

# define the optimization
criterion = MSELoss()
optimizer = SGD(model.parameters(), lr=0.01, momentum=0.9)

訓練模型涉及枚舉訓練數據集的DataLoader

首先,訓練時期的數量需要一個循環。然后,隨機梯度下降的小批量需要一個內循環。

...
# enumerate epochs
for epoch in range(100):
    # enumerate mini batches
    for i, (inputs, targets) in enumerate(train_dl):
    	...

模型的每次更新都涉及相同的一般模式,包括:

  • 清除最后一個誤差梯度。
  • 輸入通過模型的前向傳遞。
  • 計算模型輸出的損失。
  • 通過模型反向傳播錯誤。
  • 更新模型以減少損失。
...
# clear the gradients
optimizer.zero_grad()
# compute the model output
yhat = model(inputs)
# calculate loss
loss = criterion(yhat, targets)
# credit assignment
loss.backward()
# update model weights
optimizer.step()

四、評估模型

一旦模型擬合好,就可以在測試數據集上對其進行評估。

這可以通過將DataLoader用於測試數據集並收集測試集的預測,然后將預測與測試集的預期值進行比較並計算性能指標來實現。

...
for i, (inputs, targets) in enumerate(test_dl):
    # evaluate the model on the test set
    yhat = model(inputs)
    ...

五、進行預測

擬合模型可用於對新數據進行預測。

例如,您可能有一張圖像或一行數據,並且想要進行預測。

這要求您將數據包裝在PyTorch Tensor數據結構中。

Tensor只是用於保存數據的 NumPy 數組的 PyTorch 版本。它還允許您在模型圖中執行自動微分任務,例如在訓練模型時調用Backward()

預測也將是一個Tensor,盡管您可以通過從自動微分圖中分離張量並調用 NumPy 函數來檢索 NumPy 數組。

...
# convert row to data
row = Variable(Tensor([row]).float())
# make prediction
yhat = model(row)
# retrieve numpy array
yhat = yhat.detach().numpy()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM