win10系统下:keras YOLOv3 mobilenet训练中出现KeyError: 'val_loss'错误的解决办法

win10系统下:keras YOLOv3 mobilenet训练中出现KeyError: 'val_loss’错误的解决办法

yolov3是目前最为快速的目标识别工具,然而其网络十分庞大,训练的模型也很大,一般的gpu都望尘莫及。YOLOv3与mobilenet的结合恰好解决了这个问题。
MobileNet V2发表与2018年,时隔一年,谷歌的又一力作。V2在V1的基础上,引入了Inverted Residuals和Linear Bottlenecks。
简单来说,就是当低维信息映射到高维,经过ReLU后再映射回低维时,若映射到的维度相对较高,则信息变换回去的损失较小;若映射到的维度相对较低,则信息变换回去后损失很大,如下图所示。因此,认为对低维度做ReLU运算,很容易造成信息的丢失。而在高维度进行ReLU运算的话,信息的丢失则会很少。另外一种解释是,高维信息变换回低维信息时,相当于做了一次特征压缩,会损失一部分信息,而再进过relu后,损失的部分就更加大了。作者为了这个问题,就将ReLU替换成线性激活函数。

现在GitHub上面已经出现了相关代码

附上链接

代码结构和数据集处理方式

和yolov3 keras一致,这里可以查看yolov3相关文章

这里主要讲一下在训练中出现的问题

代码的作者在原来的代码基础上将train.py进行了改写,具体改写的地方如下:
原来的代码:

def _main():
    annotation_path = 'train.txt'
    log_dir = 'logs/000/'
    classes_path = 'model_data/voc_classes.txt'
    anchors_path = 'model_data/yolo_anchors.txt'
    class_names = get_classes(classes_path)
    num_classes = len(class_names)
    anchors = get_anchors(anchors_path)

    input_shape = (416,416) # multiple of 32, hw

    is_tiny_version = len(anchors)==6 # default setting
    if is_tiny_version:
        model = create_tiny_model(input_shape, anchors, num_classes,
            freeze_body=2, weights_path='model_data/tiny_yolo_weights.h5')
    else:
        model = create_model(input_shape, anchors, num_classes,
            freeze_body=2, weights_path='model_data/yolo_weights.h5') # make sure you know what you freeze

    logging = TensorBoard(log_dir=log_dir)
    checkpoint = ModelCheckpoint(log_dir + 'ep{epoch:03d}-loss{loss:.3f}-val_loss{val_loss:.3f}.h5',
        monitor='val_loss', save_weights_only=True, save_best_only=True, period=3)
    reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=3, verbose=1)
    early_stopping = EarlyStopping(monitor='val_loss', min_delta=0, patience=10, verbose=1)

    val_split = 0.1
    with open(annotation_path) as f:
        lines = f.readlines()
    np.random.seed(10101)
    np.random.shuffle(lines)
    np.random.seed(None)
    num_val = int(len(lines)*val_split)
    num_train = len(lines) - num_val

作者改后的代码:

def _main():
    train_path = '2007_train.txt'
    val_path = '2007_val.txt'
    log_dir = 'logs/carMobilenet/001_Mobilenet_finetune/'
    classes_path = 'model_data/voc_classes.txt'
    anchors_path = 'model_data/yolo_anchors.txt'
    class_names = get_classes(classes_path)
    num_classes = len(class_names)
    anchors = get_anchors(anchors_path)

    input_shape = (320,320) # multiple of 32, hw

    is_tiny_version = len(anchors)==6 # default setting
    if is_tiny_version:
        model = create_tiny_model(input_shape, anchors, num_classes,
            freeze_body=2)
    else:
        model = create_model(input_shape, anchors, num_classes,load_pretrained=False,
                             weights_path='logs/carMobilenet/000_Mobilenet_finetune/trained_weights_final.h5',
            freeze_body=2) # make sure you know what you freeze

    logging = TensorBoard(log_dir=log_dir)
    # checkpoint = ModelCheckpoint(log_dir + 'car_mobilenet_yolov3.ckpt',
    #    monitor='val_loss', save_weights_only=False, period=1)
    checkpoint = ModelCheckpoint(log_dir + 'ep{epoch:03d}-loss{loss:.3f}-val_loss{val_loss:.3f}.h5',
        monitor='val_loss', save_weights_only=True, save_best_only=True, period=3)
    reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=3, verbose=1)
    early_stopping = EarlyStopping(monitor='val_loss', min_delta=0, patience=10, verbose=1)

    with open(train_path) as t_f:
        t_lines = t_f.readlines()
    np.random.seed(10101)
    np.random.shuffle(t_lines)
    np.random.seed(None)
    v_lines = t_lines[8000:]
    t_lines = t_lines[:8000]
    num_train = len(t_lines)
    num_val = len(v_lines)

大家可能还是没有明白哪里不一样,我再具体一些

这是原来的train.py的取验证集比例的代码

 val_split = 0.1
    with open(annotation_path) as f:
        lines = f.readlines()
    np.random.seed(10101)
    np.random.shuffle(lines)
    np.random.seed(None)
    num_val = int(len(lines)*val_split)
    num_train = len(lines) - num_val

这是新的train_mobilenet.py的取验证集的代码:

    np.random.seed(10101)
    np.random.shuffle(t_lines)
    np.random.seed(None)
    v_lines = t_lines[8000:]
    t_lines = t_lines[:8000]
    num_train = len(t_lines)
    num_val = len(v_lines)

大家可以看出作者在后者中选择了手动取样的方式,这里的t_lines[8000:]表示作者用8000张验证集,我们在训练的时候可能没有这么多,所以要改写成自己的图片数量,这样KeyError: 'val_loss’报错问题就解决了!!!

你可能感兴趣的:(yolov3)