yolov3改进简述

一、完整修改版

1、函数yolov3:模型结构

修改模型输出,删减wh

# conv_lbbox = common.convolutional(conv_lobj_branch, (1, 1, 1024, 3*(NUM_CLASS + 5)), activate=False, bn=False)
conv_lbbox = common.convolutional(conv_lobj_branch, (1, 1, 1024, 3*(NUM_CLASS + 3)), activate=False, bn=False)
# conv_mbbox = common.convolutional(conv_mobj_branch, (1, 1, 512, 3*(NUM_CLASS + 5)), activate=False, bn=False)
conv_mbbox = common.convolutional(conv_mobj_branch, (1, 1, 512, 3*(NUM_CLASS + 3)), activate=False, bn=False)
# conv_sbbox = common.convolutional(conv_sobj_branch, (1, 1, 256, 3*(NUM_CLASS +5)), activate=False, bn=False)
conv_sbbox = common.convolutional(conv_sobj_branch, (1, 1, 256, 3*(NUM_CLASS +3)), activate=False, bn=False)

2、函数decode:

按照新的索引关系赋值

# conv_output = tf.reshape(conv_output, (batch_size, output_size, output_size, 3, 5 + NUM_CLASS))
conv_output = tf.reshape(conv_output, (batch_size, output_size, output_size, 3, 3 + NUM_CLASS))

# conv_raw_dxdy = conv_output[:, :, :, :, 0:2]
# conv_raw_dwdh = conv_output[:, :, :, :, 2:4]
# conv_raw_conf = conv_output[:, :, :, :, 4:5]
# conv_raw_prob = conv_output[:, :, :, :, 5: ]

conv_raw_dxdy = conv_output[:, :, :, :, 0:2]
# conv_raw_dwdh = conv_output[:, :, :, :, 2:4]
conv_raw_conf = conv_output[:, :, :, :, 2:3]
conv_raw_prob = conv_output[:, :, :, :, 3: ]

返回值中的pred_xywh改为pred_xy

pred_xy = (tf.sigmoid(conv_raw_dxdy) + xy_grid) * STRIDES[i]
# pred_wh = (tf.exp(conv_raw_dwdh) * ANCHORS[i]) * STRIDES[i]
# pred_xywh = tf.concat([pred_xy, pred_wh], axis=-1)

pred_conf = tf.sigmoid(conv_raw_conf)
pred_prob = tf.sigmoid(conv_raw_prob)

# return tf.concat([pred_xywh, pred_conf, pred_prob], axis=-1)
return tf.concat([pred_xy, pred_conf, pred_prob], axis=-1)

函数compute_loss:

首先修改对应的索引关系
使用自定义函数convert1将模型预测值pred_xy拼接上固定值wh,令pred_xywh参与loss计算

# conv_raw_conf = conv[:, :, :, :, 4:5]
# conv_raw_prob = conv[:, :, :, :, 5:]
conv_raw_conf = conv[:, :, :, :, 2:3]
conv_raw_prob = conv[:, :, :, :, 3: ]    

# pred_xywh     = pred[:, :, :, :, 0:4]
# pred_conf     = pred[:, :, :, :, 4:5]

pred_xy         = pred[:, :, :, :, 0:2]
pred_conf       = pred[:, :, :, :, 2:3]
pred_xywh       = convert1(pred_xy, box_wh)
def convert1(x, size):
    shape = tf.shape(x).numpy()
    newshape = np.append(shape[:-1],2)
    ndarray = tf.convert_to_tensor(np.full(newshape, size),dtype=tf.float32)
    out = tf.concat([x, ndarray],-1)
    return out

4、函数postprocess_boxes:处理预测框

修改对应的新索引值,同理使用函数convert1把固定的wh值拼接到预测出的pred_xy上

# pred_bbox = np.array(pred_bbox)
# pred_xywh = pred_bbox[:, 0:4]
# pred_conf = pred_bbox[:, 4]
# pred_prob = pred_bbox[:, 5:]
pred_xy         = pred_bbox[:, 0:2]
pred_conf       = pred_bbox[:, 2]
pred_prob       = pred_bbox[:, 3:]
pred_xywh       = convert1(pred_xy, box_wh)

pred_xy         = np.array(pred_xy)
pred_conf       = np.array(pred_conf)
pred_prob       = np.array(pred_prob)
pred_xywh       = np.array(pred_xywh)  

二、微调版

只修改了compute_loss函数,指定wh预测值为固定值,

函数postprocess_boxes中,模型预测出框的参数也没有修改

pred_xywh     = pred[:, :, :, :, 0:4]
# 指定wh预测值为固定值
pred_xywh     = convert(pred_xywh, 1280/10800*608, 608)
def convert(tensor, w, h):
    for i in tensor.numpy():
        for j in i:
            for m in j:
                for n in m:
                    n[2:] = [w,h]
    return tf.convert_to_tensor(tensor, dtype=tf.float32)
def compute_loss(pred, conv, label, bboxes, i=0):

    conv_shape  = tf.shape(conv)
    batch_size  = conv_shape[0]
    output_size = conv_shape[1]
    input_size  = STRIDES[i] * output_size
    conv = tf.reshape(conv, (batch_size, output_size, output_size, 3, 3 + NUM_CLASS))

    conv_raw_conf = conv[:, :, :, :, 2:3]
    conv_raw_prob = conv[:, :, :, :, 3: ]    

    pred_xy         = pred[:, :, :, :, 0:2]
    pred_conf       = pred[:, :, :, :, 2:3]
    pred_xywh       = convert1(pred_xy, box_wh)

    label_xywh    = label[:, :, :, :, 0:4]
    respond_bbox  = label[:, :, :, :, 4:5]
    label_prob    = label[:, :, :, :, 5:]

    giou = tf.expand_dims(bbox_giou(pred_xywh, label_xywh), axis=-1)
for epoch in range(cfg.TRAIN.EPOCHS):
    for image_data, target in trainset:
        train_step(image_data, target)
    model.save_weights("./yolov3")

target 部分值如下

       [[408.5, 304. ,  77. , 608. ],
        [  0. ,   0. ,   0. ,   0. ],
        [  0. ,   0. ,   0. ,   0. ],
        ...,
        [  0. ,   0. ,   0. ,   0. ],
        [  0. ,   0. ,   0. ,   0. ],
        [  0. ,   0. ,   0. ,   0. ]],

       [[457.5, 304. ,  77. , 608. ],
        [  0. ,   0. ,   0. ,   0. ],
        [  0. ,   0. ,   0. ,   0. ],
        ...,
        [  0. ,   0. ,   0. ,   0. ],
        [  0. ,   0. ,   0. ,   0. ],
        [  0. ,   0. ,   0. ,   0. ]],

       [[351. , 303.5,  78. , 607. ],
        [  0. ,   0. ,   0. ,   0. ],
        [  0. ,   0. ,   0. ,   0. ],
        ...,
        [  0. ,   0. ,   0. ,   0. ],
        [  0. ,   0. ,   0. ,   0. ],
        [  0. ,   0. ,   0. ,   0. ]]], dtype=float32)))

版权声明:本文为Winds_Up原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。