使用 PyTorch 和 TensorBoard 實時可視化模型訓練

在這個教程中,我們將使用 PyTorch 訓練一個簡單的多層感知機(MLP)模型來解決 MNIST 手寫數字分類問題,并且使用 TensorBoard 來可視化訓練過程中的不同信息,如損失、準確度、圖像、參數分布和學習率變化。


步驟 1:安裝必要的庫

首先,確保你已經安裝了必要的 Python 庫。如果尚未安裝,可以通過以下命令進行安裝:

pip install torch torchvision tensorboard

torchtorchvision 是 PyTorch 中的核心庫,而 tensorboard 是用于在瀏覽器中可視化訓練過程的工具。


步驟 2:導入庫

導入 PyTorch 及相關的庫:

import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision
import torchvision.transforms as transforms
from torch.utils.tensorboard import SummaryWriter
import os

這些庫分別用于:

  • torch:PyTorch 核心庫,包含各種模型和優化工具。
  • torchvision:包含數據集和預訓練模型。
  • SummaryWriter:用于將訓練過程中的數據寫入 TensorBoard。
  • os:文件系統操作,用于創建日志目錄。

步驟 3:加載和預處理數據

我們將使用 MNIST 數據集,它包含手寫數字的圖像。使用 torchvision 來加載并應用預處理:

# 數據預處理
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,), (0.5,))  # 歸一化
])# 下載訓練集和測試集
train_set = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
train_loader = torch.utils.data.DataLoader(train_set, batch_size=64, shuffle=True)test_set = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)
test_loader = torch.utils.data.DataLoader(test_set, batch_size=1000, shuffle=False)
  • transforms.ToTensor():將圖像數據從 PIL 圖像轉換為 PyTorch 張量。
  • transforms.Normalize():對圖像進行歸一化處理,將數據標準化為均值為 0,標準差為 1。

train_loadertest_loader 分別是用于訓練和測試的 PyTorch 數據加載器。


步驟 4:定義模型

我們將創建一個簡單的 多層感知機(MLP),包含兩個全連接層,使用 ReLU 激活函數。

# 簡單的多層感知機 (MLP)
class SimpleMLP(nn.Module):def __init__(self):super(SimpleMLP, self).__init__()self.fc1 = nn.Linear(28*28, 128)self.fc2 = nn.Linear(128, 64)self.fc3 = nn.Linear(64, 10)  # 10個輸出類def forward(self, x):x = x.view(-1, 28*28)  # 展平圖像x = F.relu(self.fc1(x))  # 激活函數x = F.relu(self.fc2(x))  # 激活函數return self.fc3(x)  # 輸出層

fc1, fc2, fc3 分別是模型的全連接層,每一層的輸入和輸出維度通過 Linear 層來定義。


步驟 5:設置損失函數和優化器

選擇適當的損失函數和優化器來訓練模型:

# 實例化模型
model = SimpleMLP()# 使用 GPU 或 CPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)# 損失函數和優化器
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
  • CrossEntropyLoss 是用于分類問題的標準損失函數。
  • Adam 優化器是一種自適應學習率的優化方法,適用于大多數任務。

步驟 6:設置 TensorBoard Writer

為 TensorBoard 創建一個日志目錄,并初始化 SummaryWriter

# TensorBoard 日志保存路徑
log_dir = "./runs/mnist_example"
if not os.path.exists(log_dir):os.makedirs(log_dir)# 初始化 TensorBoard Writer
writer = SummaryWriter(log_dir)# 添加模型的計算圖 (graph)
sample_data, _ = next(iter(train_loader))
writer.add_graph(model, sample_data.to(device))
  • log_dir 是 TensorBoard 保存日志文件的目錄。
  • SummaryWriter 用于記錄訓練過程中的數據。
  • add_graph 用于將模型結構寫入 TensorBoard。

步驟 7:訓練模型

接下來,我們定義訓練過程。在每 100 步記錄一次損失和準確度,每 1000 步記錄一次訓練圖像。

# 訓練周期
epochs = 10
global_step = 0
for epoch in range(epochs):running_loss = 0.0correct = 0total = 0# 訓練階段model.train()for i, (inputs, labels) in enumerate(train_loader):inputs, labels = inputs.to(device), labels.to(device)# 清空梯度optimizer.zero_grad()# 前向傳播outputs = model(inputs)# 計算損失loss = criterion(outputs, labels)loss.backward()  # 反向傳播optimizer.step()  # 更新參數# 累積損失和精度running_loss += loss.item()_, predicted = outputs.max(1)total += labels.size(0)correct += predicted.eq(labels).sum().item()# 每 100 步記錄一次if (i + 1) % 100 == 0:avg_loss = running_loss / 100acc = correct / totalprint(f"[Epoch {epoch+1}, Step {i+1}] Loss: {avg_loss:.4f} | Accuracy: {acc:.4f}")# 記錄損失和準確度writer.add_scalar("Loss/train", avg_loss, global_step)writer.add_scalar("Accuracy/train", acc, global_step)# 記錄每層的權重分布for name, param in model.named_parameters():writer.add_histogram(name, param, global_step)running_loss = 0.0correct = 0total = 0# 記錄每1000步的圖像(展示輸入圖像)if (i + 1) % 1000 == 0:img_grid = torchvision.utils.make_grid(inputs[:16])  # 取16個樣本writer.add_image(f"Train_Images/{epoch+1}_{i+1}", img_grid, global_step)global_step += 1
  • writer.add_scalar 用于記錄訓練中的損失和準確度。
  • writer.add_histogram 用于記錄每層參數的權重分布。
  • writer.add_image 用于記錄訓練樣本的圖像。

步驟 8:測試模型

測試模型并記錄測試集的損失和準確度。

# 測試階段
model.eval()
test_loss = 0.0
correct = 0
total = 0
with torch.no_grad():for inputs, labels in test_loader:inputs, labels = inputs.to(device), labels.to(device)outputs = model(inputs)loss = criterion(outputs, labels)test_loss += loss.item()_, predicted = outputs.max(1)total += labels.size(0)correct += predicted.eq(labels).sum().item()# 記錄測試集的損失和準確率
test_accuracy = correct / total
test_loss /= len(test_loader)
writer.add_scalar("Loss/test", test_loss, global_step)
writer.add_scalar("Accuracy/test", test_accuracy, global_step)# 測試集的圖像展示
test_images, _ = next(iter(test_loader))
img_grid = torchvision.utils.make_grid(test_images[:16])
writer.add_image('Test_Images', img_grid)

步驟 9:關閉 TensorBoard Writer

完成訓練和測試后,關閉 TensorBoard 寫入器:

# 關閉 TensorBoard 寫入器
writer.close()

步驟 10:啟動 TensorBoard

  1. 在終端中運行以下命令啟動 TensorBoard:

    tensorboard --logdir=./runs/mnist_example
    
  2. 打開瀏覽器,訪問 http://localhost:6006 即可查看:

    • 損失和精度曲線
    • 每層權重分布
    • 訓練/測試圖像樣本
    • 學習率的變化

總結

在本教程中,我們展示了如何使用 PyTorch 訓練一個簡單的 MLP 模型,利用 TensorBoard 記錄并實時可視化以下內容:

  • 損失和準確度曲線
  • 每層的權重和梯度分布
  • 訓練過程中的圖像
  • 學習率的變化

TensorBoard 提供了一種強大的可視化方式,可以幫助你深入了解模型的訓練過程,并有效地進行調優。

好的!以下是 完整的代碼,包括每個部分的實現。每個代碼塊的功能都是按步驟分開的,確保你可以從頭到尾順利運行。

完整代碼:PyTorch + TensorBoard

# 導入所需的庫
import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision
import torchvision.transforms as transforms
from torch.utils.tensorboard import SummaryWriter
import os# tensorboard --logdir=./runs/mnist_example# 設置隨機種子(可選)
torch.manual_seed(0)# 數據預處理
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,), (0.5,))  # 歸一化
])# 下載訓練集和測試集
train_set = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
train_loader = torch.utils.data.DataLoader(train_set, batch_size=64, shuffle=True)test_set = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)
test_loader = torch.utils.data.DataLoader(test_set, batch_size=1000, shuffle=False)# 定義簡單的多層感知機 (MLP) 模型
class SimpleMLP(nn.Module):def __init__(self):super(SimpleMLP, self).__init__()self.fc1 = nn.Linear(28*28, 128)self.fc2 = nn.Linear(128, 64)self.fc3 = nn.Linear(64, 10)  # 10個輸出類def forward(self, x):x = x.view(-1, 28*28)  # 展平圖像x = F.relu(self.fc1(x))  # 激活函數x = F.relu(self.fc2(x))  # 激活函數return self.fc3(x)  # 輸出層# 實例化模型
model = SimpleMLP()# 使用 GPU 或 CPU
# 設置設備并打印詳細信息
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
if device.type == "cuda":device_name = torch.cuda.get_device_name(device)
else:device_name = "CPU"print("=" * 90)
print(f"Device set to : {device_name}")
print("=" * 90)model.to(device)# 損失函數和優化器
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)# 設置 TensorBoard Writer
log_dir = "./runs/mnist_example"
if not os.path.exists(log_dir):os.makedirs(log_dir)# 初始化 TensorBoard Writer
writer = SummaryWriter(log_dir)# 添加模型的計算圖 (graph)
sample_data, _ = next(iter(train_loader))
writer.add_graph(model, sample_data.to(device))# 設置學習率調度器(可選)
lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.1)# 訓練模型
epochs = 10
global_step = 0
for epoch in range(epochs):running_loss = 0.0correct = 0total = 0# 訓練階段model.train()for i, (inputs, labels) in enumerate(train_loader):inputs, labels = inputs.to(device), labels.to(device)# 清空梯度optimizer.zero_grad()# 前向傳播outputs = model(inputs)# 計算損失loss = criterion(outputs, labels)loss.backward()  # 反向傳播optimizer.step()  # 更新參數# 累積損失和精度running_loss += loss.item()_, predicted = outputs.max(1)total += labels.size(0)correct += predicted.eq(labels).sum().item()# 每 100 步記錄一次if (i + 1) % 100 == 0:avg_loss = running_loss / 100acc = correct / totalprint(f"[Epoch {epoch+1}, Step {i+1}] Loss: {avg_loss:.4f} | Accuracy: {acc:.4f}")# 記錄損失和準確度writer.add_scalar("Loss/train", avg_loss, global_step)writer.add_scalar("Accuracy/train", acc, global_step)# 記錄每層的權重分布for name, param in model.named_parameters():writer.add_histogram(name, param, global_step)running_loss = 0.0correct = 0total = 0# 記錄每1000步的圖像(展示輸入圖像)if (i + 1) % 1000 == 0:img_grid = torchvision.utils.make_grid(inputs[:16])  # 取16個樣本writer.add_image(f"Train_Images/{epoch+1}_{i+1}", img_grid, global_step)global_step += 1# 更新學習率lr_scheduler.step()# 每個epoch記錄學習率變化writer.add_scalar("Learning_Rate", optimizer.param_groups[0]['lr'], epoch)# 測試模型
model.eval()
test_loss = 0.0
correct = 0
total = 0
with torch.no_grad():for inputs, labels in test_loader:inputs, labels = inputs.to(device), labels.to(device)outputs = model(inputs)loss = criterion(outputs, labels)test_loss += loss.item()_, predicted = outputs.max(1)total += labels.size(0)correct += predicted.eq(labels).sum().item()# 記錄測試集的損失和準確率
test_accuracy = correct / total
test_loss /= len(test_loader)
writer.add_scalar("Loss/test", test_loss, global_step)
writer.add_scalar("Accuracy/test", test_accuracy, global_step)# 測試集的圖像展示
test_images, _ = next(iter(test_loader))
img_grid = torchvision.utils.make_grid(test_images[:16])
writer.add_image('Test_Images', img_grid)# 關閉 TensorBoard 寫入器
writer.close()

解釋與步驟

  1. 導入庫:我們首先導入了 torch, torchvision, 和 SummaryWriter 來處理模型的定義、數據加載和 TensorBoard 寫入。

  2. 數據加載:使用 torchvision.datasets.MNIST 下載并加載 MNIST 數據集,使用 DataLoader 進行批量加載。

  3. 模型定義:定義了一個簡單的多層感知機(MLP)模型,包括兩層全連接層和一個輸出層。每層使用 ReLU 激活函數。

  4. 損失函數和優化器:使用交叉熵損失函數 (CrossEntropyLoss) 和 Adam 優化器。Adam 是一種常見的自適應優化算法,能有效優化深度學習模型。

  5. TensorBoard 設置

    • 創建一個 SummaryWriter 來將訓練過程中的各種信息寫入日志。
    • 使用 writer.add_graph(model, sample_data) 記錄模型結構。
    • 記錄每個訓練步驟中的損失、準確度和模型參數(權重)分布。
  6. 訓練過程

    • 每 100 步記錄一次當前損失和準確度。
    • 每 1000 步展示當前批次的圖像樣本。
  7. 學習率調度器:使用 StepLR 學習率調度器,每訓練 5 個 epoch,學習率降低 10 倍。

  8. 測試過程:在訓練結束后,評估模型在測試集上的表現,并記錄測試集的損失和準確度。

  9. 關閉 TensorBoard:訓練和測試結束后,關閉 SummaryWriter 以保存日志。


啟動 TensorBoard

  1. 運行上面的代碼后,終端會生成 TensorBoard 日志。
  2. 打開終端,使用以下命令啟動 TensorBoard:
tensorboard --logdir=./runs/mnist_example
  1. 然后,打開瀏覽器,訪問 http://localhost:6006,即可看到訓練過程的可視化界面。

在 TensorBoard 中可視化的內容

  • Scalars:損失和準確度曲線。
  • Histograms:每層權重的分布情況。
  • Images:訓練圖像和測試圖像樣本。
  • Learning Rate:學習率隨訓練過程的變化。

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

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

相關文章

第十五章 15.OSPF(CCNA)

第十五章 15.OSPF(CCNA) 介紹了大家都能用的OSPF動態路由協議 注釋: 學習資源是B站的CCNA by Sean_Ning CCNA 最新CCNA 200-301 視頻教程(含免費實驗環境) PS:喜歡的可以去買下他的課程,不貴,講的很細 To be cont…

手機連接windows遇到的問題及解決方法

文章目錄 寫在前面一、手機與windows 連接以后 無法在win端打開手機屏幕,提示801方法零、檢查連接方法一、系統修復方法二、斷開重連方法三、軟件更新方法四、關閉防火墻 寫在前面 本文主要記錄所遇到的問題以及解決方案,以備后用。 所用機型:win11 專業…

Spring Boot + MyBatis Plus 項目中,entity和 XML 映射文件的查找機制

在 Spring Boot MyBatis - Plus 項目中,entity(實體類)和 XML 映射文件的查找機制有其默認規則,也可通過配置調整,以下詳細說明: 一、實體類(entity)的查找 MyBatis - Plus 能找到…

itvbox綠豆影視tvbox手機版影視APP源碼分享搭建教程

我們先來看看今天的主題,tvbox手機版,然后再看看如何搭建: 很多愛好者都希望搭建自己的影視平臺,那該如何搭建呢? 后端開發環境: 1.易如意后臺管理優化版源碼; 2.寶塔面板; 3.ph…

Vue Electron 使用來給若依系統打包成exe程序,出現登錄成功但是不跳轉頁面(已解決)

描述 用vue打成electron可執行exe程序時,發現個問題,一直登錄之后,頁面跳轉不了,其實后臺請求已成功發送 那么懷疑就是vue頁面跳轉的事情 解決 大部分vue 前段項目 會使用 js-cookie 這個庫 來操作瀏覽器的cookie 然而這個庫 …

Blob設置type為application/msword將document DOM節點轉換為Word(.doc,.docx),并下載到本地

core code // 導出為Word文檔downloadWord({ dom, fileName "", fileType "doc", l {} } {}) {l.show && l.show();// 獲取HTML內容const content dom.innerHTML;// 構建Word文檔的HTML結構const html <!DOCTYPE html><html>&l…

無需 Mac,使用Appuploader簡化iOS上架流程

作為開發者&#xff0c;尤其是從事跨平臺開發的團隊&#xff0c;iOS應用上架一直是一項繁瑣且挑戰重重的工作。盡管Flutter、React Native等框架使得我們可以在不同平臺之間共享代碼&#xff0c;iOS上架仍然是一個不可忽視的難題。因為它不僅僅涉及代碼構建&#xff0c;還涉及到…

【JVM】Java虛擬機(二)——垃圾回收

目錄 一、如何判斷對象可以回收 &#xff08;一&#xff09;引用計數法 &#xff08;二&#xff09;可達性分析算法 二、垃圾回收算法 &#xff08;一&#xff09;標記清除 &#xff08;二&#xff09;標記整理 &#xff08;三&#xff09;復制 &#xff08;四&#xff…

Android 實現可拖動的ImageView

Android 實現可拖動的ImageView 代碼實現&#xff1a; public class DraggableImageView extends AppCompatImageView {private float lastTouchX;private float lastTouchY;public DraggableImageView(Context context) {super(context);init();}public DraggableImageView(C…

微信小程序中wxs

一、先新建wxs文件subutil.wxs 1、寫過濾器 //return class var isClass function(val) {if (val 0) {return grid-item} else if (val 1) {return temperature-error-slot} else if (val 2) {return chargingCycles-error-slot} else {return unrecognized-slot} } 2、…

Nginx攻略

&#x1f916; 作者簡介&#xff1a;水煮白菜王&#xff0c;一位前端勸退師 &#x1f47b; &#x1f440; 文章專欄&#xff1a; 前端專欄 &#xff0c;記錄一下平時在博客寫作中&#xff0c;總結出的一些開發技巧和知識歸納總結?。 感謝支持&#x1f495;&#x1f495;&#…

常見系統設計

秒殺系統 前端層&#xff1a; 靜態資源緩存&#xff1a;通過CDN緩存商品圖片、頁面靜態HTML&#xff0c;減少回源請求。 請求合并&#xff1a;合并用戶頻繁刷新的請求&#xff08;如10秒內僅允許一次真實請求&#xff09;。 端側限流&#xff1a;通過JS或APP端限制用戶高頻點擊…

git撤回commit

最常見的幾種撤回方式&#xff1a; 目標使用命令是否保留修改撤回最后一次 commit&#xff0c;但保留代碼修改git reset --soft HEAD~1? 保留撤回最后一次 commit&#xff0c;并丟棄修改git reset --hard HEAD~1? 丟棄撤回某個 commit&#xff0c;但保留后續提交git revert …

docker 安裝運行mysql8.4.4

先前一直使用mysql5.7&#xff0c;最新公司新項目&#xff0c;無意翻閱看下5.x版本mysql官方已經不再支持&#xff0c;于是準備選用MySQL8&#xff0c;官方8.4版本是個長期支持版本&#xff0c;選則最新版本8.4.4&#xff0c;如下是MySQL官方對版本支持計劃 MySQL版本下載查看地…

[java八股文][MySQL面試篇]索引

索引是什么&#xff1f;有什么好處&#xff1f; 索引類似于書籍的目錄&#xff0c;可以減少掃描的數據量&#xff0c;提高查詢效率。 如果查詢的時候&#xff0c;沒有用到索引就會全表掃描&#xff0c;這時候查詢的時間復雜度是On如果用到了索引&#xff0c;那么查詢的時候&a…

低代碼平臺的版本管理深度解析

引言 在當今快速發展的軟件開發領域&#xff0c;低代碼平臺憑借其可視化界面和拖拽功能&#xff0c;極大地減少了手動編碼的工作量&#xff0c;顯著提高了開發效率和質量。它提供了豐富的預構建模塊、組件和服務&#xff0c;讓開發者能夠根據業務需求和邏輯進行組合與配置&…

Springboot項目由JDK8升級至JDK17全過程教程【文末附源碼】

1. 前言 最近一直想把我的開源項目maple-boot升級到jdk17版本&#xff0c;然后接入Spring AI。拖延癥犯了一直拖拖拖&#xff0c;最近時間空閑較多&#xff0c;開始陸續著手升級。 整個升級過程 計劃分為3步。 step1&#xff1a;先將項目升級到jdk17&#xff0c;使用正常ste…

同步與異步:軟件工程中的時空藝術與實踐智慧-以蜻蜓hr人才系統舉例-優雅草卓伊凡

同步與異步&#xff1a;軟件工程中的時空藝術與實踐智慧-以蜻蜓hr人才系統舉例-優雅草卓伊凡 概念解析&#xff1a;時空維度的編程范式 在軟件開發的宇宙中&#xff0c;同步(Synchronous)與異步(Asynchronous)是兩種根本不同的執行模式&#xff0c;它們塑造了程序與時間和空間…

TF-IDF算法的代碼實踐應用——關鍵詞提取、文本分類、信息檢索

回顧&#xff1a;TF-IDF算法詳解與實踐總結 上一篇文章我們深入剖析了TF-IDF的原理與細節&#xff0c;但實踐才是檢驗真理的唯一標準&#xff01;今天&#xff0c;我們將從“紙上談兵”轉向“實戰演練”&#xff1a;通過純Python手寫實現與調用sklearn工具包兩種方式&#xff0…

前端面試寶典---事件循環面試題

瀏覽器進程模型與 JavaScript 執行機制 現代瀏覽器采用多進程架構&#xff0c;包含瀏覽器進程、渲染進程、網絡進程等多個核心進程。每個標簽頁會獨立創建一個渲染進程&#xff0c;負責頁面內容的解析、渲染和執行腳本代碼。 JavaScript 的單線程特性 JavaScript 采用單線程…