pytorch实现resnet34网络

yizhihongxing

PyTorch实现ResNet34网络的完整攻略

ResNet是深度学习中非常流行的卷积神经网络之一,它在ImageNet数据集上取了常好的效果。本文将详细讲解如何使用PyTorch实现ResNet34网络,包数据预处理、网络搭建、训和测试等内容。

数据预处理

在使用PyTorch实现ResNet34网络之前,需要对数据进行预处理。可以按照以下步骤预处理:

  1. 将图像缩放到256x256大小。
  2. 随机裁剪224x224大小的图像。
  3. 将图像水平翻转。
  4. 将像素值标准化为[0, 1]。

可以以下代码实现数据预处理:

import torchvision.transforms as transforms

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

transform_test = 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])
])

网络搭建

在数据预处理后,需要搭建ResNet34网络。可以使用以下代码实现网络搭建:

import torch.nn as nn
import torch.nn.functional as F

class BasicBlock(nn.Module):
    expansion = 

    def __init__(self, in_planes, planes, stride=1):
        super(BasicBlock, self).__init__()
        self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)
        self.bn1 = nn.BatchNorm2d(planes)
        self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=1, padding=1, bias=False)
        self.bn2 = nn.BatchNorm2d(planes)

        self.shortcut = nn.Sequential()
        if stride != 1 or in_planes != self.expansion*planes:
            self.shortcut = nn.Sequential(
                nn.Conv2d(in_planes, self.expansion*planes, kernel_size=1, stride=stride, bias=False),
                nn.BatchNorm2d(self.expansion*planes)
            )

    def forward(self, x):
        out = F.relu(self.bn1(self.conv1(x)))
        out = self.bn2(self.conv2(out))
        out += self.shortcut(x)
        out = F.relu(out)
        return out


class ResNet(nn.Module):
    def __init__(self, block, num_blocks, num_classes=10):
        super(ResNet, self).__init__()
        self.in_planes = 64

        self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1, bias=False)
        self.bn1 = nn.BatchNorm2d(64)
        self.layer1 = self._make_layer(block,64, num_blocks[0], stride=1)
        self.layer2 = self._make_layer(block, 128, num_blocks[1], stride=2)
        self.layer3 = self._make_layer(block, 256, num_blocks[2], stride=2)
        self.layer4 = self._make_layer(block, 512, num_blocks[3], stride=2)
        self.linear = nn.Linear512*block.expansion, num_classes)

    def _make_layer(self, block, planes, num_blocks, stride):
        strides = [stride] + [1]*(num_blocks-1)
        layers = []
        for stride in strides:
            layers.append(block(self.in_planes, planes, stride))
            self.in_planes = planes * block.expansion
        return nn.Sequential(*layers)

    def forward(self, x):
        out = F.relu(self.bn1(self.conv1(x)))
        out = self.layer1(out)
        out = self.layer2(out)
        out = self.layer3(out)
        out = self.layer4(out)
        out = F.avg_pool2d(out, 4)
        out = out.view(out.size(0), -1)
        out = self.linear(out)
        return out

def ResNet34():
    return ResNet(BasicBlock, [3,4,6,3])

在上面的代码中,BasicBlockResNet中的基本块,ResNet是ResNet网络,ResNet34是ResNet34网络。

训练和测试

在网络搭建完成后,需要进行训练和测试。可以使用以下代码实现训练和测试```python
import torch.optim as optim
import torchvision.datasets as datasets
import torchvision.models as models
from torch.utils.data import DataLoader

加载数据集

trainset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_train)
trainloader = DataLoader(trainset, batch_size=128, shuffle=True, num_workers=2)

testset = datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_test)
testloader = DataLoader(testset, batch_size=100, shuffle=False, num_workers=2)

定义模型、损失函数和优化器

net = ResNet34()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.1, momentum=0.9, weight_decay=5e-4)

训练模型

for epoch in range(100):
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
inputs, labels = data
optimizer.zero_grad()

    outputs = net(inputs)
    loss = criterion(outputs, labels)
    loss.backward()
    optimizer.step()

    running_loss += loss.item()
    if i % 100 == 99:
        print('[%d, %5d] loss: %.3f' % (epoch+1, i+1, running_loss/100))
        running_loss = 0.0

测试模型correct = 0

total = 0
with torch.no_grad():
for data in testloader:
images, labels = data
outputs = net(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()

print('Accuracy of the network on the 10000 test images: %d %%' % (100 * correct / total))


在上面的代码中,首先加载CIFAR10数据集,然后定义ResNet34网络、交叉熵损失函数和随机梯度下降优化器。着,使用训练集对模型进行训练,并使用测试集对模型进行测试。

## 示例1:使用ResNet34网络进行图像分类

以下是使用ResNet34网络进行图像分类的示例:

```python
import torch
import torchvision.transforms as transforms
from PIL import Image

# 加载模型
net = ResNet34()
net.load_state_dict(torch.load('resnet34.pth'))

# 加载图像
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])
])
image = Image.open('test.jpg')
image = transform(image)
image = image.unsqueeze(0)

# 预测图像类别
outputs = net(image)
_, predicted = torch.max(outputs.data, 1)
print(predicted.item())

在上面的示例中,首先加载ResNet34网络和预训练模型,然后加载测试图像并进行预处理,最后使用ResNet34网络对图像进行分类。

示例2使用ResNet34网络进行迁移学习

以下是使用ResNet34网络进行迁移学习的例:

import torch
import torchvision.transforms as transforms
import torchvision.models as models
from torch.utils.data import DataLoader
from torch import nn, optim

# 加载数据集
trainset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_train)
trainloader = DataLoader(trainset, batch=128, shuffle=True, num_workers=2)

testset = datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_test)
testloader = DataLoader(testset, batch_size=100, shuffle=False, num_workers=2)

# 加载预训练模型
resnet = models.resnet34(pretrained=True)
for param in resnet.parameters():
    param.requires_grad = False

# 替换最后一层全连接层
num_ftrs = resnet.fc.in_features
resnet.fc = nn.Linear(num_ftrs, 10)

# 定义损失函数和优化器criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(resnet.fc.parameters(), lr=0.1, momentum=0.9, weight_decay=5e-4)

# 训练模型
for epoch in range(100):
    running_loss = 0.0    for i, data in enumerate(trainloader, 0):
        inputs, labels = data
        optimizer.zero_grad()

        outputs = resnet(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()
        if i % 100 == 99:
            print('[%d, %5d] loss: %.3f' % (epoch+1, i+1, running_loss/100))
            running_loss = 0.0

# 测试模型
correct = 0
total = 0
with torch.no_grad():
    for data in testloader:
        images, labels = data
        outputs = resnet(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print('Accuracy of the network on the 10000 test images: %d %%' % (100 * correct / total))

在上面的示例中,首先加载CIFAR10数据集,然后加载ResNet34预训练模型并替换最后一层全连接层。接着,使用训练集对模型进行训,并使用测试集对模型进行测试。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:pytorch实现resnet34网络 - Python技术站

(0)
上一篇 2023年5月8日
下一篇 2023年5月8日

相关文章

  • shell判断一个变量是否为空方法总结

    下面是关于“shell判断一个变量是否为空方法总结”的完整攻略: 概述 在shell脚本编程中,判断变量是否为空是一项基础的操作。在实际编程中,有多种方法可以判断一个变量是否为空,本文将总结常见的方法及其使用说明。 方法一:使用if语句 使用if语句判断变量是否为空,需要注意的是if语句中的条件判断符号不能少。 示例1:判断变量是否为空 #!/bin/bas…

    other 2023年6月27日
    00
  • JavaScript使用prototype原型实现的封装继承多态示例

    下面是JavaScript使用prototype原型实现的封装继承多态示例的完整攻略。 前置知识: JavaScript的原型链和原型继承 JavaScript中的多态和封装 预备知识: 通常,我们使用这种方法,通过创建一个类,然后在类的原型上面定义方法和属性,来实现封装。而通过创建一个子类,然后继承父类的属性和方法,并定义自己的属性和方法,来实现继承。而多…

    other 2023年6月25日
    00
  • 新手必备的IDEA常用设置总结

    新手必备的IDEA常用设置总结攻略 1. 安装和配置IDEA 首先,你需要下载并安装IntelliJ IDEA。安装完成后,打开IDEA并按照以下步骤进行常用设置的配置。 2. 设置主题和外观 选择一个适合你的主题和外观可以提高你的开发体验。在IDEA的菜单栏中,依次点击\”File\” -> \”Settings\” -> \”Appearan…

    other 2023年8月3日
    00
  • 由于主引导程序引起的启动故障导致电脑无法启动解决方法

    针对“由于主引导程序引起的启动故障导致电脑无法启动解决方法”,以下是完整的攻略,希望可以帮到您。 1. 故障原因分析 在解决问题之前,我们首先要了解故障的原因。在这里,“由于主引导程序引起的启动故障导致电脑无法启动”的原因,通常有以下几种情况: 硬盘故障:由于硬盘失效、或者硬盘文件系统损坏等原因,导致主引导程序无法正常读取,造成启动故障。 操作系统故障:由于…

    other 2023年6月27日
    00
  • Android NDK 开发中 SO 包大小压缩方法详解

    Android NDK 开发中 SO 包大小压缩方法详解 在 Android Native Development Kit (NDK) 开发中,编译生成的动态链接库库(也称为SO包)体积较大是一个常见的问题,这会导致应用包的体积过大,影响应用的下载和安装速度。在本文中,我们将分享一些有用的技巧,帮助你在发布前有效地压缩SO包,减小应用的体积。 压缩SO包的方…

    other 2023年6月26日
    00
  • JAVA中堆、栈,静态方法和非静态方法的速度问题

    JAVA中堆、栈,静态方法和非静态方法的速度问题 在Java中,堆和栈是两种不同的内存区域,而静态方法和非静态方法是两种不同的方法类型。它们在速度方面有一些区别。 堆和栈的速度问题 堆 堆是用于存储对象的内存区域。在堆中分配内存需要动态分配和回收,因此速度相对较慢。堆中的对象可以被多个线程共享,因此需要进行线程同步操作。 示例说明1:堆中的对象分配和回收 p…

    other 2023年10月15日
    00
  • 带你了解C++的数组与函数

    当我们编写C++程序时,数组和函数是两个非常重要的主题。这篇文章会带你深入了解C++中的数组和函数。我们将从以下几个方面展开对这两个主题的讲解: 什么是数组?为什么使用数组? 如何声明和使用数组? 数组的常见操作-访问、修改、遍历和排序 什么是函数?为什么使用函数? 如何声明和使用函数? 两个示例说明 什么是数组?为什么使用数组? 数组是一组具有相同数据类型…

    other 2023年6月25日
    00
  • 浅谈go build后加文件和目录的区别

    浅谈go build后加文件和目录的区别 在Go语言中,使用go build命令可以将Go源代码编译成可执行文件。在使用go build命令时,可以指定要编译的文件或目录。下面将详细讲解go build后加文件和目录的区别。 编译单个文件 当使用go build命令后加文件名时,表示只编译指定的单个文件。例如: go build main.go 上述命令将只…

    other 2023年10月13日
    00
合作推广
合作推广
分享本页
返回顶部