Notes d'étude de la série de détection de cibles d'apprentissage profond Baidu Flying Paddle Zero-Basic Practice
Table des matières
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
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.
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 :
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.
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 :
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
Cette 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.