Beispiel #1
0
def _main_(args):
    config_path = args.conf
    weights_path = args.weights

    keras.backend.tensorflow_backend.set_session(get_session())

    with open(config_path) as config_buffer:
        config = json.load(config_buffer)

    if weights_path == '':
        weights_path = config['train']['saved_weights_name']

    yolo = YOLO(backend=config['model']['backend'],
                input_size=(config['model']['input_size_h'],
                            config['model']['input_size_w']),
                labels=config['model']['labels'],
                max_box_per_image=config['model']['max_box_per_image'],
                anchors=config['model']['anchors'],
                gray_mode=config['model']['gray_mode'])

    yolo.load_weights(weights_path)

    inference_model = yolo.get_inference_model()
    inference_model.save("{}_inference.h5".format(
        os.path.split(weights_path)[0]))
def _main_(args):

    config_path = args.conf
    
    with open(config_path) as config_buffer:    
        config = json.loads(config_buffer.read())

    if config['backup']['create_backup']:
        config = create_backup(config)

    keras.backend.tensorflow_backend.set_session(get_session())

    #path for the training and validation dataset
    datasetTrainPath = os.path.join(args.folder,"train")
    datasetValPath = os.path.join(args.folder,"val")

    for folder in [datasetTrainPath, datasetValPath]:
        if not os.path.isdir(folder):
            raise Exception("{} doesn't exist!".format(folder))

    classesTrain = next(os.walk(datasetTrainPath))[1]
    classesVal = next(os.walk(datasetValPath))[1]

    if not classesVal == classesTrain:
        raise Exception("The training and validation classes must be the same!")
    else:
        folders = classesTrain

    #training configuration
    epochs = config['train']['nb_epochs']
    batchSize = config['train']['batch_size']
    width = config['model']['input_size_w']
    height = config['model']['input_size_h']
    depth = 3 if config['model']['gray_mode'] == False else 1

    #config keras generators
    if len(folders) == 2: #if just have 2 classes, the model will have a binary output
        classes = 1
    else:
        classes = len(folders)

    #count all samples
    imagesTrainPaths = []
    imagesValPaths = []
    for folder in folders: 
        imagesTrainPaths+=list(list_images(os.path.join(datasetTrainPath, folder)))
        imagesValPaths+=list(list_images(os.path.join(datasetValPath, folder)))
    
    generator_config = {
        'IMAGE_H'         : height, 
        'IMAGE_W'         : width,
        'IMAGE_C'         : depth,
        'BATCH_SIZE'      : batchSize
    }  

    #callbacks    
    model_name = config['train']['saved_weights_name']
    checkPointSaverBest=ModelCheckpoint(model_name, monitor='val_acc', verbose=1, 
                                        save_best_only=True, save_weights_only=False, mode='auto', period=1)
    ckp_model_name = os.path.splitext(model_name)[1]+"_ckp.h5"
    checkPointSaver=ModelCheckpoint(ckp_model_name, verbose=1, 
                                save_best_only=False, save_weights_only=False, period=10)

    tb=TensorBoard(log_dir=config['train']['tensorboard_log_dir'], histogram_freq=0, batch_size=batchSize, write_graph=True,
                write_grads=False, write_images=False, embeddings_freq=0, embeddings_layer_names=None, embeddings_metadata=None)


    #create the classification model
    # make the feature extractor layers
    if depth == 1:
        input_size = (height, width, 1)
        input_image     = Input(shape=input_size)
    else:
        input_size = (height, width, 3)
        input_image     = Input(shape=input_size)

    feature_extractor = import_feature_extractor(config['model']['backend'], input_size)

    train_generator = BatchGenerator(imagesTrainPaths, 
                                generator_config, 
                                norm=feature_extractor.normalize,
                                jitter=True)
    val_generator = BatchGenerator(imagesValPaths, 
                                    generator_config, 
                                    norm=feature_extractor.normalize,
                                    jitter=False)  

    features = feature_extractor.extract(input_image)          

    # make the model head
    output = Conv2D(classes, (1, 1), padding="same")(features)
    output = BatchNormalization()(output)
    output = LeakyReLU(alpha=0.1)(output)
    output = GlobalAveragePooling2D()(output)
    output = Activation("sigmoid")(output) if classes == 1 else Activation("softmax")(output)

    if config['train']['pretrained_weights'] != "":
        model = load_model(config['model']['pretrained_weights'] )
    else:
        model = Model(input_image, output)   
        opt = Adam()
        model.compile(loss="binary_crossentropy" if classes == 1 else "categorical_crossentropy",
                    optimizer=opt,metrics=["accuracy"])
    model.summary()

    model.fit_generator(
            train_generator,
            steps_per_epoch=len(imagesTrainPaths)//batchSize,
            epochs=epochs,
            validation_data=val_generator,
            validation_steps=len(imagesValPaths)//batchSize,
            callbacks=[checkPointSaverBest,checkPointSaver,tb],
            workers=12,
            max_queue_size=40)
Beispiel #3
0
def _main_(args):
    config_path = args.conf

    keras.backend.tensorflow_backend.set_session(get_session())

    with open(config_path) as config_buffer:
        config = json.loads(config_buffer.read())

    if config['backup']['create_backup']:
        config = create_backup(config)
    ###############################
    #   Parse the annotations
    ###############################

    if config['parser_annotation_type'] == 'xml':
        # parse annotations of the training set
        train_imgs, train_labels = parse_annotation_xml(
            config['train']['train_annot_folder'],
            config['train']['train_image_folder'], config['model']['labels'])

        # parse annotations of the validation set, if any, otherwise split the training set
        if os.path.exists(config['valid']['valid_annot_folder']):
            valid_imgs, valid_labels = parse_annotation_xml(
                config['valid']['valid_annot_folder'],
                config['valid']['valid_image_folder'],
                config['model']['labels'])
            split = False
        else:
            split = True
    elif config['parser_annotation_type'] == 'csv':
        # parse annotations of the training set
        train_imgs, train_labels = parse_annotation_csv(
            config['train']['train_csv_file'], config['model']['labels'],
            config['train']['train_csv_base_path'])

        # parse annotations of the validation set, if any, otherwise split the training set
        if os.path.exists(config['valid']['valid_csv_file']):
            valid_imgs, valid_labels = parse_annotation_csv(
                config['valid']['valid_csv_file'], config['model']['labels'],
                config['valid']['valid_csv_base_path'])
            split = False
        else:
            split = True
    else:
        raise ValueError(
            "'parser_annotations_type' must be 'xml' or 'csv' not {}.".format(
                config['parser_annotations_type']))

    if split:
        train_valid_split = int(0.8 * len(train_imgs))
        np.random.shuffle(train_imgs)

        valid_imgs = train_imgs[train_valid_split:]
        train_imgs = train_imgs[:train_valid_split]

    if len(config['model']['labels']) > 0:
        overlap_labels = set(config['model']['labels']).intersection(
            set(train_labels.keys()))

        print('Seen labels:\t', train_labels)
        print('Given labels:\t', config['model']['labels'])
        print('Overlap labels:\t', overlap_labels)

        if len(overlap_labels) < len(config['model']['labels']):
            print(
                'Some labels have no annotations! Please revise the list of labels in the config.json file!'
            )
            return
    else:
        print('No labels are provided. Train on all seen labels.')
        config['model']['labels'] = train_labels.keys()
        with open("labels.json", 'w') as outfile:
            json.dump({"labels": list(train_labels.keys())}, outfile)

    ###############################
    #   Construct the model
    ###############################

    yolo = YOLO(backend=config['model']['backend'],
                input_size=(config['model']['input_size_h'],
                            config['model']['input_size_w']),
                labels=config['model']['labels'],
                max_box_per_image=config['model']['max_box_per_image'],
                anchors=config['model']['anchors'],
                gray_mode=config['model']['gray_mode'])

    #########################################
    #   Load the pretrained weights (if any)
    #########################################

    if os.path.exists(config['train']['pretrained_weights']):
        print("Loading pre-trained weights in",
              config['train']['pretrained_weights'])
        yolo.load_weights(config['train']['pretrained_weights'])

    ###############################
    #   Start the training process
    ###############################

    yolo.train(train_imgs=train_imgs,
               valid_imgs=valid_imgs,
               train_times=config['train']['train_times'],
               valid_times=config['valid']['valid_times'],
               nb_epochs=config['train']['nb_epochs'],
               learning_rate=config['train']['learning_rate'],
               batch_size=config['train']['batch_size'],
               warmup_epochs=config['train']['warmup_epochs'],
               object_scale=config['train']['object_scale'],
               no_object_scale=config['train']['no_object_scale'],
               coord_scale=config['train']['coord_scale'],
               class_scale=config['train']['class_scale'],
               saved_weights_name=config['train']['saved_weights_name'],
               debug=config['train']['debug'],
               early_stop=config['train']['early_stop'],
               workers=config['train']['workers'],
               max_queue_size=config['train']['max_queue_size'],
               tb_logdir=config['train']['tensorboard_log_dir'],
               train_generator_callback=config['train']['callback'],
               iou_threshold=config['valid']['iou_threshold'],
               score_threshold=config['valid']['score_threshold'])
Beispiel #4
0
def _main_(args):
    config_path = args.conf
    weights_path = args.weights
    image_path = args.input
    use_camera = args.real_time

    videos_format = [".mp4", "avi"]
    keras.backend.tensorflow_backend.set_session(get_session())

    with open(config_path) as config_buffer:
        config = json.load(config_buffer)

    if weights_path == '':
        weights_path = config['train']['pretrained_weights"']

    ###################
    #   Make the model
    ###################

    yolo = YOLO(backend=config['model']['backend'],
                input_size=(config['model']['input_size_h'],
                            config['model']['input_size_w']),
                labels=config['model']['labels'],
                anchors=config['model']['anchors'],
                gray_mode=config['model']['gray_mode'])

    #########################
    #   Load trained weights
    #########################

    yolo.load_weights(weights_path)

    ###########################
    #   Predict bounding boxes
    ###########################

    if use_camera:
        video_reader = cv2.VideoCapture(int(image_path))
        pbar = tqdm()
        while True:
            pbar.update(1)
            ret, frame = video_reader.read()
            if not ret:
                break
            boxes = yolo.predict(frame)
            frame = draw_boxes(frame, boxes, config['model']['labels'])
            cv2.imshow("frame", frame)
            key = cv2.waitKey(1)
            if key == ord("q") or key == 27:
                break
        pbar.close()
    elif os.path.splitext(image_path)[1] in videos_format:
        file, ext = os.path.splitext(image_path)
        video_out = '{}_detected.avi'.format(file)
        video_reader = cv2.VideoCapture(image_path)

        nb_frames = int(video_reader.get(cv2.CAP_PROP_FRAME_COUNT))
        frame_h = int(video_reader.get(cv2.CAP_PROP_FRAME_HEIGHT))
        frame_w = int(video_reader.get(cv2.CAP_PROP_FRAME_WIDTH))
        print(video_out)
        video_writer = cv2.VideoWriter(video_out,
                                       cv2.VideoWriter_fourcc(*'XVID'), 50.0,
                                       (frame_w, frame_h))

        for _ in tqdm(range(nb_frames)):
            _, image = video_reader.read()
            boxes = yolo.predict(
                image,
                iou_threshold=config['valid']['iou_threshold'],
                score_threshold=config['valid']['score_threshold'])

            image = draw_boxes(image, boxes, config['model']['labels'])
            video_writer.write(np.uint8(image))

        video_reader.release()
        video_writer.release()
    else:
        if os.path.isfile(image_path):
            image = cv2.imread(image_path)
            boxes = yolo.predict(
                image,
                iou_threshold=config['valid']['iou_threshold'],
                score_threshold=config['valid']['score_threshold'])
            image = draw_boxes(image, boxes, config['model']['labels'])

            print(len(boxes), 'boxes are found')
            cv2.imwrite(image_path[:-4] + '_detected' + image_path[-4:], image)
        else:
            detected_images_path = os.path.join(image_path, "detected")
            if not os.path.exists(detected_images_path):
                os.mkdir(detected_images_path)
            images = list(list_images(image_path))
            for fname in tqdm(images):
                image = cv2.imread(fname)
                boxes = yolo.predict(image)
                image = draw_boxes(image, boxes, config['model']['labels'])
                fname = os.path.basename(fname)
                cv2.imwrite(os.path.join(image_path, "detected", fname), image)
Beispiel #5
0
def _main_(args):
    config_path = args.conf
    weights_path = args.weights
    
    keras.backend.tensorflow_backend.set_session(get_session())

    with open(config_path) as config_buffer:    
        config = json.loads(config_buffer.read())

    if weights_path == '':
        weights_path = config['train']['pretrained_weights"']

    ##########################
    #   Parse the annotations 
    ##########################
    without_valid_imgs = False
    if config['parser_annotation_type'] == 'xml':
        # parse annotations of the training set
        train_imgs, train_labels = parse_annotation_xml(config['train']['train_annot_folder'], 
                                                        config['train']['train_image_folder'],
                                                        config['model']['labels'])

        # parse annotations of the validation set, if any.
        if os.path.exists(config['valid']['valid_annot_folder']):
            valid_imgs, valid_labels = parse_annotation_xml(config['valid']['valid_annot_folder'], 
                                                            config['valid']['valid_image_folder'],
                                                            config['model']['labels'])
        else:
            without_valid_imgs = True

    elif config['parser_annotation_type'] == 'csv':
        # parse annotations of the training set
        train_imgs, train_labels = parse_annotation_csv(config['train']['train_csv_file'],
                                                        config['model']['labels'],
                                                        config['train']['train_csv_base_path'])

        # parse annotations of the validation set, if any.
        if os.path.exists(config['valid']['valid_csv_file']):
            valid_imgs, valid_labels = parse_annotation_csv(config['valid']['valid_csv_file'],
                                                            config['model']['labels'],
                                                            config['valid']['valid_csv_base_path'])
        else:
            without_valid_imgs = True
    else:
        raise ValueError("'parser_annotations_type' must be 'xml' or 'csv' not {}.".format(config['parser_annotations_type']))

    # remove samples without objects in the image
    for i in range(len(train_imgs)-1, 0, -1):
        if len(train_imgs[i]['object']) == 0:
            del train_imgs[i]

    if len(config['model']['labels']) > 0:
        overlap_labels = set(config['model']['labels']).intersection(set(train_labels.keys()))

        print('Seen labels:\t', train_labels)
        print('Given labels:\t', config['model']['labels'])
        print('Overlap labels:\t', overlap_labels)           

        if len(overlap_labels) < len(config['model']['labels']):
            print('Some labels have no annotations! Please revise the list of labels in the config.json file!')
            return
    else:
        print('No labels are provided. Evaluate on all seen labels.')
        config['model']['labels'] = train_labels.keys()
        with open("labels.json", 'w') as outfile:
            json.dump({"labels": list(train_labels.keys())}, outfile)
        
    ########################
    #   Construct the model 
    ########################

    yolo = YOLO(backend=config['model']['backend'],
                input_size=(config['model']['input_size_h'], config['model']['input_size_w']),
                labels=config['model']['labels'],
                anchors=config['model']['anchors'],
                gray_mode=config['model']['gray_mode'])

    #########################################
    #   Load the pretrained weights (if any) 
    #########################################

    if weights_path != '':
        print("Loading pre-trained weights in", weights_path)
        yolo.load_weights(weights_path)
    elif os.path.exists(config['train']['pretrained_weights']):
        print("Loading pre-trained weights in", config['train']['pretrained_weights'])
        yolo.load_weights(config['train']['pretrained_weights'])
    else:
        raise Exception("No pretrained weights found.")

    #########################
    #   Evaluate the network
    #########################

    print("calculing mAP for iou threshold = {}".format(args.iou))
    generator_config = {
                'IMAGE_H': yolo._input_size[0],
                'IMAGE_W': yolo._input_size[1],
                'IMAGE_C': yolo._input_size[2],
                'GRID_H': yolo._grid_h,
                'GRID_W': yolo._grid_w,
                'BOX': yolo._nb_box,
                'LABELS': yolo.labels,
                'CLASS': len(yolo.labels),
                'ANCHORS': yolo._anchors,
                'BATCH_SIZE': 4,
                'TRUE_BOX_BUFFER': yolo._max_box_per_image,
            } 
    if not without_valid_imgs:
        valid_generator = BatchGenerator(valid_imgs, 
                                         generator_config,
                                         norm=yolo._feature_extractor.normalize,
                                         jitter=False)
        valid_eval = MapEvaluation(yolo, valid_generator,
                                   iou_threshold=args.iou)

        _map, average_precisions = valid_eval.evaluate_map()
        for label, average_precision in average_precisions.items():
            print(yolo.labels[label], '{:.4f}'.format(average_precision))
        print('validation dataset mAP: {:.4f}\n'.format(_map))

    train_generator = BatchGenerator(train_imgs, 
                                     generator_config, 
                                     norm=yolo._feature_extractor.normalize,
                                     jitter=False)  
    train_eval = MapEvaluation(yolo, train_generator,
                               iou_threshold=args.iou)

    _map, average_precisions = train_eval.evaluate_map()
    for label, average_precision in average_precisions.items():
        print(yolo.labels[label], '{:.4f}'.format(average_precision))
    print('training dataset mAP: {:.4f}'.format(_map))