发布时间:2023-04-03 文章分类:电脑基础 投稿人:樱花 字号: 默认 | | 超大 打印

Yolov5中使用Resnet18作为主干网络

预备知识

采用Resnet-18作为主干网络,首先第一件事情就要了解Resnet的网络结构
Yolov5中使用Resnet18作为主干网络
以及resnet-18中的残差层是做什么的
Yolov5中使用Resnet18作为主干网络
引入残差层是为了解决伴随着层数的递增,而出现的梯度消失的问题,从而引入了残差层即
在sigmoid中其激活函数

S
(
x
)
=
1
1
+
e

x
S

(
x
)
=
S
(
x
)
(
1

S
(
x
)
)
S(x)=\frac{1}{1+e^{-x}}\\ S`(x)=S(x)(1-S(x))
S(x)=1+ex1S(x)=S(x)(1S(x))

自此可以看出S’(x)最大就是0.5
而原层数会伴随着迭代次数而逐渐相乘即越来越小从而出现梯度消失
但残差曾的意义是让其再加一个,变成一个大于1的数字从而抵抗梯度消失

z
=
y
+
x

z

x
=

y

x
+
1
z=y+x\\ \frac{\partial z}{\partial x}=\frac{\partial y}{\partial x}+1
z=y+xxz=xy+1

如何在yolo中进行修改

首先在commmon.py添加残差层

class BasicBlock(nn.Module):
    def __init__(self,in_channels,out_channels,stride=1,padding=1) -> None:
        super(BasicBlock, self).__init__()
        self.layer = nn.Sequential(
            nn.Conv2d(in_channels,out_channels,kernel_size=3,stride=1,padding=padding,bias=False),
            nn.BatchNorm2d(out_channels),
            nn.ReLU(inplace=True), 
            nn.Conv2d(out_channels,out_channels,kernel_size=3,stride=1,padding=padding,bias=False),
            nn.BatchNorm2d(out_channels)
        )
        self.shortcut = nn.Sequential()
        if stride != 1 or in_channels != out_channels:
            self.shortcut = nn.Sequential(
                nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=1, bias=False),
                nn.BatchNorm2d(out_channels)
            )
    def forward(self, x):
        out = self.layer(x)
        out += self.shortcut(x)
        out = torch.nn.functional.relu(out)
        return out

然后再yolo.py中那一串层里面添加一个BasicBlock层
最后在你现用的模型主干里面替换即可

  [[-1, 1, Conv, [64, 1]],
   [-1, 2, BasicBlock, [64]],  
   [-1, 1, Conv, [128, 3, 2]],
   [-1, 2, BasicBlock, [128]],
   [-1, 1, Conv, [256, 3, 2]],
   [-1, 2, BasicBlock, [256]],
   [-1, 1, Conv, [512, 3, 2]],
   [-1, 2, BasicBlock, [512]],
   [-1, 1, Conv, [1024, 3, 2]],
   [-1, 2, BasicBlock, [1024]],
  ]

然后打开tensorboard

但不知道为什么修改了网络模型结构,在原始的yolov5中召回、精确啥的都等于零,可能是原版本的bug,底下这个是我在yolov7模型修改过的东西。
Yolov5中使用Resnet18作为主干网络
就很棒nice。
哦,对啦,如果不会修改模型路径,在这个里面改,还要把上边的pt文件给删掉

parser.add_argument('--weights', type=str, default= '', help='initial weights path')
parser.add_argument('--cfg', type=str, default=‘你模型的路径’,, help='model.yaml path')