pytorch实现resnet34网络

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日

相关文章

  • javascript继承之为什么要继承

    JavaScript是一种动态语言,具有一些独特的继承机制。继承是面向对象编程的一个必要组成部分。这里将讲解javascript继承的重要性,为什么要使用继承的原因和两个示例说明。 为什么要继承 继承是使面向对象编程具有灵活性和重用性的一种方式。继承可以避免代码重复、简化代码逻辑和提高程序可维护性。使用继承可以通过让子类继承父类的属性和方法来扩展功能,从而减…

    other 2023年6月26日
    00
  • Go并发编程中使用channel的方法

    下面我就来详细讲解Go并发编程中使用channel的方法的完整攻略。 什么是channel Go语言中的channel是一种通信机制,用于协调多个goroutine之间的交互和同步。简单来说,channel就是一个通道,通过它可以在goroutine之间传递数据,实现数据共享,实现同步或异步的通信。 channel的创建和关闭 channel是通过内置函数m…

    other 2023年6月27日
    00
  • latex表格内单元格内容强制换行

    Latex表格内单元格内容强制换行 在编写科技论文或是表格报告时,我们经常需要使用LaTeX中的表格来组织数据。然而,在固定列宽的表格中,单元格中的内容长度有时会超过列宽,导致表格过长。一个常见的问题就是如何将单元格中的长文本强制换行以使表格整洁美观。在本文中,我将向大家介绍两种简单的方法来解决这个问题。 方法一:p列格式 LaTeX中的p列格式是一种指定列…

    其他 2023年3月28日
    00
  • Win11打开文件资源管理器重启报错解决方法

    Win11打开文件资源管理器重启报错解决方法 在使用 Win11 操作系统时,有时会出现打开文件资源管理器后电脑突然重启的问题。下面我们将详细讲解如何解决这个问题。 解决方法 检查文件管理器中的错误 在文件管理器中打开一个文件夹时,很可能会触发一个程序崩溃,导致电脑突然重启。为了避免这种情况,我们可以先检查文件管理器中的错误。 打开文件资源管理器 点击“查看…

    other 2023年6月27日
    00
  • 20个提高开发效率的VS Code快捷键(推荐)

    20个提高开发效率的VS Code快捷键(推荐)攻略 1. 快速打开文件 使用快捷键 Ctrl + P 可以快速打开文件。在弹出的输入框中输入文件名或路径的一部分,VS Code会自动匹配并显示相关文件。 示例:要打开名为 index.html 的文件,按下 Ctrl + P,然后输入 index.html,选择匹配的文件即可。 2. 快速切换文件 使用快捷…

    other 2023年9月6日
    00
  • 浅谈将子类对象赋值给父类对象

    当将子类对象赋值给父类对象时,在某些情况下可能会涉及到向上转型和向下转型的问题。 向上转型 向上转型指将子类类型转换为父类类型,这种转型是安全且自动完成的。在这种情况下,父类对象可以引用子类对象,但只能访问父类对象的属性和方法,而不能访问子类对象的属性和方法。 例如,假设我们有一个父类Animal和一个子类Cat,如下所示: class Animal: de…

    other 2023年6月26日
    00
  • C语言实现支持动态拓展和销毁的线程池

    让我们来详细讲解一下“C语言实现支持动态拓展和销毁的线程池”的完整攻略。 什么是线程池 线程池是一种线程管理技术,用来解决线程过多而导致系统负载过高的问题。在程序启动时,线程池会创建一定数量的线程,当有任务到达时,会将任务交给池中的线程执行。当所有线程都在工作时,新的任务就会进入等待队列,直到有线程完成任务后被唤醒。 实现线程池的步骤 初始化线程池 首先,我…

    other 2023年6月27日
    00
  • Linux如何基于AIDE检测文件系统完整性

    Linux可以通过AIDE(Advanced Intrusion Detection Environment)工具来检测文件系统的完整性。AIDE可以定期巡检文件系统,记录文件的属性信息(比如文件的名字、权限、MD5值、SHA1值等),并生成相关的校验和值。通过比对前后两个时间段的校验值,可以检测出文件系统中是否存在被修改或被删除、新增的文件。下面详细讲解L…

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