Registros de aprendizaje de la serie de detección de objetivos de entrada de base cero (2): explicación detallada del algoritmo v3 de la serie YOLO

Notas de estudio de la serie de detección de objetivos de aprendizaje profundo de práctica básica cero de Baidu Flying Paddle

Estructura YOLOv3

Características de la estructura de red YOLOv3:

1. Solo convolución sin agrupación
2.3 mapas de características para detectar objetos de diferentes tamaños
3. Use la estructura ResNet
4.3 mapas de características para usar add para empalmar
5. Use sigmoide para lograr
inserte la descripción de la imagen aquí
una columna vertebral de múltiples categorías **:Darknet53** Use 1 en la red troncal Los tres mapas de características de /8, 1/16 y 1/32 se utilizan para la fusión de mapas de características. Se utiliza una estructura residual en la red.
Por qué usarlo: mucho más rápido que ResNet con la misma precisión, más lento pero con mayor precisión que Darknet19.
inserte la descripción de la imagen aquíinserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

formato de forma y cuadro anterior

SxSx3x(C+5) : tamaño, número de fotogramas anteriores 3, posición del fotograma de detección (XYHW4), confianza de detección (1), dimensión de categoría (C),
utilice agrupación para etiquetar fotogramas y obtenga 9 fotogramas como cuadro de inspección a priori:

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

El cuadro de detección de salida de red es el siguiente:
inserte la descripción de la imagen aquí

El flujo de procesamiento de la caja.

1. Obtenido a través de tres mapas de características: 8 8 3, 16 16 3 , 32 32 3 , 3 cuadros para cada cuadrícula , un total de 4032 cuadros.
2. Enviarlo al cálculo de pérdidas.
3. Establezca el umbral de confianza durante la inferencia y luego use NMS para generar el resultado de la predicción.

inserte la descripción de la imagen aquí

Estrategia de entrenamiento y función de pérdida.

Cuadro de predicción: ejemplo positivo (positivo), ejemplo negativo (negativo), ejemplo ignorado (ignorar)

Ejemplo positivo : Tome una verdad fundamental y calcule el pagaré con el marco predicho. El más grande es un ejemplo positivo. El
ejemplo positivo genera pérdida de confianza, pérdida de marco de detección y pérdida de categoría.

Ejemplo negativo: si el pagaré con toda la verdad fundamental es menor que el valor normal (0,5), es un ejemplo negativo.
Para casos negativos, solo la confianza de clasificación produce pérdida , la etiqueta de clasificación es 0 y la regresión de límites no produce pérdida.

Ignorar la muestra: excepto en el ejemplo positivo, si el pagaré con cualquier verdad fundamental es mayor que el umbral (en el artículo se usa 0,5), es una muestra ignorada. Ignorar ejemplos no genera ninguna pérdida.

Registro : para ejemplos negativos, solo participará en el cálculo de la pérdida focal de confianza de clasificación y no afectará la pérdida de clasificación ni la regresión del marco. Porque los ejemplos negativos no contienen el objeto objetivo, por lo que no necesitan participar en el cálculo de la pérdida de clasificación y la regresión de posición del objetivo.

Los ejemplos negativos, aunque no son el objetivo, pueden predecirse como algún objetivo. Si ignoramos por completo el caso de ejemplos negativos, la red puede ignorar algunos ejemplos negativos, que pueden contener algunas características que son muy similares al objetivo. Por lo tanto, para los ejemplos negativos, debemos penalizar la función de pérdida de confianza de la clasificación para alentar a la red a hacer predicciones más precisas para los ejemplos negativos. Es por eso que los ejemplos negativos también deben participar en el cálculo de la pérdida focal de confianza de clasificación.

Función de pérdida: pérdida de confianza, pérdida de cuadro de detección, pérdida de categoría

Pérdida de confianza : FOCAL = FocalLoss(gamma=2, alpha=1.0, reduction="none")
pérdida de cuadro de detección : giou = tools.GIOU_xywh_torch(p_d_xywh, label_xywh).unsqueeze(-1)
pérdida de categoría:BCE = nn.BCEWithLogitsLoss(reduction="none")

Interpretación del código YOLOv3

1. Parte delantera de la red

    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. YOLOv3_parte principal

El principio es la implementación de estas fórmulas:
inserte la descripción de la imagen aquí

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

inserte la descripción de la imagen aquíEsta sección del código es para determinar el punto central del ancla, el punto central es la esquina superior izquierda de cada cuadrícula y cada cuadrícula genera tres cuadros anteriores.

Supongo que te gusta

Origin blog.csdn.net/m0_63495706/article/details/130062471
Recomendado
Clasificación