1,本文介绍
ResNet(深度残差网络)通过引入“快捷连接”来解决深层神经网络训练中的梯度消失问题。这些快捷连接允许网络的输入直接跳过中间的层,直接传递到后面的层,从而使得网络能够专注于学习输入与输出之间的残差(即差异),而非直接学习复杂的函数映射。这种设计方式使得网络在需要时可以简单地实现恒等映射,简化了训练过程,缓解了深层网络训练中的困难。因此,ResNet 能够有效地训练非常深的网络结构,并在多个视觉识别任务上取得显著的性能提升。
关于ResNet的详细介绍可以看论文:https://arxiv.org/pdf/1512.03385.pdf
本文将讲解如何将ResNet融合进yolov8
话不多说,上代码!
2, 将ResNet融合进yolov8
2.1 步骤一
首先找到如下的目录'ultralytics/nn',然后在这个目录下创建一个'Addmodules'文件夹,然后在这个目录下创建一个ResNet.py文件,文件名字可以根据你自己的习惯起,然后将ResNet的核心代码复制进去。
from collections import OrderedDict
import torch.nn as nn
import torch.nn.functional as F
class ConvNormLayer(nn.Module):
def __init__(self,
ch_in,
ch_out,
filter_size,
stride,
groups=1,
act=None):
super(ConvNormLayer, self).__init__()
self.act = act
self.conv = nn.Conv2d(
in_channels=ch_in,
out_channels=ch_out,
kernel_size=filter_size,
stride=stride,
padding=(filter_size - 1) // 2,
groups=groups)
self.norm = nn.BatchNorm2d(ch_out)
def forward(self, inputs):
out = self.conv(inputs)
out = self.norm(out)
if self.act:
out = getattr(F, self.act)(out)
return out
class SELayer(nn.Module):
def __init__(self, ch, reduction_ratio=16):
super(SELayer, self).__init__()
self.avg_pool = nn.AdaptiveAvgPool2d(1)
self.fc = nn.Sequential(
nn.Linear(ch, ch // reduction_ratio, bias=False),
nn.ReLU(inplace=True),
nn.Linear(ch // reduction_ratio, ch, bias=False),
nn.Sigmoid()
)
def forward(self, x):
b, c, _, _ = x.size()
y = self.avg_pool(x).view(b, c)
y = self.fc(y).view(b, c, 1, 1)
return x * y.expand_as(x)
class BasicBlock(nn.Module):
expansion = 1
def __init__(self,
ch_in,
ch_out,
stride,
shortcut,
act='relu',
variant='b',
att=False):
super(BasicBlock, self).__init__()
self.shortcut = shortcut
if not shortcut:
if variant == 'd' and stride == 2:
self.short = nn.Sequential()
self.short.add_sublayer(
'pool',
nn.AvgPool2d(
kernel_size=2, stride=2, padding=0, ceil_mode=True))
self.short.add_sublayer(
'conv',
ConvNormLayer(
ch_in=ch_in,
ch_out=ch_out,
filter_size=1,