知識點回顧:
- 三種不同的模型可視化方法:推薦torchinfo打印summary+權重分布可視化
- 進度條功能:手動和自動寫法,讓打印結果更加美觀
- 推理的寫法:評估模式
可視化
理解深度學習網絡最重要的2點:
1.了解損失如何定義的,知道損失從何而來----把抽象的任務通過損失函數量化出來
2.了解參數總量,即知道每一層的設計才能退出---層設計決定參數總量
1.1 nn.model自帶的方法
#1.
# nn.Module 的內置功能,直接輸出模型結構
print(model)#2.
# nn.Module 的內置功能,返回模型的可訓練參數迭代器
for name, param in model.named_parameters():print(f"Parameter name: {name}, Shape: {param.shape}")#3.
# 提取權重數據
import numpy as np
weight_data = {}
for name, param in model.named_parameters():if 'weight' in name:weight_data[name] = param.detach().cpu().numpy()# 可視化權重分布
fig, axes = plt.subplots(1, len(weight_data), figsize=(15, 5))
fig.suptitle('Weight Distribution of Layers')for i, (name, weights) in enumerate(weight_data.items()):# 展平權重張量為一維數組weights_flat = weights.flatten()# 繪制直方圖axes[i].hist(weights_flat, bins=50, alpha=0.7)axes[i].set_title(name)axes[i].set_xlabel('Weight Value')axes[i].set_ylabel('Frequency')axes[i].grid(True, linestyle='--', alpha=0.7)plt.tight_layout()
plt.subplots_adjust(top=0.85)
plt.show()
# 計算并打印每層權重的統計信息
print("\n=== 權重統計信息 ===")
for name, weights in weight_data.items():mean = np.mean(weights)std = np.std(weights)min_val = np.min(weights)max_val = np.max(weights)print(f"{name}:")print(f" 均值: {mean:.6f}")print(f" 標準差: {std:.6f}")print(f" 最小值: {min_val:.6f}")print(f" 最大值: {max_val:.6f}")print("-" * 30)
from torchsummary import summary
# 打印模型摘要,可以放置在模型定義后面
summary(model, input_size=(4,))
該方法不顯示輸入層的尺寸,因為輸入的神經網是自己設置的,所以不需要顯示輸入層的尺寸。 但是在使用該方法時,input_size=(4,) 參數是必需的,因為 PyTorch 需要知道輸入數據的形狀才能推斷模型各層的輸出形狀和參數數量。
summary 函數的核心邏輯是:
創建一個與 input_size 形狀匹配的虛擬輸入張量(通常填充零)
將虛擬輸入傳遞給模型,執行一次前向傳播(但不計算梯度)
記錄每一層的輸入和輸出形狀,以及參數數量
生成可讀的摘要報告
from torchinfo import summary
summary(model, input_size=(4, ))
torchinfo 是提供比 torchsummary 更詳細的模型摘要信息,包括每層的輸入輸出形狀、參數數量、計算量等
from tqdm import tqdm # 先導入tqdm庫
import time # 用于模擬耗時操作# 創建一個總步數為10的進度條
with tqdm(total=10) as pbar: # pbar是進度條對象的變量名# pbar 是 progress bar(進度條)的縮寫,約定俗成的命名習慣。for i in range(10): # 循環10次(對應進度條的10步)time.sleep(0.5) # 模擬每次循環耗時0.5秒pbar.update(1) # 每次循環后,進度條前進1步
# 在測試集上評估模型,此時model內部已經是訓練好的參數了
# 評估模型
model.eval() # 設置模型為評估模式
with torch.no_grad(): # torch.no_grad()的作用是禁用梯度計算,可以提高模型推理速度outputs = model(X_test) # 對測試數據進行前向傳播,獲得預測結果_, predicted = torch.max(outputs, 1) # torch.max(outputs, 1)返回每行的最大值和對應的索引#這個函數返回2個值,分別是最大值和對應索引,參數1是在第1維度(行)上找最大值,_ 是Python的約定,表示忽略這個返回值,所以這個寫法是找到每一行最大值的下標# 此時outputs是一個tensor,p每一行是一個樣本,每一行有3個值,分別是屬于3個類別的概率,取最大值的下標就是預測的類別# predicted == y_test判斷預測值和真實值是否相等,返回一個tensor,1表示相等,0表示不等,然后求和,再除以y_test.size(0)得到準確率# 因為這個時候數據是tensor,所以需要用item()方法將tensor轉化為Python的標量# 之所以不用sklearn的accuracy_score函數,是因為這個函數是在CPU上運行的,需要將數據轉移到CPU上,這樣會慢一些# size(0)獲取第0維的長度,即樣本數量correct = (predicted == y_test).sum().item() # 計算預測正確的樣本數accuracy = correct / y_test.size(0)print(f'測試集準確率: {accuracy * 100:.2f}%')