DAY 33 MLP神經網絡的訓練
知識點回顧:
1.PyTorch和cuda的安裝
2.查看顯卡信息的命令行命令(cmd中使用)
3.cuda的檢查
4.簡單神經網絡的流程
? ? ? ? 1.數據預處理(歸一化、轉換成張量)
????????2.模型的定義
? ? ? ? ? ? ? ? 1.繼承nn.Module類
????????????????2.定義每一個層
????????????????3.定義前向傳播流程
????????3.定義損失函數和優化器
????????4.定義訓練流程
????????5.可視化loss過程
預處理補充:
注意事項:
1. 分類任務中,若標簽是整數(如 0/1/2 類別),需轉為long類型(對應 PyTorch 的torch.long),否則交叉熵損失函數會報錯。
2. 回歸任務中,標簽需轉為float類型(如torch.float32)。
作業:今日的代碼,要做到能夠手敲。這已經是最簡單最基礎的版本了。
# 仍然用4特征,3分類的鳶尾花數據集作為我們今天的數據集
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
import numpy as np# 加載鳶尾花數據集
iris = load_iris()
X = iris.data # 特征數據
y = iris.target # 標簽數據
# 劃分訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 打印下尺寸
print(X_train.shape)
print(y_train.shape)
print(X_test.shape)
print(y_test.shape)# 歸一化數據,神經網絡對于輸入數據的尺寸敏感,歸一化是最常見的處理方式
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test) #確保訓練集和測試集是相同的縮放# 將數據轉換為 PyTorch 張量,因為 PyTorch 使用張量進行訓練
# y_train和y_test是整數,所以需要轉化為long類型,如果是float32,會輸出1.0 0.0
X_train = torch.FloatTensor(X_train)
y_train = torch.LongTensor(y_train)
X_test = torch.FloatTensor(X_test)
y_test = torch.LongTensor(y_test)import torch
import torch.nn as nn
import torch.optim as optimlass MLP(nn.Module): # 定義一個多層感知機(MLP)模型,繼承父類nn.Moduledef __init__(self): # 初始化函數super(MLP, self).__init__() # 調用父類的初始化函數# 前三行是八股文,后面的是自定義的self.fc1 = nn.Linear(4, 10) # 輸入層到隱藏層self.relu = nn.ReLU()self.fc2 = nn.Linear(10, 3) # 隱藏層到輸出層
# 輸出層不需要激活函數,因為后面會用到交叉熵函數cross_entropy,交叉熵函數內部有softmax函數,會把輸出轉化為概率def forward(self, x):out = self.fc1(x)out = self.relu(out)out = self.fc2(out)return out# 實例化模型
model = MLP()# 分類問題使用交叉熵損失函數
criterion = nn.CrossEntropyLoss()# 使用隨機梯度下降優化器
optimizer = optim.SGD(model.parameters(), lr=0.01)# # 使用自適應學習率的化器
# optimizer = optim.Adam(model.parameters(), lr=0.001)# 訓練模型
num_epochs = 20000 # 訓練的輪數# 用于存儲每個 epoch 的損失值
losses = []for epoch in range(num_epochs): # range是從0開始,所以epoch是從0開始# 前向傳播outputs = model.forward(X_train) # 顯式調用forward函數# outputs = model(X_train) # 常見寫法隱式調用forward函數,其實是用了model類的__call__方法loss = criterion(outputs, y_train) # output是模型預測值,y_train是真實標簽# 反向傳播和優化optimizer.zero_grad() #梯度清零,因為PyTorch會累積梯度,所以每次迭代需要清零,梯度累計是那種小的bitchsize模擬大的bitchsizeloss.backward() # 反向傳播計算梯度optimizer.step() # 更新參數# 記錄損失值losses.append(loss.item())# 打印訓練信息if (epoch + 1) % 100 == 0: # range是從0開始,所以epoch+1是從當前epoch開始,每100個epoch打印一次print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')import matplotlib.pyplot as plt
# 可視化損失曲線
plt.plot(range(num_epochs), losses)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Training Loss over Epochs')
plt.show()
@浙大疏錦行