相关文章推荐
绅士的皮蛋  ·  JAVA 中 string 和 int ...·  1 年前    · 
还单身的苦瓜  ·  修改 android ListView ...·  1 年前    · 

resnet50构建的核心代码如下,注释内容说明了特征图分辨率和通道数的变化情况

    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) #特征图分辨率降低为1/2,通道数从3升为64
        self.bn1 = nn.BatchNorm2d(64)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)#特征图分辨率降低为1/4,通道数仍然为64
        self.layer1 = self._make_layer(block, 64, layers[0]) #stride为1,不改变分辨率,依然为1/4,通道数从64升为64*4=256
        self.layer2 = self._make_layer(block, 128, layers[1], stride=2)#stride为2,特征图分辨率降低为1/8,通道数从256升为128*4=512
        self.layer3 = self._make_layer(block, 256, layers[2], stride=2)#stride为2,特征图分辨率降低为1/16,通道数从512升为256*4=1024
        self.layer4 = self._make_layer(block, 512, layers[3], stride=2)#stride为2,特征图分辨率降低为1/32,通道数从512升为256*4=2048

一般使用resnet50输出的4个特征图。4个特征图的分辨率依次为原始图片的1/4, 1/8, 1/16, 1/32,通道数依次为256,512,1024,2048。

    def forward(self, x):
        x = self.conv1(x) #特征图分辨率降低为1/2,通道数变为64
        x = self.bn1(x)
        x = self.relu(x)
        x = self.maxpool(x)#特征图分辨率降低为1/4,通道数仍然为64
        x1 = self.layer1(x)#特征图分辨率仍然为1/4,通道数变为为256
        x2 = self.layer2(x1)#特征图分辨率变为1/8,通道数变为为512
        x3 = self.layer3(x2)#特征图分辨率变为1/16,通道数变为为1024
        x4 = self.layer4(x3)#特征图分辨率变为1/32,通道数变为为2048
        return [x4, x3, x2, x1]

完整代码如下

import torch.nn as nn
import math
import torch.utils.model_zoo as model_zoo
__all__ = ['ResNet', 'resnet18', 'resnet34', 'resnet50', 'resnet101',
           'resnet152']
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',
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 Bottleneck(nn.Module):
    expansion = 4
    def __init__(self, inplanes, planes, stride=1, downsample=None):
        super(Bottleneck, self).__init__()
        self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)
        self.bn1 = nn.BatchNorm2d(planes)
        self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride,
                               padding=1, bias=False)
        self.bn2 = nn.BatchNorm2d(planes)
        self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=False)
        self.bn3 = nn.BatchNorm2d(planes * 4)
        self.relu = nn.ReLU(inplace=True)
        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)
        out = self.relu(out)
        out = self.conv3(out)
        out = self.bn3(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)
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
                m.weight.data.normal_(0, math.sqrt(2. / n))
            elif isinstance(m, nn.BatchNorm2d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()
    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)
        x1 = self.layer1(x)
        x2 = self.layer2(x1)
        x3 = self.layer3(x2)
        x4 = self.layer4(x3)
        return [x4, x3, x2, x1]
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:
        from collections import OrderedDict
        state_dict = model.state_dict()
        pretrained_state_dict = model_zoo.load_url(model_urls['resnet18'])
        for k, v in pretrained_state_dict.items():
            if k not in state_dict:
                continue
            state_dict[k] = v
        model.load_state_dict(state_dict)
    return model
def resnet34(pretrained=False, **kwargs):
    """Constructs a ResNet-34 model.
    Args:
        pretrained (bool): If True, returns a model pre-trained on ImageNet
    model = ResNet(BasicBlock, [3, 4, 6, 3], **kwargs)
    if pretrained:
        from collections import OrderedDict
        state_dict = model.state_dict()
        pretrained_state_dict = model_zoo.load_url(model_urls['resnet34'])
        for k, v in pretrained_state_dict.items():
            if k not in state_dict:
                continue
            state_dict[k] = v
        model.load_state_dict(state_dict)
    return model
def resnet50(pretrained=False, **kwargs):
    """Constructs a ResNet-50 model.
    Args:
        pretrained (bool): If True, returns a model pre-trained on ImageNet
    model = ResNet(Bottleneck, [3, 4, 6, 3], **kwargs)
    if pretrained:
        print('Initialize with pre-trained ResNet')
        from collections import OrderedDict
        state_dict = model.state_dict()
        pretrained_state_dict = model_zoo.load_url(model_urls['resnet50'])
        for k, v in pretrained_state_dict.items():
            if k not in state_dict:
                continue
            state_dict[k] = v
        print('successfully load '+str(len(state_dict.keys()))+' keys')
        model.load_state_dict(state_dict)
    return model
def resnet101(pretrained=False, **kwargs):
    """Constructs a ResNet-101 model.
    Args:
        pretrained (bool): If True, returns a model pre-trained on ImageNet
    model = ResNet(Bottleneck, [3, 4, 23, 3], **kwargs)
    if pretrained:
        print('Initialize with pre-trained ResNet')
        from collections import OrderedDict
        state_dict = model.state_dict()
        pretrained_state_dict = model_zoo.load_url(model_urls['resnet101'])
        for k, v in pretrained_state_dict.items():
            if k not in state_dict:
                continue
            state_dict[k] = v
        print('successfully load '+str(len(state_dict.keys()))+' keys')
        model.load_state_dict(state_dict)
    return model
def resnet152(pretrained=False, **kwargs):
    """Constructs a ResNet-152 model.
    Args:
        pretrained (bool): If True, returns a model pre-trained on ImageNet
    model = ResNet(Bottleneck, [3, 8, 36, 3], **kwargs)
    if pretrained:
        from collections import OrderedDict
        state_dict = model.state_dict()
        pretrained_state_dict = model_zoo.load_url(model_urls['resnet152'])
        for k, v in pretrained_state_dict.items():
            if k not in state_dict:
                continue
            state_dict[k] = v
        model.load_state_dict(state_dict)
    return model
if __name__=='__main__':
    import torch
    model = resnet50()
    input = torch.rand([4,3,256,192])
    print(input.shape)
    output = model(input)
    print(type(output))
    print(len(output))
    print(output[0].shape)
    print(output[1].shape)
    print(output[2].shape)
    print(output[3].shape)
                    resnet50输出4个特征图。4个特征图的分辨率依次为原始图片的1/4, 1/8, 1/16, 1/32,通道数依次为256,512,1024,2048。import torch.nn as nnimport mathimport torch.utils.model_zoo as model_zoo__all__ = ['ResNet', 'resnet18', 'resnet34', 'resnet50', 'resnet101',           'resnet152']mod
				
一、基本介绍 1. 什么是语义分割 语义分割(Semantic Segmentation)是像处理和机器视觉一个重要分支,其目标是精确理解像场景与内容。语义分割是在像素级别上的分类,属于同一类的像素都要被归为一类,因此语义分割是从像素级别来理解像的。如下如所示的照片,属于人的像素部分划分成一类,属于摩托车的像素划分成一类,背景像素划分为一类。 像分割级别可以分为语义级分割、...
相关文章: . Patchmatch: A randomized correspondence algorithm for structural image editing. SIGGRAPH 2009 The generalized patchmatch correspondence algorithm ECCV2010 Deformable spatial pyramid matching...
Stage 1:包含3个卷积层和2个池化层,主要负责对输入像进行特征提取。 Stage 2:包含4个卷积层和2个池化层,主要负责对第一阶段提取的特征进一步加深和提升。 Stage 3:包含6个卷积层和2个池化层,主要负责对第二阶段提取的特征进一步加深和提升。 Stage 4:包含3个卷积层和1个池化层,主要负责对第三阶...
ResNet50是一个经典的特征提取网络结构,虽然Pytorch已有官方实现,但为了加深对网络结构的理解,还是自己动手敲敲代码搭建一下。需要特别说明的是,笔者是以熟悉网络各层输出维度变化为目的的,只对建立后的网络赋予伪输入并测试各层输出,并没有用据集训练过该网络(后续会用据集测试并更新博客)。 1 预备理论 在动手搭建ResNet50以前,首先需要明确ResNet系列网络的基本结构,其次复习与卷积相关的几个知识点,以便更好地理解网络中间输出维度的
RuntimeError: size mismatch, m1: [1 x 8192], m2: [2048 x 2] at C:\w\1\s\tmp_conda_3.7_104508\conda\conda-bld\pytorch_1572950778684\work\aten\src\TH/generic/THTensorMath.cpp:197 经过查询发现resnet50、res...
输入Input经过Resnet50到输出Output的5个阶段,共经过了50个层。其中Stage0较为简单,可以看作据的预处理;后面的Stage1、Stage2、Stage3、Stage4都由Bottleneck组成,结构相似。 Stage0 Stage0较为简单,可以看作据的预处理。(3,473,473)为输入的通道(channel)、高(height)、宽(width),即(c,h,w)。先假设输入的高和宽相等,所以表示为(c,w,w) 该Stage中第1层包括3个先后操作: 1、CONV