使用pytorch搭建ResNet网络

本文介绍了如何在PyTorch中搭建ResNet网络,通过训练和预测过程展示了模型的学习效果。经过多轮训练,模型在测试集上的准确率逐步提升,最终达到0.926。
摘要由CSDN通过智能技术生成

 

参考:https://www.cnblogs.com/jiyou/p/11272650.html

           https://zhuanlan.zhihu.com/p/77899090

导入需要使用的包 

import torch.nn as nn
import torch.utils.model_zoo as model_zoo

# 每一种架构下都有训练好的可以用的参数文件
# 默认的resnet网络,已预训练
model_urls = {
    'resnet18': 'https://download.pytorch.org/models/resnet18-5c106cde.pth',
    'resnet34': 'https://download.pytorch.org/models/resnet34-333f7ec4.pth',
    'resnet50': 'https://download.pytorch.org/models/resnet50-19c8e357.pth',
    'resnet101': 'https://download.pytorch.org/models/resnet101-5d3b4d8f.pth',
    'resnet152': 'https://download.pytorch.org/models/resnet152-b121ed2d.pth',
}

 

1.model.py 

import torch.nn as nn
import torch

#基础块 两个3x3
class BasicBlock(nn.Module):#resnet 18\34 层
    expansion = 1

    # downsample 对应有没有虚线的结构
    def __init__(self, in_channel, out_channel, stride=1, downsample=None):
        super(BasicBlock, self).__init__()
        self.conv1 = nn.Conv2d(in_channels=in_channel, out_channels=out_channel,
                               kernel_size=3, stride=stride, padding=1, bias=False)
        self.bn1 = nn.BatchNorm2d(out_channel) # 输出特征矩阵的深度
        self.relu = nn.ReLU(inplace=True)
        self.conv2 = nn.Conv2d(in_channels=out_channel, out_channels=out_channel,
                               kernel_size=3, stride=1, padding=1, bias=False)
        self.bn2 = nn.BatchNorm2d(out_channel)
        self.downsample = downsample # 传递下采样方法# 这个是shortcut的操作

    def forward(self, x): # 定义正向传播过程
        identity = x # 捷径连接
        if self.downsample is not None:
            identity = self.downsample(x)
        # 我们将上一层的输出x输入进这个downsample所拥有一些操作(卷积等),将结果赋给identity
        # 简单说,这个目的就是为了应对上下层输出输入深度不一致问题
        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        with torch.no_grad():
            out = self.bn2(out) # 这一步没有relu激活函数,是因为将输出加上捷径分支再relu

        out += identity
        out = self.relu(out)

        return out

# 瓶颈块,有三个卷积层分别是1x1,3x3,1x1,分别用来降低维度,卷积处理,升高维度
# 引入Bottleneck的目的是,减少参数的数目,Bottleneck相比较BasicBlock在参数的数目上少了许多,
# 但是精度上却差不多。减少参数同时还会减少计算量,使模型更快的收敛。

class Bottleneck(nn.Module):#resnet 50\101\152
    expansion = 4 #每个layer的第3层卷积核个数为第1,2层的4倍(eg.64 64 256)

    def __init__(self, in_channel, out_channel, stride=1, downsample=None):
        super(Bottleneck, self).__init__()
        self.conv1 = nn.Conv2d(in_channels=in_channel, out_channels=out_channel,
                               kernel_size=1, stride=1, bias=False)  # squeeze channels
        self.bn1 = nn.
好的,下面是一个简单的例子: ```python import torch.nn as nn import torch.utils.model_zoo as model_zoo __all__ = ['ResNet', 'resnet18'] model_urls = { 'resnet18': 'https://download.pytorch.org/models/resnet18-5c106cde.pth', } def conv3x3(in_planes, out_planes, stride=1): """3x3 convolution with padding""" return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride, padding=1, bias=False) class BasicBlock(nn.Module): expansion = 1 def __init__(self, inplanes, planes, stride=1, downsample=None): super(BasicBlock, self).__init__() self.conv1 = conv3x3(inplanes, planes, stride) self.bn1 = nn.BatchNorm2d(planes) self.relu = nn.ReLU(inplace=True) self.conv2 = conv3x3(planes, planes) self.bn2 = nn.BatchNorm2d(planes) self.downsample = downsample self.stride = stride def forward(self, x): residual = x out = self.conv1(x) out = self.bn1(out) out = self.relu(out) out = self.conv2(out) out = self.bn2(out) if self.downsample is not None: residual = self.downsample(x) out += residual out = self.relu(out) return out class ResNet(nn.Module): def __init__(self, block, layers, num_classes=1000): self.inplanes = 64 super(ResNet, self).__init__() self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False) self.bn1 = nn.BatchNorm2d(64) self.relu = nn.ReLU(inplace=True) self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) self.layer1 = self._make_layer(block, 64, layers[0]) self.layer2 = self._make_layer(block, 128, layers[1], stride=2) self.layer3 = self._make_layer(block, 256, layers[2], stride=2) self.layer4 = self._make_layer(block, 512, layers[3], stride=2) self.avgpool = nn.AdaptiveAvgPool2d((1, 1)) self.fc = nn.Linear(512 * block.expansion, num_classes) def _make_layer(self, block, planes, blocks, stride=1): downsample = None if stride != 1 or self.inplanes != planes * block.expansion: downsample = nn.Sequential( nn.Conv2d(self.inplanes, planes * block.expansion, kernel_size=1, stride=stride, bias=False), nn.BatchNorm2d(planes * block.expansion), ) layers = [] layers.append(block(self.inplanes, planes, stride, downsample)) self.inplanes = planes * block.expansion for i in range(1, blocks): layers.append(block(self.inplanes, planes)) return nn.Sequential(*layers) def forward(self, x): x = self.conv1(x) x = self.bn1(x) x = self.relu(x) x = self.maxpool(x) x = self.layer1(x) x = self.layer2(x) x = self.layer3(x) x = self.layer4(x) x = self.avgpool(x) x = x.view(x.size(0), -1) x = self.fc(x) return x def resnet18(pretrained=False, **kwargs): """Constructs a ResNet-18 model. Args: pretrained (bool): If True, returns a model pre-trained on ImageNet """ model = ResNet(BasicBlock, [2, 2, 2, 2], **kwargs) if pretrained: model.load_state_dict(model_zoo.load_url(model_urls['resnet18'])) return model ``` 这是一个标准的 ResNet18 的 PyTorch 实现,其中包括了 `BasicBlock` 和 `ResNet` 两个类,以及 `resnet18` 函数,用于构建 ResNet18 模型。你可以在 `ResNet` 类中自定义层数和其他参数,如 `num_classes`(分类数目)等。在 `resnet18` 函数中,你可以通过设置 `pretrained=True` 来加载预训练权重。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值