Building and basic use of yolov3 target detection environment

1. Construction of keras environment
Install tensorflow first, and then install keras (note that the version of tensorflow and keras should match)
Reduce the version of keras, install the new version directly, and the old version will be uninstalled automatically

pip install keras==2.2.5 -i https://pypi.tuna.tsinghua.edu.cn/simple/

2. Classification - Detection - segmentation

3. Preliminary use: keras+yolov3+pycharm
Import anaconda environment when using pycharm s
1) Download yolo3 code
2) Download weight
https://pjreddie.com/media/files/yolov3.weights And put the weight under the folder of keras-yolo3
3) Execute the command to convert yolo3 configuration file under darknet to h5 file applicable to keras

python convert.py yolov3.cfg yolov3.weights model_data/yolo.h5

4) Using the command line to perform a test picture

Python yolo_video.py --image

Use detection video

python yolo_video.py --input = XXX.mp4 

5) Input image path for target detection
Note: yolo's own recognition classification includes:
"Airplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "table", "dog"“ Horses, motorcycles, people, potted plants, sheep, sofas, trains, TV monitors and so on are 80 categories in total, among which there are knives involved in the classification of bad information.

4. Make your own data set for training
(1) Create file structure directory
(1) Create a folder in the keras-yolo3-master folder with the following structure:
JPEGImages is used to store your pictures; Annotations is used to store annotation files (xml format, which needs to be converted to TXT format under the Darknet framework); ImageSets/Main is used to store the txt files of the automatically generated picture paths of training sets, verification sets and test sets;

(2) Dimension data:
LabelImg software download: https://github.com/tzutalin/labelImg
(extract the labelimg master folder)
In the Anaconda environment, switch to the folder directory, and install the dependency: pyqt5 and lxml; after the installation, execute the following command to open the software for use:

pip install pyqt5
pip install lxml
pyrcc5 -o resources.py resources.qrc (No output after the sentence is executed)
python labelImg.py

Note: an error is reported when running the last command line as follows:

resolvent:
In labelimg master resources.py Copy to lib file

(3) Create a new one under voc207 folder test.py

import os
import random
 
trainval_percent = 0.1
train_percent = 0.9
xmlfilepath = 'Annotations'
txtsavepath = 'ImageSets/Main'
total_xml = os.listdir(xmlfilepath)
 
num = len(total_xml)
list = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list, tv)
train = random.sample(trainval, tr)
 
ftrainval = open('ImageSets/Main/trainval.txt', 'w')
ftest = open('ImageSets/Main/test.txt', 'w')
ftrain = open('ImageSets/Main/train.txt', 'w')
fval = open('ImageSets/Main/val.txt', 'w')
 
for i in list:
    name = total_xml[i][:-4] + '\n'
    if i in trainval:
        ftrainval.write(name)
        if i in train:
            ftest.write(name)
        else:
            fval.write(name)
    else:
        ftrain.write(name)
 
ftrainval.close()
ftrain.close()
fval.close()
ftest.close()

function test.py The following four files are generated in the ImageSets/Main directory

(4) Modify category
1. Open VOC in keras yolo3 master directory_ annotation.py file
2. Modify the category name of your dataset

After running the file, three. Txt files will be generated under the main directory keras-yolo3-master. Manually change the file name to train.txt " val.txt " test.txt

(5) Parameter setting
Modify yolo3.cfg file parameters
1. Pycham opens yolo3.cfg
2. Press Ctrl + F to find yolo (3 yolo in total). The filter, classes, and random of each location should be changed accordingly
filter = 3*(len(classes)+5) ා I have only one type here, so it's 18
classes = 1. There are several classes to write
random = 0, otherwise 1

(6) Modification classes.txt
Open model_data/coco_classes.txt And voc_classes.txt Files, modifying classes

(7) Training
Create a new folder logs/000 in the home directory
modify train.py

import numpy as np
import keras.backend as K
from keras.layers import Input, Lambda
from keras.models import Model
from keras.callbacks import TensorBoard, ModelCheckpoint, EarlyStopping
 
from yolo3.model import preprocess_true_boxes, yolo_body, tiny_yolo_body, yolo_loss
from yolo3.utils import get_random_data
 
 
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)
    anchors = get_anchors(anchors_path)
    input_shape = (416,416) # multiple of 32, hw
    model = create_model(input_shape, anchors, len(class_names) )
    train(model, annotation_path, input_shape, anchors, len(class_names), log_dir=log_dir)
 
def train(model, annotation_path, input_shape, anchors, num_classes, log_dir='logs/'):
    model.compile(optimizer='adam', loss={
        'yolo_loss': lambda y_true, y_pred: y_pred})
    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=1)
    batch_size = 10
    val_split = 0.1
    with open(annotation_path) as f:
        lines = f.readlines()
    np.random.shuffle(lines)
    num_val = int(len(lines)*val_split)
    num_train = len(lines) - num_val
    print('Train on {} samples, val on {} samples, with batch size {}.'.format(num_train, num_val, batch_size))
 
    model.fit_generator(data_generator_wrap(lines[:num_train], batch_size, input_shape, anchors, num_classes),
            steps_per_epoch=max(1, num_train//batch_size),
            validation_data=data_generator_wrap(lines[num_train:], batch_size, input_shape, anchors, num_classes),
            validation_steps=max(1, num_val//batch_size),
            epochs=500,
            initial_epoch=0)
    model.save_weights(log_dir + 'trained_weights.h5')
 
def get_classes(classes_path):
    with open(classes_path) as f:
        class_names = f.readlines()
    class_names = [c.strip() for c in class_names]
    return class_names
 
def get_anchors(anchors_path):
    with open(anchors_path) as f:
        anchors = f.readline()
    anchors = [float(x) for x in anchors.split(',')]
    return np.array(anchors).reshape(-1, 2)
 
def create_model(input_shape, anchors, num_classes, load_pretrained=False, freeze_body=False,
            weights_path='model_data/yolo_weights.h5'):
    K.clear_session() # get a new session
    image_input = Input(shape=(None, None, 3))
    h, w = input_shape
    num_anchors = len(anchors)
    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)]
 
    model_body = yolo_body(image_input, num_anchors//3, num_classes)
    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:
            # Do not freeze 3 output layers.
            num = len(model_body.layers)-7
            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([model_body.input, *y_true], model_loss)
    return model
def data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes):
    n = len(annotation_lines)
    np.random.shuffle(annotation_lines)
    i = 0
    while True:
        image_data = []
        box_data = []
        for b in range(batch_size):
            i %= n
            image, box = get_random_data(annotation_lines[i], input_shape, random=True)
            image_data.append(image)
            box_data.append(box)
            i += 1
        image_data = np.array(image_data)
        box_data = np.array(box_data)
        y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes)
        yield [image_data, *y_true], np.zeros(batch_size)
 
def data_generator_wrap(annotation_lines, batch_size, input_shape, anchors, num_classes):
    n = len(annotation_lines)
    if n==0 or batch_size<=0: return None
    return data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes)
 
if __name__ == '__main__':
    _main()

function train.py Observe the loss value of loss, you can stop training when it is down to about ten times, and generate the trained-weights.h5 under the logs/000 directory
Loss value is used to evaluate the inconsistency between the predicted value and the real value of the model. The smaller the loss function, the better the robustness of the model.
Note: in keras yolov3, because l2 regularization is used in model building, the loss of the final model will not be reduced to a very low level. Generally, the effect will be ok if keras yolov3 loss is reduced to about 10

Note: the following errors occurred during operation

resolvent:
1) Root cause: mismatch between tensorflow and keras version reduces keras version
2) At D: \ tools \ Anaconda \ lib \ site packages \ keras \ backend
Find__ init__ Add the following statement import package to. Py file
from .load_backend import control_flow_ops
from .load_backend import set_image_dim_ordering

(8) Reset parameter file path
Open yolo.py Folders, modifying
1. Weight file path
2. Classification path

(9) Testing
Test image: python yolo_video.py --image
Monitoring video: python yolo_video.py --input=run.mp4

Tags: Python pip Anaconda Lambda

Posted on Thu, 18 Jun 2020 01:55:22 -0400 by tomhath