目标检测—3 YOLO4


YOLO4相对于YOLO3改进的方面:

  1. CSPDarkNet53+SPP+PANet
  2. 数据增强
  3. loss用CIoU做回归loss
  4. MISH激活函数
CIoU = IoU - \frac{\sigma^2(b,b^{gt})}{c^2}-av

a = \frac{v}{1-IOU+v}

LOSS_{CIOU} = 1- CIoU

Mish = x* tanh(ln(1+e^x))

(1)主干网络

1 CSPDarkNet53

Input[416,416,3]-->
DarknetConv2d_BN_Mish[416,416,32]-->
RestBlock_body * 1 [208,208,64]-->
RestBlock_body * 2 [104,104,128]
RestBlock_body * 8 [52,52,256]--> Conv --> A2
RestBlock_body * 8 [26,26,512]--> Conv --> A3
RestBlock_body * 4 [13,13,1024]-->
Conv * 3 --> A1

2 SPP

A1-->concate( Pooling(5*5) +Pooling(9*9) +Pooling(13*13) +A1 )-->Conv*3--> A4

3 PANet

concat(A3,conv(A4)upsamlping())-->Conv*5-->A5
concat(A2,conv(A5)upsamlping())-->Conv*5-->output1
concat(Downsumpling(output1),A5)-->Conv*5-->output2
concat(Downsumpling(output2),A4)-->Conv*5-->output3

(2) 预测

2.1 yolo = YOLO()   # 主干模型
2.2 r_image = yolo.detect_image(image)  # 检测目标
    2.2.1 boxed_image = letterbox_image(image, new_image_size) # 加入灰条,把图片统一到(416, 416),防止图片失真。
          2.2.1.1 根据目标宽高和原图宽高得出对应最小比例。
          2.2.1.2 原图片宽高乘以最小比例得到新的宽高。
          2.2.1.3 把原始图片放缩到新图片大小。
          2.2.1.4 生成一张shape为(416, 416)灰度图片。
          2.2.1.5 计算新的宽高与灰度图片的差距,确定新图片在灰度图片上的位置,把新图片粘贴到灰度图片上。
    2.2.2 self.boxes, self.scores, self.classes = self.generate() # 预测
          2.2.2.1 self.yolo_model = yolo_body(Input(shape=(None,None,3)), num_anchors//3, num_classes)    # 模型
          2.2.2.2 self.yolo_model.output  # 输出特征层 num_anchors = 3
                  (1) Inputs = [batch_size,416,416,3]
                  (2) P5_outputs=[batch_size,13,13,num_anchors*(num_classes+5)]
                  (3) P4_outputs=[batch_size,26,26,num_anchors*(num_classes+5)]
                  (4) P3_outputs=[batch_size,52,52,num_anchors*(num_classes+5)]
          2.2.2.3 self.anchors     # 先验框的尺寸 12, 16,  19, 36,  40, 28,  36, 75,  76, 55,  72, 146,  142, 110,  192, 243,  459, 401
          2.2.2.4 boxes, scores, classes = yolo_eval(self.yolo_model.output, self.anchors,
                num_classes, self.input_image_shape,
                score_threshold=self.score, iou_threshold=self.iou)  
                  (1) _boxes, _box_scores = yolo_boxes_and_scores(yolo_outputs[l], anchors[anchor_mask[l]], num_classes, input_shape, image_shape)  # 解码
                       a. box_xy, box_wh, box_confidence, box_class_probs = yolo_head(feats, anchors, num_classes, input_shape)  # shape: -1,13,13,3,2; -1,13,13,3,2; -1,13,13,3,1; -1,13,13,3,80
                       b. boxes = yolo_correct_boxes(box_xy, box_wh, input_shape, image_shape)  # 去灰条
                       c. box_scores = box_confidence * box_class_probs # 物体概率
                  (2) mask = box_scores >= score_threshold # 筛选出大于阈值的框
                  (3) nms_index = tf.image.non_max_suppression(
            class_boxes, class_box_scores, max_boxes_tensor, iou_threshold=iou_threshold) # 非极大抑制,去掉box重合程度高的框
                       a. 遍历每一个类别
                       b. 对某一类别的框按照物体概率从大到小排列,取出概率最大框的下标
                       c. 计算其它框和第一个框的IoU,保留IoU小于阈值的框
                       e. 对剩余的框进行b~c的操作,直到剩余框为0
    2.2.3 # 设置字体,遍历所有类别,画出对应的框,标记类别和概率
2.3 r_image.show()  # 显示预测结果

(3) 训练

3.1 model_body = yolo_body(image_input, num_anchors//3, num_classes)  # 创建yolo模型
3.2 yolo_loss # 损失函数
    3.2.1 遍历每一个特征层,取出该特征层中存在目标的点的位置
    3.2.2 grid, raw_pred, pred_xy, pred_wh = yolo_head(yolo_outputs[l],
             anchors[anchor_mask[l]], num_classes, input_shape, calc_loss=True)  # 解码
    3.2.3 _, ignore_mask = K.control_flow_ops.while_loop(lambda b,*args: b<m, loop_body, [0, ignore_mask]) # 找出忽略的样本
    3.2.4 计算CIoU损失作为框的损失
    3.2.5  confidence_loss = object_mask * K.binary_crossentropy(object_mask, raw_pred[...,4:5], from_logits=True)+ \
            (1-object_mask) * K.binary_crossentropy(object_mask, raw_pred[...,4:5], from_logits=True) * ignore_mask  # 计算置信度损失
    3.2.6 class_loss = object_mask * K.binary_crossentropy(true_class_probs, raw_pred[...,5:], from_logits=True) # 类别损失
    3.2.7 loss += location_loss + confidence_loss + class_loss # 总损失
3.3 训练参数设置:TensorBoard、ModelCheckpoint、EarlyStopping、WarmUpCosineDecayScheduler、model.compile、model.fit_generator
3.4 data_generator()  # 数据生成器
    3.2.1 image, box = get_random_data_with_Mosaic()
          (1) 打开图片,框的位置
          (2) 否翻转图片
          (3) 对输入进来的图片进行缩放
          (4) 进行色域变换
          (5) 将图片进行放置,分别对应四张分割图片的位置
          (6) 对box进行重新处理
          (7) 将图片分割,放在一起
          (8) 对框进行进一步的处理
          (9) 将box进行调整
    3.2.2 image, box = get_random_data()
          (1) 对图像进行缩放并且进行长和宽的扭曲
          (2) 将图像多余的部分加上灰条
          (3) 翻转图像
          (4) 色域扭曲
          (5) 对box进行调整
    3.2.3 y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes)
          (1) 根据特征图的宽高生成网格作为先验框的中心坐标,中心点结合先验框的宽高得到先验框的左上角和右下角坐标
          (2) 把真实框映射在特征图上
          (3) 遍历每张图片,计算真实框和哪个先验框最契合
          (4) 每个先验框只配对一个真实框
          (5) 根据真实框的index和先验框的index确定y_true对应index的值

(4) 评价




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值