【卷积网络模型系列】ResNet50的实现(Pytorch+TensorFlow)

本文详细介绍了ResNet网络的背景,特别是ResNet50的结构,包括两种不同类型的残差块。通过Pytorch和TensorFlow分别展示了ResNet50的具体实现,并提供了模型参数的获取方式。
摘要由CSDN通过智能技术生成

一、ResNet简单介绍

VGGNet的提出,说明了通过提升网络模型的深度,可以提高网络的表达能力,从AlexNet的7层,到VGGNet的16或者19层,再到GoogLeNet的22层。可后来我们发现深度CNN网络达到一定深度后再一味地增加层数并不能带来进一步地分类性能提高,反而会招致网络收敛变得更慢。如下图:56层简单堆叠的网络模型在训练和测试集上表现反而没有20层的效果好。因为非常非常深的神经网络是很难训练的,因为存在梯度消失和梯度爆炸问题。

而ResNets(残差网络)的提出,则能更好的解决这个模型层数加深后带来的精度下降的问题。ResNets中提出了跳跃连接(Skip connection),它可以从某一层网络层获取激活,然后迅速反馈给另外一层,甚至是神经网络的更深层。我们可以利用跳跃连接构建能够训练深度网络的ResNets,网络深度可以达到152层。

 

二、ResNet50结构介绍

Resnet50里面有两种残差块结构,

第一种输入输出的模型大小保持一致。如下图:

                        

                                                                   

并且先经过1*1的卷积进行降低维度,然后再与3*3的核的进行卷积,最后再经过1*1的卷积恢复恢复,方便与输入连接。

第二种输入输出模型的大小不一致,用于下采样,并且降低feature map通道数时。具体结构如下图:

                     

 

三、ResNet50具体实现

1.Pytorch实现

import torch
import torch.nn as nn
from torchvision.models import resnet50
from torchvision import transforms
from PIL import Image

Layers = [3, 4, 6, 3]

class Bottleneck(nn.Module):
    def __init__(self, in_channels, filters, stride=1, is_downsample = False):
        super(Bottleneck, self).__init__()
        filter1, filter2, filter3 = filters
        self.conv1 = nn.Conv2d(in_channels, filter1, kernel_size=1, stride=stride, bias=False)
        self.bn1 = nn.BatchNorm2d(filter1)
        self.conv2 = nn.Conv2d(filter1, filter2, kernel_size=3, stride=1, padding=1, bias=False)
        self.bn2 = nn.BatchNorm2d(filter2)
        self.conv3 = nn.Conv2d(filter2, filter3, kernel_size=1, stride=1, bias=False)
        self.bn3 = nn.BatchNorm2d(filter3)
        self.relu = nn.ReLU(inplace=True)
        self.is_downsample = is_downsample
        self.parameters()
        if is_downsample:
            self.downsample = nn.Sequential(nn.Conv2d(in_channels, filter3, kernel_size=1, stride=stride, bias=False),
                                            nn.BatchNorm2d(filter3))


    def forward(self, X):
        X_shortcut = X
        X = self.conv1(X)
        X = self.bn1(X)
        X = self.relu(X)

        X = self.conv2(X)
        X = self.bn2(X)
        X = self.relu(X)

        X = self.conv3(X)
        X = self.bn3(X)

        if self.is_downsample:
            X_shortcut = self.downsample(X_shortcut)

        X = X + X_shortcut
        X = self.relu(X)
        return X


class ResNetModel(nn.Module):

    def __init__(self):
        super(ResNetModel, self).__init__()
        self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False)
        self.bn1 = nn.BatchNorm2d(num_features=64)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)

        self.layer1 
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值