Enregistrements d'apprentissage de la série de détection de cible d'entrée à base zéro (2) : explication détaillée de l'algorithme v3 de la série YOLO

Notes d'étude de la série de détection de cibles d'apprentissage profond Baidu Flying Paddle Zero-Basic Practice

Structure YOLOv3

Caractéristiques de la structure du réseau YOLOv3 :

1. Uniquement convolution sans pooling
2.3 cartes de fonctionnalités pour détecter des objets de différentes tailles
3. Utilisez la structure ResNet
4.3 cartes de fonctionnalités à utiliser pour l'épissage 5.
Utilisez sigmoïde pour obtenir
insérer la description de l'image ici
une dorsale multicatégorie **: Darknet53 ** Utilisez 1 dans le réseau fédérateur Les trois cartes de fonctionnalités de /8, 1/16 et 1/32 sont utilisées pour la fusion de cartes de fonctionnalités. Une structure résiduelle est utilisée dans le réseau.
Pourquoi l'utiliser : Beaucoup plus rapide que ResNet avec la même précision, plus lent mais plus précis que Darknet19.
insérer la description de l'image iciinsérer la description de l'image ici
insérer la description de l'image ici

format de forme et boîte préalable

SxSx3x(C+5) : taille, nombre d'images précédentes 3, position du cadre de détection (XYHW4), confiance de détection (1), dimension de catégorie (C)
utiliser le clustering pour étiqueter les images et obtenir 9 images comme boîte d'inspection a priori :

(10 × 13), (16 × 30), (33 × 23), (30 × 61), (62 × 45), (59 ×
119), (116 × 90), (156 × 198), (373 × 326).

Le boitier de détection de sortie réseau est le suivant :
insérer la description de l'image ici

Le flux de traitement de la box

1. Obtenu grâce à trois cartes de caractéristiques : 8 8 3, 16 16 3 , 32 32 3 , 3 cases pour chaque grille , un total de 4032 cases.
2. Envoyez-le au calcul des pertes.
3. Définissez le seuil de confiance pendant l'inférence, puis utilisez NMS pour générer le résultat de la prédiction.

insérer la description de l'image ici

Stratégie de formation et fonction de perte

Boîte de prédiction : exemple positif (positif), exemple négatif (négatif), exemple ignoré (ignorer)

Exemple positif : Prenez une vérité terrain et calculez l'IOU avec la trame prédite. La plus grande est un exemple positif. L'
exemple positif génère une perte de confiance, une perte de trame de détection et une perte de catégorie.

Exemple négatif : si la reconnaissance de dette avec toute la vérité terrain est inférieure à la valeur normale (0,5), il s'agit d'un exemple négatif.
Pour les cas négatifs, seule la confiance de classification produit une perte , l'étiquette de classification est 0 et la régression des limites ne produit pas de perte.

Ignorer l'échantillon : à l'exception de l'exemple positif, si la reconnaissance de dette avec une vérité terrain est supérieure au seuil (0,5 est utilisé dans l'article), il s'agit d'un échantillon ignoré. Ignorer les exemples ne génère aucune perte.

Record : Pour les exemples négatifs, il participera uniquement au calcul de la Perte Focale de confiance de classification, et n'affectera pas la Perte de classification et la régression de trame. Car pour les exemples négatifs, ils ne contiennent pas l'objet cible, ils n'ont donc pas besoin de participer au calcul de la perte de classification et de régression de position de la cible.

Les exemples négatifs, bien qu'ils ne soient pas la cible, peuvent être prédits comme une certaine cible. Si nous ignorons complètement le cas des exemples négatifs, le réseau peut ignorer certains exemples négatifs, qui peuvent contenir des caractéristiques très similaires à la cible. Par conséquent, pour les exemples négatifs, nous devons pénaliser la fonction de perte de confiance de classification afin d’encourager le réseau à faire des prédictions plus précises pour les exemples négatifs. C'est pourquoi les exemples négatifs doivent également participer au calcul de la perte focale de confiance de classification.

Fonction de perte : perte de confiance, perte de trame de détection, perte de catégorie

Perte de confiance : FOCAL = FocalLoss(gamma=2, alpha=1.0, reduction="none")
perte de trame de détection : giou = tools.GIOU_xywh_torch(p_d_xywh, label_xywh).unsqueeze(-1)
perte de catégorie :BCE = nn.BCEWithLogitsLoss(reduction="none")

Interprétation du code YOLOv3

1. Partie avant du réseau

    def forward(self, x):
        out = []
			
		#通过Darknet53提取三个feature
        x_s, x_m, x_l = self.__backnone(x)
        #通过FPN进行concat与输出
        x_s, x_m, x_l = self.__fpn(x_l, x_m, x_s)
		#将三个不同尺寸的feature送入head进行解码
		#也就是将三个输出解码成预测框!!
        out.append(self.__head_s(x_s))
        out.append(self.__head_m(x_m))
        out.append(self.__head_l(x_l))

        if self.training:
            p, p_d = list(zip(*out))
            return p, p_d  # smalll, medium, large
        else:
            p, p_d = list(zip(*out))
            return p, torch.cat(p_d, 0)

2. Partie YOLOv3_head

Le principe est la mise en œuvre de ces formules :
insérer la description de l'image ici

class Yolo_head(nn.Module):
    def __init__(self, nC, anchors, stride):
        super(Yolo_head, self).__init__()
		# anchors是先验框(v3中是每个尺度三个先验框),nA是先验框的个数,nC是类别的个数,stride是步长
        self.__anchors = anchors
        self.__nA = len(anchors)
        self.__nC = nC
        self.__stride = stride


    def forward(self, p):
        # 获取输入的batch_size和特征图大小
        bs, nG = p.shape[0], p.shape[-1]
        # 将p转为bs,nA,nC+5,nG,nG的形状,注意这里将类别+5是因为每个anchor对应的输出包含:tx,ty,tw,th,confidence,类别概率
        # 因此5+C的形状
        p = p.view(bs, self.__nA, 5 + self.__nC, nG, nG).permute(0, 3, 4, 1, 2)
	     # 将预测的特征图解码,返回解码后的预测值
        p_de = self.__decode(p.clone())

        return (p, p_de)


    def __decode(self, p):
        # 获取batch_size和输出大小
        batch_size, output_size = p.shape[:2]
		# 获取当前设备
        device = p.device
        # 获取步长和先验框,转化为device类型
        stride = self.__stride
        anchors = (1.0 * self.__anchors).to(device)
			
		# 预测中心坐标、宽高、置信度以及类别概率
        conv_raw_dxdy = p[:, :, :, :, 0:2]
        conv_raw_dwdh = p[:, :, :, :, 2:4]
        conv_raw_conf = p[:, :, :, :, 4:5]
        conv_raw_prob = p[:, :, :, :, 5:]
        
		# 将特征图中心坐标转为全图坐标
        y = torch.arange(0, output_size).unsqueeze(1).repeat(1, output_size)
        x = torch.arange(0, output_size).unsqueeze(0).repeat(output_size, 1)
        grid_xy = torch.stack([x, y], dim=-1)
        grid_xy = grid_xy.unsqueeze(0).unsqueeze(3).repeat(batch_size, 1, 1, 3, 1).float().to(device)
		# 计算预测的坐标和宽高
        pred_xy = (torch.sigmoid(conv_raw_dxdy) + grid_xy) * stride
        pred_wh = (torch.exp(conv_raw_dwdh) * anchors) * stride
        # 将预测的坐标和宽高拼接在一起得到预测的边界框
        pred_xywh = torch.cat([pred_xy, pred_wh], dim=-1)
        # 计算预测的置信度和类别概率
        pred_conf = torch.sigmoid(conv_raw_conf)
        pred_prob = torch.sigmoid(conv_raw_prob)
        # # 将预测的边界框、置信度和类别概率拼接在一起得到最终的预测
        pred_bbox = torch.cat([pred_xywh, pred_conf, pred_prob], dim=-1)

        return pred_bbox.view(-1, 5 + self.__nC) if not self.training else pred_bbox

insérer la description de l'image iciCette section du code consiste à déterminer le point central de l'ancre, le point central est le coin supérieur gauche de chaque grille et chaque grille génère trois cases antérieures.

Je suppose que tu aimes

Origine blog.csdn.net/m0_63495706/article/details/130062471
conseillé
Classement