一、模型框架概述
YoloV5模型框架採用了改進版本的SPP(Spatial Pyramid Pooling)結構和PANet(Path Aggregation Network)模塊,同時採用了Swish激活函數,Padding=Same卷積核和Focus分離卷積等技術。整個模型包括Backbone、Neck和Head三個部分,其中Backbone部分為CSPdarknet53卷積神經網路,Neck部分為PANet模塊,Head部分為YOLOv5模型的檢測頭部分。
二、數據預處理
YoloV5模型的輸入數據格式為416×416的RGB圖像,輸入圖像會經過歸一化而統一成0~1之間的數值,之後進行圖像增強操作,主要包括隨機縮放、隨機裁剪、隨機反轉、色彩調整等操作,這些操作能夠增加模型的魯棒性,提高模型的泛化能力。
def pre_process(img, img_size):
img = letterbox(img, new_shape=img_size)[0]
img = img[:, :, ::-1].transpose(2, 0, 1).astype(np.float32)
img /= 255.0
return img
三、Backbone
YoloV5的Backbone部分採用了CSPdarknet53卷積神經網路結構。CSPdarknet53中的CSP(Block)模塊是一種卷積神經網路結構,它採用了殘差連接、通道分離和聚合(Bottleneck)的方式,融合了兩條不同的特徵傳遞路徑,用於深度特徵的提取和運算。使用這種方式可以避免特徵信息損失,提高模型的擬合能力。
class CSP(nn.Module):
def __init__(self, in_channels, out_channels, n=1, shortcut=True, activation=True):
super(CSP, self).__init__()
self.shortcut = shortcut
self.activation = activation
self.layers = nn.Sequential()
self.layers.add_module("conv1", nn.Conv2d(in_channels, out_channels // 2, 1, 1, 0, bias=False))
self.layers.add_module("bn1", nn.BatchNorm2d(out_channels // 2))
self.layers.add_module("act1", nn.LeakyReLU(0.1))
for i in range(n):
self.layers.add_module("conv2_%d" % i, nn.Conv2d(out_channels // 2, out_channels // 2, 3, 1, 1, bias=False))
self.layers.add_module("bn2_%d" % i, nn.BatchNorm2d(out_channels // 2))
self.layers.add_module("act2_%d" % i, nn.LeakyReLU(0.1))
self.layers.add_module("conv3", nn.Conv2d(out_channels // 2, out_channels, 1, 1, 0, bias=False))
self.layers.add_module("bn3", nn.BatchNorm2d(out_channels))
if self.activation:
self.layers.add_module("act3", nn.LeakyReLU(0.1))
def forward(self, x):
if self.shortcut:
x1, x2 = x.chunk(2, dim=1)
out = self.layers(x2)
out = torch.cat([out, x1], dim=1)
else:
out = self.layers(x)
return out
四、Neck
YoloV5的Neck部分採用了PANet模塊。PANet是一種基於特徵金字塔(FPN)和聚合網路的模塊,可用於網路特徵表達的增強,實現多尺度特徵的聚合與利用。PANet模塊中採用了一個自上而下及自下而上的聚合過程,該過程能夠解決不同尺度特徵信息的傳遞問題,提高模型對小目標的檢測率和準確率。
class PANet(nn.Module):
def __init__(self, channels):
super(PANet, self).__init__()
self.layers1 = nn.Sequential(
nn.Conv2d(channels[1], channels[1], kernel_size=3, stride=2, padding=1),
nn.BatchNorm2d(channels[1]),
nn.LeakyReLU(0.1),
nn.Conv2d(channels[1], channels[0], kernel_size=1, stride=1, padding=0),
nn.BatchNorm2d(channels[0]),
nn.LeakyReLU(0.1)
)
self.layers2 = nn.Sequential(
nn.Conv2d(channels[0], channels[0], kernel_size=3, stride=2, padding=1),
nn.BatchNorm2d(channels[0]),
nn.LeakyReLU(0.1),
nn.Conv2d(channels[0], channels[0], kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(channels[0]),
nn.LeakyReLU(0.1)
)
self.layers3 = nn.Sequential(
nn.Conv2d(channels[0], channels[0], kernel_size=3, stride=2, padding=1),
nn.BatchNorm2d(channels[0]),
nn.LeakyReLU(0.1),
nn.Conv2d(channels[0], channels[0], kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(channels[0]),
nn.LeakyReLU(0.1)
)
self.layers4 = nn.Sequential(
nn.Conv2d(channels[0], channels[0], kernel_size=3, stride=2, padding=1),
nn.BatchNorm2d(channels[0]),
nn.LeakyReLU(0.1),
nn.Conv2d(channels[0], channels[0], kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(channels[0]),
nn.LeakyReLU(0.1)
)
self.fuse = nn.Sequential(
nn.Conv2d(channels[0], channels[0], kernel_size=1, stride=1, padding=0),
nn.BatchNorm2d(channels[0]),
nn.LeakyReLU(0.1)
)
self.downsample = nn.MaxPool2d(kernel_size=2, stride=2)
def forward(self, x):
out = self.layers1(x[0])
x2 = self.fuse(torch.cat((out, F.upsample(x[1], scale_factor=2)), dim=1))
x3 = self.layers2(x2)
x4 = self.layers3(x3)
x5 = self.layers4(x4)
x5 = self.downsample(x5)
return x2, x3, x4, x5
五、Head
YoloV5的Head部分採用了YOLOv5模型的檢測頭部分。在YoloV5中,檢測頭主要包括Anchor定義、預測調整、處理NMS、處理特徵圖等操作。採用這種方式可以有效地提高模型的準確率和召回率,同時還能夠保證目標檢測的穩定性和一致性。
class Detection(nn.Module):
def __init__(self, in_channels, num_classes, anchors):
super(Detection, self).__init__()
self.num_anchors = len(anchors)
self.num_classes = num_classes
self.in_channels = in_channels
self.conv = nn.Conv2d(self.in_channels, self.num_anchors * (self.num_classes + 5), kernel_size=1, stride=1, padding=0)
self.init_conv2d()
def forward(self, x):
out = self.conv(x)
out = out.permute(0, 2, 3, 1)
return out.reshape(out.shape[0], -1, self.num_classes + 5)
def init_conv2d(self):
bias_value = -4.0
nn.init.normal_(self.conv.weight, std=0.01)
nn.init.constant_(self.conv.bias, bias_value)
六、總結
綜上所述,YoloV5模型採用了CSPdarknet53卷積神經網路、PANet模塊等技術,通過Backbone、Neck和Head三部分實現了高效、準確的目標檢測。除此之外,模型還採用了圖像增強、Swish激活函數、Padding=Same卷積核和Focus分離卷積等技術來提高模型的魯棒性和泛化能力。
原創文章,作者:CVOIM,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/334135.html