## 0609-搭建ResNet网络

pytorch完整教程目录： https://www.cnblogs.com/nickchen121/p/14662511.html

## 一、ResNet 网络概述

Kaiming He 的深度残差网络（ResNet）相比较传统的深度深度神经网络，解决了训练极深网络的梯度消失问题。

`nn.Module``nn.Funcitonal` 结合使用

## 二、利用 torch 实现 ResNet34 网络

```import torch as t
from torch import nn
from torch.nn import functional as F

class ResidualBlock(nn.Module):
"""
实现子 module：Residual Block
"""
def __init__(self, inchannel, outchannel, stride=1, shortcut=None):
super(ResidualBlock, self).__init__()
# 由于 Residual Block 分为左右两部分，因此定义左右两边的 layer
# 定义左边
self.left = nn.Sequential(
nn.Conv2d(inchannel, outchannel, 3, stride, 1, bias=False),
nn.BatchNorm2d(outchannel),
nn.ReLU(inplace=True),
nn.Conv2d(outchannel, outchannel, 3, 1, 1, bias=False),
nn.BatchNorm2d(outchannel))
# 定义右边
self.right = shortcut
def forward(self, x):
out = self.left(x)
residual = x if self.right is None else self.right(x)  # 检测右边直连的情况
out += residual
return F.relu(out)

class ResNet(nn.Module):
"""
实现主 module：ResNet34
ResNet34 包含多个 layer，每个 layer 又包含多个 residual block
用子 module 实现 residual block，用 _make_layer 函数实现 layer
"""
def __init__(self, num_classes=1000):
super(ResNet, self).__init__()
# 前几层图像转换
self.pre = nn.Sequential(
nn.Conv2d(3, 64, 7, 2, 3, bias=False),
nn.BatchNorm2d(64),
nn.ReLU(inplace=True),
nn.MaxPool2d(3, 2, 1),
)
# 重复的 layer 分别有 3，4，6，3 个 residual block
self.layer1 = self._make_layer(64, 128, 3)
self.layer2 = self._make_layer(128, 256, 4, stride=2)
self.layer3 = self._make_layer(256, 512, 6, stride=2)
self.layer4 = self._make_layer(512, 512, 3, stride=2)
# 分类用的全连接
self.fc = nn.Linear(512, num_classes)
def _make_layer(self, inchannel, outchannel, block_num, stride=1):
"""
构建 layer，包含多个 residual block
"""
shortcut = nn.Sequential(
nn.Conv2d(inchannel, outchannel, 1, stride, bias=False),
nn.BatchNorm2d(outchannel))
layers = []
layers.append(ResidualBlock(inchannel, outchannel, stride, shortcut))
for i in range(1, block_num):
layers.append(ResidualBlock(outchannel, outchannel))
return nn.Sequential(*layers)
def forward(self, x):
x = self.pre(x)
x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
x = self.layer4(x)
x = F.avg_pool2d(x, 7)
x = x.view(x.size(0), -1)
return self.fc(x)```

```res_net = ResNet()
inp = t.autograd.Variable(t.randn(1, 3, 224, 224))
output = res_net(inp)
output.size()```

`torch.Size([1, 1000])`

## 三、torchvision 中的 resnet34网络调用

```from torchvision import models
res_net = models.resnet34()
inp = t.autograd.Variable(t.randn(1, 3, 224, 224))
output = res_net(inp)
output.size()```

`torch.Size([1, 1000])`