yolo笔记4

https://blog.csdn.net/weixin_33743703/article/details/87985568

https://github.com/SpikeKing/keras-yolo3-detection

训练时的网络模型

def create_model(input_shape, anchors, num_classes, load_pretrained=True, freeze_body=2,
                 weights_path='model_data/yolo_weights.h5'):
#input_shape:输入图片的尺寸,默认是(416, 416);
#anchors:默认的9种anchor box,结构是(9, 2);
#num_classes:类别个数,在创建网络时,只需类别数即可。在网络中,类别值按0~n排列,同时,输入数据的类别也是用索引表示;
#load_pretrained:是否使用预训练权重。预训练权重,既可以产生更好的效果,也可以加快模型的训练速度;
#freeze_body:冻结模式,1或2。其中,1是冻结DarkNet53网络中的层,2是只保留最后3个1x1的卷积层,其#余层全部冻结;
#weights_path:预训练权重的读取路径;

    K.clear_session()  # 清除session
    h, w = input_shape  # 拆分图片尺寸的宽h和高w;
    image_input = Input(shape=(w, h, 3))  # 创建图片的输入层image_input。在输入层中,既可显##式指定图片尺寸,如(416, 416, 3),也可隐式指定,用“?”代替,如(?, ?, 3);
    num_anchors = len(anchors)  # anchor数量

    # YOLO的三种尺度,每个尺度的anchor数,类别数+边框4个+置信度1
    y_true = [Input(shape=(h // {0: 32, 1: 16, 2: 8}[l], w // {0: 32, 1: 16, 2: 8}[l],
                           num_anchors // 3, num_classes + 5)) for l in range(3)]


#真值即Ground Truth。“//”是Python语法中的整除符号。通过循环,创建3个Input层的列表,作为#y_true。y_true的张量(Tensor)结构


    model_body = yolo_body(image_input, num_anchors // 3, num_classes)  # model
    print('Create YOLOv3 model with {} anchors and {} classes.'.format(num_anchors, num_classes))

    if load_pretrained:  # 加载预训练模型
        model_body.load_weights(weights_path, by_name=True, skip_mismatch=True)  # 加载参数,跳过错误
        print('Load weights {}.'.format(weights_path))
        if freeze_body in [1, 2]:
            # Freeze darknet53 body or freeze all but 3 output layers.
            num = (185, len(model_body.layers) - 3)[freeze_body - 1]
            for i in range(num):
                model_body.layers[i].trainable = False  # 将其他层的训练关闭
            print('Freeze the first {} layers of total {} layers.'.format(num, len(model_body.layers)))

    model_loss = Lambda(yolo_loss,
                        output_shape=(1,), name='yolo_loss',
                        arguments={'anchors': anchors,
                                   'num_classes': num_classes,
                                   'ignore_thresh': 0.5}
                        )(model_body.output + y_true)
    model = Model(inputs=[model_body.input] + y_true, outputs=model_loss)  # 模型,inputs和outputs
    plot_model(model, to_file=os.path.join('model_data', 'model.png'), show_shapes=True, show_layer_names=True)
    model.summary()

    return model

下一步,是加载预训练权重的逻辑块:

根据预训练权重的地址weights_path,加载权重文件,设置参数为,按名称对应by_name,略过不匹配skip_mismatch;
选择冻结模式:
模式1是冻结185层,模式2是保留最底部3层,其余全部冻结。整个模型共有252层;
将所冻结的层,设置为不可训练,model_body.layers[i].trainable=False;
实现:

if load_pretrained:  # 加载预训练模型
    model_body.load_weights(weights_path, by_name=True, skip_mismatch=True)
    if freeze_body in [1, 2]:
        # Freeze darknet53 body or freeze all but 3 output layers.
        num = (185, len(model_body.layers) - 3)[freeze_body - 1]#比如若网络为253层,则
num=(185,250)[0]=185,或者num=(185,250)[1]=250,下面会冻结前面185曾或者时冻结250层
        for i in range(num):
            model_body.layers[i].trainable = False  # 将其他层的训练关闭

IOU计算

IoU 的全称为交并比(Intersection over Union),通过这个名称我们大概可以猜到 IoU 的计算方法。IoU 计算的是 “预测的边框” 和 “真实的边框” 的交集和并集的比值。

猜你喜欢

转载自blog.csdn.net/weixin_38145317/article/details/89209815
今日推荐