打卡day41

知識回顧

  1. 數據增強
  2. 卷積神經網絡定義的寫法
  3. batch歸一化:調整一個批次的分布,常用與圖像數據
  4. 特征圖:只有卷積操作輸出的才叫特征圖
  5. 調度器:直接修改基礎學習率

卷積操作常見流程如下:

1. 輸入 → 卷積層 → Batch歸一化層(可選) → 池化層 → 激活函數 → 下一層

  1. Flatten -> Dense (with Dropout,可選) -> Dense (Output)

作業:嘗試手動修改下不同的調度器和CNN的結構,觀察訓練的差異。

import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
import numpy as np# 設置中文字體支持
plt.rcParams["font.family"] = ["SimHei"]
plt.rcParams['axes.unicode_minus'] = False  # 解決負號顯示問題# 檢查GPU是否可用
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"使用設備: {device}")# 1. 數據預處理
# 訓練集:使用多種數據增強方法提高模型泛化能力
train_transform = transforms.Compose([# 隨機裁剪圖像,從原圖中隨機截取32x32大小的區域transforms.RandomCrop(32, padding=4),# 隨機水平翻轉圖像(概率0.5)transforms.RandomHorizontalFlip(),# 隨機顏色抖動:亮度、對比度、飽和度和色調隨機變化transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2, hue=0.1),# 隨機旋轉圖像(最大角度15度)transforms.RandomRotation(15),# 將PIL圖像或numpy數組轉換為張量transforms.ToTensor(),# 標準化處理:每個通道的均值和標準差,使數據分布更合理transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010))
])# 測試集:僅進行必要的標準化,保持數據原始特性,標準化不損失數據信息,可還原
test_transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010))
])# 2. 加載CIFAR-10數據集
train_dataset = datasets.CIFAR10(root='./data',train=True,download=True,transform=train_transform  # 使用增強后的預處理
)test_dataset = datasets.CIFAR10(root='./data',train=False,transform=test_transform  # 測試集不使用增強
)# 3. 創建數據加載器
batch_size = 64
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
# 4. 定義CNN模型的定義(替代原MLP)
class CNN(nn.Module):def __init__(self):super(CNN, self).__init__()  # 繼承父類初始化# ---------------------- 第一個卷積塊 ----------------------# 卷積層1:輸入3通道(RGB),輸出32個特征圖,卷積核3x3,邊緣填充1像素self.conv1 = nn.Conv2d(in_channels=3,       # 輸入通道數(圖像的RGB通道)out_channels=32,     # 輸出通道數(生成32個新特征圖)kernel_size=3,       # 卷積核尺寸(3x3像素)padding=1            # 邊緣填充1像素,保持輸出尺寸與輸入相同)# 批量歸一化層:對32個輸出通道進行歸一化,加速訓練self.bn1 = nn.BatchNorm2d(num_features=32)# ReLU激活函數:引入非線性,公式:max(0, x)self.relu1 = nn.ReLU()# 最大池化層:窗口2x2,步長2,特征圖尺寸減半(32x32→16x16)self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)  # stride默認等于kernel_size# ---------------------- 第二個卷積塊 ----------------------# 卷積層2:輸入32通道(來自conv1的輸出),輸出64通道self.conv2 = nn.Conv2d(in_channels=32,      # 輸入通道數(前一層的輸出通道數)out_channels=64,     # 輸出通道數(特征圖數量翻倍)kernel_size=3,       # 卷積核尺寸不變padding=1            # 保持尺寸:16x16→16x16(卷積后)→8x8(池化后))self.bn2 = nn.BatchNorm2d(num_features=64)self.relu2 = nn.ReLU()self.pool2 = nn.MaxPool2d(kernel_size=2)  # 尺寸減半:16x16→8x8# ---------------------- 第三個卷積塊 ----------------------# 卷積層3:輸入64通道,輸出128通道self.conv3 = nn.Conv2d(in_channels=64,      # 輸入通道數(前一層的輸出通道數)out_channels=128,    # 輸出通道數(特征圖數量再次翻倍)kernel_size=3,padding=1            # 保持尺寸:8x8→8x8(卷積后)→4x4(池化后))self.bn3 = nn.BatchNorm2d(num_features=128)self.relu3 = nn.ReLU()  # 復用激活函數對象(節省內存)self.pool3 = nn.MaxPool2d(kernel_size=2)  # 尺寸減半:8x8→4x4# ---------------------- 全連接層(分類器) ----------------------# 計算展平后的特征維度:128通道 × 4x4尺寸 = 128×16=2048維self.fc1 = nn.Linear(in_features=128 * 4 * 4,  # 輸入維度(卷積層輸出的特征數)out_features=512          # 輸出維度(隱藏層神經元數))# Dropout層:訓練時隨機丟棄50%神經元,防止過擬合self.dropout = nn.Dropout(p=0.5)# 輸出層:將512維特征映射到10個類別(CIFAR-10的類別數)self.fc2 = nn.Linear(in_features=512, out_features=10)def forward(self, x):# 輸入尺寸:[batch_size, 3, 32, 32](batch_size=批量大小,3=通道數,32x32=圖像尺寸)# ---------- 卷積塊1處理 ----------x = self.conv1(x)       # 卷積后尺寸:[batch_size, 32, 32, 32](padding=1保持尺寸)x = self.bn1(x)         # 批量歸一化,不改變尺寸x = self.relu1(x)       # 激活函數,不改變尺寸x = self.pool1(x)       # 池化后尺寸:[batch_size, 32, 16, 16](32→16是因為池化窗口2x2)# ---------- 卷積塊2處理 ----------x = self.conv2(x)       # 卷積后尺寸:[batch_size, 64, 16, 16](padding=1保持尺寸)x = self.bn2(x)x = self.relu2(x)x = self.pool2(x)       # 池化后尺寸:[batch_size, 64, 8, 8]# ---------- 卷積塊3處理 ----------x = self.conv3(x)       # 卷積后尺寸:[batch_size, 128, 8, 8](padding=1保持尺寸)x = self.bn3(x)x = self.relu3(x)x = self.pool3(x)       # 池化后尺寸:[batch_size, 128, 4, 4]# ---------- 展平與全連接層 ----------# 將多維特征圖展平為一維向量:[batch_size, 128*4*4] = [batch_size, 2048]x = x.view(-1, 128 * 4 * 4)  # -1自動計算批量維度,保持批量大小不變x = self.fc1(x)           # 全連接層:2048→512,尺寸變為[batch_size, 512]x = self.relu3(x)         # 激活函數(復用relu3,與卷積塊3共用)x = self.dropout(x)       # Dropout隨機丟棄神經元,不改變尺寸x = self.fc2(x)           # 全連接層:512→10,尺寸變為[batch_size, 10](未激活,直接輸出logits)return x  # 輸出未經過Softmax的logits,適用于交叉熵損失函數# 初始化模型
model = CNN()
#model = model.to(device)  # 將模型移至GPU(如果可用)
# 5. 定義損失函數和優化器
criterion = nn.CrossEntropyLoss()  # 交叉熵損失函數,適用于多分類任務
optimizer = optim.Adam(model.parameters(), lr=0.001)  # Adam優化器,學習率0.001
# 引入學習率調度器,在訓練過程中動態調整學習率--訓練初期使用較大的 LR 快速降低損失,訓練后期使用較小的 LR 更精細地逼近全局最優解。
# 在每個 epoch 結束后,需要手動調用調度器來更新學習率,可以在訓練過程中調用 scheduler.step()
scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer,        # 指定要控制的優化器(這里是Adam)mode='min',       # 監測的指標是"最小化"(如損失函數)patience=3,       # 如果連續3個epoch指標沒有改善,才降低LRfactor=0.5        # 降低LR的比例(新LR = 舊LR × 0.5)
)
# scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.1)  
# # 每5個epoch,LR = LR × 0.1  # scheduler = optim.lr_scheduler.MultiStepLR(optimizer, milestones=[10, 20, 30], gamma=0.5)  
# # 當epoch=10、20、30時,LR = LR × 0.5  # scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=10, eta_min=0.0001)  
# # LR在[0.0001, LR_initial]之間按余弦曲線變化,周期為2×T_max  
# 5. 訓練模型(記錄每個 iteration 的損失)
def train(model, train_loader, test_loader, criterion, optimizer, scheduler, device, epochs):model.train()  # 設置為訓練模式# 記錄每個 iteration 的損失all_iter_losses = []  # 存儲所有 batch 的損失iter_indices = []     # 存儲 iteration 序號# 記錄每個 epoch 的準確率和損失train_acc_history = []test_acc_history = []train_loss_history = []test_loss_history = []for epoch in range(epochs):running_loss = 0.0correct = 0total = 0for batch_idx, (data, target) in enumerate(train_loader):data, target = data.to(device), target.to(device)  # 移至GPUoptimizer.zero_grad()  # 梯度清零output = model(data)  # 前向傳播loss = criterion(output, target)  # 計算損失loss.backward()  # 反向傳播optimizer.step()  # 更新參數# 記錄當前 iteration 的損失iter_loss = loss.item()all_iter_losses.append(iter_loss)iter_indices.append(epoch * len(train_loader) + batch_idx + 1)# 統計準確率和損失running_loss += iter_loss_, predicted = output.max(1)total += target.size(0)correct += predicted.eq(target).sum().item()# 每100個批次打印一次訓練信息if (batch_idx + 1) % 100 == 0:print(f'Epoch: {epoch+1}/{epochs} | Batch: {batch_idx+1}/{len(train_loader)} 'f'| 單Batch損失: {iter_loss:.4f} | 累計平均損失: {running_loss/(batch_idx+1):.4f}')# 計算當前epoch的平均訓練損失和準確率epoch_train_loss = running_loss / len(train_loader)epoch_train_acc = 100. * correct / totaltrain_acc_history.append(epoch_train_acc)train_loss_history.append(epoch_train_loss)# 測試階段model.eval()  # 設置為評估模式test_loss = 0correct_test = 0total_test = 0with torch.no_grad():for data, target in test_loader:data, target = data.to(device), target.to(device)output = model(data)test_loss += criterion(output, target).item()_, predicted = output.max(1)total_test += target.size(0)correct_test += predicted.eq(target).sum().item()epoch_test_loss = test_loss / len(test_loader)epoch_test_acc = 100. * correct_test / total_testtest_acc_history.append(epoch_test_acc)test_loss_history.append(epoch_test_loss)# 更新學習率調度器scheduler.step(epoch_test_loss)print(f'Epoch {epoch+1}/{epochs} 完成 | 訓練準確率: {epoch_train_acc:.2f}% | 測試準確率: {epoch_test_acc:.2f}%')# 繪制所有 iteration 的損失曲線plot_iter_losses(all_iter_losses, iter_indices)# 繪制每個 epoch 的準確率和損失曲線plot_epoch_metrics(train_acc_history, test_acc_history, train_loss_history, test_loss_history)return epoch_test_acc  # 返回最終測試準確率# 6. 繪制每個 iteration 的損失曲線
def plot_iter_losses(losses, indices):plt.figure(figsize=(10, 4))plt.plot(indices, losses, 'b-', alpha=0.7, label='Iteration Loss')plt.xlabel('Iteration(Batch序號)')plt.ylabel('損失值')plt.title('每個 Iteration 的訓練損失')plt.legend()plt.grid(True)plt.tight_layout()plt.show()# 7. 繪制每個 epoch 的準確率和損失曲線
def plot_epoch_metrics(train_acc, test_acc, train_loss, test_loss):epochs = range(1, len(train_acc) + 1)plt.figure(figsize=(12, 4))# 繪制準確率曲線plt.subplot(1, 2, 1)plt.plot(epochs, train_acc, 'b-', label='訓練準確率')plt.plot(epochs, test_acc, 'r-', label='測試準確率')plt.xlabel('Epoch')plt.ylabel('準確率 (%)')plt.title('訓練和測試準確率')plt.legend()plt.grid(True)# 繪制損失曲線plt.subplot(1, 2, 2)plt.plot(epochs, train_loss, 'b-', label='訓練損失')plt.plot(epochs, test_loss, 'r-', label='測試損失')plt.xlabel('Epoch')plt.ylabel('損失值')plt.title('訓練和測試損失')plt.legend()plt.grid(True)plt.tight_layout()plt.show()# 8. 執行訓練和測試
epochs = 20  # 增加訓練輪次以獲得更好效果
print("開始使用CNN訓練模型...")
final_accuracy = train(model, train_loader, test_loader, criterion, optimizer, scheduler, device, epochs)
print(f"訓練完成!最終測試準確率: {final_accuracy:.2f}%")# # 保存模型
# torch.save(model.state_dict(), 'cifar10_cnn_model.pth')
# print("模型已保存為: cifar10_cnn_model.pth")

?@浙大疏錦行

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

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

相關文章

MySQL高級查詢技巧:分組、聚合、子查詢與分頁【MySQL系列】

本文將深入探討 MySQL 高級查詢技巧,重點講解 GROUP BY、HAVING、各種聚合函數、子查詢以及分頁查詢(LIMIT 語法)的使用。文章內容涵蓋實際應用中最常見的報表需求和分頁實現技巧,適合有一定 SQL 基礎的開發者進一步提升技能。 一…

現代 CSS 高階技巧:實現平滑內凹圓角的工程化實踐

通過 數學計算 CSS mask 復合遮罩 實現的真正幾何內凹效果: 背景是一張圖片,用來證明中間的凹陷是透明的。 完整代碼: app.js import FormPage from "./pages/formPage"; import "./App.css"; const App () > {re…

Qt不同布局添加不同控件

對于這種 不同布局添加不同控件 的情況,可以采用以下幾種簡化方法: 方法 1:使用 std::pair 或 std::tuple 配對(C++17 推薦) for (auto [layout, widget] : {std::pair{m_layoutMistakeCalibrate,

MySQL 事務解析

1. 事務簡介 事務(Transaction) 是一組操作的集合,它是一個不可分割的工作單位,事務會把所有的操作作為一個整體一起向系統提交或撤銷操作請求,即這些操作要么同時成功,要么同時失敗。 經典案例&#xff1…

PyTorch中 torch.utils.data.DataLoader 的詳細解析和讀取點云數據示例

一、DataLoader 是什么? torch.utils.data.DataLoader 是 PyTorch 中用于加載數據的核心接口,它支持: 批量讀取(batch)數據打亂(shuffle)多線程并行加載(num_workers)自…

在MDK中自動部署LVGL,在stm32f407ZGT6移植LVGL-8.4,運行demo,顯示label

在MDK中自動部署LVGL,在stm32f407ZGT6移植LVGL-8.4 一、硬件平臺二、實現功能三、移植步驟1、下載LVGL-8.42、MDK中安裝LVGL-8.43、配置RTE4、配置頭文件 lv_conf_cmsis.h5、配置lv_port_disp_template 四、添加心跳相關文件1、在STM32CubeMX中配置TIM7的參數2、使能…

德思特新聞 | 德思特與es:saar正式建立合作伙伴關系

德思特新聞 2025年5月9日,德思特科技有限公司(以下簡稱“德思特”)與德國嵌入式系統專家es:saar GmbH正式達成合作伙伴關系。此次合作旨在將 es:saar 的先進嵌入式開發與測試工具引入中國及亞太市場,助力本地客戶提升產品開發效率…

fork函數小解

學了好久終于搞懂fork函數的一些作用 1. fork函數作用:用于創建新的子進程 這是fork最根本的功能,在父進程里創建新的子進程、 但是創建新的子進程之后呢? 子進程和父進程的關系是什么樣的? 為什么fork得到的子進程返回值為0&am…

opencv(C++) 變換圖像與形態學操作

文章目錄 使用腐蝕和膨脹圖像形態濾波器實現案例使用形態學濾波器對圖像進行開運算和閉運算實現案例在灰度圖像上應用形態學操作算子形態學梯度(Morphological Gradient)黑帽變換(Black-hat Transform)使用分水嶺算法進行圖像分割使用 MSER 提取顯著區域MSER 檢測與可視化使…

測試工程師學LangChain之promptTemplate 實戰筆記

一、引言:大模型時代的測試自動化革命 2025 年,隨著大模型(如 DeepSeek)在自動化測試領域的廣泛應用,Prompt 編寫已成為測試工程師的核心技能之一。 為什么? 大模型輸出的質量 90% 取決于輸入的 PromptLangChain 的 PromptTemplate 提供了參數化 Prompt 的標準化方案Ope…

CP2K 軟件介紹與使用指南

CP2K 軟件介紹與使用指南 一、CP2K簡介 CP2K是一款開源的量子化學和固態物理模擬軟件包,主要用于原子尺度模擬,特別擅長以下領域: 第一性原理計算:基于密度泛函理論(DFT)的電子結構計算分子動力學(MD):包括從頭算分…

npm、pnpm、yarn使用以及區別

npm 使用 安裝包&#xff1a;在項目目錄下&#xff0c;npm install <包名> 用于本地安裝包到 node_modules 目錄&#xff0c;并添加到 package.json 的 dependencies 中&#xff1b;npm install -g <包名> 用于全局安裝&#xff0c;適用于命令行工具等。初始化項目…

2025年北京市職工職業技能大賽第六屆信息通信行業網絡安全技能大賽復賽CTF部分WP-哥斯拉流量分析

2025年北京市職工職業技能大賽第六屆信息通信行業網絡安全技能大賽復賽CTF部分WP-哥斯拉流量分析 一、流量分析 題目沒有任何提示,附件gzl.pcap 解題哥斯拉流量300多KB包很多,沒啥經驗只能挨個看回來之后又狠狠得擼了一把哥斯拉流量分析我這里用的是哥斯拉4.0.1 測試鏈接…

GitLab 18.0 正式發布,15.0 將不再受技術支持,須升級【六】

GitLab 是一個全球知名的一體化 DevOps 平臺&#xff0c;很多人都通過私有化部署 GitLab 來進行源代碼托管。極狐GitLab 是 GitLab 在中國的發行版&#xff0c;專門為中國程序員服務。可以一鍵式部署極狐GitLab。 學習極狐GitLab 的相關資料&#xff1a; 極狐GitLab 官網極狐…

React 項目中封裝 Excel 導入導出組件:技術分享與實踐

文章目錄 前言一、為什么需要封裝 Excel 組件&#xff1f;二、技術選型三、核心實現1. 安裝依賴2. 封裝Excel導出3. 封裝導入組件 &#xff08;UploadExcel&#xff09; 總結 前言 在 React 項目中&#xff0c;處理 Excel 文件的導入和導出是常見的業務需求。無論是導出報表數…

RustDesk 搭建自建服務器并設置服務自啟動

目錄 0. 介紹 1. 事前準備 1.1 有公網 ip 的云服務器一臺 1.2 服務端部署包 1.3 客戶端安裝包 2. 部署 2.1 服務器環境準備 2.2 上傳服務端部署包 2.3 運行 pm2 3. 客戶端使用 3.1 安裝 3.2 配置 3.2.1 解鎖網絡設置 3.2.2 ID / 中級服務器 3.3 啟動效果 > …

基于Qt封裝數據庫基本增刪改查操作,支持多線程,并實現SQLite數據庫單例訪問

抽出來的&#xff0c;直接用就行 頭文件CPP文件使用示例 頭文件 #ifndef DATABASECOMMON_H #define DATABASECOMMON_H/** 單例封裝SQLite通用操作&#xff0c;支持多線程調用&#xff1b;可擴展兼容其他數據庫&#xff0c;照著SysRunDatabase寫&#xff0c;并且重載openDataba…

AI筆記 - 網絡模型 - mobileNet

網絡模型 mobileNet mobileNet V1網絡結構深度可分離卷積空間可分![在這里插入圖片描述](https://i-blog.csdnimg.cn/direct/aff06377feac40b787cfc882be7c6e5d.png) 參考 mobileNet V1 網絡結構 MobileNetV1可以理解為VGG中的標準卷積層換成深度可分離卷積 可分離卷積主要有…

第十五篇:MySQL 高級實戰項目:構建高可用、可觀測、性能優化一體化數據庫平臺

本篇聚焦于如何基于 MySQL 構建一個真正面向生產環境的數據庫平臺&#xff0c;集成高可用、可觀測與性能調優三大核心能力&#xff0c;助力穩定、可擴展的系統運行。 一、項目背景與目標 在實際生產環境中&#xff0c;數據庫系統需要應對以下挑戰&#xff1a; 業務高速增長帶來…

華為OD機試真題——文件目錄大小(2025 A卷:100分)Java/python/JavaScript/C++/C語言/GO六種語言最佳實現

2025 A卷 100分 題型 本文涵蓋詳細的問題分析、解題思路、代碼實現、代碼詳解、測試用例以及綜合分析; 并提供Java、python、JavaScript、C++、C語言、GO六種語言的最佳實現方式! 2025華為OD真題目錄+全流程解析/備考攻略/經驗分享 華為OD機試真題《文件目錄大小》: 目錄 題…