Esempio n. 1
0
    def test_compute_gt(self):
        level = 3
        ds = voc.build_dataset('test/data/VOC2007', im_input_size=(512, 512))

        anchors = self.generate_anchors(config.AnchorsConfig(), 512)
        im, (l, bbs) = next(iter(ds.take(1)))

        gt_reg, gt_labels = utils.anchors.anchor_targets_bbox(
            anchors, tf.expand_dims(im, 0), tf.expand_dims(bbs, 0),
            tf.expand_dims(l, 0), len(voc.IDX_2_LABEL))

        nearest_anchors = anchors[gt_reg[0, :, -1] == 1].numpy()
        im_random = unnormalize_image(im)
        im_random = visualizer.draw_boxes(im_random, nearest_anchors)
        im_random = visualizer.draw_boxes(im_random, bbs, colors=[0, 0, 255])

        for label in l:
            print(voc.IDX_2_LABEL[int(label)])

        plt.imshow(im_random)
        plt.show(block=True)

        print('GT shapes:', gt_labels.shape, gt_reg.shape)
        print('Found any overlapping anchor?', np.any(gt_labels[:, :,
                                                                -1] == 1.))
Esempio n. 2
0
    def test_regress_boxes(self):
        print('Regress anchors test')

        ds = voc.build_dataset('test/data/VOC2007', im_input_size=(512, 512))

        anchors = self.generate_anchors(config.AnchorsConfig(), 512)
        im, (l, bbs) = next(iter(ds.take(1)))

        gt_reg, gt_labels = utils.anchors.anchor_targets_bbox(
            anchors, tf.expand_dims(im, 0), tf.expand_dims(bbs, 0),
            tf.expand_dims(l, 0), len(voc.IDX_2_LABEL))

        near_mask = gt_reg[0, :, -1] == 1
        nearest_regressors = tf.expand_dims(
            tf.boolean_mask(gt_reg[0], near_mask)[:, :-1], 0)
        nearest_anchors = tf.expand_dims(anchors[near_mask], 0)

        # apply regression to boxes
        regressed_boxes = utils.bndbox.regress_bndboxes(
            nearest_anchors, nearest_regressors)

        im_random = unnormalize_image(im)
        im_random = visualizer.draw_boxes(im_random, regressed_boxes[0])

        plt.imshow(im_random)
        plt.show(block=True)
Esempio n. 3
0
    def test_regress_boxes(self):
        print('Regress anchors test')

        level = 3
        ds = voc.build_dataset('test/data/VOC2007',
                               im_input_size=(512, 512))

        anchors = self.generate_anchors(config.AnchorsConfig(), 
                                        512)
        
        for im, (l, bbs) in ds.take(1):
            
            gt_reg, gt_labels = \
                utils.anchors.anchor_targets_bbox(anchors.numpy(), 
                                                  im.numpy(), 
                                                  bbs.numpy(), l.numpy(), 
                                                  len(voc.IDX_2_LABEL))
            near_mask = gt_reg[0, :, -1] == 1
            nearest_regressors = tf.expand_dims(gt_reg[0, near_mask][:, :-1], 0)
            nearest_anchors = tf.expand_dims(anchors[near_mask], 0)

            # apply regression to boxes
            regressed_boxes = utils.bndbox.regress_bndboxes(nearest_anchors, 
                                                            nearest_regressors)

            im_random = im[0].numpy()
            for box in regressed_boxes[0].numpy():
                box = box.astype('int32')
                cv2.rectangle(im_random, 
                              (box[0], box[1]), 
                              (box[2], box[3]), (0, 255, 0), 1)
            
            cv2.imshow('', im_random)
            cv2.waitKey()
Esempio n. 4
0
    def __init__(self,
                 num_classes: int,
                 D: int = 0,
                 bidirectional: bool = True,
                 freeze_backbone: bool = False,
                 score_threshold: float = .1,
                 weights: str = 'imagenet'):

        super(EfficientDet, self).__init__()
        self.config = config.EfficientDetCompudScaling(D=D)
        self.anchors_config = config.AnchorsConfig()
        self.num_classes = num_classes
        self.score_threshold = score_threshold
        self.backbone = (models.build_efficient_net_backbone(
            self.config.B, weights))
        self.backbone.trainable = not freeze_backbone

        if bidirectional:
            self.neck = models.BiFPN(self.config.Wbifpn, self.config.Dbifpn)
        else:
            self.neck = models.FPN(self.config.Wbifpn)

        self.class_head = models.RetinaNetClassifier(self.config.Wbifpn,
                                                     self.config.Dclass,
                                                     num_classes)
        self.bb_head = models.RetinaNetBBPredictor(self.config.Wbifpn,
                                                   self.config.Dclass)

        self.anchors_gen = [
            utils.anchors.AnchorGenerator(
                size=self.anchors_config.sizes[i - 3],
                aspect_ratios=self.anchors_config.ratios,
                stride=self.anchors_config.strides[i - 3])
            for i in range(3, 8)
        ]  # 3 to 7 pyramid levels
Esempio n. 5
0
    def test_compute_gt(self):
        level = 3
        ds = voc.build_dataset('test/data/VOC2007', im_input_size=(512, 512))

        anchors = self.generate_anchors(config.AnchorsConfig(), 512)

        for im, (l, bbs) in ds.take(1):

            gt_reg, gt_labels = utils.anchors.anchor_targets_bbox(
                anchors, im, bbs, l, len(voc.IDX_2_LABEL))

            nearest_anchors = anchors[gt_reg[0, :, -1] == 1].numpy()
            im_random = im[0].numpy()
            for box in nearest_anchors:
                box = box.astype('int32')
                cv2.rectangle(im_random, (box[0], box[1]), (box[2], box[3]),
                              (0, 255, 0), 1)

            for box in bbs.numpy()[0]:
                box = box.astype('int32')
                cv2.rectangle(im_random, (box[0], box[1]), (box[2], box[3]),
                              (0, 0, 255), 3)

            for label in l[0]:
                print(voc.IDX_2_LABEL[int(label)])

            plt.imshow(im_random)
            plt.show(block=True)

            print('GT shapes:', gt_labels.shape, gt_reg.shape)
            print('Found any overlapping anchor?',
                  np.any(gt_labels[:, :, -1] == 1.))
Esempio n. 6
0
    def test_compute_gt(self):
        ds = voc.build_dataset('test/data/VOC2007',
                               im_input_size=(512, 512),
                               shuffle=False)
        ds = ds.skip(1).batch(1)

        wrapped_ds = utils.training.wrap_detection_dataset(ds, (512, 512), 20)
        anchors = self.generate_anchors(config.AnchorsConfig(), 512)

        im, (regressors, l) = next(iter(wrapped_ds.take(1)))

        im = unnormalize_image(im[0])
        near_mask = regressors[0, :, -1] == 1
        nearest_regressors = tf.expand_dims(
            tf.boolean_mask(regressors[0], near_mask)[:, :-1], 0)
        nearest_anchors = tf.expand_dims(anchors[near_mask], 0)

        # apply regression to boxes
        regressed_boxes = utils.bndbox.regress_bndboxes(
            nearest_anchors, nearest_regressors)

        im = utils.visualizer.draw_boxes(im,
                                         nearest_anchors[0],
                                         colors=[(255, 255, 0)])
        im = utils.visualizer.draw_boxes(im,
                                         regressed_boxes[0],
                                         colors=[(0, 255, 255)])

        plt.imshow(im)
        plt.axis('off')
        plt.show(block=True)

        print('GT shapes:', l.shape, regressors.shape)
        print('Found any overlapping anchor?',
              tf.reduce_any(tf.equal(l[:, :, -1], 1.)))
Esempio n. 7
0
    def test_compute_gt(self):
        classes = ['treecko', 'psyduck', 'greninja', 'solgaleo', 'mewtwo']
        class2idx = {c: i for i, c in enumerate(classes)}
        ds = labelme.build_dataset('test/data/pokemon',
                                   'test/data/pokemon',
                                   class2idx=class2idx,
                                   im_input_size=(512, 512))

        anchors = self.generate_anchors(config.AnchorsConfig(), 512)
        im, (l, bbs) = next(iter(ds.take(1)))
        im = unnormalize_image(im)

        gt_reg, gt_labels = utils.anchors.anchor_targets_bbox(
            anchors, tf.expand_dims(im, 0), tf.expand_dims(bbs, 0),
            tf.expand_dims(l, 0), len(classes))

        nearest_anchors = anchors[gt_reg[0, :, -1] == 1]
        im = utils.visualizer.draw_boxes(im, nearest_anchors)
        im = utils.visualizer.draw_boxes(im, bbs, colors=[(255, 0, 0)])

        plt.imshow(im)
        plt.axis('off')
        plt.show(block=True)

        print('GT shapes:', gt_labels.shape, gt_reg.shape)
        print('Found any overlapping anchor?', np.any(gt_labels[:, :,
                                                                -1] == 1.))
Esempio n. 8
0
    def test_nms(self):
        anchors_config = config.AnchorsConfig()

        classes, class2idx = utils.io.read_class_names(
            'test/data/pokemon/classes.names')
        n_classes = len(classes)
        ds = labelme.build_dataset('test/data/pokemon',
                                   'test/data/pokemon',
                                   class2idx=class2idx,
                                   im_input_size=(512, 512))

        anchors_gen = [
            utils.anchors.AnchorGenerator(size=anchors_config.sizes[i - 3],
                                          aspect_ratios=anchors_config.ratios,
                                          stride=anchors_config.strides[i - 3])
            for i in range(3, 8)
        ]

        sizes = (80, 40, 20, 10, 5)
        im, (l, bbs) = next(iter(ds.take(1)))

        anchors = [
            anchor_gen((size, size, 3))
            for anchor_gen, size in zip(anchors_gen, sizes)
        ]
        anchors = tf.concat(anchors, axis=0)

        gt_reg, gt_labels = utils.anchors.anchor_targets_bbox(
            anchors, tf.expand_dims(im, 0), tf.expand_dims(bbs, 0),
            tf.expand_dims(l, 0), n_classes)

        box_score = gt_labels[0]
        true_idx = tf.reshape(tf.where(box_score[:, -1] == 1), [-1])

        box_score = tf.gather(box_score, true_idx)
        anchors = tf.gather(anchors, true_idx)

        before_nms_shape = anchors.shape

        anchors = tf.expand_dims(anchors, 0)
        box_score = tf.expand_dims(box_score[:, :-1], 0)
        boxes, labels, scores = bb_utils.nms(anchors, box_score)
        after_nms_shape = boxes[0].shape

        if anchors.shape[0] != 0:
            self.assertTrue(after_nms_shape[0] < before_nms_shape[0],
                            'After nms boxes should be reduced')
        else:
            print('No ground truth anchors')

        im_random = utils.visualizer.draw_boxes(im, boxes[0])
        plt.imshow(im_random)
        plt.axis('off')
        plt.show(block=True)
Esempio n. 9
0
    def test_tile_anchors(self):
        level = 3
        feature_size = 512
        im_random = np.zeros((512, 512, 3))

        boxes = self.generate_anchors(config.AnchorsConfig(),
                                      im_random.shape[0])

        im_random = visualizer.draw_boxes(im_random, boxes)

        plt.imshow(im_random)
        plt.show(block=True)
Esempio n. 10
0
    def test_tile_anchors(self):
        level = 3
        feature_size = 512
        im_random = np.zeros((512, 512, 3))

        boxes = self.generate_anchors(config.AnchorsConfig(),
                                      im_random.shape[0])

        for box in boxes.numpy():
            box = box.astype('int32')
            cv2.rectangle(im_random, (box[0], box[1]), (box[2], box[3]),
                          (0, 255, 0), 1)

        plt.imshow(im_random)
        plt.show(block=True)
Esempio n. 11
0
    def test_compute_gt(self):
        classes = ['treecko', 'psyduck', 'greninja', 'solgaleo', 'mewtwo']
        class2idx = {c: i for i, c in enumerate(classes)}
        ds = labelme.build_dataset('test/data/pokemon',
                                   'test/data/pokemon',
                                   class2idx=class2idx,
                                   im_input_size=(512, 512))

        anchors = self.generate_anchors(config.AnchorsConfig(), 512)

        for im, (l, bbs) in ds.take(1):

            gt_reg, gt_labels = \
                utils.anchors.anchor_targets_bbox(anchors.numpy(),
                                                  im.numpy(),
                                                  bbs.numpy(), l.numpy(),
                                                  len(classes))
            nearest_anchors = anchors[gt_reg[0, :, -1] == 1].numpy()

            im_random = im[0].numpy()[..., ::-1].copy()
            for box in nearest_anchors:
                box = box.astype('int32')
                cv2.rectangle(im_random, (box[0], box[1]), (box[2], box[3]),
                              (0, 255, 0), 1)

            for box in bbs.numpy()[0]:
                box = box.astype('int32')
                cv2.rectangle(im_random, (box[0], box[1]), (box[2], box[3]),
                              (0, 0, 255), 1)

            for label in l[0]:
                print(classes[int(label)])

            cv2.imshow('', im_random)
            cv2.waitKey()

            print('GT shapes:', gt_labels.shape, gt_reg.shape)
            print('Found any overlapping anchor?',
                  np.any(gt_labels[:, :, -1] == 1.))
Esempio n. 12
0
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt

import efficientdet.data.voc as voc
import efficientdet.config as config
from efficientdet import utils, visualizer
from efficientdet.data.preprocess import unnormalize_image


def _get_res_at_level_i(res, i):
    return int(res / (2**i))


anchors_config = config.AnchorsConfig()


class AnchorsTest(unittest.TestCase):
    def generate_anchors(self, anchors_config: config.AnchorsConfig,
                         im_shape: int) -> tf.Tensor:

        anchors_gen = [
            utils.anchors.AnchorGenerator(size=anchors_config.sizes[i - 3],
                                          aspect_ratios=anchors_config.ratios,
                                          stride=anchors_config.strides[i - 3])
            for i in range(3, 8)
        ]

        shapes = [im_shape // (2**x) for x in range(3, 8)]
Esempio n. 13
0
    def __init__(self, 
                 num_classes: Optional[int] = None,
                 D : int = 0, 
                 bidirectional: bool = True,
                 freeze_backbone: bool = False,
                 score_threshold: float = .1,
                 weights : Optional[str] = 'imagenet',
                 custom_head_classifier: bool = False,
                 training_mode: bool = False) -> None:
                 
        super(EfficientDet, self).__init__()

        # Check arguments coherency 
        if custom_head_classifier is True and num_classes is None:
            raise ValueError('If include_top is False, you must specify '
                             'the num_classes')
        
        if weights not in _AVAILABLE_WEIGHTS:
            raise ValueError(f'Weights {weights} not available.\n'
                             f'The available weights are '
                             f'{list(_AVAILABLE_WEIGHTS)}')
        
        if ((weights is 'imagenet' or weights is None) 
            and custom_head_classifier):
            raise ValueError('Custom Head does not make sense when '
                             'training the model from scratch. '
                             'Set custom_head_classifier to False or specify '
                             'other weights.')

        # If weights related to efficientdet are set,
        # update the model hyperparameters according to the checkpoint,
        # but printing a warning
        if weights != 'imagenet' and weights is not None:
            from efficientdet.utils.checkpoint import download_folder
            checkpoint_path = _WEIGHTS_PATHS[weights]
            save_dir = Path(download_folder(checkpoint_path))

            params = json.load((save_dir / 'hp.json').open())

            # If num_classes is specified it must be the same as in the 
            # weights checkpoint except if the custom head classifier is set
            # to true
            if (num_classes is not None and not custom_head_classifier and
                num_classes != params['n_classes']):
                raise ValueError(f'Weights {weights} num classes are different'
                                  'from num_classes argument, please leave it '
                                  ' as None or specify the correct classes')
            
            bidirectional = params['bidirectional']
            D = params['efficientdet']

        # Declare the model architecture
        self.config = config.EfficientDetCompudScaling(D=D)
        
        # Setup efficientnet backbone
        backbone_weights = 'imagenet' if weights == 'imagenet' else None
        self.backbone = (models
                         .build_efficient_net_backbone(
                             self.config.B, backbone_weights))
        for l in self.backbone.layers:
            l.trainable = not freeze_backbone
        self.backbone.trainable = not freeze_backbone
        
        # Setup the feature extractor neck
        if bidirectional:
            self.neck = models.BiFPN(self.config.Wbifpn, self.config.Dbifpn, 
                                     prefix='bifpn/')
        else:
            self.neck = models.FPN(self.config.Wbifpn)

        # Setup the heads
        if num_classes is None:
            raise ValueError('You have to specify the number of classes.')

        self.num_classes = num_classes
        self.class_head = models.RetinaNetClassifier(
            self.config.Wbifpn,
            self.config.Dclass,
            num_classes=self.num_classes,
            prefix='class_head/')
        self.bb_head = models.RetinaNetBBPredictor(self.config.Wbifpn,
                                                   self.config.Dclass,
                                                   prefix='regress_head/')
        
        self.training_mode = training_mode

        # Inference variables, won't be used during training
        self.filter_detections = models.layers.FilterDetections(
            config.AnchorsConfig(), score_threshold)

        # Load the weights if needed
        if weights is not None and weights != 'imagenet':
            tmp = training_mode
            self.training_mode = True
            self.build([None, *self.config.input_size, 3])
            self.load_weights(str(save_dir / 'model.h5'),
                              by_name=True,
                              skip_mismatch=custom_head_classifier)
            self.training_mode = tmp
            self.training_mode = tmp

            # Append a custom classifier
            if custom_head_classifier:
                self.class_head = models.RetinaNetClassifier(
                    self.config.Wbifpn, self.config.Dclass,
                    num_classes=num_classes, prefix='class_head/')