From bf1585038230a53a763e855b1b51f96ecf530dcd Mon Sep 17 00:00:00 2001 From: aiwithshekhar Date: Wed, 13 May 2020 01:52:10 +0530 Subject: [PATCH 1/2] Modified Object detection SSD to encorporate [4,6,6,6,4,4] priors for corresponding feature maps. --- model/detection/generate_priors.py | 50 ++++++++++---------- model/detection/ssd_config.py | 74 +++++++++++++++++++----------- 2 files changed, 73 insertions(+), 51 deletions(-) diff --git a/model/detection/generate_priors.py b/model/detection/generate_priors.py index 6696713..212bbb5 100644 --- a/model/detection/generate_priors.py +++ b/model/detection/generate_priors.py @@ -9,14 +9,16 @@ import torch.nn as nn from math import sqrt + class PriorBox(nn.Module): def __init__(self, cfg): super(PriorBox, self).__init__() self.image_size = cfg.image_size self.feature_maps = cfg.feature_maps - self.min_sizes = cfg.min_sizes - self.max_sizes = cfg.max_sizes - self.strides = cfg.strides + # self.min_sizes = cfg.min_sizes + # self.max_sizes = cfg.max_sizes + # self.strides = cfg.strides + self.scales = cfg.scales self.aspect_ratios = cfg.aspect_ratio self.clip = cfg.clip @@ -29,29 +31,28 @@ def forward(self): """ priors = [] for k, f in enumerate(self.feature_maps): - scale = self.image_size / self.strides[k] for i, j in product(range(f), repeat=2): # unit center x,y - cx = (j + 0.5) / scale - cy = (i + 0.5) / scale - - # small sized square box - size = self.min_sizes[k] - h = w = size / self.image_size - priors.append([cx, cy, w, h]) - - # big sized square box - size = sqrt(self.min_sizes[k] * self.max_sizes[k]) - h = w = size / self.image_size - priors.append([cx, cy, w, h]) + cx = (j + 0.5) / self.scales[k] + cy = (i + 0.5) / self.scales[k] - # change h/w ratio of the small sized box - size = self.min_sizes[k] - h = w = size / self.image_size for ratio in self.aspect_ratios[k]: - ratio = sqrt(ratio) - priors.append([cx, cy, w * ratio, h / ratio]) - priors.append([cx, cy, w / ratio, h * ratio]) + priors.append( + [ + cx, + cy, + self.scales[k] * sqrt(ratio), + self.scales[k] / sqrt(ratio), + ] + ) + # If aspect ratio is 1 prior scale is geometric_mean of (scale of the current feature map, scale of the next feature map) + if ratio == 1: + try: + extra_scale = sqrt(self.scales[k] * self.scales[k + 1]) + # last feature map scale is 1 + except IndexError: + extra_scale = 1 + priors.append([cx, cy, extra_scale, extra_scale]) priors = torch.Tensor(priors) if self.clip: @@ -59,10 +60,11 @@ def forward(self): return priors -if __name__ == '__main__': +if __name__ == "__main__": from model.detection.ssd_config import SSD300Configuration as cfg + center_form_priors = PriorBox(cfg)() from utilities import box_utils + corner_form_priors = box_utils.center_form_to_corner_form(center_form_priors) print(corner_form_priors) - diff --git a/model/detection/ssd_config.py b/model/detection/ssd_config.py index d2797e8..082607f 100644 --- a/model/detection/ssd_config.py +++ b/model/detection/ssd_config.py @@ -28,28 +28,38 @@ class SSD300Configuration(object): feature_maps.append(temp) #feature_maps = [38, 19, 10, 5, 3, 1] - - s_max_size = int(math.ceil(1.05 * image_size)) - s_min_size = int(math.ceil(0.1 * image_size)) - sizes = [int(k) for k in np.linspace(s_min_size, s_max_size, m+1)] - min_sizes = sizes[:m] - max_sizes = sizes[1:] + scales = [0.1, 0.2, 0.375, 0.55, 0.725, 0.9] #priors scales + # s_max_size = int(math.ceil(1.05 * image_size)) + # s_min_size = int(math.ceil(0.1 * image_size)) + # sizes = [int(k) for k in np.linspace(s_min_size, s_max_size, m+1)] + # min_sizes = sizes[:m] + # max_sizes = sizes[1:] #min_sizes = [30, 60, 111, 162, 213, 264] #max_sizes = [60, 111, 162, 213, 264, 315] # aspect ratio contains a list of pair (e.g. [2, 2] or [2,3] or single valued list e.g. [2,] # This has a relationship with # of boxes per location. For example, [2,] means that 4 (=2*2) boxes per location # [2, 3] means that 6=(2*2) boxes per location - aspect_ratio = [[2, 3]] * m - - box_per_location = [] # number of boxes per feature map location - for pair in aspect_ratio: - if len(pair) == 1: - box_per_location.append(pair[0] * pair[0]) + # aspect_ratio = [[2, 3]] * m + + # Aspects ratios for diffrent feature maps + aspect_ratios = [ + [1.0, 2.0, 0.5], + [1.0, 2.0, 3.0, 0.5, 0.333], + [1.0, 2.0, 3.0, 0.5, 0.333], + [1.0, 2.0, 3.0, 0.5, 0.333], + [1.0, 2.0, 0.5], + [1.0, 2.0, 0.5], + ] + + box_per_location = [] # number of boxes per feature map location [4,6,6,6,4,4] + for pair in aspect_ratios: + if len(pair) == 3: + box_per_location.append(4) else: - box_per_location.append(np.prod(pair)) + box_per_location.append(6) - assert len(feature_maps) == len(strides) == len(min_sizes) == len(max_sizes) == len(aspect_ratio) + assert len(feature_maps) == len(scales) == len(aspect_ratio) clip = True @@ -76,28 +86,38 @@ class SSD512Configuration(object): for stride in strides: temp = int(math.ceil(image_size / stride)) feature_maps.append(temp) - + + scales = [0.1, 0.2, 0.375, 0.55, 0.725, 0.9] #priors scales #min_sizes = [36, 77, 154, 230, 307, 461] #max_sizes = [77, 154, 230, 307, 384, 538] - s_max_size = int(math.ceil(1.05 * image_size)) - s_min_size = int(math.ceil(0.1 * image_size)) - sizes = [int(k) for k in np.linspace(s_min_size, s_max_size, m + 1)] - min_sizes = sizes[:m] - max_sizes = sizes[1:] + # s_max_size = int(math.ceil(1.05 * image_size)) + # s_min_size = int(math.ceil(0.1 * image_size)) + # sizes = [int(k) for k in np.linspace(s_min_size, s_max_size, m + 1)] + # min_sizes = sizes[:m] + # max_sizes = sizes[1:] # aspect ratio contains a list of pair (e.g. [2, 2] or [2,3] or single valued list e.g. [2,] # This has a relationship with # of boxes per location. For example, [2,] means that 4 (=2*2) boxes per location # [2, 3] means that 6=(2*2) boxes per location - aspect_ratio = [[2, 3]] * m - box_per_location = [] # number of boxes per feature map location - for pair in aspect_ratio: - if len(pair) == 1: - box_per_location.append(pair[0] * pair[0]) + + # Aspects ratios for diffrent feature maps + aspect_ratios = [ + [1.0, 2.0, 0.5], + [1.0, 2.0, 3.0, 0.5, 0.333], + [1.0, 2.0, 3.0, 0.5, 0.333], + [1.0, 2.0, 3.0, 0.5, 0.333], + [1.0, 2.0, 0.5], + [1.0, 2.0, 0.5], + ] + box_per_location = [] # number of boxes per feature map location [4,6,6,6,4,4] + for pair in aspect_ratios: + if len(pair) == 3: + box_per_location.append(4) else: - box_per_location.append(np.prod(pair)) + box_per_location.append(6) clip = True - assert len(feature_maps) == len(strides) == len(min_sizes) == len(max_sizes) == len(aspect_ratio) + assert len(feature_maps) == len(scales) == len(aspect_ratio) # test specific options nms_threshold = 0.45 From ddf91fa6c4ee3014019c5b8897f6f087e73f51da Mon Sep 17 00:00:00 2001 From: aiwithshekhar Date: Wed, 13 May 2020 14:30:34 +0530 Subject: [PATCH 2/2] minor updates in cx, cy denominator values. --- model/detection/generate_priors.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/model/detection/generate_priors.py b/model/detection/generate_priors.py index 212bbb5..5a34585 100644 --- a/model/detection/generate_priors.py +++ b/model/detection/generate_priors.py @@ -33,8 +33,8 @@ def forward(self): for k, f in enumerate(self.feature_maps): for i, j in product(range(f), repeat=2): # unit center x,y - cx = (j + 0.5) / self.scales[k] - cy = (i + 0.5) / self.scales[k] + cx = (j + 0.5) / self.feature_maps[k] + cy = (i + 0.5) / self.feature_maps[k] for ratio in self.aspect_ratios[k]: priors.append(