Ejemplo n.º 1
0
def create_darknet_model(input_shape: Tuple[int, int], anchors: List[List[float]], num_classes: int,
                 load_pretrained: bool = True,
                 freeze_body: int = 2,
                 weights_path: str = 'model_data/yolo_weights.h5') -> tf.keras.models.Model:
    """create the training model"""
    h, w = input_shape
    num_anchors = len(anchors)
    x_data = tf.keras.layers.Input(shape=(None, None, 3))
    y_data = [tf.keras.layers.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 = darknet_yolo_body(x_data, num_anchors // 3, num_classes)
    print('Create Darknet-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 in [1, 2]:
        # Freeze the darknet body or freeze all but 2 output layers.
        num = (155, len(model_body.layers) - 2)[freeze_body - 1]
        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 = tf.keras.layers.Lambda(yolo_loss, output_shape=(1,), name='yolo_loss',
                                        arguments={'anchors': anchors, 'num_classes': num_classes,
                                                   'ignore_thresh': 0.5})(
        [*model_body.output, *y_data])
    model = tf.keras.models.Model([model_body.input, *y_data], model_loss)
    return model
Ejemplo 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.'

        # Load model, or construct model and load weights.
        num_anchors = len(self.anchors)
        num_classes = len(self.class_names)
        is_tiny_version = True  # default setting
        try:
            self.yolo_model = tf.keras.models.load_model(model_path,
                                                         compile=False)
        except:
            self.yolo_model = mobilenetv2_yolo_body(tf.keras.layers.Input(shape=(None, None, 3)), num_anchors // 3, num_classes, self.alpha) \
                if is_tiny_version else darknet_yolo_body(tf.keras.layers.Input(shape=(None, None, 3)), num_anchors // 3, num_classes)
            self.yolo_model.load_weights(
                self.model_path)  # make sure model, anchors and classes match
        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: List[Tuple[float, float, float]] = [
            (x / len(self.class_names), 1., 1.)
            for x in range(len(self.class_names))
        ]
        self.colors: List[Tuple[float, float, float]] = list(
            map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))
        self.colors: List[Tuple[int, int, int]] = 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 = tf.placeholder(tf.float32, shape=(2, ))
        if self.gpu_num >= 2:
            self.yolo_model = tf.keras.utils.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
Ejemplo n.º 3
0
    def generate(self):
        model_path = os.path.expanduser(
            self.model_config[self.backbone]['model_path'])
        assert model_path.endswith(
            '.h5'), 'Keras model or weights must be a .h5 file.'

        # Load model, or construct model and load weights.
        num_anchors = len(self.anchors)
        num_classes = len(self.class_names)
        try:
            self.yolo_model = tf.keras.models.load_model(model_path,
                                                         compile=False)
        except:
            if self.backbone == BACKBONE.MOBILENETV2:
                self.yolo_model = mobilenetv2_yolo_body(
                    tf.keras.layers.Input(
                        shape=(*self.model_config[self.backbone]['input_size'],
                               3),
                        name='predict_image'), num_anchors // 3, num_classes,
                    self.alpha)
            elif self.backbone == BACKBONE.DARKNET53:
                self.yolo_model = darknet_yolo_body(
                    tf.keras.layers.Input(shape=(None, None, 3)),
                    num_anchors // 3, num_classes)
            elif self.backbone == BACKBONE.DENSENET:
                self.yolo_model = densenet_yolo_body(
                    tf.keras.layers.Input(shape=(None, None, 3)),
                    num_anchors // 3, num_classes)
            elif self.backbone == BACKBONE.INCEPTION_RESNET2:
                self.yolo_model = inception_yolo_body(
                    tf.keras.layers.Input(shape=(None, None, 3)),
                    num_anchors // 3, num_classes)
            self.yolo_model.load_weights(
                model_path)  # make sure model, anchors and classes match
        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: List[Tuple[float, float, float]] = [
            (x / len(self.class_names), 1., 1.)
            for x in range(len(self.class_names))
        ]
        self.colors: List[Tuple[float, float, float]] = list(
            map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))
        self.colors: List[Tuple[int, int, int]] = 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.
        if gpu_num >= 2:
            self.yolo_model = tf.keras.utils.multi_gpu_model(self.yolo_model,
                                                             gpus=gpu_num)
        if tf.executing_eagerly() is not True:
            self.input_image_shape = tf.placeholder(tf.float32,
                                                    shape=(2, ),
                                                    name="image_size")
            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