参考: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.