pytorch-RefineDet------PriorBox

假如想象 提交于 2020-01-02 08:49:48

相关函数

1、torch.clamp()

torch.clamp(input, min, max, out=None) --> Tensor

将输入input Tensor中每个元素约束到【min,max】,返回一个截断后的new Tensor

例子:

input = torch.Tensor([2,1,0.5,-0.5])
output = torch.clamp(input,0,1)
print(output)

'''
output
Out[16]: tensor([1.000, 1.000, 0.500, 0.000])
'''

2、itertools.product( )

product(*iterables,repeat=1) --> product object

iterable是可迭代对象,repeat指定iterable重复几次,即product(A,repeat=3)等价于product(A,A,A)

该函数用于求输入迭代对象的笛卡尔集,相当于一个前天的for循环。product返回的是一个迭代器。

import itertools.product as product

list1=['a','b']
list2=['c','d']

for item in product(list1,list2):
    print(item)


'''
...
('a','c')
('a','d')
('b','c')
('b','d')
'''

list1 = [1,2,3,4]
for item in product(list1,repeat=2):
    print(item)

'''
用于生成笛卡尔坐标
(1,1)
(1,2)
(1,3)
(1,4)
  ...
(4,1)
(4,2)
(4,3)
(4,4)
'''

相关参数

# RefineDet CONFIGS
voc_refinedet = { 
    '320': {
        'num_classes': 21, 
        'lr_steps': (80000, 100000, 120000),
        'max_iter': 120000,
        'feature_maps': [40, 20, 10, 5], 
        'min_dim': 320,
        'steps': [8, 16, 32, 64],
        'min_sizes': [32, 64, 128, 256],
        'max_sizes': [], 
        'aspect_ratios': [[2], [2], [2], [2]],
        'variance': [0.1, 0.2],
        'clip': True,
        'name': 'RefineDet_VOC_320',
    },  
    '512': {
        'num_classes': 21, 
        'lr_steps': (80000, 100000, 120000),
        'max_iter': 120000,
        'feature_maps': [64, 32, 16, 8], 
        'min_dim': 512,
        'steps': [8, 16, 32, 64],
        'min_sizes': [32, 64, 128, 256],
        'max_sizes': [], 
        'aspect_ratios': [[2], [2], [2], [2]],
        'variance': [0.1, 0.2],
        'clip': True,
        'name': 'RefineDet_VOC_320',
    }   
}

num_class为当前的数据集类别数+背景(voc为20+1)

feature_maps为FPN的特征图大小

steps特征图相对于输入图像的下采样率,用于计算当前特征图上某一位置处所有默认框中心坐标在输入图像的坐标

min_sizes&max_size为当前特征层的默认尺寸,个人感觉这里直接写出来的意思是表示该层的anchor大小在这两个值之间。

aspect_ratios anchor的长宽比

代码解读

class PriorBox(object):
    """Compute priorbox coordinates in center-offset form for each source
    feature map.
    """
    def __init__(self, cfg):
        super(PriorBox, self).__init__()
        self.image_size = cfg['min_dim']
        # number of priors for feature map location (either 4 or 6)
        self.num_priors = len(cfg['aspect_ratios'])
        self.variance = cfg['variance'] or [0.1]  # [0.1, 0.2]
        self.feature_maps = cfg['feature_maps']   #[64, 32, 16, 8]
        self.min_sizes = cfg['min_sizes']         #[32, 64, 128, 256]
        self.max_sizes = cfg['max_sizes']         #[] 
        self.steps = cfg['steps']                 #[8, 16, 32, 64]
        self.aspect_ratios = cfg['aspect_ratios'] #[[2],[2],[2],[2]]
        self.clip = cfg['clip']                   # True
        self.version = cfg['name']                # RefineDet_VOC_512
        for v in self.variance:
            if v <= 0:
                raise ValueError('Variances must be greater than 0')

    def forward(self):
        mean = []
        for k, f in enumerate(self.feature_maps):   #遍历4个特征图,每个特征图分别生成anchor
            for i, j in product(range(f), repeat=2):#针对每个特征图遍历所有坐标
            '''
            将特征图的坐标对应回原图坐标,然后缩放到0~1的相对距离
            原始公式应该为cx = (j+0.5)* step /min_dim,这里拆成两步计算
            '''
                f_k = self.image_size / self.steps[k]
                # unit center x,y
                cx = (j + 0.5) / f_k 
                cy = (i + 0.5) / f_k 

                # aspect_ratio: 1
                # rel size: min_size
              
                s_k = self.min_sizes[k]/self.image_size
                mean += [cx, cy, s_k, s_k]

                # aspect_ratio: 1
                # rel size: sqrt(s_k * s_(k+1))
                if self.max_sizes:
                    s_k_prime = sqrt(s_k * (self.max_sizes[k]/self.image_size))
                    mean += [cx, cy, s_k_prime, s_k_prime]

                # rest of aspect ratios
                for ar in self.aspect_ratios[k]:
                    mean += [cx, cy, s_k*sqrt(ar), s_k/sqrt(ar)]
                    mean += [cx, cy, s_k/sqrt(ar), s_k*sqrt(ar)]
        # back to torch land将产生的anchor转化成n行4列的标准格式
        output = torch.Tensor(mean).view(-1, 4)

        if self.clip:
            output.clamp_(max=1, min=0)
        return output
                                      

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!