简介:
首先,ResNet是何凯明大神在2015年提出的,该模型提出后立刻引起轰动。因为在传统卷积神经网络中,当深度越来越深,就会出现梯度消失或者梯度爆炸等问题,从而使准确率降低。
结构理解:
残差块的短路部分被称作Shortcut Connection,单个残差块的期待输出为H(x),H(x)是由传统卷积层的输出F(x)加短路部分携带的初始数据x求得。
特征变换:
为了更直观的显示特征图的大小在执行过程中是怎样变换的,所以在这里详细列了一下。
代码实现:
resnet.py页面:
'''ResNet-18 Image classfication for cifar-10 with PyTorch
Author 'Sun-qian'.
'''
import torch
import torch.nn as nn
import torch.nn.functional as F
"""每一个残差块"""
class ResidualBlock(nn.Module): #继承nn.Module
def __init__(self, inchannel, outchannel, stride=1): #__init()中必须自己定义可学习的参数
super(ResidualBlock, self).__init__() #调用nn.Module的构造函数
self.left = nn.Sequential( #左边,指残差块中按顺序执行的普通卷积网络
nn.Conv2d(inchannel, outchannel, kernel_size=3, stride=stride, padding=1, bias=False),
nn.BatchNorm2d(outchannel), #最常用于卷积网络中(防止梯度消失或爆炸)
nn.ReLU(inplace=True), #implace=True是把输出直接覆盖到输入中,节省内存
nn.Conv2d(outchannel, outchannel, kernel_size=3, stride=1, padding=1, bias=False),
nn.BatchNorm2d(outchannel)
)
self.shortcut = nn.Sequential()
if stride != 1 or inchannel != outchannel: #只有步长为1并且输入通道和输出通道相等特征图大小才会一样,如果不一样,需要在合并之前进行统一
self.shortcut = nn.Sequential(
nn.Conv2d(inchannel, outchannel, kernel_size=1, stride=stride, bias=False),
nn.BatchNorm2d(outchannel)
)
def forward(self, x): #实现前向传播过程