首页 > 编程语言 >目标检测算法之YOLO(YOLOv4-YOLOv6)

目标检测算法之YOLO(YOLOv4-YOLOv6)

时间:2024-06-17 21:32:00浏览次数:13  
标签:YOLOv6 YOLOv4 anchors 卷积 self YOLO batch image size

YOLO算法理解


本文是yolov1-yolov3(https://blog.csdn.net/weixin_52862386/article/details/139563416)的延续,所以有一些内容在上篇文章已经叙述,下面更多的叙述它们的改进和一些新的思想。yolo的损失函数特别多,主要的更新都是框的loss上做改进,所以后面再写一篇关于loss function的。

YOLOv4

YOLOv4是在YOLOv3的基础上提出了一些改进trick,实现了map的提升同时仍具备65FPS的推理速度。作者提出了Bag of freebies和Bag of specials俩个概念。其中Bag of freebies是指仅改变训练策略或者提高训练cost从而提高模型精度的方法,例如数据增强;Bag of specials是指仅插入一些模块或者后处理后能提高模型精度,且对推理速度影响比较小的方法,如加入attention机制、托大感受野等方法。然后作者通过一些Bag of freebies和Bag of specials的方法实现了精度的提升。

Bag of specials

Cross-stage partial connections(CSP)

CSP一种降低计算量,同时精度没有太大影响的方法。它的思想是将特征按channel进行切分,将一半的特征按原路径进行计算,剩下一般直接和结果进行concat,从而实现计算量减少的目的。
在这里插入图片描述
上图展示了CSPNet应用于Resnet的过程,假设原本Resnet的输出为 d 1 d_1 d1​,Base layer的输出为 d 2 d_2 d2​,那么在CSPResnet,Part1和Part2的维度都为 d 2 / 2 d_2/2 d2​/2,Partial Transition的输入为 c o n c a t ( [ d / 2 , d / 2 ] ) concat([d/2,d/2]) concat([d/2,d/2]),最终输出为 d 1 d_1 d1​。简单而言就是部分特征不计算。实现方式可以参考下面的代码(代码来自yolov5)

class Bottleneck(nn.Module):
    # Standard bottleneck
    def __init__(self, c1, c2, shortcut=True, g=1, e=0.5):
        """Initializes a standard bottleneck layer with optional shortcut and group convolution, supporting channel
        expansion.
        """
        super().__init__()
        c_ = int(c2 * e)  # hidden channels
        self.cv1 = Conv(c1, c_, 1, 1)
        self.cv2 = Conv(c_, c2, 3, 1, g=g)
        self.add = shortcut and c1 == c2

    def forward(self, x):
        """Processes input through two convolutions, optionally adds shortcut if channel dimensions match; input is a
        tensor.
        """
        return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x))


class BottleneckCSP(nn.Module):
    # CSP Bottleneck https://github.com/WongKinYiu/CrossStagePartialNetworks
    def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):
        """Initializes CSP bottleneck with optional shortcuts; args: ch_in, ch_out, number of repeats, shortcut bool,
        groups, expansion.
        """
        super().__init__()
        c_ = int(c2 * e)  # hidden channels
        self.cv1 = Conv(c1, c_, 1, 1)
        self.cv2 = nn.Conv2d(c1, c_, 1, 1, bias=False)
        self.cv3 = nn.Conv2d(c_, c_, 1, 1, bias=False)
        self.cv4 = Conv(2 * c_, c2, 1, 1)
        self.bn = nn.BatchNorm2d(2 * c_)  # applied to cat(cv2, cv3)
        self.act = nn.SiLU()
        self.m = nn.Sequential(*(Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)))

    def forward(self, x):
        """Performs forward pass by applying layers, activation, and concatenation on input x, returning feature-
        enhanced output.
        """
        y1 = self.cv3(self.m(self.cv1(x)))
        y2 = self.cv2(x)
        return self.cv4(self.act(self.bn(torch.cat((y1, y2), 1))))

Spatial Pyramid Pooling(SPP)

Spatial Pyramid Pooling叫做空间金字塔池化,它的作用是将任意大小的特征图Pooling到固定的大小,从而使得输入全连接层时具有固定的维度。
在这里插入图片描述
上图为SPP的结构图,它将卷积图的输出使用adptive-pooling的方式,分别pooling到 4 × 4 4\times 4 4×4、 2 × 2 2\times 2 2×2和 1 × 1 1\times 1 1×1的大小,然后将它们打平后concatenate,得到 4 × 4 + 2 × 2 + 1 × 1 = 21 4\times4+2\times2+1\times1=21 4×4+2×2+1×1=21的固定长度。通过这种方式就可以实现任意大小的特征图flatten至固定长度。

PAN path-aggregation block

PAN网络是在FPN的基础增加了从Bottom-up的模块,提高模型对不同尺度特征的学习能力。FPN的网络结构如下图所示
在这里插入图片描述
FPN是在对图像做特征提取后,再进行一次上采样的操作。再看PANnet的结构图
在这里插入图片描述
可以发现PAN网络增加了Bottom-up的模块,即对特征图进行下采样再融合。原始的PAN特征图 P k P_k Pk​和 N k − 1 N_{k-1} Nk−1​的上采样是通过addition融合的,在yolov4中采用了concatenation的方式。具体改变如下图所示,这样就可以比较好地理解yolov4地PAN模块
在这里插入图片描述

SAM

SAM模快来自CBAM: Convolutional Block Attention Module,它是指空间注意力机制模块。在CBAM中,SAM模的实现在特征图的channel维度上使用maxpooling和avg-pooling,然后concatenate,再通过卷积至一维,在经过激活函数,得到空间的注意力分数( 1 × H × W 1\times H\times W 1×H×W)。下图是SAM的实现方法
在这里插入图片描述
在yolov4中,对SAM模块进行了修改,直接通过一个卷积层和激活函数,获得注意力分数。这里的不同就是它没有进行池化,算出的注意力是每一个位置的,即( C × H × W C\times H\times W C×H×W)。
在这里插入图片描述

Mish activation

mish激活函数的表达式为 m i s h ( x ) = x tanh ⁡ ( ln ⁡ ( 1 + e x ) ) mish(x) = x\tanh(\ln(1+e^x)) mish(x)=xtanh(ln(1+ex))它的函数图像如下
在这里插入图片描述
可以发现函数图像是连续的但不单调,但它相较于Relu函数,处理x在负半轴上的问题以及图像不连续的问题,但是它先减后增,理论上不太合理,但它在负半轴上的值较小,所以这个问题就不太明显。

Multi-input weighted residual connections(MiWRC)

Bag of freebies

文中提出了许多的方法,这里主要讲几个比较重要的,数据增强中的Mosaic,处理标签不平衡的Class label smoothing,训练中batch的优化方法 CmBN和Dynamic mini-batch size

Mosaic方法

Mosaic的数据增强方法是将四个图片拼接在一起,具体见下面的代码

def load_mosaic(self, index):
    """Loads a 4-image mosaic for YOLOv5, combining 1 selected and 3 random images, with labels and segments."""
    labels4, segments4 = [], []
    s = self.img_size
    yc, xc = (int(random.uniform(-x, 2 * s + x)) for x in self.mosaic_border)  # mosaic center x, y
    indices = [index] + random.choices(self.indices, k=3)  # 3 additional image indices
    random.shuffle(indices)
    for i, index in enumerate(indices):
        # Load image
        img, _, (h, w) = self.load_image(index)

        # place img in img4
        if i == 0:  # top left
            img4 = np.full((s * 2, s * 2, img.shape[2]), 114, dtype=np.uint8)  # base image with 4 tiles
            x1a, y1a, x2a, y2a = max(xc - w, 0), max(yc - h, 0), xc, yc  # xmin, ymin, xmax, ymax (large image)
            x1b, y1b, x2b, y2b = w - (x2a - x1a), h - (y2a - y1a), w, h  # xmin, ymin, xmax, ymax (small image)
        elif i == 1:  # top right
            x1a, y1a, x2a, y2a = xc, max(yc - h, 0), min(xc + w, s * 2), yc
            x1b, y1b, x2b, y2b = 0, h - (y2a - y1a), min(w, x2a - x1a), h
        elif i == 2:  # bottom left
            x1a, y1a, x2a, y2a = max(xc - w, 0), yc, xc, min(s * 2, yc + h)
            x1b, y1b, x2b, y2b = w - (x2a - x1a), 0, w, min(y2a - y1a, h)
        elif i == 3:  # bottom right
            x1a, y1a, x2a, y2a = xc, yc, min(xc + w, s * 2), min(s * 2, yc + h)
            x1b, y1b, x2b, y2b = 0, 0, min(w, x2a - x1a), min(y2a - y1a, h)

        img4[y1a:y2a, x1a:x2a] = img[y1b:y2b, x1b:x2b]  # img4[ymin:ymax, xmin:xmax]
        padw = x1a - x1b
        padh = y1a - y1b

        # Labels
        labels, segments = self.labels[index].copy(), self.segments[index].copy()
        if labels.size:
            labels[:, 1:] = xywhn2xyxy(labels[:, 1:], w, h, padw, padh)  # normalized xywh to pixel xyxy format
            segments = [xyn2xy(x, w, h, padw, padh) for x in segments]
        labels4.append(labels)
        segments4.extend(segments)

    # Concat/clip labels
    labels4 = np.concatenate(labels4, 0)
    for x in (labels4[:, 1:], *segments4):
        np.clip(x, 0, 2 * s, out=x)  # clip when using random_perspective()
    # img4, labels4 = replicate(img4, labels4)  # replicate

    # Augment
    img4, labels4, segments4 = copy_paste(img4, labels4, segments4, p=self.hyp["copy_paste"])
    img4, labels4 = random_perspective(
        img4,
        labels4,
        segments4,
        degrees=self.hyp["degrees"],
        translate=self.hyp["translate"],
        scale=self.hyp["scale"],
        shear=self.hyp["shear"],
        perspective=self.hyp["perspective"],
        border=self.mosaic_border,
    )  # border to remove

    return img4, labels4

Mosaic是先选定一张图片,然后再随机选择其他三张图片,从而凑齐四张图片。然后选择Mosaic的中心点,这里是从 ( i m a g e _ s i z e / / 2 , 1.5 ∗ ( i m a g e _ s i z e / / 2 ) ) (image\_size//2,1.5*(image\_size//2)) (image_size//2,1.5∗(image_size//2))中任意选择一个整数,从而获取 x , y x,y x,y。这里Mosaic是给定一个 ( 2 ∗ i m a g e _ s i z e , 2 ∗ i m a g e _ s i z e ) (2*image\_size,2*image\_size) (2∗image_size,2∗image_size)的画布,所以中心点是在画布的中心区域进行选取的。然后根据中心点将画布分为四块,分别填入四张图片。最后将画布中的中心部分 [ − i m a g e _ s i z e / / 2 : i m a g e _ s i z e / / 2 , − i m a g e _ s i z e / / 2 : i m a g e _ s i z e / / 2 ] [-image\_size//2:image\_size//2,-image\_size//2:image\_size//2] [−image_size//2:image_size//2,−image_size//2:image_size//2]提取出来作为增强后的图片,这一步的实现是在random_perspective中。
这个方法是可以丰富图片的信息,但是这种方法要根据任务场景去使用,因为它是会丢失一些重要信息的,对于一些上下文信息需求比较大的场景,这种方式明显会丢失很多重要的信息。

Class label smooth

class label smooth是一种soft label的方式,它使分类标签不再是(0,1),而是通过如下公式进行转换 l a b e l = l a b e l ∗ ( 1 − ϵ ) + ϵ / K label = label*(1-\epsilon)+\epsilon/K label=label∗(1−ϵ)+ϵ/K这里 ϵ \epsilon ϵ是一个比较小的常数如0.01, K K K是分类的总数。
当做二分类任务时,标签0和1分别变成0.005和0.995。这种方式可以防止模型过拟合,提高模型的泛化能力。也可以当标签中存在错标的情况时,降低噪音数据带来的影响。

CmBN和Dynamic mini-batch size

CmBN是对Mini Batch进行标准化的一种新方法,具体见下图
在这里插入图片描述
这里假设一个batch有4个mini-batch,在BN层中,它对每个mini-batch都计算权重、均值和方差,然后进行标准化,完成一个batch之后更新权重。在CBN则是每次都计算和更新权重,跨越四个mini batch计算均值和方差,然后对数据进行标准化。而CmBN则是在一个batch中,每个mini-batch都计算权重,均值和方差,然后进行标准化,但是这里第 k ( k > 1 ) k(k>1) k(k>1)会将 ( 0 − k ) (0-k) (0−k)的数据一起计算方差和均值,在进行标准化,所以也称之为跨mini batch标准化。

Dynamic mini-batch size是指训练中使用动态mini-batch大小,原文中的解释使用随机训练维度时随着像素变小自动增加mini-batch的大小。个人理解,这是指multi-scale训练是,当选择像素比较小时,可以采用较大的mini-batch。

YOLOv5

yolov5相较于yolov4的变化不大,不过yolov5的工程化做的非常好,许多方法的实现更精简高效,提供了许多模块的实现,使用者可以根据需求去修改config文件来调用相应的模块

autoanchor

autoanchor的方法是anchor生成自动化了,首先它会将数据中的标签和给定的anchor进行匹配,然后在给定阈值在匹配的anchor超过98%,则认为默认anchor是匹配的。否则的话,根据labels使用kmeans进行聚类,生成9个prior-anchor。这里可以分析一下它的anchor匹配方式,yolov5的实现方式如下

def check_anchors(dataset, model, thr=4.0, imgsz=640):
    """Evaluates anchor fit to dataset and adjusts if necessary, supporting customizable threshold and image size."""
    m = model.module.model[-1] if hasattr(model, "module") else model.model[-1]  # Detect()
    shapes = imgsz * dataset.shapes / dataset.shapes.max(1, keepdims=True)
    scale = np.random.uniform(0.9, 1.1, size=(shapes.shape[0], 1))  # augment scale
    wh = torch.tensor(np.concatenate([l[:, 3:5] * s for s, l in zip(shapes * scale, dataset.labels)])).float()  # wh

    def metric(k):  # compute metric
        r = wh[:, None] / k[None]
        x = torch.min(r, 1 / r).min(2)[0]  # ratio metric
        best = x.max(1)[0]  # best_x
        aat = (x > 1 / thr).float().sum(1).mean()  # anchors above threshold
        bpr = (best > 1 / thr).float().mean()  # best possible recall
        return bpr, aat

    stride = m.stride.to(m.anchors.device).view(-1, 1, 1)  # model strides
    anchors = m.anchors.clone() * stride  # current anchors
    bpr, aat = metric(anchors.cpu().view(-1, 2))
    s = f"\n{PREFIX}{aat:.2f} anchors/target, {bpr:.3f} Best Possible Recall (BPR). "
    if bpr > 0.98:  # threshold to recompute
        LOGGER.info(f"{s}Current anchors are a good fit to dataset ✅")
    else:
        LOGGER.info(f"{s}Anchors are a poor fit to dataset ⚠️, attempting to improve...")
        na = m.anchors.numel() // 2  # number of anchors
        anchors = kmean_anchors(dataset, n=na, img_size=imgsz, thr=thr, gen=1000, verbose=False)
        new_bpr = metric(anchors)[0]
        if new_bpr > bpr:  # replace anchors
            anchors = torch.tensor(anchors, device=m.anchors.device).type_as(m.anchors)
            m.anchors[:] = anchors.clone().view_as(m.anchors)
            check_anchor_order(m)  # must be in pixel-space (not grid-space)
            m.anchors /= stride
            s = f"{PREFIX}Done ✅ (optional: update model *.yaml to use these anchors in the future)"
        else:
            s = f"{PREFIX}Done ⚠️ (original anchors better than new anchors, proceeding with original anchors)"
        LOGGER.info(s)

这里仔细分析一下实现的代码

shapes = imgsz * dataset.shapes / dataset.shapes.max(1, keepdims=True)
scale = np.random.uniform(0.9, 1.1, size=(shapes.shape[0], 1))  # augment scale
wh = torch.tensor(np.concatenate([l[:, 3:5] * s for s, l in zip(shapes * scale, dataset.labels)])).float()  # wh

这里是对输入的label进行resize,将标签中的长宽转化为resize之后的长宽。然后用均匀分布将长宽进行稍微的缩放。

然后这里着重看metric函数,可以看到首先计算了 r r r

r = wh[:, None] / k[None]

这里是通过计标签中的宽高和prior anchor的宽高相除,求出真实宽和真实高与先验框宽和先验框高的比例。

x = torch.min(r, 1 / r).min(2)[0]

这里是由于真实宽和先验框存在 d t > d p d_t>d_p dt​>dp​或者 d t < d p d_t<d_p dt​<dp​的情况,由于无法确定哪个比较大,所以通过去倒数的方式,取出最小值,那么就可以保证 r r r值是小比大的情况。然后这里对长和宽的最小比率中选择它们之间的最小值。假设真实宽高为 d t , h t d_t,h_t dt​,ht​,先验框的宽高为 d p , h p d_p,h_p dp​,hp​,比率 r r r为 r = min ⁡ ( min ⁡ ( d t d p , d p d t ) , min ⁡ ( h t h p , h p h t ) ) r=\min(\min(\frac{d_t}{d_p},\frac{d_p}{d_t}),\min(\frac{h_t}{h_p},\frac{h_p}{h_t})) r=min(min(dp​dt​​,dt​dp​​),min(hp​ht​​,ht​hp​​))

best = x.max(1)[0]  # best_x

这里是由于先验框有九个,每个都与真实框进行对比,所以只需找出9个框中最匹配的那个。

bpr = (best > 1 / thr).float().mean()

这里是将它们匹配比率大于 1 / t h r 1/thr 1/thr的认为是匹配上了,然后统计匹配的比率。这里默认thr为4,即 r > 0.25 r>0.25 r>0.25则认为匹配,这个约束特别小了。

if bpr > 0.98:  # threshold to recompute
        LOGGER.info(f"{s}Current anchors are a good fit to dataset ✅")

这里是指当匹配率超过0.98,则认为默认的先验框是合理的,否则就进行kmeans聚类。

Focus层

yolov5的foucus层,是实现了类似于yolov2中的Fine-Grained Features操作,具体代码如下,这里也没有什么比较新颖的地方。

class Focus(nn.Module):
    # Focus wh information into c-space
    def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True):
        """Initializes Focus module to concentrate width-height info into channel space with configurable convolution
        parameters.
        """
        super().__init__()
        self.conv = Conv(c1 * 4, c2, k, s, p, g, act=act)
        # self.contract = Contract(gain=2)

    def forward(self, x):
        """Processes input through Focus mechanism, reshaping (b,c,w,h) to (b,4c,w/2,h/2) then applies convolution."""
        return self.conv(torch.cat((x[..., ::2, ::2], x[..., 1::2, ::2], x[..., ::2, 1::2], x[..., 1::2, 1::2]), 1))
        # return self.conv(self.contract(x))

yolov5严格而言是一个工程任务,它将yolov1-4的工作做了整合,使其具备很高的适用性,方便人们的使用,所以这也是它在发布后备受关注的主要原因,同时应该也是因为这样所以没有发表论文。

YOLOv6

yolov6是美团发布的,他在22年发布了yolov6(YOLOv6: A Single-Stage Object Detection Framework for Industrial Applications)
yolov6的主要创新点为

  1. 针对不同的工业场景提出了一系列,主要是引入了多分支模块。
  2. 在分类和回归任务上采用了自蒸馏的策略,并动态调整来自teacher model和标签的知识,帮助student model更高效地学习知识。
  3. 验证了一些标签分配、损失函数和数据增强策略的有效性
  4. 使用了ReOptimizer和channel wise distillation来改变检测中的量化策略

Network

yolov6的网络结构如下,其中Backbone有俩个,一个是EfficientRep用于小模型,另一个是CSPStackRep用于大模型。在Neck模块采用改进的PAN模块Rep-PAN。在Head模块采用了Efficient decoupled head,同时采用achor-free的anchor point-based的范式。
在这里插入图片描述

Backbone

Rep(Re-param)

Rep是(RepVGG: Making VGG-style ConvNets Great Again)中提出的一种新方法,它可以降低模型的推理速度,即在训练时用multi-branch,而在推理时转换成single-branch。下图是RepVGG的结构图
在这里插入图片描述
通过上图可以发现,RepVGG借鉴了ResNet的方式,在训练时引入了残差连接,但是在推理时仍保持 3 × 3 3\times 3 3×3卷积堆叠的形式。接下来了解一些具体如何实现。

在这里插入图片描述

上图展示了转换的过程。对于 1 × 1 1\times 1 1×1的卷积可以看成 3 × 3 3\times 3 3×3的卷积,其中仅有中心点的值有权重,其他部分都为0,这样就可以实现 1 × 1 1\times1 1×1卷积转换为 3 × 3 3\times3 3×3卷积。对于 x x x转换为 x x x,可以看成 3 × 3 3\times3 3×3卷积,但中心点的权重为1,且卷积的stride为1。这样就可以等效实现残差连接的效果。最后将三个卷积合并成一个 3 × 3 3\times3 3×3的卷积。同时,需要考虑BN层的问题,因为实际推理中的实现形式为 M ( 2 ) = b n ( M ( 1 ) ∗ W ( 3 ) , μ ( 3 ) , σ ( 3 ) , γ ( 3 ) , β ( 3 ) ) + b n ( M ( 1 ) ∗ W ( 1 ) , μ ( 1 ) , σ ( 1 ) , γ ( 1 ) , β ( 1 ) ) + b n ( M ( 1 ) , μ ( 0 ) , σ ( 0 ) , γ ( 0 , β ( 0 ) ) \begin{align*}M^{(2)} =& bn(M^{(1)}*W^{(3)},\mu^{(3)},\sigma^{(3)},\gamma^{(3)},\beta^{(3)})\\ &+bn(M^{(1)}*W^{(1)},\mu^{(1)},\sigma^{(1)},\gamma^{(1)},\beta^{(1)})\\ &+bn(M^{(1)},\mu^{(0)},\sigma^{(0)},\gamma^{(0},\beta^{(0)})\end{align*} M(2)=​bn(M(1)∗W(3),μ(3),σ(3),γ(3),β(3))+bn(M(1)∗W(1),μ(1),σ(1),γ(1),β(1))+bn(M(1),μ(0),σ(0),γ(0,β(0))​
其中, μ , σ , γ , β \mu,\sigma,\gamma,\beta μ,σ,γ,β都是BN层的参数, W ( 3 ) W^{(3)} W(3)指 3 × 3 3\times 3 3×3卷积的权重, W ( 1 ) W^{(1)} W(1)指 3 × 3 3\times 3 3×3卷积的权重, M ( i ) M^{(i)} M(i)则是第 i i i层的输入。
由于BN层的公式为 b n ( x , μ , σ , γ , β ) = x − μ σ × γ + β bn(x,\mu,\sigma,\gamma,\beta)=\frac{x-\mu}{\sigma}\times\gamma+\beta bn(x,μ,σ,γ,β)=σx−μ​×γ+β
当 x x x为 M ∗ W ( 3 ) M*W^{(3)} M∗W(3)时,有 b n ( M ∗ W ( i ) , μ , σ , γ , β ) = M ∗ W ( 3 ) − μ σ × γ + β = γ ∗ W ( 3 ) σ × M + ( β − μ σ ) = M W ′ + β ′ \begin{align*}bn(M*W^{(i)},\mu,\sigma,\gamma,\beta)=&\frac{M*W^{(3)}-\mu}{\sigma}\times\gamma+\beta\\ =&\frac{\gamma*W^{(3)}}{\sigma}\times M+\left(\beta -\frac{\mu}{\sigma}\right)\\ =&MW'+\beta'\end{align*} bn(M∗W(i),μ,σ,γ,β)===​σM∗W(3)−μ​×γ+βσγ∗W(3)​×M+(β−σμ​)MW′+β′​通过这种方法可以实现BN层和卷积层的参数融合。

EfficientRep和CSPStackRep

EfficientRep的结构见下图,其中stride为2时代表下采样2倍,只有2个branch,没有残差连接的branch。RepBLock则是由N个RepConv组成,这里stride为1。
在这里插入图片描述

CSPStackRep则是CSPNet的基础上进行改进,引入RepConv,将CSPnet block改进为CSPStackRep block。理解了Rep的过程之后,这些改进操作其实就是用RepConv改进之前的Block
在这里插入图片描述

Head

Head部分采用的是PAN结构,但是这里也是将其中的CSPblock换成RepBlock。
在这里插入图片描述

Efficient decoupled head

yolov5的头部是通过权重共享的方式,而yolov6是学习了yolox的方式将它们解耦,分解为分类头和回归头。论文中提到了它用了hybrid-channel的方式,将三层的卷积降至一层(如下图所示),但是它说了头部的宽度由neck和backbone决定,个人认为,这里应该类似于yolov5中定义了大中小三种头。
在这里插入图片描述

Anchor point-based

anchor point-based是一种anchor free的方式,它是基于一个点然后预测距离anchor四个边框点的距离,如中心点为 ( x , y ) (x,y) (x,y),左上点为 ( x 1 , y 1 ) (x_1,y_1) (x1​,y1​),右下点为 ( x 2 , y 2 ) (x_2,y_2) (x2​,y2​),然后预测 ( x − x 1 , y − y 1 , x 2 − x , y 2 − y 1 ) (x-x1,y-y1,x2-x,y2-y1) (x−x1,y−y1,x2−x,y2−y1)这四个距离。对于point的选取方式,在yolov6的实现方式取每个grid的中心点作为point。

Label Assignment

作者首先使用了yolox中的SimOTA的方法,但是发现其效果表现得并不好,所以作者又使用了TOOD(TOOD方法在另一篇文章中也介绍了)中TAL的方法。SimOTA后面在yolox中再介绍,这里介绍TAL(task alignment learning)方法,TAL提出了新的度量标准 t t t,其中 t = s α + μ β t= s^{\alpha}+\mu^{\beta} t=sα+μβ其中 s s s为预测分类分数, μ \mu μ为预测的iou大小,同时 α \alpha α和 β \beta β是超参数。
将分数按 t t t的值进行排序,将 t t t值的前 k k k个作为 p o s pos pos样本,其他的作为 n e g neg neg样本。

标签:YOLOv6,YOLOv4,anchors,卷积,self,YOLO,batch,image,size
From: https://blog.csdn.net/weixin_52862386/article/details/139664320

相关文章

  • 助力樱桃智能自动化采摘,基于YOLOv5全系列【n/s/m/l/x】参数模型开发构建果园种植采摘
    随着科技的飞速发展,人工智能(AI)技术已经渗透到我们生活的方方面面,从智能家居到自动驾驶,再到医疗健康,其影响力无处不在。然而,当我们把目光转向中国的农业领域时,一个令人惊讶的事实映入眼帘——在这片广袤的土地上,农业生产仍然大量依赖人力,而非智能机械化。与此同时,国外的农业生产......
  • 海思SD3403,SS928/926,hi3519dv500,hi3516dv500移植yolov7,yolov8(22)hi3516dv500/19dv5
     最近太忙更新不及时,SS928跑yolov8的文章各位朋友不要催,最近在测试自己魔改的yolov8,测完有结论了跟大家分享。魔改的yolov8在dv500系列里有些小问题,能正常运行,但是优化报错,在做更细致的测试。 先分享一下最近对比RK3588做的测试结果。RK3588算是嵌入式AI里的顶配级别存在......
  • 《YOLOv5入门 + 改进涨点》专栏介绍 & 专栏目录 |目前已有40+篇内容,内含各种Head检测
    《YOLOv5入门+改进涨点》介绍&目录本专栏是博主精心设计的专门为了提升检测效果,希望改进YOLOv5并发表论文的同学们而设计。专栏的内容紧跟学术届的热点更新最新内容,紧跟YOLOv5的官方项目的实时更新。本专栏的内容是基于YOLOv5-6.1的版本进行改进专栏聚焦前沿方法,本专栏的......
  • [YOLOv10涨点改进:注意力魔改 | 轻量级的 Mixed Local Channel Attention (MLCA),加强通
    本文属于原创独家改进:一种轻量级的MixedLocalChannelAttention(MLCA)模块,该模块考虑通道信息和空间信息,并结合局部信息和全局信息以提高网络的表达效果1.YOLOv10介绍论文:[https://arxiv.org/pdf/2405.14458]代码:https://gitcode.com/THU-MIG/yolov10?utm_source=c......
  • yolov5训练日志
       (wind_2021)J:\PytorchProject\yolov5_train_pest_2024061501>(wind_2021)J:\PytorchProject\yolov5_train_pest_2024061501>(wind_2021)J:\PytorchProject\yolov5_train_pest_2024061501>pythontrain_20230320.py--img-size640--batch-size2......
  • 利用基于 Yolo 技术进行植物检测和计数
    这篇论文介绍了一种使用YOLO算法进行植物检测和计数的技术,旨在为农业实践提供一种自动化、有效的解决方案。作者通过收集大量的农田照片,并对每张照片中的植物实例进行精确的边界框标注,训练了这个算法。YOLO算法以其实时物体检测能力而闻名,在图像中将输入图像划分为网格,并预测每个......
  • 机器视觉入门学习:YOLOV5自定义数据集部署、网络详解、损失函数(学习笔记)
     前言源码学习资源:YOLOV5预处理和后处理,源码详细分析-CSDN博客网络学习资源:YOLOv5网络详解_yolov5网络结构详解-CSDN博客YOLOv5-v6.0学习笔记_yolov5的置信度损失公式-CSDN博客 本文为个人学习,整合各路大佬的资料进行V5-6.0版本的网络分析,在开始学习之前最好先去学习YOL......
  • YOLOv5改进策略|YOLOv5鸟类检测,准确率可以达到 87.40%,提升了21.25%,实时检测⻛力发电
    订阅专栏后私信获取完整源码+远程部署目录简介材料和数据收集实验环境实验数据方法YOLOv5RetinexNet模型测试结果与分析结论        ⻛力发电机组的安全是海上⻛电场稳定运行的前提。然而,⻦害对⻛力发电机和⻛力发电机叶片的安全运行构成直接威胁。此......
  • 目标检测数据集 - PCB板表面缺陷检测数据集下载「包含VOC、COCO、YOLO三种格式」
    数据集介绍:PCB板表面缺陷检测数据集,真实采集高质量PCB板表面含缺陷图片数据,数据集含多款不同PCB板高清表面图片数据,包括俯拍正拍、旋转拍摄姿态。数据标注标签包括missing_hole、mouse_bite、open_circuit、short、spur、spurious_copper六个缺陷类别;适用实际项目应用:P......
  • 河道漂浮物识别 YOLOv8
    河道漂浮物识别根据智能视频分析,河道漂浮物识别自动分析识别视频图像信息内容,不用人工干涉;河道漂浮物识别监控区域里的河面漂浮物,出现异常状况时更快开展预警信息,真真正正完成预警信息、正常的检验、规范化管理,合理帮助管理者最大限度地降低乱报和少报;还能够查询视频录像,便捷过......