示例#1
0
    def __init__(self,
                 input_size=300,
                 num_classes=81,
                 in_channels=(512, 1024, 512, 256, 256, 256),
                 anchor_strides=(8, 16, 32, 64, 100, 300),
                 basesize_ratio_range=(0.1, 0.9),
                 anchor_ratios=([2], [2, 3], [2, 3], [2, 3], [2], [2]),
                 target_means=(.0, .0, .0, .0),
                 target_stds=(1.0, 1.0, 1.0, 1.0)):
        super(AnchorHead, self).__init__()
        self.input_size = input_size
        self.num_classes = num_classes
        self.in_channels = in_channels
        self.cls_out_channels = num_classes
        num_anchors = [len(ratios) * 2 + 2 for ratios in anchor_ratios]
        reg_convs = []
        cls_convs = []
        for i in range(len(in_channels)):
            reg_convs.append(
                nn.Conv2d(in_channels[i],
                          num_anchors[i] * 4,
                          kernel_size=3,
                          padding=1))
            cls_convs.append(
                nn.Conv2d(in_channels[i],
                          num_anchors[i] * num_classes,
                          kernel_size=3,
                          padding=1))
        self.reg_convs = nn.ModuleList(reg_convs)
        self.cls_convs = nn.ModuleList(cls_convs)

        min_ratio, max_ratio = basesize_ratio_range
        min_ratio = int(min_ratio * 100)
        max_ratio = int(max_ratio * 100)
        step = int(np.floor(max_ratio - min_ratio) / (len(in_channels) - 2))
        min_sizes = []
        max_sizes = []
        for r in range(int(min_ratio), int(max_ratio) + 1, step):
            min_sizes.append(int(input_size * r / 100))
            max_sizes.append(int(input_size * (r + step) / 100))
        if input_size == 300:
            if basesize_ratio_range[0] == 0.15:  # SSD300 COCO
                min_sizes.insert(0, int(input_size * 7 / 100))
                max_sizes.insert(0, int(input_size * 15 / 100))
            elif basesize_ratio_range[0] == 0.2:  # SSD300 VOC
                min_sizes.insert(0, int(input_size * 10 / 100))
                max_sizes.insert(0, int(input_size * 20 / 100))
        elif input_size == 512:
            if basesize_ratio_range[0] == 0.1:  # SSD512 COCO
                min_sizes.insert(0, int(input_size * 4 / 100))
                max_sizes.insert(0, int(input_size * 10 / 100))
            elif basesize_ratio_range[0] == 0.15:  # SSD512 VOC
                min_sizes.insert(0, int(input_size * 7 / 100))
                max_sizes.insert(0, int(input_size * 15 / 100))
        self.anchor_generators = []
        self.anchor_strides = anchor_strides
        for k in range(len(anchor_strides)):
            base_size = min_sizes[k]
            stride = anchor_strides[k]
            ctr = ((stride - 1) / 2., (stride - 1) / 2.)
            scales = [1., np.sqrt(max_sizes[k] / min_sizes[k])]
            ratios = [1.]
            for r in anchor_ratios[k]:
                ratios += [1 / r, r]  # 4 or 6 ratio
            anchor_generator = AnchorGenerator(base_size,
                                               scales,
                                               ratios,
                                               scale_major=False,
                                               ctr=ctr)
            indices = list(range(len(ratios)))
            indices.insert(1, len(indices))
            anchor_generator.base_anchors = torch.index_select(
                anchor_generator.base_anchors, 0, torch.LongTensor(indices))
            self.anchor_generators.append(anchor_generator)

        self.target_means = target_means
        self.target_stds = target_stds
        self.use_sigmoid_cls = False
        self.cls_focal_loss = False
        self.fp16_enabled = False
    def __init__(self,
                 input_size=300,
                 num_classes=81,
                 in_channels=(512, 1024, 512, 256, 256, 256),
                 anchor_strides=(8, 16, 32, 64, 100, 300),
                 # basesize_ratio_range=(0.1, 0.9),
                 basesize_ratio_range=(0.2, 0.9),
                 anchor_ratios=([2], [2, 3], [2, 3], [2, 3], [2], [2]),
                 target_means=(.0, .0, .0, .0),
                 target_stds=(1.0, 1.0, 1.0, 1.0)):
        super(AnchorHead, self).__init__()
        self.input_size = input_size
        self.num_classes = num_classes
        self.in_channels = in_channels
        self.cls_out_channels = num_classes
        # num_anchors = [4, 6, 6, 6, 4, 4]
        num_anchors = [len(ratios) * 2 + 2 for ratios in anchor_ratios]
        reg_convs = []
        cls_convs = []
        for i in range(len(in_channels)):
            reg_convs.append(
                nn.Conv2d(
                    in_channels[i],
                    num_anchors[i] * 4,
                    kernel_size=3,
                    padding=1))
            cls_convs.append(
                nn.Conv2d(
                    in_channels[i],
                    num_anchors[i] * num_classes,
                    kernel_size=3,
                    padding=1))
        self.reg_convs = nn.ModuleList(reg_convs)
        self.cls_convs = nn.ModuleList(cls_convs)

        min_ratio, max_ratio = basesize_ratio_range
        # min_ratio = 20
        # max_ratio = 90
        min_ratio = int(min_ratio * 100)
        max_ratio = int(max_ratio * 100)
        # step = 17
        step = int(np.floor(max_ratio - min_ratio) / (len(in_channels) - 2))
        min_sizes = []
        max_sizes = []
        # for r in range(20, 91, 17)
        # r = 10, 30, 50, 70, 90
        for r in range(int(min_ratio), int(max_ratio) + 1, step):
            # min_sizes = [60, 111, 162, 213, 264]
            # max_sizes = [111, 162, 213, 264, 315]
            min_sizes.append(int(input_size * r / 100))
            max_sizes.append(int(input_size * (r + step) / 100))
        # min_sizes = [30, 60, 111, 162, 213, 264]
        # max_sizes = [60, 111, 162, 213, 264, 315]
        if input_size == 300:
            if basesize_ratio_range[0] == 0.15:  # SSD300 COCO
                min_sizes.insert(0, int(input_size * 7 / 100))
                max_sizes.insert(0, int(input_size * 15 / 100))
            elif basesize_ratio_range[0] == 0.2:  # SSD300 VOC
                min_sizes.insert(0, int(input_size * 10 / 100))
                max_sizes.insert(0, int(input_size * 20 / 100))
        elif input_size == 512:
            if basesize_ratio_range[0] == 0.1:  # SSD512 COCO
                min_sizes.insert(0, int(input_size * 4 / 100))
                max_sizes.insert(0, int(input_size * 10 / 100))
            elif basesize_ratio_range[0] == 0.15:  # SSD512 VOC
                min_sizes.insert(0, int(input_size * 7 / 100))
                max_sizes.insert(0, int(input_size * 15 / 100))
        self.anchor_generators = []
        self.anchor_strides = anchor_strides
        # for k in range(6):
        for k in range(len(anchor_strides)):
            base_size = min_sizes[k] # 30, 60, 111, 162, 213, 264
            stride = anchor_strides[k] # 8, 16, 32, 64, 100, 300
            # ctr : 中心点坐标(cx, cy)
            # ctr : (3.5, 3.5)、(7.5, 7.5)、 (15.5, 15.5)、(31.5, 31.5)、 (49.5, 49.5)、 (149.5, 149.5)
            ctr = ((stride - 1) / 2., (stride - 1) / 2.)
            # scales: [1.0, 1.4142135623730951] [1.0, 1.3601470508735443] [1.0, 1.2080808993852437]
            #         [1.0, 1.1466537466972386] [1.0, 1.1132998786123665] [1.0, 1.0923286218816286]
            scales = [1., np.sqrt(max_sizes[k] / min_sizes[k])]
            # ratios : [1.0, 0.5, 2]
            #          [1.0, 0.5, 2, 0.3333333333333333, 3]
            #          [1.0, 0.5, 2, 0.3333333333333333, 3]
            #          [1.0, 0.5, 2, 0.3333333333333333, 3]
            #          [1.0, 0.5, 2]
            #          [1.0, 0.5, 2]
            ratios = [1.]
            # r = [2] 或者 [2, 3]
            for r in anchor_ratios[k]:
                # r=2  ratios=[1.0, 0.5, 2]
                # r=3, ratios=[1.0, 0.5, 2, 0.3333333333333333, 3]
                ratios += [1 / r, r]  # 4 or 6 ratio

            # 根据6个anchor_strides、base_size、scales、ratios、ctr产生每个anchor_strides对应产生的
            # 不同种类anchor的坐标:torch.Size([6, 4]、[10, 4]、[10, 4]、[10, 4]、[6, 4]、[6, 4])
            anchor_generator = AnchorGenerator(
                base_size, scales, ratios, scale_major=False, ctr=ctr)
            indices = list(range(len(ratios)))
            # indices : [0, 3, 1, 2]
            #           [0, 5, 1, 2, 3, 4]
            #           [0, 5, 1, 2, 3, 4]
            #           [0, 5, 1, 2, 3, 4]
            #           [0, 3, 1, 2]
            #           [0, 3, 1, 2]
            indices.insert(1, len(indices))
            # 将anchor_generator.base_anchors产生的base_anchors按照indices选出来
            # 此时anchor_generator.base_anchors :torch.Size([4, 4]、[6, 4]、[6, 4]、[6, 4]、[4, 4]、[4, 4])
            anchor_generator.base_anchors = torch.index_select(
                anchor_generator.base_anchors, 0, torch.LongTensor(indices))
            # self.anchor_generators 表示每个 anchor_strides 下对应的 AnchorGenerator
            self.anchor_generators.append(anchor_generator)

        self.target_means = target_means
        self.target_stds = target_stds
        self.use_sigmoid_cls = False
        self.use_focal_loss = False
    def __init__(
        self,
        input_size=300,  # 512: 512
        num_classes=81,
        in_channels=(512, 1024, 512, 256, 256,
                     256),  # 512: (512, 1024, 512, 256, 256, 256, 256)
        anchor_strides=(8, 16, 32, 64, 100,
                        300),  #512:(8, 16, 32, 64, 128, 256, 512)
        anchor_ratios=([2, 3], [2, 3], [2, 3], [2, 3], [2], [
            2
        ]),  #512:([2, 3],[2, 3], [2, 3], [2, 3], [2, 3], [2], [2])
        target_means=(.0, .0, .0, .0),
        target_stds=(0.1, 0.1, 0.2, 0.2)):
        super(AnchorHead, self).__init__()
        self.input_size = input_size
        self.num_classes = num_classes
        self.in_channels = in_channels
        self.cls_out_channels = num_classes
        num_anchors = [len(ratios) * 2 + 2 for ratios in anchor_ratios]
        reg_convs = []
        cls_convs = []
        for i in range(len(in_channels)):
            reg_convs.append(
                nn.Conv2d(in_channels[i],
                          num_anchors[i] * 4,
                          kernel_size=3,
                          padding=1))
            cls_convs.append(
                nn.Conv2d(in_channels[i],
                          num_anchors[i] * num_classes,
                          kernel_size=3,
                          padding=1))
        self.reg_convs = nn.ModuleList(reg_convs)
        self.cls_convs = nn.ModuleList(cls_convs)
        # coco
        if (input_size == 300) & (num_classes == 81):
            min_sizes = [21, 45, 99, 153, 207, 261]
            max_sizes = [45, 99, 153, 207, 261, 315]
        elif (input_size == 512) & (num_classes == 81):
            min_sizes = [20.48, 51.2, 133.12, 215.04, 296.96, 378.88, 460.8]
            max_sizes = [51.2, 133.12, 215.04, 296.96, 378.88, 460.8, 542.72]
        # voc
        if (input_size == 300) & (num_classes == 21):
            min_sizes = [30, 60, 111, 162, 213, 264]
            max_sizes = [60, 111, 162, 213, 264, 315]
        elif (input_size == 512) & (num_classes == 21):
            min_sizes = [35, 76, 153, 220, 307, 384, 460]
            max_sizes = [76, 153, 230, 307, 384, 460, 537]

        self.anchor_generators = []
        self.anchor_strides = anchor_strides
        for k in range(len(anchor_strides)):
            base_size = min_sizes[k]
            stride = anchor_strides[k]
            ctr = ((stride - 1) / 2., (stride - 1) / 2.)
            scales = [1., np.sqrt(max_sizes[k] / min_sizes[k])]
            ratios = [1.]
            for r in anchor_ratios[k]:
                ratios += [1 / r, r]  # 4 or 6 ratio
            anchor_generator = AnchorGenerator(base_size,
                                               scales,
                                               ratios,
                                               scale_major=False,
                                               ctr=ctr)
            indices = list(range(len(ratios)))
            indices.insert(1, len(indices))
            anchor_generator.base_anchors = torch.index_select(
                anchor_generator.base_anchors, 0, torch.LongTensor(indices))
            self.anchor_generators.append(anchor_generator)

        self.target_means = target_means
        self.target_stds = target_stds
        self.use_sigmoid_cls = False
        self.cls_focal_loss = False
        self.fp16_enabled = False
示例#4
0
    def __init__(self,
                 input_size=300,
                 num_classes=81,
                 norm_eval=False,
                 freeze_all=False,
                 in_channels=(576, 1280, 512, 256, 256, 128),
                 anchor_strides=(16, 32, 64, 128, 150, 300),
                 basesize_ratio_range=(0.1, 0.9),
                 anchor_ratios=([2], [2, 3], [2, 3], [2, 3], [2], [2]),
                 target_means=(.0, .0, .0, .0),
                 target_stds=(1.0, 1.0, 1.0, 1.0)):
        super(AnchorHead, self).__init__()
        self.input_size = input_size
        self.num_classes = num_classes
        self.in_channels = in_channels
        self.cls_out_channels = num_classes
        self.norm_eval = norm_eval
        self.freeze_all = freeze_all
        num_anchors = [len(ratios) * 2 + 2 for ratios in anchor_ratios]
        # num_anchors = [4, 6, 6, 6, 4, 4], (if 1 then 4, if 2 then 6)
        reg_convs = []
        cls_convs = []
        for i in range(len(in_channels)):
            reg_convs.append(
                SeperableConv2d(
                    in_channels[i],
                    num_anchors[i] * 4,
                    kernel_size=3,
                    padding=1))
            cls_convs.append(
                SeperableConv2d(
                    in_channels[i],
                    num_anchors[i] * num_classes,
                    kernel_size=3,
                    padding=1))
        self.reg_convs = nn.ModuleList(reg_convs)
        self.cls_convs = nn.ModuleList(cls_convs)

        min_ratio, max_ratio = basesize_ratio_range
        min_ratio = int(min_ratio * 100)
        max_ratio = int(max_ratio * 100)
        step = int(np.floor(max_ratio - min_ratio) / (len(in_channels) - 2))
        min_sizes = []
        max_sizes = []
        for r in range(int(min_ratio), int(max_ratio) + 1, step):
            min_sizes.append(int(input_size * r / 100))
            max_sizes.append(int(input_size * (r + step) / 100))
        if input_size == 300:
            if basesize_ratio_range[0] == 0.15:  # SSD300 COCO
                min_sizes.insert(0, int(input_size * 7 / 100))
                max_sizes.insert(0, int(input_size * 15 / 100))
            elif basesize_ratio_range[0] == 0.2:  # SSD300 VOC
                min_sizes.insert(0, int(input_size * 10 / 100))
                max_sizes.insert(0, int(input_size * 20 / 100))
        elif input_size == 512:
            if basesize_ratio_range[0] == 0.1:  # SSD512 COCO
                min_sizes.insert(0, int(input_size * 4 / 100))
                max_sizes.insert(0, int(input_size * 10 / 100))
            elif basesize_ratio_range[0] == 0.15:  # SSD512 VOC
                min_sizes.insert(0, int(input_size * 7 / 100))
                max_sizes.insert(0, int(input_size * 15 / 100))
        self.anchor_generators = []
        self.anchor_strides = anchor_strides
        for k in range(len(anchor_strides)):
            base_size = min_sizes[k]
            stride = anchor_strides[k]
            ctr = ((stride - 1) / 2., (stride - 1) / 2.)
            scales = [1., np.sqrt(max_sizes[k] / min_sizes[k])]  # Typical value: [1., 1.414]
            ratios = [1.]
            for r in anchor_ratios[k]:
                ratios += [1 / r, r]
            anchor_generator = AnchorGenerator(
                base_size, scales, ratios, scale_major=False, ctr=ctr)
            indices = list(range(len(ratios)))
            indices.insert(1, len(indices))
            anchor_generator.base_anchors = torch.index_select(
                anchor_generator.base_anchors, 0, torch.LongTensor(indices))
            self.anchor_generators.append(anchor_generator)

        self.target_means = target_means
        self.target_stds = target_stds
        self.use_sigmoid_cls = False
        self.cls_focal_loss = False
        self.fp16_enabled = False

        if self.norm_eval:
            self.apply(set_bn_to_eval)

        if self.freeze_all:
            def _freeze_conv(m):
                classname = m.__class__.__name__
                if classname.find('Conv') != -1:
                    m.requires_grad = False
            self.apply(_freeze_conv)
示例#5
0
    def __init__(
            self,
            input_size=300,
            num_classes=81,
            in_channels=(512, 1024, 512, 256, 256, 256),
            anchor_strides=(8, 16, 32, 64, 100, 300),
            basesize_ratio_range=(0.1, 0.9),
            anchor_ratios=([2], [2, 3], [2, 3], [2, 3], [2], [2]),
            anchor_heights=[],
            anchor_widths=[],
            target_means=(.0, .0, .0, .0),
            # target_stds=(1.0, 1.0, 1.0, 1.0)):
            target_stds=(1.0, 1.0, 1.0, 1.0),
            loss_balancing=False,
            depthwise_heads=False):
        super(AnchorHead, self).__init__()
        self.input_size = input_size
        self.num_classes = num_classes
        self.in_channels = in_channels
        self.cls_out_channels = num_classes
        # num_anchors = [len(ratios) * 2 + 2 for ratios in anchor_ratios]
        if len(anchor_heights):
            assert len(anchor_heights) == len(anchor_widths)
            num_anchors = [len(anc_conf) for anc_conf in anchor_heights]
        else:
            num_anchors = [len(ratios) * 2 + 2 for ratios in anchor_ratios]
        reg_convs = []
        cls_convs = []
        for i in range(len(in_channels)):
            # reg_convs.append(
            #     nn.Conv2d(
            if depthwise_heads:
                reg_conv = nn.Sequential(
                    nn.Conv2d(in_channels[i],
                              in_channels[i],
                              kernel_size=3,
                              padding=1,
                              groups=in_channels[i]),
                    nn.BatchNorm2d(in_channels[i]), nn.ReLU6(inplace=True),
                    nn.Conv2d(in_channels[i],
                              num_anchors[i] * 4,
                              kernel_size=1,
                              padding=0))
                cls_conv = nn.Sequential(
                    nn.Conv2d(in_channels[i],
                              in_channels[i],
                              kernel_size=3,
                              padding=1,
                              groups=in_channels[i]),
                    nn.BatchNorm2d(in_channels[i]), nn.ReLU6(inplace=True),
                    nn.Conv2d(in_channels[i],
                              num_anchors[i] * num_classes,
                              kernel_size=1,
                              padding=0))
            else:
                reg_conv = nn.Conv2d(
                    in_channels[i],
                    num_anchors[i] * 4,
                    kernel_size=3,
                    #         padding=1))
                    # cls_convs.append(
                    #     nn.Conv2d(
                    padding=1)
                cls_conv = nn.Conv2d(
                    in_channels[i],
                    num_anchors[i] * num_classes,
                    kernel_size=3,
                    # padding=1))
                    padding=1)
            reg_convs.append(reg_conv)
            cls_convs.append(cls_conv)
        self.reg_convs = nn.ModuleList(reg_convs)
        self.cls_convs = nn.ModuleList(cls_convs)

        # min_ratio, max_ratio = basesize_ratio_range
        # min_ratio = int(min_ratio * 100)
        # max_ratio = int(max_ratio * 100)
        # step = int(np.floor(max_ratio - min_ratio) / (len(in_channels) - 2))
        # min_sizes = []
        # max_sizes = []
        # for r in range(int(min_ratio), int(max_ratio) + 1, step):
        #     min_sizes.append(int(input_size * r / 100))
        #     max_sizes.append(int(input_size * (r + step) / 100))
        # if input_size == 300:
        #     if basesize_ratio_range[0] == 0.15:  # SSD300 COCO
        #         min_sizes.insert(0, int(input_size * 7 / 100))
        #         max_sizes.insert(0, int(input_size * 15 / 100))
        #     elif basesize_ratio_range[0] == 0.2:  # SSD300 VOC
        #         min_sizes.insert(0, int(input_size * 10 / 100))
        #         max_sizes.insert(0, int(input_size * 20 / 100))
        # elif input_size == 512:
        #     if basesize_ratio_range[0] == 0.1:  # SSD512 COCO
        #         min_sizes.insert(0, int(input_size * 4 / 100))
        #         max_sizes.insert(0, int(input_size * 10 / 100))
        #     elif basesize_ratio_range[0] == 0.15:  # SSD512 VOC
        #         min_sizes.insert(0, int(input_size * 7 / 100))
        #         max_sizes.insert(0, int(input_size * 15 / 100))

        self.anchor_generators = []
        self.anchor_strides = anchor_strides
        # for k in range(len(anchor_strides)):
        #     base_size = min_sizes[k]
        #     stride = anchor_strides[k]
        #     ctr = ((stride - 1) / 2., (stride - 1) / 2.)
        #     scales = [1., np.sqrt(max_sizes[k] / min_sizes[k])]
        #     ratios = [1.]
        #     for r in anchor_ratios[k]:
        #         ratios += [1 / r, r]  # 4 or 6 ratio
        #     anchor_generator = AnchorGenerator(
        #         base_size, scales, ratios, scale_major=False, ctr=ctr)
        #     indices = list(range(len(ratios)))
        #     indices.insert(1, len(indices))
        #     anchor_generator.base_anchors = torch.index_select(
        #         anchor_generator.base_anchors, 0, torch.LongTensor(indices))
        #     self.anchor_generators.append(anchor_generator)

        if len(anchor_heights):
            assert len(anchor_heights) == len(anchor_widths)
            for k in range(len(anchor_strides)):
                assert len(anchor_widths[i]) == len(anchor_heights[i])
                stride = anchor_strides[k]
                if isinstance(stride, tuple):
                    ctr = ((stride[0] - 1) / 2., (stride[1] - 1) / 2.)
                else:
                    ctr = ((stride - 1) / 2., (stride - 1) / 2.)
                anchor_generator = AnchorGenerator(0, [], [],
                                                   widths=anchor_widths[k],
                                                   heights=anchor_heights[k],
                                                   scale_major=False,
                                                   ctr=ctr)
                self.anchor_generators.append(anchor_generator)
        else:
            min_ratio, max_ratio = basesize_ratio_range
            min_ratio = int(min_ratio * 100)
            max_ratio = int(max_ratio * 100)
            step = int(
                np.floor(max_ratio - min_ratio) / (len(in_channels) - 2))
            min_sizes = []
            max_sizes = []
            for r in range(int(min_ratio), int(max_ratio) + 1, step):
                min_sizes.append(int(input_size * r / 100))
                max_sizes.append(int(input_size * (r + step) / 100))
            min_sizes.insert(0, int(input_size * basesize_ratio_range[0] / 2))
            max_sizes.insert(0, int(input_size * basesize_ratio_range[0]))
            for k in range(len(anchor_strides)):
                base_size = min_sizes[k]
                stride = anchor_strides[k]
                if isinstance(stride, tuple):
                    ctr = ((stride[0] - 1) / 2., (stride[1] - 1) / 2.)
                else:
                    ctr = ((stride - 1) / 2., (stride - 1) / 2.)
                scales = [1., np.sqrt(max_sizes[k] / min_sizes[k])]
                ratios = [1.]
                for r in anchor_ratios[k]:
                    ratios += [1 / r, r]  # 4 or 6 ratio
                anchor_generator = AnchorGenerator(base_size,
                                                   scales,
                                                   ratios,
                                                   scale_major=False,
                                                   ctr=ctr)
                indices = list(range(len(ratios)))
                indices.insert(1, len(indices))
                anchor_generator.base_anchors = torch.index_select(
                    anchor_generator.base_anchors, 0,
                    torch.LongTensor(indices))
                self.anchor_generators.append(anchor_generator)

        self.target_means = target_means
        self.target_stds = target_stds
        self.use_sigmoid_cls = False
        self.cls_focal_loss = False
        self.fp16_enabled = False
        self.loss_balancing = loss_balancing
        if self.loss_balancing:
            self.loss_weights = torch.nn.Parameter(torch.FloatTensor(2))
            for i in range(2):
                self.loss_weights.data[i] = 0.
    def __init__(self,
                 input_size=300,
                 num_classes=81,
                 in_channels=(672, 960, 512, 256, 256, 128),
                 anchor_strides=(8, 16, 32, 64, 100, 300),
                 basesize_ratio_range=(0.1, 0.9),
                 anchor_ratios=([2], [2, 3], [2, 3], [2, 3], [2], [2]),
                 anchor_heights=[],
                 anchor_widths=[],
                 target_means=(.0, .0, .0, .0),
                 target_stds=(1.0, 1.0, 1.0, 1.0),
                 loss_balancing=False,
                 depthwise_heads=False):
        super(AnchorHead, self).__init__()
        self.input_size = input_size
        self.num_classes = num_classes
        self.in_channels = in_channels
        self.cls_out_channels = num_classes
        if len(anchor_heights):
            assert len(anchor_heights) == len(anchor_widths)
            num_anchors = [len(anc_conf) for anc_conf in anchor_heights]
        else:
            num_anchors = [len(ratios) * 2 + 2 for ratios in anchor_ratios]
        reg_convs = []
        cls_convs = []
        for i in range(len(in_channels)):
            if depthwise_heads:
                reg_conv = nn.Sequential(
                    nn.Conv2d(in_channels[i], in_channels[i],
                              kernel_size=3, padding=1, groups=in_channels[i]),
                    nn.BatchNorm2d(in_channels[i]),
                    nn.ReLU6(inplace=True),
                    nn.Conv2d(in_channels[i], num_anchors[i] * 4,
                              kernel_size=1, padding=0))
                cls_conv = nn.Sequential(
                    nn.Conv2d(in_channels[i], in_channels[i],
                              kernel_size=3, padding=1, groups=in_channels[i]),
                    nn.BatchNorm2d(in_channels[i]),
                    nn.ReLU6(inplace=True),
                    nn.Conv2d(in_channels[i], num_anchors[i] * num_classes,
                              kernel_size=1, padding=0))
            else:
                reg_conv = nn.Conv2d(
                    in_channels[i],
                    num_anchors[i] * 4,
                    kernel_size=3,
                    padding=1)
                cls_conv = nn.Conv2d(
                    in_channels[i],
                    num_anchors[i] * num_classes,
                    kernel_size=3,
                    padding=1)
            reg_convs.append(reg_conv)
            cls_convs.append(cls_conv)
        self.reg_convs = nn.ModuleList(reg_convs)
        self.cls_convs = nn.ModuleList(cls_convs)

        self.anchor_generators = []
        self.anchor_strides = anchor_strides
        if len(anchor_heights):
            assert len(anchor_heights) == len(anchor_widths)
            for k in range(len(anchor_strides)):
                assert len(anchor_widths[i]) == len(anchor_heights[i])
                stride = anchor_strides[k]
                if isinstance(stride, tuple):
                    ctr = ((stride[0] - 1) / 2., (stride[1] - 1) / 2.)
                else:
                    ctr = ((stride - 1) / 2., (stride - 1) / 2.)
                anchor_generator = AnchorGenerator(
                    0, [], [], widths=anchor_widths[k],
                    heights=anchor_heights[k],
                    scale_major=False, ctr=ctr)
                self.anchor_generators.append(anchor_generator)
        else:
            min_ratio, max_ratio = basesize_ratio_range
            min_ratio = int(min_ratio * 100)
            max_ratio = int(max_ratio * 100)
            step = int(np.floor(max_ratio - min_ratio) /
                       (len(in_channels) - 2))
            min_sizes = []
            max_sizes = []
            for r in range(int(min_ratio), int(max_ratio) + 1, step):
                min_sizes.append(int(input_size * r / 100))
                max_sizes.append(int(input_size * (r + step) / 100))
            min_sizes.insert(0, int(input_size * basesize_ratio_range[0] / 2))
            max_sizes.insert(0, int(input_size * basesize_ratio_range[0]))
            #print (min_sizes)
            #print (max_sizes)
            min_sizes = [60, 105, 150, 195, 240, 285]
            max_sizes = [105, 150, 195, 240, 285, 300]
            print ('!!!!!!!!!!!!!!!!!!!!!!!')
            #min_sizes = [77, 154, 230, 307, 384, 461]
            #max_sizes = [154, 230, 307, 384, 461, 512]
            print (min_sizes)
            print (max_sizes)
            for k in range(len(anchor_strides)):
                base_size = min_sizes[k]
                stride = anchor_strides[k]
                #print (stride)
                if isinstance(stride, tuple):
                    print ('tuple')
                    ctr = ((stride[0] - 1) / 2., (stride[1] - 1) / 2.)
                else:
                    # jump here
                    # not tuple
                    #print ('not tuple')
                    ctr = ((stride - 1) / 2., (stride - 1) / 2.)
                    #print ('ctr: ', ctr)
                # just calculate ratio=1, height = width = sqrt(min_size * max_size)
                scales = [1., np.sqrt(max_sizes[k] / min_sizes[k])]
                ratios = [1.]
                for r in anchor_ratios[k]:
                    ratios += [1 / r, r]  # 4 or 6 ratio
                anchor_generator = AnchorGenerator(
                    base_size, scales, ratios, scale_major=False, ctr=ctr)
                indices = list(range(len(ratios)))
                #print ('indices: ', indices, len(indices))
                indices.insert(1, len(indices))
                #print ('indices: ', indices, len(indices))
                anchor_generator.base_anchors = torch.index_select(
                    anchor_generator.base_anchors, 0,
                    torch.LongTensor(indices))
                #print ('anchor: ', anchor_generator.base_anchors)
                #print ('anchor num: ', len(anchor_generator.base_anchors))
                self.anchor_generators.append(anchor_generator)
                #print ('anchor generator size: ', anchor_generator.sh)


        self.target_means = target_means
        self.target_stds = target_stds
        self.use_sigmoid_cls = False
        self.cls_focal_loss = False
        self.loss_balancing = loss_balancing
        if self.loss_balancing:
            self.loss_weights = torch.nn.Parameter(torch.FloatTensor(2))
            for i in range(2):
                self.loss_weights.data[i] = 0.