python訓練day44 預訓練模型

預訓練模型發展史

預訓練模型的訓練策略

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# 設置中文字體支持
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([transforms.RandomCrop(32, padding=4),transforms.RandomHorizontalFlip(),transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2, hue=0.1),transforms.RandomRotation(15),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)
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. 訓練函數(支持學習率調度器)
def train(model, train_loader, test_loader, criterion, optimizer, scheduler, device, epochs):model.train()  # 設置為訓練模式train_loss_history = []test_loss_history = []train_acc_history = []test_acc_history = []all_iter_losses = []iter_indices = []for epoch in range(epochs):running_loss = 0.0correct_train = 0total_train = 0for batch_idx, (data, target) in enumerate(train_loader):data, target = data.to(device), target.to(device)optimizer.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_train += target.size(0)correct_train += 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}")# 計算 epoch 級指標epoch_train_loss = running_loss / len(train_loader)epoch_train_acc = 100. * correct_train / total_train# 測試階段model.eval()correct_test = 0total_test = 0test_loss = 0.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_test# 記錄歷史數據train_loss_history.append(epoch_train_loss)test_loss_history.append(epoch_test_loss)train_acc_history.append(epoch_train_acc)test_acc_history.append(epoch_test_acc)# 更新學習率調度器if scheduler is not None:scheduler.step(epoch_test_loss)# 打印 epoch 結果print(f"Epoch {epoch+1} 完成 | 訓練損失: {epoch_train_loss:.4f} "f"| 訓練準確率: {epoch_train_acc:.2f}% | 測試準確率: {epoch_test_acc:.2f}%")# 繪制損失和準確率曲線plot_iter_losses(all_iter_losses, iter_indices)plot_epoch_metrics(train_acc_history, test_acc_history, train_loss_history, test_loss_history)return epoch_test_acc  # 返回最終測試準確率# 5. 繪制Iteration損失曲線
def plot_iter_losses(losses, indices):plt.figure(figsize=(10, 4))plt.plot(indices, losses, 'b-', alpha=0.7)plt.xlabel('Iteration(Batch序號)')plt.ylabel('損失值')plt.title('訓練過程中的Iteration損失變化')plt.grid(True)plt.show()# 6. 繪制Epoch級指標曲線
def plot_epoch_metrics(train_acc, test_acc, train_loss, test_loss):epochs = range(1, len(train_acc) + 1)plt.figure(figsize=(12, 5))# 準確率曲線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('準確率隨Epoch變化')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('損失值隨Epoch變化')plt.legend()plt.grid(True)plt.tight_layout()plt.show()# 導入ResNet模型
from torchvision.models import resnet18# 定義ResNet18模型(支持預訓練權重加載)
def create_resnet18(pretrained=True, num_classes=10):# 加載預訓練模型(ImageNet權重)model = resnet18(pretrained=pretrained)# 修改最后一層全連接層,適配CIFAR-10的10分類任務in_features = model.fc.in_featuresmodel.fc = nn.Linear(in_features, num_classes)# 將模型轉移到指定設備(CPU/GPU)model = model.to(device)return model# 創建ResNet18模型(加載ImageNet預訓練權重,不進行微調)
model = create_resnet18(pretrained=True, num_classes=10)
model.eval()  # 設置為推理模式# 測試單張圖片(示例)
from torchvision import utils# 從測試數據集中獲取一張圖片
dataiter = iter(test_loader)
images, labels = dataiter.next()
images = images[:1].to(device)  # 取第1張圖片# 前向傳播
with torch.no_grad():outputs = model(images)_, predicted = torch.max(outputs.data, 1)# 顯示圖片和預測結果
plt.imshow(utils.make_grid(images.cpu(), normalize=True).permute(1, 2, 0))
plt.title(f"預測類別: {predicted.item()}")
plt.axis('off')
plt.show()
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms, models
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
import os# 設置中文字體支持
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([transforms.RandomCrop(32, padding=4),transforms.RandomHorizontalFlip(),transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2, hue=0.1),transforms.RandomRotation(15),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. 定義ResNet18模型
def create_resnet18(pretrained=True, num_classes=10):model = models.resnet18(pretrained=pretrained)# 修改最后一層全連接層in_features = model.fc.in_featuresmodel.fc = nn.Linear(in_features, num_classes)return model.to(device)# 5. 凍結/解凍模型層的函數
def freeze_model(model, freeze=True):"""凍結或解凍模型的卷積層參數"""# 凍結/解凍除fc層外的所有參數for name, param in model.named_parameters():if 'fc' not in name:param.requires_grad = not freeze# 打印凍結狀態frozen_params = sum(p.numel() for p in model.parameters() if not p.requires_grad)total_params = sum(p.numel() for p in model.parameters())if freeze:print(f"已凍結模型卷積層參數 ({frozen_params}/{total_params} 參數)")else:print(f"已解凍模型所有參數 ({total_params}/{total_params} 參數可訓練)")return model# 6. 訓練函數(支持階段式訓練)
def train_with_freeze_schedule(model, train_loader, test_loader, criterion, optimizer, scheduler, device, epochs, freeze_epochs=5):"""前freeze_epochs輪凍結卷積層,之后解凍所有層進行訓練"""train_loss_history = []test_loss_history = []train_acc_history = []test_acc_history = []all_iter_losses = []iter_indices = []# 初始凍結卷積層if freeze_epochs > 0:model = freeze_model(model, freeze=True)for epoch in range(epochs):# 解凍控制:在指定輪次后解凍所有層if epoch == freeze_epochs:model = freeze_model(model, freeze=False)# 解凍后調整優化器(可選)optimizer.param_groups[0]['lr'] = 1e-4  # 降低學習率防止過擬合model.train()  # 設置為訓練模式running_loss = 0.0correct_train = 0total_train = 0for batch_idx, (data, target) in enumerate(train_loader):data, target = data.to(device), target.to(device)optimizer.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_train += target.size(0)correct_train += 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}")# 計算 epoch 級指標epoch_train_loss = running_loss / len(train_loader)epoch_train_acc = 100. * correct_train / total_train# 測試階段model.eval()correct_test = 0total_test = 0test_loss = 0.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_test# 記錄歷史數據train_loss_history.append(epoch_train_loss)test_loss_history.append(epoch_test_loss)train_acc_history.append(epoch_train_acc)test_acc_history.append(epoch_test_acc)# 更新學習率調度器if scheduler is not None:scheduler.step(epoch_test_loss)# 打印 epoch 結果print(f"Epoch {epoch+1} 完成 | 訓練損失: {epoch_train_loss:.4f} "f"| 訓練準確率: {epoch_train_acc:.2f}% | 測試準確率: {epoch_test_acc:.2f}%")# 繪制損失和準確率曲線plot_iter_losses(all_iter_losses, iter_indices)plot_epoch_metrics(train_acc_history, test_acc_history, train_loss_history, test_loss_history)return epoch_test_acc  # 返回最終測試準確率# 7. 繪制Iteration損失曲線
def plot_iter_losses(losses, indices):plt.figure(figsize=(10, 4))plt.plot(indices, losses, 'b-', alpha=0.7)plt.xlabel('Iteration(Batch序號)')plt.ylabel('損失值')plt.title('訓練過程中的Iteration損失變化')plt.grid(True)plt.show()# 8. 繪制Epoch級指標曲線
def plot_epoch_metrics(train_acc, test_acc, train_loss, test_loss):epochs = range(1, len(train_acc) + 1)plt.figure(figsize=(12, 5))# 準確率曲線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('準確率隨Epoch變化')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('損失值隨Epoch變化')plt.legend()plt.grid(True)plt.tight_layout()plt.show()# 主函數:訓練模型
def main():# 參數設置epochs = 40  # 總訓練輪次freeze_epochs = 5  # 凍結卷積層的輪次learning_rate = 1e-3  # 初始學習率weight_decay = 1e-4  # 權重衰減# 創建ResNet18模型(加載預訓練權重)model = create_resnet18(pretrained=True, num_classes=10)# 定義優化器和損失函數optimizer = optim.Adam(model.parameters(), lr=learning_rate, weight_decay=weight_decay)criterion = nn.CrossEntropyLoss()# 定義學習率調度器scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.5, patience=2, verbose=True)# 開始訓練(前5輪凍結卷積層,之后解凍)final_accuracy = train_with_freeze_schedule(model=model,train_loader=train_loader,test_loader=test_loader,criterion=criterion,optimizer=optimizer,scheduler=scheduler,device=device,epochs=epochs,freeze_epochs=freeze_epochs)print(f"訓練完成!最終測試準確率: {final_accuracy:.2f}%")# # 保存模型# torch.save(model.state_dict(), 'resnet18_cifar10_finetuned.pth')# print("模型已保存至: resnet18_cifar10_finetuned.pth")if __name__ == "__main__":main()

@浙大疏錦行

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

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

相關文章

[論文閱讀]MISSRce

論文title: MISSRec: Pre-training and Transferring Multi-modal Interest-aware Sequence Representation for Recommendation

Redis學習筆記——黑馬點評 附近商鋪到UV統計 完結

前言: 今天完結了Redis的所有實戰篇。 學習收獲: GEO數據結構: GEO就是Geolocation的簡寫形式,代表地理坐標。Redis在3.2版本中加入對Geo的支持,存儲、管理和操作地理空間數據的特殊數據結構,它能高效處…

【客戶端排查】mac電腦怎么查看客戶端的實時運行日志

先退出客戶端;打開訪達里的應用程序; 打開【顯示包內容】; 找到MacOS 雙擊里面的終端程序; 雙擊后,客戶端會自動啟動,且可以在終端中查看客戶端的實時日志啦~

HarmonyOS NEXT倉頡開發語言實戰案例:健身App

各位好,今日分享一個健身app的首頁: 這個頁面看起比之前的案例要稍微復雜一些,主要在于頂部部分,有重疊的背景,還有偏移的部分。重疊布局可以使用Stack容器實現,超出容器范圍的偏移可以使用負數間距來實現&…

TreeMap源碼分析 紅黑樹

今天嘗試刨一下TreeMap的祖墳。 底層結構對比 先來看一下與HashMap、LinkedHashMap和TreeMap的對比,同時就當是復習一下: HashMap使用數組存儲數據,并使用單向鏈表結構存儲hash沖突數據,同一個沖突桶中數據量大的時候&#xff…

華為云Flexus+DeepSeek征文|基于Dify構建拍照識題智能學習助手

華為云FlexusDeepSeek征文|基于Dify構建拍照識題智能學習助手 一、構建拍照識題智能學習助手前言二、構建拍照識題智能學習助手環境2.1 基于FlexusX實例的Dify平臺2.2 基于MaaS的模型API商用服務 三、構建拍照識題智能學習助手實戰3.1 配置Dify環境3.2 配置Dify工具…

題解:CF2120E Lanes of Cars

根據貪心,不難想到每次會把最長隊伍末尾的那輛車移動到最短隊伍的末尾。但由于 k k k 的存在,會導致一些冗余移動的存在。設需要挪動 C C C 輛車,則怒氣值可以表示為 f ( C ) k C f(C) kC f(C)kC,其中 f ( C ) f(C) f(C) 是…

Excel基礎:選擇和移動

本文演示Excel中基礎的選擇和移動操作,并在最后提供了一張思維導圖,方便記憶。 文章目錄 一、選擇1.1 基礎選擇1.1.1 選擇單個單元格1.1.2 選擇連續范圍 1.2 行列選擇1.2.1 選擇整行整列1.2.2 選擇多行多列 1.3 全選1.3.1 全選所有單元格1.3.2 智能選擇…

Java面試寶典:基礎四

80. int vs Integer 維度intInteger類型基本數據類型(8種之一)包裝類默認值0null應用場景性能敏感場景(計算密集)Web表單、ORM框架(區分null和0)特殊能力無提供工具方法(如parseInt())和常量(如MAX_VALUE)示例:

RabbitMQ + JMeter 深度集成指南:中間件性能優化全流程解析!

在 2025 年的數字化浪潮中,中間件性能直接決定系統的穩定性和用戶體驗,而 RabbitMQ 作為消息隊列的“老大哥”,在分布式系統中扮演著關鍵角色。然而,高并發場景下,消息堆積、延遲激增等問題可能讓系統不堪重負&#xf…

uniapp image引用本地圖片不顯示問題

1. uniapp image引用本地圖片不顯示問題 在uniapp 開發過程中采用image引入本地資源圖片。 1.1. 相對路徑和絕對路徑問題 在UniApp中開發微信小程序時,引入圖片時,相對路徑和絕對路徑可能會有一些差異。這差異主要涉及到小程序和UniApp框架的文件結構、…

論文閱讀:arxiv 2025 ThinkSwitcher: When to Think Hard, When to Think Fast

總目錄 大模型安全相關研究:https://blog.csdn.net/WhiffeYF/article/details/142132328 ThinkSwitcher: When to Think Hard, When to Think Fast https://arxiv.org/pdf/2505.14183#page2.08 https://www.doubao.com/chat/10031179784579842 文章目錄 速覽一、…

智能體記憶原理-prompt設計

智能體記憶的管理與設計開發分為以下幾步: 1.記憶的抽取; 2.記憶的存儲; 3.記憶的搜索; 一、記憶抽取一: FACT_RETRIEVAL_PROMPT f"""你是一位個人信息整理助手,專門負責準確存儲事實、用…

026 在線文檔管理系統技術架構解析:基于 Spring Boot 的企業級文檔管理平臺

在線文檔管理系統技術架構解析:基于Spring Boot的企業級文檔管理平臺 在企業數字化轉型的進程中,高效的文檔管理系統已成為提升協作效率的核心基礎設施。本文將深入解析基于Spring Boot框架構建的在線文檔管理系統,該系統整合公告信息管理、…

AWTK-MVVM的一些使用技巧總結(1)

在項目中用了一段時間的AWTK-MVVM框架,由于AWTK-MVVM本身的文檔十分欠缺,自己經過一段時間的研究折騰出了幾個技巧,在此記錄總結。 用fscript啟用傳統UI代碼 AWTK-MVVM里面重新設計了navigator機制,重定位了navigator_to的調用方…

openwrt使用quilt工具制作補丁

前言:簡單聊一下為什么需要制作補丁,因為openwrt的編譯是去下載很多組件放到dl目錄下面,這些組件都是壓縮包。如果我們要修改這些組件里面的源碼,就需要對這些組件打pacth,也就是把我們的差異點在編譯的時候合入到對應…

強化學習 (1)基本概念

grid-world example 一個由多個格子組成的二維網格 三種格子:accessible可通行的; forbidden禁止通行的; target目標 state狀態 state是智能體相對于環境的狀態(情況) 在grid-world example里,state指的…

【Typst】縱向時間軸

概述 6月10日實驗了一個縱向時間軸排版效果,當時沒有做成單獨的模塊,也存在一些Bug。 今天(6月29日)在原基礎上進行了一些改進,并總結為模塊。 目前暫時發布出來,可用,后續可能會進行大改。 使用案例 導入模塊使用…

【Visual Studio Code上傳文件到服務器】

在 Visual Studio Code (VS Code) 中上傳文件到 Linux 系統主要通過 SSH 協議實現,結合圖形界面(GUI)或命令行工具操作。以下是具體說明及進度查看、斷點續傳的實現方法: ?? 一、VS Code 上傳文件到 Linux 的機制 SSH 遠程連接 …

手機控車一鍵啟動汽車智能鑰匙

手機一鍵啟動車輛的方法 手機一鍵啟動車輛是一種便捷的汽車啟動方式,它通過智能手機應用程序實現對車輛的遠程控制。以下是詳細的步驟: 完成必要的認證與激活步驟。打開手機上的相關移動管家手機控車APP,并與車載藍牙建立連接。在APP的主界面…