目標:
實現一個簡單的二分類模型的訓練過程,通過模擬數據集進行訓練和優化,訓練目標是使模型能夠根據輸入特征正確分類數據。
演示:
1.通過PyTorch生成了一個模擬的二分類數據集,包括特征矩陣data_x
和對應的標簽數據data_y
。標簽數據通過基于特征的線性組合生成,并轉換成獨熱編碼的形式。
import torch
# 從torch庫中導入神經網絡模塊nn,用于構建神經網絡模型
from torch import nn
# 導入torch.nn模塊中的functional子模塊,可用于訪問各種函數,例如激活函數
import torch.nn.functional as Fn_item = 1000
n_feature = 2
learning_rate = 0.01
epochs = 100# 生成一個模擬的數據集,其中包括一個隨機生成的特征矩陣data_x和相應生成的標簽數據data_y。標簽數據通過基于特征的線性組合生成,并且轉換成獨熱編碼的形式。# 設置隨機數生成器的種子為123,通過設置隨機種子,我們可以確保在每次運行代碼時生成的隨機數相同,這對于結果的可重現性非常重要。
torch.manual_seed(123)
# 生成一個隨機數矩陣data_x,其中包含n_item行和n_feature列。矩陣中的元素是從標準正態分布(均值為0,標準差為1)中隨機采樣的。
data_x = torch.randn(size=(n_item, n_feature)).float()
# torch.where(...): 根據條件返回兩個張量中相應位置的值。如果條件成立,將為0,否則為1。 long(): 用于將張量轉換為Long型數據類型。
data_y = torch.where(torch.subtract(data_x[:, 0]*0.5, data_x[:, 1]*1.5)+0.02 > 0, 0, 1).long()
# 將標簽數據data_y轉換為獨熱編碼形式,即將每個標簽轉換為一個相應長度的獨熱向量
data_y = F.one_hot(data_y)# print(data_x)
# print(data_y)
2.定義了一個簡單的二分類模型BinaryClassificationModel
,包含一個單層感知器(Single Perceptron)結構,其中使用了一個線性層和sigmoid激活函數,用于將輸入特征映射到概率空間。
# 定義了一個簡單的二分類模型,采用單層感知器的結構,包含一個線性層和sigmoid激活函數,用于將輸入特征映射到概率空間。這樣的模型可以用來對數據集進行二分類任務的預測。# 定義了一個名為BinaryClassificationModel的類,其繼承自nn.Module類,這意味著這個類是一個PyTorch模型。
class BinaryClassificationModel(nn.Module):def __init__(self, in_feature):# 調用了父類nn.Module的構造函數,確保正確初始化模型。super(BinaryClassificationModel, self).__init__()"""single perception"""# 這行代碼定義了模型的第一層,是一個線性層(Fully Connected Layer)。in_features參數指定輸入特征的數量,out_features指定輸出特征的數量,這里設置為2表示二分類問題。bias=True表示該層包含偏置項。self.layer_1 = nn.Linear(in_features=in_feature, out_features=2, bias=True)# 定義模型前向傳播的方法,即輸入數據x通過模型前向計算得到輸出。def forward(self, x):# 輸入數據x首先通過定義的線性層self.layer_1進行線性變換,然后通過F.sigmoid()函數進行激活函數處理。return F.sigmoid(self.layer_1(x))
3.創建了該二分類模型的實例model
、使用隨機梯度下降(SGD)優化器opt
、以及二分類問題常用的損失函數BCELoss(Binary Cross Entropy Loss)。
4.在訓練過程中,通過多個epoch和每個樣本的批處理(在這里是一次處理一個樣本),計算模型預測輸出和真實標簽之間的損失值,進行反向傳播計算梯度,并更新模型參數以最小化損失函數。
# 完成對模型的訓練過程,每個epoch中通過優化器進行參數更新,計算損失,反向傳播更新梯度。最終我們會得到訓練過程中每個epoch的損失值,并可以觀察損失的變化情況。# 創建了一個二分類模型實例model,參數n_feature表示輸入特征的數量。
model = BinaryClassificationModel(n_feature)
# 創建了一個隨機梯度下降(SGD)優化器opt,用于根據計算出的梯度更新模型參數。
opt = torch.optim.SGD(model.parameters(), lr=learning_rate)
# 創建了一個二分類問題常用的損失函數BCELoss(Binary Cross Entropy Loss),用于衡量模型輸出與真實標簽之間的差異。
criteria = nn.BCELoss()for epoch in range(epochs):# 對每個樣本進行訓練。for step in range(n_item):x = data_x[step]y = data_y[step]# 梯度清零,避免梯度累加影響優化結果。opt.zero_grad()# 將輸入特征x通過模型前向傳播得到預測輸出y_hat。unsqueeze(0)是因為我們的模型期望輸入是(batch_size, n_feature)的形式。y_hat = model(x.unsqueeze(0))# 計算預測輸出y_hat和真實標簽y之間的損失值。loss = criteria(y_hat, y.unsqueeze(0).float())# 反向傳播計算梯度。loss.backward()# 根據計算出的梯度更新模型參數。opt.step()print("Epoch: %03d, Loss: %.3f" % (epoch, loss.item()))
5.打印出每個epoch的序號和損失值,用于監控訓練過程中損失值的變化情況。