欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Pytorch框架構(gòu)建ResNet模型的實(shí)現(xiàn)示例

 更新時(shí)間:2024年06月25日 10:10:04   作者:88conch  
本文主要介紹了Pytorch框架構(gòu)建ResNet模型的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

一、訓(xùn)練模型

1.導(dǎo)入資源包

import torch.optim as optim: 導(dǎo)入PyTorch的優(yōu)化工具包,其中包括了各種優(yōu)化算法,如SGD、Adam等。
import torchvision.transforms as transforms: 導(dǎo)入PyTorch的視覺(jué)變換工具包,用于對(duì)圖像進(jìn)行預(yù)處理和變換,如調(diào)整大小、裁剪、歸一化等。
from torchvision import models: 從torchvision模塊中導(dǎo)入預(yù)訓(xùn)練的模型,如ResNet、AlexNet、VGG等。

from sched import scheduler
import torch.optim as optim
import torch
import torch.nn as nn
import torch.utils.data
import torchvision.transforms as transforms
import torchvision.datasets as datasets
from torch.utils.data import DataLoader
import torch.optim.lr_scheduler as lr_scheduler
import os
from torchvision import models

2.定義數(shù)據(jù)預(yù)處理

這些預(yù)處理操作的目的是為了增強(qiáng)模型的泛化能力,并確保模型在訓(xùn)練和驗(yàn)證時(shí)輸入數(shù)據(jù)的格式一致。通過(guò)這些操作,模型能夠接受不同尺寸、角度和方向的圖像,從而提高其在實(shí)際應(yīng)用中的表現(xiàn)。同時(shí),歸一化處理有助于穩(wěn)定訓(xùn)練過(guò)程,加速模型收斂。,這些預(yù)處理操作的目的是為了增強(qiáng)模型的泛化能力,并確保模型在訓(xùn)練和驗(yàn)證時(shí)輸入數(shù)據(jù)的格式一致。通過(guò)這些操作,模型能夠接受不同尺寸、角度和方向的圖像,從而提高其在實(shí)際應(yīng)用中的表現(xiàn)。同時(shí),歸一化處理有助于穩(wěn)定訓(xùn)練過(guò)程,加速模型收斂。

# 定義數(shù)據(jù)預(yù)處理
transform = {
    'train': transforms.Compose([
        transforms.RandomResizedCrop(size=256, scale=(0.8, 1.0)),
        transforms.RandomRotation(degrees=15),
        transforms.RandomHorizontalFlip(),
        transforms.CenterCrop(size=224),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406],
                             [0.229, 0.224, 0.225])
    ]),
    'val': transforms.Compose([
        transforms.Resize(size=256),
        transforms.CenterCrop(size=224),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406],
                             [0.229, 0.224, 0.225])
    ])
}

3.讀取數(shù)據(jù)

# 讀取數(shù)據(jù)
dataset = './dataset'
train_directory = os.path.join(dataset, 'train')
valid_directory = os.path.join(dataset, 'val')

batch_size = 32
num_classes = 2  # 修改為您的分類數(shù)

data = {
    'train': datasets.ImageFolder(root=train_directory, transform=transform['train']),
    'val': datasets.ImageFolder(root=valid_directory, transform=transform['val'])
}

train_loader = DataLoader(data['train'], batch_size=batch_size, shuffle=True, num_workers=8)
test_loader = DataLoader(data['val'], batch_size=batch_size, shuffle=False, num_workers=8)

注:這段代碼的主要目的是讀取和準(zhǔn)備圖像數(shù)據(jù)集,以便用于訓(xùn)練和驗(yàn)證深度學(xué)習(xí)模型,這段代碼設(shè)置了數(shù)據(jù)加載器,它們將在訓(xùn)練和驗(yàn)證過(guò)程中提供經(jīng)過(guò)預(yù)處理的圖像數(shù)據(jù)。這些數(shù)據(jù)加載器是PyTorch中用于批量加載數(shù)據(jù)并使其易于迭代的重要工具。

二、定義卷積神經(jīng)網(wǎng)絡(luò)

1.導(dǎo)入必要的庫(kù)

from torch.autograd import Variable: 從torch.autograd模塊中導(dǎo)入Variable類。Variable是PyTorch中自動(dòng)微分的關(guān)鍵類,它封裝了張量,并提供了自動(dòng)計(jì)算梯度等功能。然而,從PyTorch 0.4版本開(kāi)始,Variable已經(jīng)被整合到torch.Tensor中,因此不再需要顯式地從torch.autograd中導(dǎo)入Variable。在最新的PyTorch版本中,直接使用torch.Tensor即可,它繼承了Variable的所有功能。

# 神經(jīng)網(wǎng)絡(luò)
import torch
import torch.nn as nn
from torch.autograd import Variable

2.定義名為convolutional_block的卷積塊類

這個(gè)convolutional_block類定義了一個(gè)卷積塊,它將輸入張量通過(guò)兩個(gè)并行路徑(step1和step2),然后將它們的結(jié)果相加,并應(yīng)用ReLU激活函數(shù)。這種結(jié)構(gòu)通常用于殘差網(wǎng)絡(luò)(ResNet)中,有助于解決深度網(wǎng)絡(luò)訓(xùn)練過(guò)程中的梯度消失問(wèn)題。

class convolutional_block(nn.Module):#convolutional_block層
    def __init__(self,cn_input,cn_middle,cn_output,s=2):
        super(convolutional_block,self).__init__()
        self.step1=nn.Sequential(nn.Conv2d(cn_input,cn_middle,(1,1),(s,s),padding=0,bias=False),nn.BatchNorm2d(cn_middle,affine=False),nn.ReLU(inplace=True),
                            nn.Conv2d(cn_middle,cn_middle,(3,3),(1,1),padding=(1,1),bias=False),nn.BatchNorm2d(cn_middle,affine=False),nn.ReLU(inplace=True),
                            nn.Conv2d(cn_middle,cn_output,(1,1),(1,1),padding=0,bias=False),nn.BatchNorm2d(cn_output,affine=False))
        self.step2=nn.Sequential(nn.Conv2d(cn_input,cn_output,(1,1),(s,s),padding=0,bias=False),nn.BatchNorm2d(cn_output,affine=False))
        self.relu=nn.ReLU(inplace=True)
        
    def forward(self,x):
        x_tmp=x
        x=self.step1(x)
        x_tmp=self.step2(x_tmp)
        x=x+x_tmp
        x=self.relu(x)
        return x

3.定義了一個(gè)名為identity_block的恒等塊類

定義了一個(gè)名為identity_block的恒等塊類,它也是nn.Module的子類。這個(gè)類實(shí)現(xiàn)了一個(gè)恒等塊的構(gòu)造和前向傳播過(guò)程,它通常用于深度卷積神經(jīng)網(wǎng)絡(luò)(CNN)中,特別是在殘差網(wǎng)絡(luò)(ResNet)結(jié)構(gòu)中。恒等塊的主要特點(diǎn)是輸入和輸出之間有一個(gè)直接的聯(lián)系(即殘差連接),這有助于解決深度網(wǎng)絡(luò)訓(xùn)練過(guò)程中的梯度消失問(wèn)題。

class identity_block(nn.Module):#identity_block層
def __init__(self,cn,cn_middle):
super(identity_block,self).__init__()
self.step=nn.Sequential(nn.Conv2d(cn,cn_middle,(1,1),(1,1),padding=0,bias=False),nn.BatchNorm2d(cn_middle,affine=False),nn.ReLU(inplace=True),
nn.Conv2d(cn_middle,cn_middle,(3,3),(1,1),padding=1,bias=False),nn.BatchNorm2d(cn_middle,affine=False),nn.ReLU(inplace=True),
nn.Conv2d(cn_middle,cn,(1,1),(1,1),padding=0,bias=False),nn.BatchNorm2d(cn,affine=False))
self.relu=nn.ReLU(inplace=True)
def forward(self,x):
x_tmp=x
x=self.step(x)
x=x+x_tmp
x=self.relu(x)
return x

4.定義了一個(gè)名為Resnet的深度卷積神經(jīng)網(wǎng)絡(luò)類

class Resnet(nn.Module):#主層
def __init__(self,c_block,i_block):
super(Resnet,self).__init__()
self.conv=nn.Sequential(nn.Conv2d(3,64,(7,7),(2,2),padding=(3,3),bias=False),nn.BatchNorm2d(64,affine=False),nn.ReLU(inplace=True),nn.MaxPool2d((3,3),2,1))      
self.layer1=c_block(64,64,256,1)
self.layer2=i_block(256,64)
self.layer3=c_block(256,128,512)
self.layer4=i_block(512,128)
self.layer5=c_block(512,256,1024)
self.layer6=i_block(1024,256)
self.layer7=c_block(1024,512,2048)
self.layer8=i_block(2048,512)
self.out=nn.Linear(2048,2,bias=False)
self.avgpool=nn.AvgPool2d(7,7)


def forward(self,input):
x=self.conv(input)
x=self.layer1(x)
for i in range(2):            
x=self.layer2(x)
x=self.layer3(x)
for i in range(3):
x=self.layer4(x)
x=self.layer5(x)
for i in range(5):
x=self.layer6(x)
x=self.layer7(x)
for i in range(2):
x=self.layer8(x)


x=self.avgpool(x)
x=x.view(x.size(0),-1)
output=self.out(x)
return output

net=Resnet(convolutional_block,identity_block).cuda()

注:這段代碼定義了一個(gè)ResNet結(jié)構(gòu)的深度學(xué)習(xí)模型,它可以用于圖像分類任務(wù)。模型的結(jié)構(gòu)是模塊化的,可以通過(guò)調(diào)整卷積塊和恒等塊的數(shù)量和配置來(lái)適應(yīng)不同的需求和數(shù)據(jù)集。最后,模型被移動(dòng)到GPU上以加速訓(xùn)練和推理過(guò)程。

三、創(chuàng)建模型

1. 檢查GPU設(shè)備

如果 GPU 可用,則定義一個(gè) torch.device 對(duì)象,表示使用 GPU。如果 GPU 不可用,則定義一個(gè) torch.device 對(duì)象,表示使用 CPU。

以下是函數(shù)的詳細(xì)步驟:
1)檢查 GPU 可用性:

  • if torch.cuda.is_available(): 這行代碼檢查是否有可用的 GPU 設(shè)備。

  • device = torch.device(‘cuda’): 如果 GPU 可用,則定義一個(gè) torch.device 對(duì)象,表示使用 GPU。

  • print(“CUDA is available! Using GPU for training.”): 打印一條消息,表示 CUDA
    可用,并且使用 GPU 進(jìn)行訓(xùn)練。

  • else: 如果 GPU 不可用,則執(zhí)行以下代碼。

2)使用 CPU 進(jìn)行訓(xùn)練:

  • evice = torch.device(‘cpu’): 定義一個(gè) torch.device 對(duì)象,表示使用 CPU。
  • print(“CUDA is not available. Using CPU for training.”): 打印一條消息,表示 CUDA 不可用,并且使用 CPU 進(jìn)行訓(xùn)練。
# 首先,檢查是否有可用的 GPU
if torch.cuda.is_available():
    # 定義 GPU 設(shè)備
    device = torch.device('cuda')
    print("CUDA is available! Using GPU for training.")
else:
    # 如果沒(méi)有可用的 GPU,則使用 CPU
    device = torch.device('cpu')
    print("CUDA is not available. Using CPU for training.")

2. 訓(xùn)練過(guò)程

如果 GPU 可用,將模型移動(dòng)到 GPU 上,并使用 GPU 進(jìn)行訓(xùn)練;如果 GPU 不可用,則使用 CPU 進(jìn)行訓(xùn)練。

3)將模型移動(dòng)到 GPU:

  • model.to(device): 將模型移動(dòng)到之前定義的 device 對(duì)象所表示的設(shè)備上。如果 device 是 ‘cuda’,則模型將被移動(dòng)到 GPU;如果 device 是 ‘cpu’,則模型將被移動(dòng)到 CPU。

4)定義損失函數(shù):

  • criterion = nn.CrossEntropyLoss(): 定義交叉熵?fù)p失函數(shù),這是用于分類問(wèn)題的常見(jiàn)損失函數(shù)。

5)創(chuàng)建優(yōu)化器:

  • optimizer = optim.Adam(Alex_model.parameters(), lr=0.001, weight_decay=1e-4): 創(chuàng)建Adam 優(yōu)化器,其中 lr=0.001 表示學(xué)習(xí)率為 0.001,weight_decay=1e-4 表示權(quán)重衰減為 0.0001。
# 將模型移動(dòng)到 GPU
model.to(device)

# 定義損失函數(shù)
criterion = nn.CrossEntropyLoss()

# 創(chuàng)建優(yōu)化器
optimizer = optim.Adam(Alex_model.parameters(), lr=0.001, weight_decay=1e-4)

運(yùn)行結(jié)果:

在這里插入圖片描述

四、訓(xùn)練模型

1. 設(shè)置模型為訓(xùn)練模式

這個(gè)函數(shù)是訓(xùn)練過(guò)程中的核心部分,它執(zhí)行了模型的前向傳播、損失計(jì)算、反向傳播和參數(shù)更新,以及定期輸出訓(xùn)練進(jìn)度和性能指標(biāo)。

def train(model, device, train_loader, optimizer, epoch):
model.train()
running_loss = 0.0
correct = 0
total = 0
for 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()
running_loss += loss.item()
_, predicted = torch.max(output.data, 1)
total += target.size(0)
correct += (predicted == target).sum().item()

if batch_idx % 10 == 0:  # 每10個(gè)批次打印一次
print(f'Epoch {epoch}, Batch {batch_idx}, Loss: {loss.item()}')

print(f'Epoch {epoch}, Loss: {running_loss / len(train_loader)}, Accuracy: {100 * correct / total}%')

2.定義實(shí)驗(yàn)過(guò)程

這個(gè)函數(shù)是模型評(píng)估過(guò)程中的核心部分,它計(jì)算了模型在驗(yàn)證集上的損失和準(zhǔn)確率,這些指標(biāo)對(duì)于監(jiān)控模型性能和調(diào)整訓(xùn)練策略非常重要。

# 定義驗(yàn)證過(guò)程
def val(model, device, test_loader, criterion):
model.eval()
running_loss = 0.0
correct = 0
total = 0
with torch.no_grad():
for data, target in test_loader:
data, target = data.to(device), target.to(device)
output = model(data)
loss = criterion(output, target)
running_loss += loss.item()
_, predicted = torch.max(output.data, 1)
total += target.size(0)
correct += (predicted == target).sum().item()

print(f'Validation, Loss: {running_loss / len(test_loader)}, Accuracy: {100 * correct / total}%')

3.增加學(xué)習(xí)率調(diào)度器

通過(guò)訓(xùn)練和驗(yàn)證過(guò)程來(lái)優(yōu)化模型參數(shù),并使用學(xué)習(xí)率調(diào)度器來(lái)調(diào)整學(xué)習(xí)率,以提高模型的性能。在實(shí)際應(yīng)用中,EPOCHS通常會(huì)設(shè)置為一個(gè)較大的值,以確保模型得到充分的訓(xùn)練。

# 創(chuàng)建優(yōu)化器
optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4)

# 創(chuàng)建學(xué)習(xí)率調(diào)度器
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.1)

# 訓(xùn)練模型
EPOCHS = 1
for epoch in range(1, EPOCHS + 1):
train(model, device, train_loader, optimizer, epoch)
val(model, device, test_loader, criterion)
scheduler.step()  # 調(diào)整學(xué)習(xí)率

運(yùn)行結(jié)果:

在這里插入圖片描述

六、測(cè)試模型

1.導(dǎo)入資源包

torchvision.transforms:這個(gè)模塊提供了一組圖像轉(zhuǎn)換操作,可以在數(shù)據(jù)加載時(shí)對(duì)圖像進(jìn)行預(yù)處理,例如調(diào)整大小、裁剪、翻轉(zhuǎn)等。

import torch
from PIL import Image
import torchvision.transforms as transforms
from torchvision import models
from torch.autograd import Variable

2.定義數(shù)據(jù)預(yù)處理

定義圖像的預(yù)處理步驟,并將使用GPU(如果可用)進(jìn)行模型訓(xùn)練。在實(shí)際應(yīng)用中,您需要根據(jù)自己的數(shù)據(jù)集和任務(wù)需求來(lái)調(diào)整這些參數(shù)。

定義數(shù)據(jù)預(yù)處理

transform = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])

# 定義類別
classes = ['cat', 'dog']  # 替換為您的實(shí)際類別名稱

# 檢查是否有可用的 GPU
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")

3.自定義Resnet50模型

定義了一個(gè)自定義的ResNet-50模型,這是一個(gè)在圖像識(shí)別任務(wù)中廣泛使用的卷積神經(jīng)網(wǎng)絡(luò)(CNN)架構(gòu)。代碼中使用了一些簡(jiǎn)寫,比如c_block和i_block,這些應(yīng)該是在代碼的其他部分定義的類,分別代表ResNet中的convolution block(卷積塊)和identity block(恒等塊)。

# 定義自定義的  Resnet50 模型
class Resnet(nn.Module):#主層
def __init__(self,c_block,i_block):
super(Resnet,self).__init__()
self.conv=nn.Sequential(nn.Conv2d(3,64,(7,7),(2,2),padding=(3,3),bias=False),nn.BatchNorm2d(64,affine=False),nn.ReLU(inplace=True),nn.MaxPool2d((3,3),2,1))      
self.layer1=c_block(64,64,256,1)
self.layer2=i_block(256,64)
self.layer3=c_block(256,128,512)
self.layer4=i_block(512,128)
self.layer5=c_block(512,256,1024)
self.layer6=i_block(1024,256)
self.layer7=c_block(1024,512,2048)
self.layer8=i_block(2048,512)
self.out=nn.Linear(2048,2,bias=False)
self.avgpool=nn.AvgPool2d(7,7)


def forward(self,input):
x=self.conv(input)
x=self.layer1(x)
for i in range(2):            
x=self.layer2(x)
x=self.layer3(x)
for i in range(3):
x=self.layer4(x)
x=self.layer5(x)
for i in range(5):
x=self.layer6(x)
x=self.layer7(x)
for i in range(2):
x=self.layer8(x)


x=self.avgpool(x)
x=x.view(x.size(0),-1)
output=self.out(x)
return output

4.實(shí)例化 Resnet50 類

用于加載預(yù)訓(xùn)練的ResNet-50模型,并使用該模型對(duì)上傳的圖片進(jìn)行預(yù)測(cè),image = Variable(image).to(DEVICE): 這一行將預(yù)處理后的圖像轉(zhuǎn)換為PyTorch變量(如果您的模型需要),并將其移動(dòng)到DEVICE上。

# 實(shí)例化 Resnet50 類
model=Resnet(convolutional_block,identity_block).cuda()
# 加載權(quán)重
model.load_state_dict(torch.load("Resnet50.pth"))
model.to(DEVICE)
model.eval()

# 定義預(yù)測(cè)函數(shù)
def predict_image(image_path):
# 打開(kāi)圖片
image = Image.open(image_path)
# 應(yīng)用預(yù)處理
image = transform(image).unsqueeze(0)  # 添加batch維度
# 轉(zhuǎn)換為Variable(如果模型需要)
image = Variable(image).to(DEVICE)
# 獲取模型預(yù)測(cè)
output = model(image)
_, prediction = torch.max(output.data, 1)
return classes[prediction.item()]

# 上傳的圖片路徑
uploaded_image_path = '77.jpg'
# 進(jìn)行預(yù)測(cè)
predicted_class = predict_image(uploaded_image_path)

print(f"The uploaded image is predicted as: {predicted_class}")

運(yùn)行結(jié)果:

在這里插入圖片描述

到此這篇關(guān)于Pytorch框架構(gòu)建ResNet模型的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Pytorch構(gòu)建ResNet模型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

最新評(píng)論