Focal-Eiou

yolov4损失函数替换

根据数学公式:

  • https://gitee.com/Brief-rf/BlogImages/raw/master/img/202101211702104.png
    Leiou

  • https://gitee.com/Brief-rf/BlogImages/raw/master/img/20210121170231641.png
    Lfocal-Eiou

损失函数替换

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
from keras import backend as K
import tensorflow as tf

def focal_eiou(b1, b2):
    """
    输入为:
    ----------
    b1: tensor, shape=(batch, feat_w, feat_h, anchor_num, 4), xywh
    b2: tensor, shape=(batch, feat_w, feat_h, anchor_num, 4), xywh

    返回为:
    -------
    ciou: tensor, shape=(batch, feat_w, feat_h, anchor_num, 1)
    """

    #-----------------------------------------------------------#
    #   求出预测框左上角右下角
    #   b1_mins     (batch, feat_w, feat_h, anchor_num, 2)
    #   b1_maxes    (batch, feat_w, feat_h, anchor_num, 2)
    #-----------------------------------------------------------#
    b1_xy = b1[..., :2]
    b1_wh = b1[..., 2:4]
    b1_wh_half = b1_wh/2.
    b1_mins = b1_xy - b1_wh_half
    b1_maxes = b1_xy + b1_wh_half
    #-----------------------------------------------------------#
    #   求出真实框左上角右下角
    #   b2_mins     (batch, feat_w, feat_h, anchor_num, 2)
    #   b2_maxes    (batch, feat_w, feat_h, anchor_num, 2)
    #-----------------------------------------------------------#
    b2_xy = b2[..., :2]
    b2_wh = b2[..., 2:4]
    b2_wh_half = b2_wh/2.
    b2_mins = b2_xy - b2_wh_half
    b2_maxes = b2_xy + b2_wh_half

    #-----------------------------------------------------------#
    #   求真实框和预测框所有的iou
    #   iou         (batch, feat_w, feat_h, anchor_num)
    #-----------------------------------------------------------#
    intersect_mins = K.maximum(b1_mins, b2_mins)
    intersect_maxes = K.minimum(b1_maxes, b2_maxes)
    intersect_wh = K.maximum(intersect_maxes - intersect_mins, 0.)
    # ∩面积
    intersect_area = intersect_wh[..., 0] * intersect_wh[..., 1]
    b1_area = b1_wh[..., 0] * b1_wh[..., 1]
    b2_area = b2_wh[..., 0] * b2_wh[..., 1]
    # ∪面积
    union_area = b1_area + b2_area - intersect_area
    # ∩/∪
    iou = intersect_area / K.maximum(union_area, K.epsilon())

    #-----------------------------------------------------------#
    #   计算中心的差距 c**2
    #   center_distance (batch, feat_w, feat_h, anchor_num)
    #-----------------------------------------------------------#
    # p**2 中心点距离
    center_distance = K.sum(K.square(b1_xy - b2_xy), axis=-1)
    # 左上和右下的最小外接矩形w、h
    enclose_mins = K.minimum(b1_mins, b2_mins)
    enclose_maxes = K.maximum(b1_maxes, b2_maxes)
    enclose_wh = K.maximum(enclose_maxes - enclose_mins, 0.0)
    #-----------------------------------------------------------#
    #   计算对角线距离 c**2
    #   enclose_diagonal (batch, feat_w, feat_h, anchor_num)
    #-----------------------------------------------------------#
    enclose_diagonal = K.sum(K.square(enclose_wh), axis=-1)

    w_h = K.square(b1_wh - b2_wh)
    Cw_Ch = K.maximum(K.square(enclose_wh) ,K.epsilon())

    squares =  w_h / Cw_Ch

    Leiou = 1 - iou + 1.0 * (center_distance) / K.maximum(enclose_diagonal ,K.epsilon()) + K.sum( 1.0 * squares)

    gamma = 0.5
    focal_eiou_loss = Leiou * iou ** gamma


    return focal_eiou_loss
if __name__ == "__main__":

    # 导入tensorflow库进行变量创建
    import tensorflow as tf

    # 创建两个变量 predict, truth进行测试
    predict = tf.constant(0.6, shape=(1, 13, 13, 1, 4), dtype=tf.float32)
    truth = tf.constant(0.5, shape=(1, 13, 13, 1, 4), dtype=tf.float32)

    # 调用定义的函数
    result = focal_eiou(predict,truth)

    with tf.Session() as sess:
        print(sess.run(result))

相关损失函数文章连接点我跳转