Exemplo n.º 1
0
    def generate(self):
        self.score = 0.01
        self.iou = 0.5
        model_path = os.path.expanduser(self.model_path)
        assert model_path.endswith(
            '.h5'), 'Keras model or weights must be a .h5 file.'

        #---------------------------------------------------#
        #   计算先验框的数量和种类的数量
        #---------------------------------------------------#
        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.backbone, self.alpha)
            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, ))

        #---------------------------------------------------------#
        #   在yolo_eval函数中,我们会对预测结果进行后处理
        #   后处理的内容包括,解码、非极大抑制、门限筛选等
        #---------------------------------------------------------#
        boxes, scores, classes = yolo_eval(
            self.yolo_model.output,
            self.anchors,
            num_classes,
            self.input_image_shape,
            max_boxes=self.max_boxes,
            score_threshold=self.score,
            iou_threshold=self.iou,
            letterbox_image=self.letterbox_image)
        return boxes, scores, classes
Exemplo n.º 2
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)

        # 载入模型,如果原来的模型里已经包括了模型结构则直接载入。
        # 否则先构建模型再载入
        self.yolo_model = yolo_body(Input(shape=(None, None, 3)),
                                    num_anchors // 3, num_classes)
        self.yolo_model.load_weights(self.model_path)

        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)

        if self.eager:
            self.input_image_shape = Input([
                2,
            ], batch_size=1)
            inputs = [*self.yolo_model.output, self.input_image_shape]
            outputs = Lambda(yolo_eval,
                             output_shape=(1, ),
                             name='yolo_eval',
                             arguments={
                                 'anchors': self.anchors,
                                 'num_classes': len(self.class_names),
                                 'image_shape': self.model_image_size,
                                 'score_threshold': self.score,
                                 'eager': True,
                                 'max_boxes': self.max_boxes
                             })(inputs)
            self.yolo_model = Model(
                [self.yolo_model.input, self.input_image_shape], outputs)
        else:
            self.input_image_shape = K.placeholder(shape=(2, ))

            self.boxes, self.scores, self.classes = yolo_eval(
                self.yolo_model.output,
                self.anchors,
                num_classes,
                self.input_image_shape,
                max_boxes=self.max_boxes,
                score_threshold=self.score,
                iou_threshold=self.iou)
Exemplo n.º 3
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))

        # 画框设置不同的颜色
        #参数前带个*表示元组,
        #里是因为colorsys.hsv_to_rgb函数所需传入对象必须是元组,map函数则要求hsv_tuples为可迭代对象
        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))  # 将存有hsv颜色空间的颜色元组列表,转换成rgb颜色空间的颜色元组列表
        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, ))  # 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
    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.'
        
        #---------------------------------------------------#
        #   计算先验框的数量和种类的数量
        #---------------------------------------------------#
        num_anchors = len(self.anchors)
        num_classes = len(self.class_names)

        #---------------------------------------------------------#
        #   载入模型
        #---------------------------------------------------------#
        self.yolo_model = yolo_body(Input(shape=(None,None,3)), num_anchors//3, num_classes, self.backbone, self.alpha)
        self.yolo_model.load_weights(self.model_path)

        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)

        #---------------------------------------------------------#
        #   在yolo_eval函数中,我们会对预测结果进行后处理
        #   后处理的内容包括,解码、非极大抑制、门限筛选等
        #---------------------------------------------------------#
        if self.eager:
            self.input_image_shape = Input([2,],batch_size=1)
            inputs = [*self.yolo_model.output, self.input_image_shape]
            outputs = Lambda(yolo_eval, output_shape=(1,), name='yolo_eval',
                arguments={'anchors': self.anchors, 'num_classes': len(self.class_names), 'image_shape': self.model_image_size, 
                'score_threshold': self.score, 'eager': True, 'max_boxes': self.max_boxes, 'letterbox_image': self.letterbox_image})(inputs)
            self.yolo_model = Model([self.yolo_model.input, self.input_image_shape], outputs)
        else:
            self.input_image_shape = K.placeholder(shape=(2, ))
            
            self.boxes, self.scores, self.classes = yolo_eval(self.yolo_model.output, self.anchors,
                    num_classes, self.input_image_shape, max_boxes=self.max_boxes,
                    score_threshold=self.score, iou_threshold=self.iou, letterbox_image = self.letterbox_image)
Exemplo n.º 5
0
    def generate(self):
        score = CONFIG.DETECT.SCORE
        iou = CONFIG.DETECT.IOU

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

        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))

        # draw bounding boxes
        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))

        # random color
        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=score,
                                           iou_threshold=iou,
                                           nms_method=self.nms_method,
                                           diou_threshold=self.diou_threshold)
        return boxes, scores, classes
    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.'
        '''
        self.yolo_model = load_model(model_path, custom_objects={'Mish': Mish}, compile=False)

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

        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))
        # Generate colors for drawing bounding boxes.
        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)  # Fixed seed for consistent colors across runs.
        np.random.shuffle(
            self.colors)  # Shuffle colors to decorrelate adjacent classes.
        np.random.seed(None)  # Reset seed to default.

        # Generate output tensor targets for filtered bounding boxes.
        self.input_image_shape = K.placeholder(shape=(2, ))
        if self.gpu_num >= 2:
            self.yolo_model = multi_gpu_model(self.yolo_model,
                                              gpus=self.gpu_num)
        boxes, scores, classes = yolo_eval(self.yolo_model.output,
                                           self.anchors,
                                           len(self.class_names),
                                           self.input_image_shape,
                                           score_threshold=self.score,
                                           iou_threshold=self.iou)
        return boxes, scores, classes
Exemplo n.º 7
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.'
        
        #---------------------------------------------------#
        #   计算先验框的数量和种类的数量
        #---------------------------------------------------#
        num_anchors = len(self.anchors)
        num_classes = len(self.class_names)

        #---------------------------------------------------------#
        #   载入模型,如果原来的模型里已经包括了模型结构则直接载入。
        #   否则先构建模型再载入
        #---------------------------------------------------------#
        try:
            print("load model")
            self.yolo_model = load_model(model_path, compile=False)
        except:
            print("build model")
            self.yolo_model = yolo_body(Input(shape=(self.model_image_size[0],self.model_image_size[1],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))
            
        self.yolo_model.summary()

        # 画框设置不同的颜色
        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)
        
        return 
Exemplo n.º 8
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.'

        # Calculate the number of Anchor
        num_anchors = len(self.anchors)
        num_classes = len(self.class_names)

        # Load the model directly if the original model already contains the model structure.
        # Otherwise, build the model first and load it later
        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))

        # The frame is set in different colors
        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))

        # Disturb the color
        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
Exemplo n.º 9
0
    def generate(self):
        num_anchors = len(self.anchors)
        num_classes = len(self.class_names)

        try:
            self.yolo_model = load_model(self.model_path, compile=False)
        except Exception:
            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(self.model_path))

        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
Exemplo n.º 10
0
#--------------------------------------------#
#   该部分代码只用于看网络结构,并非测试代码
#   map测试请看get_dr_txt.py、get_gt_txt.py
#   和get_map.py
#--------------------------------------------#
from tensorflow.keras.layers import Input

from nets.yolo4 import yolo_body

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

    for i, layer in enumerate(model.layers):
        print(i, layer.name)
    label_smoothing = 0

    regularization = True
    #-------------------------------#
    #   Dataloder的使用
    #-------------------------------#
    Use_Data_Loader = True

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

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

    #-------------------------------------------------------------------------------#
    #   训练参数的设置
    #   logging表示tensorboard的保存地址
    #   checkpoint用于设置权值保存的细节,period用于修改多少epoch保存一次
    #   reduce_lr用于设置学习率下降的方式
    #   early_stopping用于设定早停,val_loss多次不下降自动结束训练,表示模型基本收敛
    #-------------------------------------------------------------------------------#
    val_split = 0.1
Exemplo n.º 12
0
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)

inputs_keras = keras.Input(shape=(416, 416, 3))
yolo4 = yolo_body(inputs=inputs_keras,
                  num_anchors=num_anchors,
                  num_classes=num_classes)

yolo4.load_weights(weight_path)


def save_model(inputs,
               image_shape,
               input_shape,
               num_anchors,
               num_classes,
               score_thres,
               iou_thres,
               scales_xy=None):
    """package model with forward propagation and post processing
Exemplo n.º 13
0
def main():
    # 标签的位置
    annotation_path = '2020_train_all.txt'
    # 获取classes和anchor的位置
    classes_path = 'model_data/our_classes.txt'
    anchors_path = 'model_data/yolo4_anchors.txt'
    #------------------------------------------------------#
    #   权值文件请看README,百度网盘下载
    #   训练自己的数据集时提示维度不匹配正常
    #   预测的东西都不一样了自然维度不匹配
    #------------------------------------------------------#
    weights_path = 'model_data/last9.h5'
    # 获得classes和anchor
    class_names = get_classes(classes_path)
    anchors = get_anchors(anchors_path)
    # 一共有多少类
    num_classes = len(class_names)
    num_anchors = len(anchors)
    # 训练后的模型保存的位置
    log_dir = 'logs/'
    # 输入的shape大小
    # 显存比较小可以使用416x416
    # 现存比较大可以使用608x608
    input_shape = (608, 608)
    mosaic = True
    Cosine_scheduler = False
    label_smoothing = 0

    # 清除session
    K.clear_session()

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

    # 创建yolo模型
    print('Create YOLOv4 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,
                        output_shape=(1, ),
                        name='yolo_loss',
                        arguments={
                            'anchors': anchors,
                            'num_classes': num_classes,
                            'ignore_thresh': 0.5,
                            'label_smoothing': label_smoothing
                        })(loss_input)

    model = Model([model_body.input, *y_true], model_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=True,
        save_best_only=False,
        period=1)
    early_stopping = EarlyStopping(monitor='val_loss',
                                   min_delta=0,
                                   patience=6,
                                   verbose=1)

    # 0.1用于验证,0.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
    #------------------------------------------------------#
    freeze_layers = 249
    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)))

    # 调整非主干模型first
    if True:
        Init_epoch = 0
        Freeze_epoch = 50
        # batch_size大小,每次喂入多少数据
        batch_size = 8
        # 最大学习率
        learning_rate_base = 1e-3
        if Cosine_scheduler:
            # 预热期
            warmup_epoch = int((Freeze_epoch - Init_epoch) * 0.2)
            # 总共的步长
            total_steps = int(
                (Freeze_epoch - Init_epoch) * num_train / batch_size)
            # 预热步长
            warmup_steps = int(warmup_epoch * num_train / batch_size)
            # 学习率
            reduce_lr = WarmUpCosineDecayScheduler(
                learning_rate_base=learning_rate_base,
                total_steps=total_steps,
                warmup_learning_rate=1e-4,
                warmup_steps=warmup_steps,
                hold_base_rate_steps=num_train,
                min_learn_rate=1e-6)
            model.compile(optimizer=Adam(),
                          loss={
                              'yolo_loss': lambda y_true, y_pred: y_pred
                          })
        else:
            reduce_lr = ReduceLROnPlateau(monitor='val_loss',
                                          factor=0.5,
                                          patience=2,
                                          verbose=1)
            model.compile(optimizer=Adam(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,
                           mosaic=mosaic),
            steps_per_epoch=max(1, num_train // batch_size),
            validation_data=data_generator(lines[num_train:],
                                           batch_size,
                                           input_shape,
                                           anchors,
                                           num_classes,
                                           mosaic=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')

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

    # 解冻后训练
    if True:
        Freeze_epoch = 50
        Epoch = 100
        # batch_size大小,每次喂入多少数据
        batch_size = 2

        # 最大学习率
        learning_rate_base = 1e-4
        if Cosine_scheduler:
            # 预热期
            warmup_epoch = int((Epoch - Freeze_epoch) * 0.2)
            # 总共的步长
            total_steps = int((Epoch - Freeze_epoch) * num_train / batch_size)
            # 预热步长
            warmup_steps = int(warmup_epoch * num_train / batch_size)
            # 学习率
            reduce_lr = WarmUpCosineDecayScheduler(
                learning_rate_base=learning_rate_base,
                total_steps=total_steps,
                warmup_learning_rate=1e-5,
                warmup_steps=warmup_steps,
                hold_base_rate_steps=num_train // 2,
                min_learn_rate=1e-6)
            model.compile(optimizer=Adam(),
                          loss={
                              'yolo_loss': lambda y_true, y_pred: y_pred
                          })
        else:
            reduce_lr = ReduceLROnPlateau(monitor='val_loss',
                                          factor=0.5,
                                          patience=2,
                                          verbose=1)
            model.compile(optimizer=Adam(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,
                           mosaic=mosaic),
            steps_per_epoch=max(1, num_train // batch_size),
            validation_data=data_generator(lines[num_train:],
                                           batch_size,
                                           input_shape,
                                           anchors,
                                           num_classes,
                                           mosaic=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 + 'last1.h5')
Exemplo n.º 14
0
    def trainModel(self, mosaic=True, cosine_scheduler=True, label_smoothing=0.1):
        """
        """
        anchors = get_anchors(self.anchors_path)
        num_classes = len(self.classes)
        num_anchors = len(anchors)

        K.clear_session()

        image_input = Input(shape=(None, None, 3))
        h, w = self.input_shape

        print('Create YOLOv4 model with {} anchors and {} classes.'.format(num_anchors, num_classes))
        # model_body = Model(image_input, [P5_output, P4_output, P3_output])
        model_body = yolo_body(image_input, num_anchors // 3, num_classes)

        print('Load weights {}.'.format(self.pretrain_model))
        model_body.load_weights(self.pretrain_model, by_name=True, skip_mismatch=True)

        # y_true = [Input(shape=(h//32,w//32,3,cls+5), Input(shape=(h//16,w//16,3,cls+5), Input(shape=(h//8,w//8,3,cls+5)]
        y_true = [Input(shape=(h // {0: 32, 1: 16, 2: 8}[i], w // {0: 32, 1: 16, 2: 8}[i], num_anchors // 3, num_classes + 5))
                  for i in range(3)]

        # model_body.output = [P5_output, P4_output, P3_output]
        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,
                                       'label_smoothing': label_smoothing})(loss_input)

        model = Model([model_body.input, *y_true], model_loss)
        # plot_model(model, to_file="yolov4_loss_model.png", show_shapes=True, show_layer_names=True)

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

        val_split = 0.1
        with open(self.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

        # ------------------------------------------------------#
        #   backbone extract general feature in network
        #   freeze some head layers can speed up training, and prevent weights from influence in early epoch
        # ------------------------------------------------------#
        freeze_layers = 249
        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)))

        init_epoch = 0
        freeze_epoch = self.epochs // 2
        batch_size = self.batch_size * 2
        learning_rate_base = 1e-3

        if cosine_scheduler:
            warm_up_epoch = int((freeze_epoch - init_epoch) * 0.2)
            total_steps = int((freeze_epoch - init_epoch) * num_train / batch_size)
            warm_up_steps = int(warm_up_epoch * num_train / batch_size)

            reduce_lr = WarmUpCosineDecayScheduler(learning_rate_base=learning_rate_base,
                                                   total_steps=total_steps,
                                                   warmup_learning_rate=1e-4,
                                                   warmup_steps=warm_up_steps,
                                                   hold_base_rate_steps=num_train,
                                                   min_learn_rate=1e-6)
            model.compile(optimizer=Adam(), loss=dummy_loss)
        else:
            reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=2, verbose=1, min_lr=1e-6)
            model.compile(optimizer=Adam(learning_rate_base), loss=dummy_loss)

        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, self.input_shape, anchors, num_classes, mosaic=mosaic),
            steps_per_epoch=max(1, num_train // batch_size),
            validation_data=data_generator(lines[num_train:], batch_size, self.input_shape, anchors, num_classes, mosaic=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(self.log_dir + 'trained_weights_stage_1.h5')

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

        print("\n\nStarting Training all Layers....\n\n")

        batch_size = self.batch_size

        learning_rate_base = 1e-4
        if cosine_scheduler:
            warm_up_epoch = int((self.epochs - freeze_epoch) * 0.2)
            total_steps = int((self.epochs - freeze_epoch) * num_train / batch_size)
            warm_up_steps = int(warm_up_epoch * num_train / batch_size)
            reduce_lr = WarmUpCosineDecayScheduler(learning_rate_base=learning_rate_base,
                                                   total_steps=total_steps,
                                                   warmup_learning_rate=1e-5,
                                                   warmup_steps=warm_up_steps,
                                                   hold_base_rate_steps=num_train // 2,
                                                   min_learn_rate=1e-6)
            model.compile(optimizer=Adam(), loss=dummy_loss)
        else:
            reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=2, verbose=1, min_lr=1e-6)
            model.compile(optimizer=Adam(learning_rate_base), loss=dummy_loss)

        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, self.input_shape, anchors, num_classes, mosaic=mosaic),
            steps_per_epoch=max(1, num_train // batch_size),
            validation_data=data_generator(lines[num_train:], batch_size, self.input_shape, anchors, num_classes, mosaic=False),
            validation_steps=max(1, num_val // batch_size),
            epochs=self.epochs,
            initial_epoch=freeze_epoch,
            callbacks=[logging, checkpoint, reduce_lr, early_stopping])

        model.save_weights(self.log_dir + 'last1.h5')
Exemplo n.º 15
0
#--------------------------------------------#
#   该部分代码只用于看网络结构,并非测试代码
#   map测试请看get_dr_txt.py、get_gt_txt.py
#   和get_map.py
#--------------------------------------------#
from keras.layers import Input

from nets.yolo4 import yolo_body

if __name__ == "__main__":
    inputs = Input([416,416,3])
    
    model = yolo_body(inputs, 3, 80, backbone='mobilenetv1', alpha=1)
    model.summary()
    # mobilenetv1 41,005,757
    # mobilenetv2 39,124,541
    # mobilenetv3 40,043,389

    # 修改了PANET的mobilenetv1  12,754,109
    # 修改了PANET的mobilenetv2  10,872,893
    # 修改了PANET的mobilenetv3  11,791,741

    # 修改了PANET的mobilenetv1-0.25     680,381
    # 修改了PANET的mobilenetv2-0.5      2,370,541
    # 修改了PANET的mobilenetv3-0.75     6,315,309

    # for i,layer in enumerate(model.layers):
    #     print(i,layer.name)
Exemplo n.º 16
0
    def build_model(self, training=True):

        input_width = self.config['model']['input_width']
        input_height = self.config['model']['input_height']
        input_depth = self.config['model']['input_depth']
        class_num = self.config['model']['class_num']
        backbone = self.config['model']['backbone']

        train_base = self.config['train']['train_base']
        weights_path = self.config['train']['pretrained_weights']

        num_anchors = len(self.anchors)
        label_smoothing = 0
        normalize = False

        K.clear_session()
        #------------------------------------------------------#
        #   创建yolo模型
        #------------------------------------------------------#
        image_input = Input(shape=(input_width, input_height, 3))
        print('Create YOLOv4 model with {} anchors and {} classes.'.format(
            num_anchors, class_num))
        model_body = yolo_body(image_input, num_anchors // 3, class_num)

        if training is False:
            return model_body

        if train_base is False:
            freeze_layers = 249
            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)))

#         model_body.summary()

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

#------------------------------------------------------#
#   在这个地方设置损失,将网络的输出结果传入loss函数
#   把整个模型的输出作为loss
#------------------------------------------------------#
        y_true = [Input(shape=(input_height//{0:32, 1:16, 2:8}[l], input_width//{0:32, 1:16, 2:8}[l], \
            num_anchors//3, class_num+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': self.anchors,
                                'num_classes': class_num,
                                'ignore_thresh': 0.5,
                                'label_smoothing': label_smoothing,
                                'normalize': normalize
                            })(loss_input)

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

        return model
Exemplo n.º 17
0
    #   mosaic 马赛克数据增强 True or False
    #   Cosine_scheduler 余弦退火学习率 True or False
    #   label_smoothing 标签平滑 0.01以下一般 如0.01、0.005
    #------------------------------------------------------#
    mosaic = True
    Cosine_scheduler = False
    label_smoothing = 0

    #------------------------------------------------------#
    #   创建yolo模型
    #------------------------------------------------------#
    image_input = Input(shape=(None, None, 3))
    h, w = input_shape
    print('Create YOLOv4 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,
Exemplo n.º 18
0
    def load_yolo(self):
        model_path = os.path.expanduser(self.model_path)
        assert model_path.endswith('.h5'), 'Keras model or weights must be a .h5 file.'

        self.class_names = self.get_class()
        self.anchors = self.get_anchors()

        num_anchors = len(self.anchors)
        num_classes = len(self.class_names)

        # Generate colors for drawing bounding boxes.
        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))

#         self.sess = K.get_session()

        # Load model, or construct model and load weights.
        self.yolo_model = yolo_body(Input(shape=(608, 608, 3)), num_anchors//3, num_classes)
        self.yolo_model.summary()

        # Read and convert darknet weight
        print('Loading weights.')
        weights_file = open(self.weights_path, 'rb')
        major, minor, revision = np.ndarray(
            shape=(3, ), dtype='int32', buffer=weights_file.read(12))
        if (major*10+minor)>=2 and major<1000 and minor<1000:
            seen = np.ndarray(shape=(1,), dtype='int64', buffer=weights_file.read(8))
        else:
            seen = np.ndarray(shape=(1,), dtype='int32', buffer=weights_file.read(4))
        print('Weights Header: ', major, minor, revision, seen)

        convs_to_load = []
        bns_to_load = []
        for i in range(len(self.yolo_model.layers)):
            layer_name = self.yolo_model.layers[i].name
            if layer_name.startswith('conv2d_'):
                convs_to_load.append((int(layer_name[7:]), i))
            if layer_name.startswith('batch_normalization_'):
                bns_to_load.append((int(layer_name[20:]), i))

        convs_sorted = sorted(convs_to_load, key=itemgetter(0))
        bns_sorted = sorted(bns_to_load, key=itemgetter(0))
        
        print('conv2d layers: ', len(convs_to_load))
        print('batch_normalization_ layers: ', len(bns_to_load))

        bn_index = 0
        for i in range(len(convs_sorted)):
            print('Converting ', i)
            if i == 93 or i == 101 or i == 109:
                #no bn, with bias
                weights_shape = self.yolo_model.layers[convs_sorted[i][1]].get_weights()[0].shape
                bias_shape = self.yolo_model.layers[convs_sorted[i][1]].get_weights()[0].shape[3]
                filters = bias_shape
                size = weights_shape[0]
                darknet_w_shape = (filters, weights_shape[2], size, size)
                weights_size = np.product(weights_shape)

                conv_bias = np.ndarray(
                    shape=(filters, ),
                    dtype='float32',
                    buffer=weights_file.read(filters * 4))
                conv_weights = np.ndarray(
                    shape=darknet_w_shape,
                    dtype='float32',
                    buffer=weights_file.read(weights_size * 4))
                conv_weights = np.transpose(conv_weights, [2, 3, 1, 0])
                self.yolo_model.layers[convs_sorted[i][1]].set_weights([conv_weights, conv_bias])
            else:
                #with bn, no bias
                weights_shape = self.yolo_model.layers[convs_sorted[i][1]].get_weights()[0].shape
                size = weights_shape[0]
                bn_shape = self.yolo_model.layers[bns_sorted[bn_index][1]].get_weights()[0].shape
                filters = bn_shape[0]
                darknet_w_shape = (filters, weights_shape[2], size, size)
                weights_size = np.product(weights_shape)

                conv_bias = np.ndarray(
                    shape=(filters, ),
                    dtype='float32',
                    buffer=weights_file.read(filters * 4))
                bn_weights = np.ndarray(
                    shape=(3, filters),
                    dtype='float32',
                    buffer=weights_file.read(filters * 12))

                bn_weight_list = [
                    bn_weights[0],  # scale gamma
                    conv_bias,  # shift beta
                    bn_weights[1],  # running mean
                    bn_weights[2]  # running var
                ]
                self.yolo_model.layers[bns_sorted[bn_index][1]].set_weights(bn_weight_list)

                print(weights_size)
                conv_weights = np.ndarray(
                    shape=darknet_w_shape,
                    dtype='float32',
                    buffer=weights_file.read(weights_size * 4))
                conv_weights = np.transpose(conv_weights, [2, 3, 1, 0])
                self.yolo_model.layers[convs_sorted[i][1]].set_weights([conv_weights])

                bn_index += 1

        weights_file.close()

        self.yolo_model.save(self.model_path)