DAY 35 模型可視化與推理

知識點回顧:
  1. 三種不同的模型可視化方法:推薦torchinfo打印summary+權重分布可視化
  2. 進度條功能:手動和自動寫法,讓打印結果更加美觀
  3. 推理的寫法:評估模式

作業:調整模型定義時的超參數,對比下效果。

(一)三種不同的模型結構可視化方法

理解一個深度學習網絡最重要的2點:

1. 了解損失如何定義的,知道損失從何而來----把抽象的任務通過損失函數量化出來

2. 了解參數總量,即知道每一層的設計才能退出---層設計決定參數總量

  • nn.model自帶的方法

這是最基礎、最簡單的方法,直接打印模型對象,它會輸出模型的結構,顯示模型中各個層的名稱和參數信息。

#  nn.Module 的內置功能,直接輸出模型結構
print(model)
MLP((fc1): Linear(in_features=4, out_features=10, bias=True)(relu): ReLU()(fc2): Linear(in_features=10, out_features=3, bias=True)
)
# nn.Module 的內置功能,返回模型的可訓練參數迭代器
for name, param in model.named_parameters():print(f"Parameter name: {name}, Shape: {param.shape}")
Parameter name: fc1.weight, Shape: torch.Size([10, 4])
Parameter name: fc1.bias, Shape: torch.Size([10])
Parameter name: fc2.weight, Shape: torch.Size([3, 10])
Parameter name: fc2.bias, Shape: torch.Size([3])

可以將模型中帶有weight的參數(即權重)提取出來,并轉為 numpy 數組形式,對其計算統計分布,并且繪制可視化圖表

# 提取權重數據
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)

=== 權重統計信息 ===
fc1.weight:均值: 0.013520標準差: 0.935024最小值: -2.185144最大值: 2.903806
------------------------------
fc2.weight:均值: 0.027174標準差: 1.232366最小值: -3.307564最大值: 3.074636
------------------------------

對比 fc1.weight 和 fc2.weight 的統計信息 ,可以發現它們的均值、標準差、最值等存在差異。這反映了不同層在模型中的作用不同。

權重統計信息可以為超參數調整提供參考。例如,如果發現權重標準差過大導致訓練不穩定,可以嘗試調整學習率,使權重更新更平穩;或者改變權重初始化方法,使初始權重分布更合理。如果最小值和最大值在訓練后期仍波動較大,可能需要考慮調整正則化參數,防止過擬合或欠擬合。

  • torchsummary庫的summary方法
from torchsummary import summary
# 打印模型摘要,可以放置在模型定義后面
summary(model, input_size=(4,))

?

----------------------------------------------------------------Layer (type)               Output Shape         Param #
================================================================Linear-1                   [-1, 10]              50ReLU-2                   [-1, 10]               0Linear-3                    [-1, 3]              33
================================================================
Total params: 83
Trainable params: 83
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.00
Forward/backward pass size (MB): 0.00
Params size (MB): 0.00
Estimated Total Size (MB): 0.00
----------------------------------------------------------------

該方法不顯示輸入層的尺寸,因為輸入的神經網是自己設置的,所以不需要顯示輸入層的尺寸。但是在使用該方法時,input_size=(4,) 參數是必需的,因為 PyTorch 需要知道輸入數據的形狀才能推斷模型各層的輸出形狀和參數數量。這是因為PyTorch 的模型在定義時是動態的,它不會預先知道輸入數據的具體形狀。nn.Linear(4, 10) 只定義了 “輸入維度是 4,輸出維度是 10”,但不知道輸入的批量大小和其他維度,比如卷積層需要知道輸入的通道數、高度、寬度等信息。----并非所有輸入數據都是結構化數據。因此,要生成模型摘要(如每層的輸出形狀、參數數量),必須提供一個示例輸入形狀,讓 PyTorch “運行” 一次模型,從而推斷出各層的信息。

summary 函數的核心邏輯是:

1. 創建一個與 input_size 形狀匹配的虛擬輸入張量(通常填充零)

2. 將虛擬輸入傳遞給模型,執行一次前向傳播(但不計算梯度)

3. 記錄每一層的輸入和輸出形狀,以及參數數量

4. 生成可讀的摘要報告

不同場景下的?input_size?示例

模型類型輸入類型input_size?示例實際輸入形狀(batch_size=32)
MLP(單樣本)一維特征向量(4,)(32, 4)
CNN(圖像)三維圖像(C,H,W)(3, 224, 224)(32, 3, 224, 224)
RNN(序列)二維序列(seq_len, feat)(10, 5)(32, 10, 5)

構建神經網絡的時候

1. 輸入層不需要寫:x多少個特征 輸入層就有多少神經元

2. 隱藏層需要寫,從第一個隱藏層可以看出特征的個數

3. 輸出層的神經元和任務有關,比如分類任務,輸出層有3個神經元,一個對應每個類別

  • ?torchinfo庫的summary方法

torchinfo 是提供比 torchsummary 更詳細的模型摘要信息,包括每層的輸入輸出形狀、參數數量、計算量等。

from torchinfo import summary
summary(model, input_size=(4, ))
==========================================================================================
Layer (type:depth-idx)                   Output Shape              Param #
==========================================================================================
MLP                                      [3]                       --
├─Linear: 1-1                            [10]                      50
├─ReLU: 1-2                              [10]                      --
├─Linear: 1-3                            [3]                       33
==========================================================================================
Total params: 83
Trainable params: 83
Non-trainable params: 0
Total mult-adds (M): 0.00
==========================================================================================
Input size (MB): 0.00
Forward/backward pass size (MB): 0.00
Params size (MB): 0.00
Estimated Total Size (MB): 0.00
==========================================================================================

(二)進度條功能

tqdm庫:

1. 創建一個進度條對象,并傳入總迭代次數。一般用with語句創建對象,這樣對象會在with語句結束后自動銷毀,保證資源釋放。with是常見的上下文管理器,這樣的使用方式還有用with打開文件,結束后會自動關閉文件。

2. 更新進度條,通過pbar.update(n)指定每次前進的步數n(適用于非固定步長的循環)。

  • 手動更新
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步
from tqdm import tqdm
import time# 創建進度條時添加描述(desc)和單位(unit)
with tqdm(total=5, desc="下載文件", unit="個") as pbar:# 進度條這個對象,可以設置描述和單位# desc是描述,在左側顯示# unit是單位,在進度條右側顯示for i in range(5):time.sleep(1)pbar.update(1)  # 每次循環進度+1

unit 參數的核心作用是明確進度條中每個進度單位的含義,使可視化信息更具可讀性。在深度學習訓練中,常用的單位包括:

- epoch:訓練輪次(遍歷整個數據集一次)。

- batch:批次(每次梯度更新處理的樣本組)。

- sample:樣本(單個數據點)

  • 自動更新
from tqdm import tqdm
import time# 直接將range(3)傳給tqdm,自動生成進度條
# 這個寫法我覺得是有點神奇的,直接可以給這個對象內部傳入一個可迭代對象,然后自動生成進度條
for i in tqdm(range(3), desc="處理任務", unit="epoch"):time.sleep(1)
處理任務: 100%|██████████| 3/3 [00:03<00:00,  1.01s/epoch]
import torch
import torch.nn as nn
import torch.optim as optim
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
import time
import matplotlib.pyplot as plt
from tqdm import tqdm  # 導入tqdm庫用于進度條顯示# 設置GPU設備
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(f"使用設備: {device}")# 加載鳶尾花數據集
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)# 歸一化數據
scaler = MinMaxScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)# 將數據轉換為PyTorch張量并移至GPU
X_train = torch.FloatTensor(X_train).to(device)
y_train = torch.LongTensor(y_train).to(device)
X_test = torch.FloatTensor(X_test).to(device)
y_test = torch.LongTensor(y_test).to(device)class MLP(nn.Module):def __init__(self):super(MLP, self).__init__()self.fc1 = nn.Linear(4, 10)  # 輸入層到隱藏層self.relu = nn.ReLU()self.fc2 = nn.Linear(10, 3)  # 隱藏層到輸出層def forward(self, x):out = self.fc1(x)out = self.relu(out)out = self.fc2(out)return out# 實例化模型并移至GPU
model = MLP().to(device)# 分類問題使用交叉熵損失函數
criterion = nn.CrossEntropyLoss()# 使用隨機梯度下降優化器
optimizer = optim.SGD(model.parameters(), lr=0.01)# 訓練模型
num_epochs = 20000  # 訓練的輪數# 用于存儲每100個epoch的損失值和對應的epoch數
losses = []
epochs = []start_time = time.time()  # 記錄開始時間# 創建tqdm進度條
with tqdm(total=num_epochs, desc="訓練進度", unit="epoch") as pbar:# 訓練模型for epoch in range(num_epochs):# 前向傳播outputs = model(X_train)  # 隱式調用forward函數loss = criterion(outputs, y_train)# 反向傳播和優化optimizer.zero_grad()loss.backward()optimizer.step()# 記錄損失值并更新進度條if (epoch + 1) % 200 == 0:losses.append(loss.item())epochs.append(epoch + 1)# 更新進度條的描述信息pbar.set_postfix({'Loss': f'{loss.item():.4f}'})# 每1000個epoch更新一次進度條if (epoch + 1) % 1000 == 0:pbar.update(1000)  # 更新進度條# 確保進度條達到100%if pbar.n < num_epochs:pbar.update(num_epochs - pbar.n)  # 計算剩余的進度并更新time_all = time.time() - start_time  # 計算訓練時間
print(f'Training time: {time_all:.2f} seconds')# # 可視化損失曲線
# plt.figure(figsize=(10, 6))
# plt.plot(epochs, losses)
# plt.xlabel('Epoch')
# plt.ylabel('Loss')
# plt.title('Training Loss over Epochs')
# plt.grid(True)
# plt.show()
訓練進度: 100%|██████████| 20000/20000 [00:10<00:00, 1885.37epoch/s, Loss=0.0630]Training time: 10.61 seconds

(三)模型推理

測試模型的測試這個詞在大模型領域叫做推理(inference),意味著把數據輸入到訓練好的模型的過程。?

# 在測試集上評估模型,此時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}%')

?測試集準確率: 96.67%

模型的評估模式簡單來說就是評估階段會關閉一些訓練相關的操作和策略 ,比如更新參數 正則化等操作,確保模型輸出結果的穩定性和一致性。

可能會有問題為什么評估模式不關閉梯度計算,推理不是不需要更新參數么?

主要還是因為在某些場景下,評估階段可能需要計算梯度(雖然不更新參數)。例如:計算梯度用于可視化(如 CAM 熱力圖,主要用于cnn相關)。所以為了避免這種需求不被滿足,還是需要手動關閉梯度計算。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/82217.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/82217.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/82217.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

20250523-BUG-E1696:無法打開元數據文件“platform.winmd(已解決)

BUG&#xff1a;E1696&#xff1a;無法打開元數據文件“platform.winmd&#xff08;已解決&#xff09; 最近在用VisualStudio2022打開一個VisualStudio2017的C老項目后報了這個錯&#xff0c;幾經周折終于解決了&#xff0c;以下是我用的解決方法&#xff1a; 將Debug從Win32改…

Hellorobot 移動操作機器人開源實踐:HPR 模型 + 全棧資源,降低家庭機器人開發門檻

Hellorobot在DobbE框架中扮演了重要的技術支柱角色。通過其尖端的模塊化設計和高效算法優化&#xff0c;Hellorobot為家庭機器人領域注入了強大的創新動力。DobbE框架的核心技術——Home Pretrained Representations (HPR) 模型&#xff0c;得益于Hellorobot的技術支持&#xf…

onnx模型轉入rknn3399平臺上工作記錄

1.rknn虛擬環境使用時報錯問題 使用rknn17環境的報錯&#xff1a; ImportError: libdc1394.so.22: cannot open shared object file: No such file or directory 參考鏈接&#xff1a;https://blog.csdn.net/2301_80032564/article/details/142316410 創作軟連接&#xff1a; …

杰發科技AC7840——CSE硬件加密模塊使用(1)

1. 簡介 2. 功能概述 3. 簡單的代碼分析 測試第二個代碼例程 初始化隨機數 這里的CSE_CMD_RND在FuncID中體現了 CSE_SECRET_KEY在17個用戶KEY中體現 最后的讀取RNG值&#xff0c;可以看出計算結果在PRAM中。 總的來看 和示例說明一樣&#xff0c;CSE 初次使用&#xff0c;添加…

AI要掌握的知識

AI&#xff08;人工智能&#xff09;是一個跨學科的復雜領域&#xff0c;其知識體系涵蓋理論基礎、技術工具和實踐應用等多個層面。以下從核心知識模塊、技術工具、實踐方向等角度&#xff0c;詳細梳理 AI 從業者需要掌握的知識體系&#xff1a; 一、數學基礎&#xff1a;AI 的…

Python Click庫:輕松構建優雅的命令行工具

Python Click庫&#xff1a;輕松構建優雅的命令行工具 引言一、Click 適用場景二、安裝 Click三、基礎使用1. 第一個 Click 程序2. 添加位置參數3. 使用選項參數 四、高級功能1. 子命令分組&#xff08;多級命令&#xff09;2. 參數類型驗證3. 彩色終端輸出 五、實用功能示例&a…

三種常見脈沖神經網絡編碼方式解讀

速率編碼&#xff08;rate coding) 速率編碼使用輸入特征來確定尖峰頻率&#xff0c;例如將靜態輸入數據&#xff08;如 MNIST 圖像&#xff09;轉換為時間上的脈沖&#xff08;spike&#xff09;序列。它是將神經元發放脈沖的頻率與輸入值&#xff08;如像素強度&#xff09;…

Selenium 測試框架 - Python

??Selenium Python 實戰指南:從入門到進階 Selenium 是 Web 自動化測試中最受歡迎的工具之一,支持多種瀏覽器和語言。本文將從環境搭建到多瀏覽器兼容、測試框架集成、元素定位方式、常用操作、瀏覽器配置等多個方面進行詳細講解,并分享常見的最佳實踐建議。 ??一、環境…

第四十九節:圖像分割-基于深度學習的圖像分割

1. 引言 在計算機視覺領域,圖像分割(Image Segmentation)是一項基礎且關鍵的技術,其目標是將圖像劃分為多個具有特定語義的區域。隨著深度學習技術的突破,基于神經網絡的圖像分割方法在精度和效率上都實現了質的飛躍。本文將重點介紹如何利用OpenCV結合深度學習模型實現高…

【GESP】C++三級真題 luogu-B4039 [GESP202409 三級] 回文拼接

GESP三級真題&#xff0c;字符串相關題目&#xff0c;難度★★?☆☆。 題目題解詳見&#xff1a;https://www.coderli.com/gesp-3-luogu-b4039/ 【GESP】C三級真題 luogu-B4039 [GESP202409 三級] 回文拼接 | OneCoderGESP三級真題&#xff0c;字符串相關題目&#xff0c;難…

什么是深度學習中的層次分類問題?

深度學習中的層次分類問題&#xff08;Hierarchical Classification&#xff09;是指分類任務中存在類別間的層次結構&#xff0c;且模型需要根據這種層次關系進行預測的問題。與傳統的扁平分類&#xff08;Flat Classification&#xff09;不同&#xff0c;層次分類要求模型在…

黑馬點評-樂觀鎖/悲觀鎖/synchronized/@Transactional

文章目錄 全局ID生成器超賣樂觀鎖 一人一單悲觀鎖 當我們確認訂單時&#xff0c;系統需要給我們返回我們的訂單編號。這個時候就會出現兩個大問題。 1.訂單id采用數據庫里的自增的話&#xff0c;安全性降低。比如今天我的訂單是10&#xff0c;我明天的訂單是100&#xff0c;那…

python下通過wmic設置程序的優先級~~~

在開發過程中&#xff0c;經常會碰到需要設置程序優先級&#xff0c;這時候可以手動到任務管理器中調整&#xff0c;但是這多多少少有些不方便&#xff0c;那么這時候我們就可以通過subprocess調用wmic命令來實現&#xff0c;方法如下: step 1 必要的引用: import subprocess…

在Mac中使用pyenv管理Python版本:從安裝到虛擬環境的全流程指南

# 在Mac中使用pyenv管理Python版本&#xff1a;從安裝到虛擬環境的全流程指南 ## 一、為什么選擇pyenv&#xff1f; 在開發過程中&#xff0c;不同項目往往需要不同的Python版本&#xff08;如3.8 vs 3.10&#xff09;&#xff0c;而系統默認的Python環境難以滿足靈活切換的需…

FFT Shift

在頻域圖像處理中,交換四個象限實現FFT移位(也稱為FFT Shift)是一種將頻域圖像的低頻成分移動到中心的標準化操作。 1. 為什么需要FFT移位? 原始FFT輸出特性: 二維FFT的直接計算結果中: 低頻分量(圖像的整體亮度和平滑部分)位于頻譜圖的四個角落 高頻分量(邊緣、細節…

python打卡day34@浙大疏錦行

知識點回歸&#xff1a; CPU性能的查看&#xff1a;看架構代際、核心數、線程數GPU性能的查看&#xff1a;看顯存、看級別、看架構代際GPU訓練的方法&#xff1a;數據和模型移動到GPU device上類的call方法&#xff1a;為什么定義前向傳播時可以直接寫作self.fc1(x) ①CPU性能查…

Windows 配置 ssh 秘鑰登錄 Ubuntu

在 Windows 上推送 SSH 公鑰到遠程服務器&#xff08;類似于 Linux 上的 ssh-copy-id&#xff09;可以通過以下幾種方法實現&#xff1a; ** 手動復制公鑰內容** 查看本地公鑰內容&#xff1a;type $env:USERPROFILE\.ssh\id_rsa.pub登錄遠程服務器&#xff0c;將公鑰內容粘貼…

SAP全面轉向AI戰略,S/4HANA悄然隱身

在2025年SAP Sapphire大會上&#xff0c;SAP首席執行官Christian Klein提出了一個雄心勃勃的愿景&#xff1a;讓人工智能&#xff08;AI&#xff09;無處不在&#xff0c;推動企業數字化轉型。SAP的AI戰略核心是將AI深度融入其業務應用生態&#xff0c;包括推出全新版本的AI助手…

Athena 執行引擎:在線服務計算的效率王者

引言 在在線服務領域&#xff0c;計算任務呈現出獨特的特性&#xff1a;一方面&#xff0c;數據量通常不會過于龐大&#xff0c;因為在線服務對耗時和響應速度有著嚴苛要求&#xff1b;另一方面&#xff0c;計算任務具有可控性&#xff0c;其大多并非由用戶實時輸入動態生成&a…

傳奇各種怪物一覽/圖像/爆率/產出/刷新地/刷新時間/刷怪時間

名稱圖像顯示名等級血量攻擊可召喚產出刷新蝙蝠蝙蝠530-22,0,0可誘惑回城卷(1.00%) 金幣(1.00%*500)雞雞551-1,0,0可誘惑雞肉(100.00%)比奇省(29550,62550)5分鐘35只 比奇省(35025,20025)5分鐘25只 比奇省(34025,31025)5分鐘25只 比奇省(40525,24025)5分鐘25只 比奇省(28025,26…