一、數據集的劃分
(1)按一定比例劃分為訓練集和測試集
我們通常取8-2、7-3、6-4、5-5比例切分,直接將數據隨機劃分為訓練集和測試集,然后使用訓練集來生成模型,再用測試集來測試模型的正確率和誤差,以驗證模型的有效性。
這種方法常見于決策樹、樸素貝葉斯分類器、線性回歸和邏輯回歸等任務中。
(2)交叉驗證法
交叉驗證一般采用k折交叉驗證,即k-fold cross validation,往往k取為10。在這種數據集劃分法中,我們將數據集劃分為k個子集,每個子集均做一次測試集,每次將其余的作為訓練集。在交叉驗證時,我們重復訓練k次,每次選擇一個子集作為測試集,并將k次的平均交叉驗證的正確率作為最終的結果。
from sklearn.model_selection import KFold
import numpy as np# 將PyTorch Tensor轉為Numpy
X_np = X.numpy()
y_np = y.numpy()# 5折交叉驗證
kf = KFold(n_splits=5, shuffle=True, random_state=42)
for fold, (train_idx, val_idx) in enumerate(kf.split(X_np)):# 轉換為PyTorch DataLoadertrain_fold = TensorDataset(torch.from_numpy(X_np[train_idx]), torch.from_numpy(y_np[train_idx]))val_fold = TensorDataset(torch.from_numpy(X_np[val_idx]), torch.from_numpy(y_np[val_idx]))train_loader = DataLoader(train_fold, batch_size=32, shuffle=True)val_loader = DataLoader(val_fold, batch_size=32)print(f"Fold {fold+1}: Train {len(train_fold)}, Val {len(val_fold)}")
(3)訓練集、驗證集、測試集法
我們首先將數據集劃分為訓練集和測試集,由于模型的構建過程中也需要檢驗模型,檢驗模型的配置,以及訓練程度,過擬合還是欠擬合,所以會將訓練數據再劃分為兩個部分,一部分是用于訓練的訓練集,另一部分是進行檢驗的驗證集。驗證集可以重復使用,主要是用來輔助我們構建模型的。
訓練集用于訓練得到神經網絡模型,然后用驗證集驗證模型的有效性,挑選獲得最佳效果的模型,直到我們得到一個滿意的模型為止。最后,當模型“通過”驗證集之后,我們再使用測試集測試模型的最終效果,評估模型的準確率,以及誤差等。測試集只在模型檢驗時使用,絕對不能根據測試集上的結果來調整網絡參數配置,以及選擇訓練好的模型,否則會導致模型在測試集上過擬合。
一般來說,最終的正確率,訓練集大于驗證集,驗證集大于測試集。
對于部分機器學習任務,我們劃分的測試集必須是模型從未見過的數據,比如語音識別中一個完全不同的人的說話聲,圖像識別中一個完全不同的識別個體。這時,一般來說,訓練集和驗證集的數據分布是同分布的,而測試集的數據分布與前兩者會略有不同。在這種情況下,通常,測試集的正確率會比驗證集的正確率低得多,這樣就可以看出模型的泛化能力,可以預測出實際應用中的真實效果。
下面是按照 8-1-1 劃分數據集的代碼示例:
import torch
from torch.utils.data import DataLoader, TensorDataset, random_split# 生成示例數據
X = torch.randn(1000, 10) # 1000個樣本,10維特征
y = torch.randint(0, 2, (1000,)) # 二分類標簽
dataset = TensorDataset(X, y)# 劃分比例:80%訓練,10%驗證,10%測試
train_size = int(0.8 * len(dataset))
val_size = int(0.1 * len(dataset))
test_size = len(dataset) - train_size - val_sizetrain_dataset, val_dataset, test_dataset = random_split(dataset, [train_size, val_size, test_size],generator=torch.Generator().manual_seed(42) # 固定隨機種子
)# 創建DataLoader
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
val_loader = DataLoader(val_dataset, batch_size=32)
test_loader = DataLoader(test_dataset, batch_size=32)print(f"訓練集樣本數: {len(train_dataset)}") # 直接查看原始數據集
print(f"DataLoader 批次數量: {len(train_loader)}") # 總批次 = 樣本數 // batch_size# 獲取第一個批次的數據
batch = next(iter(train_loader)) # 返回的是 (features, labels)
features, labels = batch# 查看特征和標簽的形狀
print("特征張量形狀:", features.shape) # [batch_size, 10]
print("標簽張量形狀:", labels.shape) # [batch_size]
print("標簽示例:", labels[:5]) # 查看前5個標簽
二、偏差與方差
-
假設這就是數據集,如果給這個數據集擬合一條直線,可能得到一個邏輯回歸擬合,但它并不能很好地擬合該數據,這是高偏差(high bias)的情況,我們稱為**“欠擬合”(underfitting)**。
-
相反的如果我們擬合一個非常復雜的分類器,比如深度神經網絡或含有隱藏單元的神經網絡,可能就非常適用于這個數據集,但是這看起來也不是一種很好的擬合方式分類器方差較高(high variance),數據過度擬合(overfitting)。
衡量方式
- 一般可通過查看訓練集與驗證集誤差來診斷。
-
評估偏差(bias),一般看訓練集 訓練集誤差大——偏差較高,欠擬合
-
評估方差(variance),一般看驗證集 訓練集誤差小,驗證集誤差大——方差較高,過擬合
學習曲線
-
學習曲線作用: 查看模型的學習效果; 通過學習曲線可以清晰的看出模型對數據的過擬合和欠擬合;
-
學習曲線:隨著訓練樣本的逐漸增多,算法訓練出的模型的表現能力;
-
表現能力:也就是模型的預測準確情況。
?
總結就是如果訓練樣本準確率一直上不去就是欠擬合,如果訓練集準確率很高,但是驗證集很低,就是過擬合。下面是兩個案例
案例 1——欠擬合
import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt# 生成非線性數據(100個樣本)
torch.manual_seed(42)
x = torch.unsqueeze(torch.linspace(-5, 5, 100), 1)
y = torch.sin(x) * 2 + torch.normal(0, 0.3, x.shape)# 劃分訓練集(70%)和驗證集(30%)
split = int(0.7 * len(x))
x_train, y_train = x[:split], y[:split]
x_val, y_val = x[split:], y[split:]# 構建欠擬合模型(單層線性回歸)
class UnderfitModel(nn.Module):def __init__(self):super().__init__()self.linear = nn.Linear(1, 1) # 僅一個線性層def forward(self, x):return self.linear(x)model = UnderfitModel()
optimizer = optim.SGD(model.parameters(), lr=0.01) # 使用低學習率
criterion = nn.MSELoss()# 訓練過程(僅50次迭代)
train_loss = []
val_loss = []
for epoch in range(50):# 訓練模式model.train()output = model(x_train)loss = criterion(output, y_train)optimizer.zero_grad()loss.backward()optimizer.step()# 驗證模式model.eval()with torch.no_grad():val_pred = model(x_val)v_loss = criterion(val_pred, y_val)# 記錄損失train_loss.append(loss.item())val_loss.append(v_loss.item())# 可視化損失曲線
plt.figure(figsize=(10,5))
plt.plot(train_loss, label='train_loss')
plt.plot(val_loss, label='valid_loss')
plt.ylim(0, 5)
plt.legend()
plt.title("欠擬合訓練過程")
plt.show()# 最終預測可視化
model.eval()
with torch.no_grad():pred = model(x)plt.figure(figsize=(12,5))
plt.scatter(x_train, y_train, c='r', label='train_data')
plt.scatter(x_val, y_val, c='g', label='valid_data')
plt.plot(x, pred.numpy(), 'b-', lw=3, label='model_predict')
plt.plot(x, torch.sin(x)*2, 'k--', label='true_function')
plt.legend()
plt.show()# 輸出誤差指標
print(f'[最終誤差] 訓練集:{train_loss[-1]:.4f} | 驗證集:{val_loss[-1]:.4f}')
print(f'模型參數:w={model.linear.weight.item():.2f}, b={model.linear.bias.item():.2f}')
它最終的學習曲線如下
可以很明顯看到模型預測與真實曲線相差很遠
案例 2——過擬合?
import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt# 生成少量訓練數據(20個樣本)
torch.manual_seed(1)
x_train = torch.unsqueeze(torch.linspace(-5, 5, 20), dim=1)
y_train = 1.2 * x_train + 0.8 + torch.normal(0, 0.5, size=x_train.size())# 構建過參數化模型(4層全連接網絡)
class OverfitModel(nn.Module):def __init__(self):super().__init__()self.net = nn.Sequential(nn.Linear(1, 100),nn.ReLU(),nn.Linear(100, 100),nn.ReLU(),nn.Linear(100, 100),nn.ReLU(),nn.Linear(100, 1))def forward(self, x):return self.net(x)model = OverfitModel()
optimizer = optim.Adam(model.parameters(), lr=0.01)
criterion = nn.MSELoss()# 訓練循環(3000次迭代)
loss_history = []
for epoch in range(3000):output = model(x_train)loss = criterion(output, y_train)optimizer.zero_grad()loss.backward()optimizer.step()loss_history.append(loss.item())# 生成測試數據(同分布但未參與訓練)
x_test = torch.unsqueeze(torch.linspace(-6, 6, 100), dim=1)
y_test = 1.2 * x_test + 0.8 + torch.normal(0, 0.5, size=x_test.size())# 繪制結果對比
plt.figure(figsize=(12,5))
plt.scatter(x_train.numpy(), y_train.numpy(), c='r', label='train_data')
plt.plot(x_test.numpy(), model(x_test).detach().numpy(), 'b-', lw=3, label='predict')
plt.plot(x_test.numpy(), 1.2*x_test+0.8, 'g--', label='true_function')
plt.legend()
plt.show()# 輸出訓練誤差和測試誤差
train_loss = criterion(model(x_train), y_train)
test_loss = criterion(model(x_test), y_test)
print(f'訓練誤差:{train_loss.item():.4f}')
print(f'測試誤差:{test_loss.item():.4f}')
可以看到最后生成的擬合曲線如藍色所示,很明顯過擬合,切測試誤差比訓練誤差大很多?
三、過擬合&欠擬合的處理方式
1、首先根據訓練集效果來判斷是否是高偏差?也就是是否欠擬合。
如果不是,跳轉到下一步(判斷是否高方差)。
如果是,有四種可嘗試的方法:
A、新網絡,比如:更多的隱藏層或隱藏單元。
B、增加新特征,可以考慮加入進特征組合、高次特征或者添加多項式特征(將線性模型通過添加二次項或者三次項使模型泛化能力更強)
C、用更多時間訓練算法。
D、嘗試更先進的優化算法。
反復調試,直到偏差降到和接受范圍內,然后進行下一步。
2、根據驗證集效果來判斷是否是高方差?也就是是否過擬合。
如果不是,說明得到了很好的結果,訓練結束,開始將該模型放入測試集。
如果是,有三種可嘗試的方法:
A、更多數據來訓練。
B、正則化來減少過擬合。
C、控制模型的復雜度,用dropout、early stopping等方法
D、嘗試新網絡框架(有時有用有時沒用)。
名詞解釋
- 正則化
L2正則化:目標函數中增加所有權重w參數的平方之和, 逼迫所有w盡可能趨向零但不為零. 因為過擬合的時候, 擬合函數需要顧忌每一個點, 最終形成的擬合函數波動很大, 在某些很小的區間里, 函數值的變化很劇烈, 也就是某些w非常大. 為此, L2正則化的加入就懲罰了權重變大的趨勢.
model = nn.Sequential(nn.Linear(784, 256),nn.ReLU(),nn.Linear(256, 10)
)# 設置優化器時添加weight_decay參數(L2系數)
optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4)
L1正則化:目標函數中增加所有權重w參數的絕對值之和, 逼迫更多w為零(也就是變稀疏. L2因為其導數也趨0, 奔向零的速度不如L1給力了).大家對稀疏規則化趨之若鶩的一個關鍵原因在于它能實現特征的自動選擇。一般來說,xi的大部分元素(也就是特征)都是和最終的輸出yi沒有關系或者不提供任何信息的,在最小化目標函數的時候考慮xi這些額外的特征,雖然可以獲得更小的訓練誤差,但在預測新的樣本時,這些沒用的特征權重反而會被考慮,從而干擾了對正確yi的預測。稀疏規則化算子的引入就是為了完成特征自動選擇的光榮使命,它會學習地去掉這些無用的特征,也就是把這些特征對應的權重置為0。
L1 正則化 torch 沒有直接實現,可以手動實現
def l1_regularization(model, lambda_l1):l1_loss = 0for param in model.parameters():l1_loss += torch.sum(torch.abs(param))return lambda_l1 * l1_loss# 訓練循環
for data, target in dataloader:optimizer.zero_grad()output = model(data)loss = F.cross_entropy(output, target)# 添加L1正則項l1_lambda = 0.001loss += l1_regularization(model, l1_lambda)loss.backward()optimizer.step()
下面是一個同時引用 L1 正則化和 L2 正則化的案例
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as Fclass RegularizedModel(nn.Module):def __init__(self):super().__init__()self.fc = nn.Sequential(nn.Flatten(), nn.Linear(784, 256),nn.BatchNorm1d(256),nn.ReLU(),nn.Linear(256, 10))def forward(self, x):return self.fc(x)def train(model, train_loader, lambda_l1=0, lambda_l2=0):optimizer = optim.AdamW(model.parameters(), lr=0.001)for epoch in range(100):total_loss = 0for x, y in train_loader:optimizer.zero_grad()pred = model(x)loss = F.cross_entropy(pred, y)# L1正則項if lambda_l1 > 0:l1 = sum(p.abs().sum() for p in model.parameters())loss += lambda_l1 * l1# L2正則項if lambda_l2 > 0:l2 = sum(p.pow(2).sum() for p in model.parameters())loss += 0.5 * lambda_l2 * l2loss.backward()optimizer.step()total_loss += loss.item()print(f"Epoch {epoch}: Loss={total_loss/len(train_loader):.4f}")# 使用示例import torch
from torch.utils.data import DataLoader, TensorDataset# 參數配置
batch_size = 16
input_dim = 784 # 對應模型輸入維度
num_classes = 10
num_samples = 1000 # 總樣本量# 生成正態分布虛擬數據
X = torch.randn(num_samples, input_dim) # 形狀 (1000, 784)
y = torch.randint(0, num_classes, (num_samples,)) # 隨機標簽# 創建數據集和數據加載器
dataset = TensorDataset(X, y)
train_loader = DataLoader(dataset, batch_size=batch_size, shuffle=True)# 驗證數據形狀
sample_X, sample_y = next(iter(train_loader))
print(f"輸入數據形狀: {sample_X.shape}") # 應輸出 torch.Size([16, 784])
print(f"標簽形狀: {sample_y.shape}") # 應輸出 torch.Size([16])model = RegularizedModel()
train(model, train_loader, lambda_l1=1e-5, lambda_l2=1e-4)
- dropout
在訓練的運行的時候,讓神經元以超參數p的概率被激活(也就是1-p的概率被設置為0), 每個w因此隨機參與, 使得任意w都不是不可或缺的, 效果類似于數量巨大的模型集成。
class RegularizedModel(nn.Module):def __init__(self, input_dim):super().__init__()self.net = nn.Sequential(nn.Linear(input_dim, 128),nn.ReLU(),nn.Dropout(0.5), # 添加Dropout層nn.Linear(128, 64),nn.ReLU(),nn.Dropout(0.3),nn.Linear(64, 1))def forward(self, x):return torch.sigmoid(self.net(x)).squeeze()
- early stop
提前終止訓練,即在模型對訓練數據集迭代收斂之前停止迭代來防止過擬合,常用的停止條件就是當 N 輪迭代都loss 都沒有降低后可以停止迭代
下面案例的停止條件就是當 loss 連續 10 次都沒有低于最佳 loss-0.001時就觸發,這里設置了一個delta為 0.001,就能保證即使損失有波動,只要未突破閾值就計數
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt
from torch.utils.data import DataLoader, TensorDataset# 早停監控器(帶模型保存功能)
class EarlyStopper:def __init__(self, patience=5, delta=0, path='best_model.pth'):self.patience = patience # 容忍epoch數self.delta = delta # 視為改進的最小變化量self.path = path # 最佳模型保存路徑self.counter = 0 # 未改進計數器self.best_score = None # 最佳監控指標值self.early_stop = False # 停止標志def __call__(self, val_loss, model):score = -val_loss # 默認監控驗證損失(越大越好)if self.best_score is None:self.best_score = scoreself.save_checkpoint(model)elif score < self.best_score + self.delta:self.counter += 1print(f'EarlyStopping counter: {self.counter}/{self.patience}')if self.counter >= self.patience:self.early_stop = Trueelse:self.best_score = scoreself.save_checkpoint(model)self.counter = 0def save_checkpoint(self, model):torch.save(model.state_dict(), self.path)# 生成模擬數據(回歸任務)
def generate_data(samples=1000):X = torch.linspace(-10, 10, samples).unsqueeze(1)y = 0.5 * X**3 - 2 * X**2 + 3 * X + torch.randn(X.size()) * 10return X, y# 過參數化的全連接網絡
class OverfitModel(nn.Module):def __init__(self):super().__init__()self.net = nn.Sequential(nn.Linear(1, 128),nn.ReLU(),nn.Linear(128, 256),nn.ReLU(),nn.Linear(256, 128),nn.ReLU(),nn.Linear(128, 1))def forward(self, x):return self.net(x)# 訓練函數(集成早停)
def train_with_earlystop(model, train_loader, val_loader, epochs=1000):optimizer = optim.Adam(model.parameters(), lr=0.001)criterion = nn.MSELoss()early_stopper = EarlyStopper(patience=10, delta=0.001)train_losses = []val_losses = []for epoch in range(epochs):# 訓練階段model.train()train_loss = 0for X_batch, y_batch in train_loader:optimizer.zero_grad()pred = model(X_batch)loss = criterion(pred, y_batch)loss.backward()optimizer.step()train_loss += loss.item()train_loss /= len(train_loader)train_losses.append(train_loss)# 驗證階段model.eval()val_loss = 0with torch.no_grad():for X_val, y_val in val_loader:pred_val = model(X_val)val_loss += criterion(pred_val, y_val).item()val_loss /= len(val_loader)val_losses.append(val_loss)print(f'Epoch {epoch+1:03d} | 'f'Train Loss: {train_loss:.4f} | 'f'Val Loss: {val_loss:.4f}')# 早停檢查early_stopper(val_loss, model)if early_stopper.early_stop:print("==> Early stopping triggered")break# 恢復最佳模型model.load_state_dict(torch.load('best_model.pth'))return train_losses, val_losses# 可視化訓練過程
def plot_learning_curve(train_loss, val_loss):plt.figure(figsize=(10, 6))plt.plot(train_loss, label='Training Loss')plt.plot(val_loss, label='Validation Loss')plt.xlabel('Epochs')plt.ylabel('Loss')plt.title('Learning Curve with Early Stopping')plt.legend()plt.grid(True)plt.show()# 主程序
if __name__ == "__main__":# 數據準備X, y = generate_data()dataset = TensorDataset(X, y)# 劃分訓練集和驗證集(8:2)train_size = int(0.8 * len(dataset))val_size = len(dataset) - train_sizetrain_dataset, val_dataset = torch.utils.data.random_split(dataset, [train_size, val_size])train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)val_loader = DataLoader(val_dataset, batch_size=32)# 初始化模型model = OverfitModel()# 開始訓練train_loss, val_loss = train_with_earlystop(model, train_loader, val_loader, epochs=1000)# 繪制學習曲線plot_learning_curve(train_loss, val_loss)# 最終模型測試model.eval()with torch.no_grad():test_input = torch.tensor([[5.0], [-3.0], [8.0]])predictions = model(test_input)print("\nModel Predictions at x=5, -3, 8:")print(predictions.numpy())
四、模型的效果評估
具體模型的評估方法也可以看我之前的文章,本文主要補充一些代碼案例【Python數據分析】數據挖掘建模——分類與預測算法評價(含ROC曲線、F1等指標的解釋)_分類f1指標 python-CSDN博客
(1)分類任務評估(混淆矩陣、AUC)
from sklearn.metrics import confusion_matrix, roc_auc_scoredef evaluate_model(model, loader):model.eval()all_preds = []all_labels = []with torch.no_grad():for X_batch, y_batch in loader:outputs = model(X_batch)preds = (outputs > 0.5).float()all_preds.extend(preds.cpu().numpy())all_labels.extend(y_batch.cpu().numpy())# 計算指標cm = confusion_matrix(all_labels, all_preds)auc = roc_auc_score(all_labels, all_preds)print("Confusion Matrix:")print(cm)print(f"AUC Score: {auc:.4f}")# 在測試集上評估
evaluate_model(model, test_loader)
(2)回歸任務評估(MAE、MSE)?
def evaluate_regression(model, loader):model.eval()total_mae = 0total_mse = 0with torch.no_grad():for X_batch, y_batch in loader:outputs = model(X_batch)mae = torch.abs(outputs - y_batch).mean()mse = ((outputs - y_batch)**2).mean()total_mae += mae.item() * X_batch.size(0)total_mse += mse.item() * X_batch.size(0)mae = total_mae / len(loader.dataset)mse = total_mse / len(loader.dataset)print(f"MAE: {mae:.4f}, MSE: {mse:.4f}")
當然也可以把二者結合一下
import torch
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import (roc_curve, auc, confusion_matrix, precision_recall_curve,r2_score,mean_squared_error
)
import seaborn as snsdef evaluate_model(model, data_loader, task_type='classification'):"""綜合模型評估函數參數:model : 訓練好的PyTorch模型data_loader : 數據加載器task_type : 任務類型 ['classification', 'regression']返回:包含各項指標的字典"""model.eval()device = next(model.parameters()).deviceall_targets = []all_outputs = []with torch.no_grad():for inputs, targets in data_loader:inputs = inputs.to(device)outputs = model(inputs)all_targets.append(targets.cpu().numpy())all_outputs.append(outputs.cpu().numpy())y_true = np.concatenate(all_targets)y_pred = np.concatenate(all_outputs)metrics = {}if task_type == 'classification':# 分類任務指標y_prob = torch.softmax(torch.tensor(y_pred), dim=1).numpy()y_pred_labels = np.argmax(y_pred, axis=1)# 多分類AUC計算(OvR策略)fpr = dict()tpr = dict()roc_auc = dict()n_classes = y_prob.shape[1]for i in range(n_classes):fpr[i], tpr[i], _ = roc_curve((y_true == i).astype(int), y_prob[:, i])roc_auc[i] = auc(fpr[i], tpr[i])# 計算宏觀平均AUCfpr["macro"], tpr["macro"], _ = roc_curve(y_true.ravel(), y_prob.ravel())roc_auc["macro"] = auc(fpr["macro"], tpr["macro"])metrics.update({'accuracy': np.mean(y_pred_labels == y_true),'auc_macro': roc_auc["macro"],'confusion_matrix': confusion_matrix(y_true, y_pred_labels),'classification_report': classification_report(y_true, y_pred_labels)})# 繪制ROC曲線plt.figure(figsize=(10, 6))for i in range(n_classes):plt.plot(fpr[i], tpr[i], lw=1,label=f'Class {i} (AUC = {roc_auc[i]:.2f})')plt.plot([0, 1], [0, 1], 'k--', lw=1)plt.xlim([0.0, 1.0])plt.ylim([0.0, 1.05])plt.xlabel('False Positive Rate')plt.ylabel('True Positive Rate')plt.title('ROC Curves')plt.legend(loc="lower right")plt.show()elif task_type == 'regression':# 回歸任務指標metrics.update({'mse': mean_squared_error(y_true, y_pred),'mae': np.mean(np.abs(y_true - y_pred)),'r2': r2_score(y_true, y_pred)})# 繪制預測值與真實值散點圖plt.figure(figsize=(8, 6))plt.scatter(y_true, y_pred, alpha=0.5)plt.plot([y_true.min(), y_true.max()], [y_true.min(), y_true.max()], 'r--')plt.xlabel('True Values')plt.ylabel('Predictions')plt.title('Regression Evaluation')plt.show()return metrics# 使用示例(分類任務)
if __name__ == "__main__":# 假設已有訓練好的分類模型和數據加載器from sklearn.metrics import classification_report# 加載測試數據test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)# 進行評估classification_metrics = evaluate_model(model, test_loader, 'classification')# 打印關鍵指標print(f"準確率: {classification_metrics['accuracy']:.4f}")print(f"宏觀平均AUC: {classification_metrics['auc_macro']:.4f}")print("\n分類報告:")print(classification_metrics['classification_report'])# 繪制混淆矩陣plt.figure(figsize=(10, 8))sns.heatmap(classification_metrics['confusion_matrix'], annot=True, fmt='d', cmap='Blues')plt.title('Confusion Matrix')plt.xlabel('Predicted Label')plt.ylabel('True Label')plt.show()# 回歸任務使用示例
# regression_metrics = evaluate_model(model, test_loader, 'regression')
# print(f"MSE: {regression_metrics['mse']:.4f}")
# print(f"R2: {regression_metrics['r2']:.4f}")
好啦 神經網絡的基礎就在這結束啦,之后就開始進一步講深度學習內容(包括 RNN、LSTM、transformer 等)最后就引出大模型的原理,繼續期待叭~?