Exemplo n.º 1
0
    def generate(self):
        model_path = os.path.expanduser(self.model_path)
        assert model_path.endswith('.h5'), 'Keras model or weights must be a .h5 file.'
        
        # 计算anchor数量
        num_anchors = len(self.anchors)
        num_classes = len(self.class_names)

        # 载入模型,如果原来的模型里已经包括了模型结构则直接载入。
        # 否则先构建模型再载入
        try:
            self.yolo_model = load_model(model_path, compile=False)
        except:
            self.yolo_model = yolo_body(Input(shape=(None,None,3)), num_anchors//3, num_classes)
            self.yolo_model.load_weights(self.model_path)
        else:
            assert self.yolo_model.layers[-1].output_shape[-1] == \
                num_anchors/len(self.yolo_model.output) * (num_classes + 5), \
                'Mismatch between model and given anchor and class sizes'

        print('{} model, anchors, and classes loaded.'.format(model_path))

        # 画框设置不同的颜色
        hsv_tuples = [(x / len(self.class_names), 1., 1.)
                      for x in range(len(self.class_names))]
        self.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))
        self.colors = list(
            map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)),
                self.colors))

        # 打乱颜色
        np.random.seed(10101)
        np.random.shuffle(self.colors)
        np.random.seed(None)

        self.input_image_shape = K.placeholder(shape=(2, ))

        boxes, scores, classes = yolo_eval(self.yolo_model.output, self.anchors,
                num_classes, self.input_image_shape,
                score_threshold=self.score, iou_threshold=self.iou)
        return boxes, scores, classes
anchor_wh.append(anchors_wh_13)

anchors_wh_26 = np.array(anchors[3:6])
anchors_wh_26 = np.tile(np.reshape(anchors_wh_26, (1, 1, 3, 2)), reps=(26, 26, 1, 1))
anchors_wh_26 = tf.constant(anchors_wh_26, dtype=tf.float32)
anchor_wh.append(anchors_wh_26)

anchors_wh_52 = np.array(anchors[:3])
anchors_wh_52 = np.tile(np.reshape(anchors_wh_52, (1, 1, 3, 2)), reps=(52, 52, 1, 1))
anchors_wh_52 = tf.constant(anchors_wh_52, dtype=tf.float32)
anchor_wh.append(anchors_wh_52)

# yoloV3
inputs_keras = keras.Input(shape=(416, 416, 3))
yolo3 = yolo_body(inputs=inputs_keras,
                  num_anchors=num_anchors,
                  num_classes=num_classes)

yolo3.load_weights(weight_path)


def save_model(inputs,
               image_shape,
               input_shape,
               num_anchors,
               num_classes,
               score_thres,
               iou_thres):
    """package model with forward propagation and post processing

    # The output of my model is boxes, scores and classes, so it is
Exemplo n.º 3
0
    # 训练后的模型保存的位置
    log_dir = 'logs/'
    # 输入的shape大小
    input_shape = (416, 416)

    # 清除session
    K.clear_session()

    # 输入的图像为
    image_input = Input(shape=(None, None, 3))
    h, w = input_shape

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

    # 载入预训练权重
    print('Load weights {}.'.format(weights_path))
    model_body.load_weights(weights_path, by_name=True, skip_mismatch=True)

    # y_true为13,13,3,85
    # 26,26,3,85
    # 52,52,3,85
    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.input, *y_true
    # 输出为model_loss
    loss_input = [*model_body.output, *y_true]
    model_loss = Lambda(yolo_loss,
Exemplo n.º 4
0
#--------------------------------------------#
#   该部分代码只用于看网络结构,并非测试代码
#   map测试请看get_dr_txt.py、get_gt_txt.py
#   和get_map.py
#--------------------------------------------#
from keras.layers import Input

from nets.yolo3 import yolo_body

if __name__ == "__main__":
    inputs = Input([None, None, 3])
    model = yolo_body(inputs, 3, 80)
    model.summary()

    # for i,layer in enumerate(model.layers):
    #     print(i,layer.name)
Exemplo n.º 5
0
    num_anchors = len(anchors)
    # 训练后的模型保存的位置
    log_dir = 'logs/'
    # 输入的shape大小
    input_shape = (416,416)

    # 清除session
    K.clear_session()

    # 输入的图像为
    image_input = Input(shape=(None, None, 3))
    h, w = input_shape

    # 创建yolo模型
    print('Create YOLOv3 model with {} anchors and {} classes.'.format(num_anchors, num_classes))
    model_body = yolo_body(image_input, num_anchors//3, num_classes) # model_body = [y1,y2,y3],得到框、分数、类别概率、修正框、筛选框
    '''
    image_input.shape[?,?,?,3],num_classes=20,num_anchors//3=3
    '''
    # 载入预训练权重
    print('Load weights {}.'.format(weights_path))
    model_body.load_weights(weights_path, by_name=True, skip_mismatch=True)  # 加载模型所需的参数
    
    # y_true为13,13,3,25
    # 26,26,3,25
    # 52,52,3,25
    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.input, *y_true
    # 输出为model_loss
Exemplo n.º 6
0
     # 13,13,3,85
     # 26,26,3,85
     # 13,26是grid,3是每个尺度的anchor个数,num_classes+5是框的4个坐标信息,objectness score一位,类别1位和类别数
     y_true = [
         Input(shape=(h // {
             0: 32,
             1: 16
         }[l], w // {
             0: 32,
             1: 16
         }[l], num_anchors // 2, num_classes + 5)) for l in range(2)
     ]
 else:
     print('Create YOLOv3 model with {} anchors and {} classes.'.format(
         num_anchors, num_classes))
     model_body = yolo_body(image_input, num_anchors // 3,
                            num_classes)  #调用yolo3.py的yolo_body生成yolo计算图
     # y_true为[(13, 13, 3, num_classes+5), (26, 26, 3, num_classes+5), (52, 52, 3, num_classes+5)]三种大小,
     # 13,13,3,85
     # 26,26,3,85
     # 52,52,3,85
     # 13,26,52是grid,3是每个尺度的anchor个数,num_classes+5是框的4个坐标信息,objectness score一位,类别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)
Exemplo n.º 7
0
#--------------------------------------------#
#   该部分代码只用于看网络结构,并非测试代码
#   map测试请看get_dr_txt.py、get_gt_txt.py
#   和get_map.py
#--------------------------------------------#
from nets.yolo3 import yolo_body
from keras.layers import Input
inputs = Input([416, 416, 3])
model = yolo_body(inputs, 3, 80, phi=3)
model.summary()

# for i,layer in enumerate(model.layers):
#     print(i,layer.name)
Exemplo n.º 8
0
# -------------------------------------------------
# @Time    : 2020/7/2 0:39
# @Author  : RunRun
# @File    : net
# @Software: PyCharm
#
# -------------------------------------------------
# 功能
#
#  查看整个网络的架构
#
#
# 结果
#
#
#
#
#
from nets.yolo3 import yolo_body
from keras.layers import  Input

Inputs = Input([416,416,3])
model = yolo_body(Inputs,3,10)
model.summary()
Exemplo n.º 9
0
def train_process(config_dic):
    # ----------------------------------------------------#
    #   获得图片路径和标签
    # ----------------------------------------------------#
    annotation_path = str(config_dic["annotation_path"])
    # ------------------------------------------------------#
    #   训练后的模型保存的位置,保存在logs文件夹里面
    # ------------------------------------------------------#
    log_dir = 'logs/'
    # ----------------------------------------------------#
    #   classes和anchor的路径,非常重要
    #   训练前一定要修改classes_path,使其对应自己的数据集
    # ----------------------------------------------------#
    classes_path = str(config_dic["classes_path"])
    anchors_path = str(config_dic["anchors_path"])
    # ------------------------------------------------------#
    #   权值文件请看README,百度网盘下载
    #   训练自己的数据集时提示维度不匹配正常
    #   预测的东西都不一样了自然维度不匹配
    # ------------------------------------------------------#
    weights_path = str(config_dic["pretained_model"])
    # ------------------------------------------------------#
    #   输入的shape大小
    # ------------------------------------------------------#
    input_shape = (int(config_dic["model_image_size"]),
                   int(config_dic["model_image_size"]))
    print("input shape:", input_shape)
    # ------------------------------------------------------#
    #   是否对损失进行归一化
    # ------------------------------------------------------#
    normalize = True

    # ----------------------------------------------------#
    #   获取classes和anchor
    # ----------------------------------------------------#
    class_names = get_classes(classes_path)
    anchors = get_anchors(anchors_path)
    # ------------------------------------------------------#
    #   一共有多少类和多少先验框
    # ------------------------------------------------------#
    num_classes = len(class_names)
    num_anchors = len(anchors)

    K.clear_session()
    # ------------------------------------------------------#
    #   创建yolo模型
    # ------------------------------------------------------#
    image_input = Input(shape=(None, None, 3))
    h, w = input_shape
    print('Create YOLOv3 model with {} anchors and {} classes.'.format(
        num_anchors, num_classes))
    model_body = yolo_body(image_input, num_anchors // 3, num_classes)

    # ------------------------------------------------------#
    #   载入预训练权重
    # ------------------------------------------------------#
    print('Load weights {}.'.format(weights_path))
    model_body.load_weights(weights_path, by_name=True, skip_mismatch=True)

    # ------------------------------------------------------#
    #   在这个地方设置损失,将网络的输出结果传入loss函数
    #   把整个模型的输出作为loss
    # ------------------------------------------------------#
    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)]
    loss_input = [*model_body.output, *y_true]
    model_loss = Lambda(yolo_loss,
                        output_shape=(1, ),
                        name='yolo_loss',
                        arguments={
                            'anchors': anchors,
                            'num_classes': num_classes,
                            'ignore_thresh': 0.5,
                            'normalize': normalize
                        })(loss_input)

    model = Model([model_body.input, *y_true], model_loss)

    # ------------------------------------------------------#
    #   主干特征提取网络特征通用,冻结训练可以加快训练速度
    #   也可以在训练初期防止权值被破坏。
    #   提示OOM或者显存不足请调小Batch_size
    # ------------------------------------------------------#
    freeze_layers = 184
    for i in range(freeze_layers):
        model_body.layers[i].trainable = False
    print('Freeze the first {} layers of total {} layers.'.format(
        freeze_layers, len(model_body.layers)))

    # -------------------------------------------------------------------------------#
    #   训练参数的设置
    #   logging表示tensorboard的保存地址
    #   checkpoint用于设置权值保存的细节,period用于修改多少epoch保存一次
    #   reduce_lr用于设置学习率下降的方式
    #   early_stopping用于设定早停,val_loss多次不下降自动结束训练,表示模型基本收敛
    # -------------------------------------------------------------------------------#
    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=False,
        save_best_only=True,
        period=20)
    reduce_lr = ReduceLROnPlateau(monitor='val_loss',
                                  factor=0.5,
                                  patience=3,
                                  verbose=1)
    early_stopping = EarlyStopping(monitor='val_loss',
                                   min_delta=0,
                                   patience=10,
                                   verbose=1)

    # ----------------------------------------------------------------------#
    #   验证集的划分在train.py代码里面进行
    #   2007_test.txt和2007_val.txt里面没有内容是正常的。训练不会使用到。
    #   当前划分方式下,验证集和训练集的比例为1:9
    # ----------------------------------------------------------------------#
    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

    # ------------------------------------------------------#
    #   主干特征提取网络特征通用,冻结训练可以加快训练速度
    #   也可以在训练初期防止权值被破坏。
    #   Init_Epoch为起始世代
    #   Freeze_Epoch为冻结训练的世代
    #   Epoch总训练世代
    #   提示OOM或者显存不足请调小Batch_size
    # ------------------------------------------------------#
    if True:
        Init_epoch = 0
        Freeze_epoch = int(config_dic["Freeze_epoch"])
        batch_size = 8
        learning_rate_base = 1e-3

        model.compile(optimizer=Adam(lr=learning_rate_base),
                      loss={
                          'yolo_loss': lambda y_true, y_pred: y_pred
                      })

        print('Train on {} samples, val on {} samples, with batch size {}.'.
              format(num_train, num_val, batch_size))
        model.fit_generator(
            data_generator(lines[:num_train],
                           batch_size,
                           input_shape,
                           anchors,
                           num_classes,
                           random=True),
            steps_per_epoch=max(1, num_train // batch_size),
            validation_data=data_generator(lines[num_train:],
                                           batch_size,
                                           input_shape,
                                           anchors,
                                           num_classes,
                                           random=False),
            validation_steps=max(1, num_val // batch_size),
            epochs=Freeze_epoch,
            initial_epoch=Init_epoch,
            callbacks=[logging, checkpoint, reduce_lr, early_stopping])
        model.save_weights(log_dir + 'trained_weights_stage_1.h5')
        # model.save(log_dir+"stage1.h5")

    for i in range(freeze_layers):
        model_body.layers[i].trainable = True

    # 解冻后训练
    if True:
        Freeze_epoch = int(config_dic["Freeze_epoch"])
        Epoch = int(config_dic["Epoch"])
        batch_size = 4
        learning_rate_base = 1e-4

        model.compile(optimizer=Adam(lr=learning_rate_base),
                      loss={
                          'yolo_loss': lambda y_true, y_pred: y_pred
                      })

        print('Train on {} samples, val on {} samples, with batch size {}.'.
              format(num_train, num_val, batch_size))
        model.fit_generator(
            data_generator(lines[:num_train],
                           batch_size,
                           input_shape,
                           anchors,
                           num_classes,
                           random=True),
            steps_per_epoch=max(1, num_train // batch_size),
            validation_data=data_generator(lines[num_train:],
                                           batch_size,
                                           input_shape,
                                           anchors,
                                           num_classes,
                                           random=False),
            validation_steps=max(1, num_val // batch_size),
            epochs=Epoch,
            initial_epoch=Freeze_epoch,
            callbacks=[logging, checkpoint, reduce_lr, early_stopping])
        # model.save_weights(log_dir + config_dic["save_rknn_name"] + ".h5")
        model.save(log_dir + config_dic["save_rknn_name"] + ".h5")
        model_body.save(log_dir + config_dic["save_rknn_name"] + "_body.h5")
    K.clear_session()
Exemplo n.º 10
0
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2020/2/12 20:58
# @Author  : codingchaozhang
from nets.yolo3 import yolo_body
from keras.layers import Input

Inputs = Input([416,416,3])
model = yolo_body(Inputs,3,20)
model.save("yolov3.h5")
model.summary()
Exemplo n.º 11
0
    def generate(self):
        '''

        Parameters
        ----------

        Returns
        -------
            boxes: 
            scores: 
            classes: 

        '''
        model_path = os.path.expanduser(self.model_path)
        assert model_path.endswith(
            '.h5'), 'Keras model or weights must be a .h5 file.'

        # 计算anchor数量
        num_anchors = len(self.anchors)
        num_classes = len(self.class_names)

        # 载入模型,如果原来的模型里已经包括了模型结构则直接载入。
        # 否则先构建模型再载入
        try:
            self.yolo_model = load_model(model_path, compile=False)
        except:
            self.yolo_model = yolo_body(Input(shape=(None, None, 3)),
                                        num_anchors // 3, num_classes)
            self.yolo_model.load_weights(self.model_path)
        else:
            assert self.yolo_model.layers[-1].output_shape[-1] == \
                num_anchors/len(self.yolo_model.output) * (num_classes + 5), \
                'Mismatch between model and given anchor and class sizes'

        print('{} model, anchors, and classes loaded.'.format(model_path))

        # 画框设置不同的颜色,每个类设置一种颜色
        # colors:array, shape=(20, 3), eg:[(0,178,255), (255,153,0), ..., (255,0,0)]
        hsv_tuples = [(x / len(self.class_names), 1., 1.)
                      for x in range(len(self.class_names))]
        self.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))

        self.colors = list(
            map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)),
                self.colors))

        # 打乱颜色
        np.random.seed(10101)
        np.random.shuffle(self.colors)
        np.random.seed(None)

        # 根据检测参数,过滤框
        # <tf.Tensor 'Placeholder_366:0' shape=(2,) dtype=float32>
        self.input_image_shape = K.placeholder(shape=(2, ))
        # 图片预测
        boxes, scores, classes = yolo_eval(self.yolo_model.output,
                                           self.anchors,
                                           num_classes,
                                           self.input_image_shape,
                                           score_threshold=self.score,
                                           iou_threshold=self.iou)
        return boxes, scores, classes