Example #1
0
        def forward(self,fast_feature, proposal_bboxes: Tensor,
                    gt_classes_batch: Optional[Tensor] = None, gt_bboxes_batch: Optional[Tensor] = None)  \
                -> Union[Tuple[Tensor], Tuple[Tensor, Tensor, Tensor, Tensor]]:                ## slow_feature,   , Tensor
            batch_size = fast_feature.shape[0]  ## fast_feature:{1,256,16,16]
            feature = nn.AvgPool3d(
                kernel_size=(fast_feature.shape[2], 1,
                             1))(fast_feature).squeeze(
                                 2)  ## feature: [1,2304,16,16]
            # slow_feature = nn.AvgPool3d(kernel_size=(slow_feature.shape[2], 1, 1))(slow_feature).squeeze(2)
            # feature=torch.cat([fast_feature, slow_feature],dim=1)
            if not self.training:
                assert batch_size == 1
                proposal_batch_indices = torch.arange(
                    end=batch_size,
                    dtype=torch.long,
                    device=proposal_bboxes.device).view(-1, 1).repeat(
                        1, proposal_bboxes.shape[0])[0]
                pool = Pooler.apply(feature,
                                    proposal_bboxes,
                                    proposal_batch_indices,
                                    mode=Pooler.Mode.POOLING)
                hidden = self.hidden(pool)
                proposal_classes = self._proposal_class(hidden)
                return proposal_classes
            else:
                #过滤掉补充的0
                # find labels for each `proposal_bboxes`
                ious = BBox.iou(proposal_bboxes, gt_bboxes_batch)
                proposal_max_ious, proposal_assignments = ious.max(dim=2)
                fg_masks = proposal_max_ious >= 0.85
                if len(fg_masks.nonzero()) > 0:
                    #fg_masks.nonzero()[:, 0]是在获取batch
                    proposal_bboxes = proposal_bboxes[fg_masks.nonzero()[:, 0],
                                                      fg_masks.nonzero()[:, 1]]
                    batch_indices = fg_masks.nonzero()[:, 0]
                    labels = gt_classes_batch[fg_masks.nonzero()[:, 0],
                                              proposal_assignments[fg_masks]]
                else:
                    print('bbox warning')
                    fg_masks = proposal_max_ious >= 0.5
                    proposal_bboxes = proposal_bboxes[fg_masks.nonzero()[:, 0],
                                                      fg_masks.nonzero()[:, 1]]
                    batch_indices = fg_masks.nonzero()[:, 0]
                    labels = gt_classes_batch[fg_masks.nonzero()[:, 0],
                                              proposal_assignments[fg_masks]]

                #  # #空间池化,拼接
                pool = Pooler.apply(feature,
                                    proposal_bboxes,
                                    batch_indices,
                                    mode=Pooler.Mode.POOLING)
                # print("******** pool shape *******", pool.shape)   [6, 2048, 3, 3]

                hidden = self.hidden(pool)
                proposal_classes = self._proposal_class(hidden)
                proposal_class_losses = self.loss(proposal_classes, labels,
                                                  batch_size, batch_indices)
                return proposal_classes, proposal_class_losses
Example #2
0
        def forward(self, features: Tensor, proposal_bboxes: Tensor,
                    gt_classes_batch: Optional[Tensor] = None, gt_bboxes_batch: Optional[Tensor] = None) -> Union[Tuple[Tensor, Tensor], Tuple[Tensor, Tensor, Tensor, Tensor]]:
            batch_size = features.shape[0]

            if not self.training:
                proposal_batch_indices = torch.arange(end=batch_size, dtype=torch.long, device=proposal_bboxes.device).view(-1, 1).repeat(1, proposal_bboxes.shape[1])
                pool = Pooler.apply(features, proposal_bboxes.view(-1, 4), proposal_batch_indices.view(-1), mode=self._pooler_mode)
                hidden = self.hidden(pool)
                hidden = F.adaptive_max_pool2d(input=hidden, output_size=1)
                hidden = hidden.view(hidden.shape[0], -1)

                proposal_classes = self._proposal_class(hidden)
                proposal_transformers = self._proposal_transformer(hidden)

                proposal_classes = proposal_classes.view(batch_size, -1, proposal_classes.shape[-1])
                proposal_transformers = proposal_transformers.view(batch_size, -1, proposal_transformers.shape[-1])
                return proposal_classes, proposal_transformers
            else:
                # find labels for each `proposal_bboxes`
                labels = torch.full((batch_size, proposal_bboxes.shape[1]), -1, dtype=torch.long, device=proposal_bboxes.device)
                ious = BBox.iou(proposal_bboxes, gt_bboxes_batch)
                proposal_max_ious, proposal_assignments = ious.max(dim=2)
                labels[proposal_max_ious < 0.5] = 0
                fg_masks = proposal_max_ious >= 0.5
                if len(fg_masks.nonzero()) > 0:
                    labels[fg_masks] = gt_classes_batch[fg_masks.nonzero()[:, 0], proposal_assignments[fg_masks]]

                # select 128 x `batch_size` samples
                fg_indices = (labels > 0).nonzero()
                bg_indices = (labels == 0).nonzero()
                fg_indices = fg_indices[torch.randperm(len(fg_indices))[:min(len(fg_indices), 32 * batch_size)]]
                bg_indices = bg_indices[torch.randperm(len(bg_indices))[:128 * batch_size - len(fg_indices)]]
                selected_indices = torch.cat([fg_indices, bg_indices], dim=0)
                selected_indices = selected_indices[torch.randperm(len(selected_indices))].unbind(dim=1)

                proposal_bboxes = proposal_bboxes[selected_indices]
                gt_bboxes = gt_bboxes_batch[selected_indices[0], proposal_assignments[selected_indices]]
                gt_proposal_classes = labels[selected_indices]
                gt_proposal_transformers = BBox.calc_transformer(proposal_bboxes, gt_bboxes)
                batch_indices = selected_indices[0]

                pool = Pooler.apply(features, proposal_bboxes, proposal_batch_indices=batch_indices, mode=self._pooler_mode)
                hidden = self.hidden(pool)
                hidden = F.adaptive_max_pool2d(input=hidden, output_size=1)
                hidden = hidden.view(hidden.shape[0], -1)

                proposal_classes = self._proposal_class(hidden)
                proposal_transformers = self._proposal_transformer(hidden)
                proposal_class_losses, proposal_transformer_losses = self.loss(proposal_classes, proposal_transformers,
                                                                               gt_proposal_classes, gt_proposal_transformers,
                                                                               batch_size, batch_indices)

                return proposal_classes, proposal_transformers, proposal_class_losses, proposal_transformer_losses
Example #3
0
    def setup(cls, image_min_side: float = None, image_max_side: float = None,
              anchor_ratios: List[Tuple[int, int]] = None, anchor_sizes: List[int] = None, pooler_mode: str = None):
        if image_min_side is not None:
            cls.IMAGE_MIN_SIDE = image_min_side
        if image_max_side is not None:
            cls.IMAGE_MAX_SIDE = image_max_side

        if anchor_ratios is not None:
            cls.ANCHOR_RATIOS = ast.literal_eval(anchor_ratios)
        if anchor_sizes is not None:
            cls.ANCHOR_SIZES = ast.literal_eval(anchor_sizes)
        if pooler_mode is not None:
            cls.POOLER_MODE = Pooler.Mode(pooler_mode)
Example #4
0
        def forward(self, p2: Tensor, p3: Tensor, p4: Tensor, p5: Tensor,
                    proposal_bboxes: Tensor, image_width: int,
                    image_height: int) -> Tuple[Tensor, Tensor]:
            w = proposal_bboxes[:, 2] - proposal_bboxes[:, 0]
            h = proposal_bboxes[:, 3] - proposal_bboxes[:, 1]
            k0 = 4
            k = torch.floor(k0 + torch.log2(torch.sqrt(w * h) / 224)).long()
            k = torch.clamp(k, min=2, max=5)

            k_to_p_dict = {2: p2, 3: p3, 4: p4, 5: p5}
            unique_k = torch.unique(k)

            # NOTE: `picked_indices` is for recording the order of selection from `proposal_bboxes`
            #       so that `pools` can be then restored to make it have a consistent correspondence
            #       with `proposal_bboxes`. For example:
            #
            #           proposal_bboxes =>  B0  B1  B2
            #            picked_indices =>   1   2   0
            #                     pools => BP1 BP2 BP0
            #            sorted_indices =>   2   0   1
            #                     pools => BP0 BP1 BP2

            pools = []
            picked_indices = []

            for uk in unique_k:
                uk = uk.item()
                p = k_to_p_dict[uk]
                uk_indices = (k == uk).nonzero().view(-1)
                uk_proposal_bboxes = proposal_bboxes[uk_indices]
                pool = Pooler.apply(p,
                                    uk_proposal_bboxes,
                                    mode=self._pooler_mode)
                pools.append(pool)
                picked_indices.append(uk_indices)

            pools = torch.cat(pools, dim=0)
            picked_indices = torch.cat(picked_indices, dim=0)

            _, sorted_indices = torch.sort(picked_indices)
            pools = pools[sorted_indices]

            pools = pools.view(pools.shape[0], -1)
            hidden = self._hidden(pools)
            classes = self._class(hidden)
            transformers = self._transformer(hidden)
            return classes, transformers
Example #5
0
        def forward(
            self,
            fast_feature,
            slow_feature,
            proposal_bboxes: Tensor,
            gt_classes_batch: Optional[Tensor] = None,
            gt_bboxes_batch: Optional[Tensor] = None
        ) -> Union[Tuple[Tensor, Tensor], Tuple[Tensor, Tensor, Tensor,
                                                Tensor]]:
            batch_size = fast_feature.shape[0]
            fast_feature = nn.AvgPool3d(
                kernel_size=(fast_feature.shape[2], 1,
                             1))(fast_feature).squeeze(2)
            #print("fast_feature:",fast_feature.shape)
            slow_feature = nn.AvgPool3d(
                kernel_size=(slow_feature.shape[2], 1,
                             1))(slow_feature).squeeze(2)
            feature = torch.cat([fast_feature, slow_feature], dim=1)
            if not self.training:
                assert batch_size == 1
                # a=torch.arange(end=batch_size, dtype=torch.long, device=proposal_bboxes.device).view(-1, 1)
                # b=a.repeat(1, proposal_bboxes.shape[1])
                ######################################
                ########  @ FATAL ERROR @  ###############
                ######################################
                proposal_batch_indices = torch.arange(
                    end=batch_size,
                    dtype=torch.long,
                    device=proposal_bboxes.device).view(-1, 1).repeat(
                        1, proposal_bboxes.shape[0])[0]
                # pool_f = Pooler.apply(fast_feature, proposal_bboxes.view(-1, 4), proposal_batch_indices.view(-1), mode=self._pooler_mode)
                # pool_s = Pooler.apply(slow_feature, proposal_bboxes.view(-1, 4), proposal_batch_indices.view(-1), mode=self._pooler_mode)
                # # 空间池化,拼接
                # pool_f = nn.AdaptiveAvgPool3d((1, pool_f.shape[3], pool_f.shape[4]))(pool_f)
                # pool_s = nn.AdaptiveAvgPool3d((1, pool_s.shape[3], pool_s.shape[4]))(pool_s)
                # pool_f = pool_f.squeeze(2)
                # pool_s = pool_s.squeeze(2)
                # pool = torch.cat([pool_f, pool_s], dim=1)
                pool = Pooler.apply(feature,
                                    proposal_bboxes,
                                    proposal_batch_indices,
                                    mode=Pooler.Mode.POOLING)
                hidden = self.hidden(pool)
                proposal_classes = self._proposal_class(hidden)
                #proposal_classes = proposal_classes.view(batch_size, -1, proposal_classes.shape[-1])
                return proposal_classes
            else:
                #过滤掉补充的0

                # find labels for each `proposal_bboxes`
                ious = BBox.iou(proposal_bboxes, gt_bboxes_batch)
                proposal_max_ious, proposal_assignments = ious.max(dim=2)
                #_, proposal_which = ious.max(dim=1)
                fg_masks = proposal_max_ious >= 0.85
                if len(fg_masks.nonzero()) > 0:
                    #fg_masks.nonzero()[:, 0]是在获取batch
                    proposal_bboxes = proposal_bboxes[fg_masks.nonzero()[:, 0],
                                                      fg_masks.nonzero()[:, 1]]
                    batch_indices = fg_masks.nonzero()[:, 0]
                    labels = gt_classes_batch[fg_masks.nonzero()[:, 0],
                                              proposal_assignments[fg_masks]]
                else:
                    print('bbox warning')
                    fg_masks = proposal_max_ious >= 0.5
                    proposal_bboxes = proposal_bboxes[fg_masks.nonzero()[:, 0],
                                                      fg_masks.nonzero()[:, 1]]
                    batch_indices = fg_masks.nonzero()[:, 0]
                    labels = gt_classes_batch[fg_masks.nonzero()[:, 0],
                                              proposal_assignments[fg_masks]]
                # pool_f_pre= Pooler.apply(fast_feature, proposal_bboxes, batch_indices,mode=self._pooler_mode)
                # pool_s_pre= Pooler.apply(slow_feature, proposal_bboxes,batch_indices, mode=self._pooler_mode)
                # #空间池化,拼接
                # pool_f_a = nn.AdaptiveAvgPool3d((1, pool_f_pre.shape[3], pool_f_pre.shape[4]))(pool_f_pre)
                # pool_s_a = nn.AdaptiveAvgPool3d((1, pool_s_pre.shape[3], pool_s_pre.shape[4]))(pool_s_pre)
                # pool_f_s = pool_f_a.squeeze(2)
                # pool_s_s = pool_s_a.squeeze(2)
                # pool=torch.cat([pool_f_s, pool_s_s], dim=1)
                pool = Pooler.apply(feature,
                                    proposal_bboxes,
                                    batch_indices,
                                    mode=Pooler.Mode.POOLING)
                #sure 5
                #print("cls_labels:",labels)
                hidden = self.hidden(pool)
                proposal_classes = self._proposal_class(hidden)
                proposal_class_losses = self.loss(proposal_classes, labels,
                                                  batch_size, batch_indices)

                return proposal_classes, proposal_class_losses
Example #6
0
        def forward(
            self,
            features: Tensor,
            proposal_bboxes: Tensor,
            gt_classes_batch: Optional[Tensor] = None,
            gt_bboxes_batch: Optional[Tensor] = None
        ) -> Union[Tuple[Tensor, Tensor], Tuple[Tensor, Tensor, Tensor,
                                                Tensor]]:

            #features@(bn,1024,h/16,w/16)
            #pb@(bn,gp_n,4)

            batch_size = features.shape[0]

            if not self.training:
                #(bn,gp_n)
                proposal_batch_indices = torch.arange(
                    end=batch_size,
                    dtype=torch.long,
                    device=proposal_bboxes.device).view(-1, 1).repeat(
                        1, proposal_bboxes.shape[1])
                #ROI pooling:(bn,gp_n,1024,7,7). 这里的ROI pooling相当于把features与pb进行合并
                pool = Pooler.apply(features,
                                    proposal_bboxes.view(-1, 4),
                                    proposal_batch_indices.view(-1),
                                    mode=self._pooler_mode)

                hidden = self.hidden(
                    pool
                )  #(bn,gp_n,2048,4,4). 这里(7,7)变为(4,4)的原因是hidden中还有个stride=2的卷积层.
                hidden = F.adaptive_max_pool2d(
                    input=hidden, output_size=1)  #(bn,gp_n,2048,1,1)
                hidden = hidden.view(hidden.shape[0], -1)  #(bn,gp_n,2048)

                #self._proposal_class@Linear(2048,num_cls) self._proposal_transformer@Linear(2048,4*num_cls)
                proposal_classes = self._proposal_class(
                    hidden)  #作分类的线性变换:(bn,gp_n,num_cls)
                proposal_transformers = self._proposal_transformer(
                    hidden)  #框回归:(bn,gp_n,num_cls*4)

                proposal_classes = proposal_classes.view(
                    batch_size, -1,
                    proposal_classes.shape[-1])  #(bn,gp_n,num_cls)
                proposal_transformers = proposal_transformers.view(
                    batch_size, -1,
                    proposal_transformers.shape[-1])  #(bn,gp_n,num_cls*4)
                return proposal_classes, proposal_transformers
            else:
                #NOTE 总的处理流程类似rpn的训练forward: ious->labels->fg/bg->selected_indices.

                # find labels for each `proposal_bboxes`
                # 1.为每个pb找到类label@(bn,gp_n),默认值为-1
                labels = torch.full((batch_size, proposal_bboxes.shape[1]),
                                    -1,
                                    dtype=torch.long,
                                    device=proposal_bboxes.device)
                # ious@(bn,gp_n,gb_n) ious是确定labels的关键
                ious = BBox.iou(
                    proposal_bboxes, gt_bboxes_batch
                )  #NOTE iou在detection.forward中只用到一次,在rpn.forward中也只用到一次
                proposal_max_ious, proposal_assignments = ious.max(
                    dim=2)  #(bn,gp_n)
                labels[proposal_max_ious < 0.5] = 0  #背景类
                fg_masks = proposal_max_ious >= 0.5  #(bn,gp_n) 前景类的条件
                if len(fg_masks.nonzero()) > 0:
                    labels[fg_masks] = gt_classes_batch[
                        fg_masks.nonzero()[:,
                                           0], proposal_assignments[fg_masks]]
                    # gt_classes_batch@(b,gt_n).  为前景类设置 类label

                #现在labels共分为3种:
                #a. 为0 ,对应背景proposal
                #b. 为cls_label(>0),对应前景proposal
                #c. 为-1的默认值,忽略

                # select 128 x `batch_size` samples
                #2.确定selected_indices, 选出 batch_size x 128 个训练样本
                fg_indices = (labels > 0).nonzero()  #(fg_n,2)
                bg_indices = (labels == 0).nonzero()  #(bg_n,2)
                fg_indices = fg_indices[torch.randperm(
                    len(fg_indices))[:min(len(fg_indices), 32 *
                                          batch_size)]]  #最少len_fg,最多32个
                bg_indices = bg_indices[torch.randperm(
                    len(bg_indices))[:128 * batch_size - len(fg_indices)]]
                selected_indices = torch.cat([fg_indices, bg_indices],
                                             dim=0)  #(bn*128,2)
                #分裂为元素为2的tuple,每个元素是上面的一列:([批内索引],[pb内索引])
                selected_indices = selected_indices[torch.randperm(
                    len(selected_indices))].unbind(dim=1)

                proposal_bboxes = proposal_bboxes[
                    selected_indices]  #(bn*128,4)
                #以下是对gt_bboxes_batch的多维索引:selected_indices[0]是128个批内图像的索引,表示选择128个图像,
                #proposal_assignments[selected_indices]表示128个图像对应的gt_box序号,也是128个
                #最终选择了128个gt_bboxes.
                gt_bboxes = gt_bboxes_batch[
                    selected_indices[0],
                    proposal_assignments[selected_indices]]  #(bn*128,4)
                gt_proposal_classes = labels[selected_indices]  #(bn*128,)
                gt_proposal_transformers = BBox.calc_transformer(
                    proposal_bboxes, gt_bboxes)  #(bn*128,4)
                batch_indices = selected_indices[0]  #(bn*128)

                #features@(bn,1024,w/16,h/16) proposal_bboxes@(bn*128,4)
                #pool@(bn*128,1024,7,7)
                pool = Pooler.apply(features,
                                    proposal_bboxes,
                                    proposal_batch_indices=batch_indices,
                                    mode=self._pooler_mode)
                hidden = self.hidden(pool)  #(bn*128,2048,4,4)
                hidden = F.adaptive_max_pool2d(
                    input=hidden, output_size=1)  #(bn*128,2048,1,1)
                hidden = hidden.view(hidden.shape[0], -1)  #(bn*128,2048)

                #self._proposal_class@Linear(2048,num_cls) self._proposal_transformer@Linear(2048,4*num_cls)
                proposal_classes = self._proposal_class(
                    hidden)  #(bn*128,num_cls)
                proposal_transformers = self._proposal_transformer(
                    hidden)  #(bn*128,num_cls*4)

                proposal_class_losses, proposal_transformer_losses = self.loss(
                    proposal_classes, proposal_transformers,
                    gt_proposal_classes, gt_proposal_transformers, batch_size,
                    batch_indices)

                return proposal_classes, proposal_transformers, proposal_class_losses, proposal_transformer_losses
Example #7
0
        def forward(
            self,
            features: Tensor,
            proposal_bboxes: Tensor,
            gt_classes_batch: Optional[Tensor] = None,
            gt_bboxes_batch: Optional[Tensor] = None,
            gt_vertices_batch: Optional[Tensor] = None,
            image_width=None,
            image_height=None
        ) -> Union[Tuple[Tensor, Tensor, Tensor], Tuple[Tensor, Tensor, Tensor,
                                                        Tensor, Tensor]]:
            batch_size = features.shape[0]

            if not self.training:
                proposal_batch_indices = torch.arange(
                    end=batch_size,
                    dtype=torch.long,
                    device=proposal_bboxes.device).view(-1, 1).repeat(
                        1, proposal_bboxes.shape[1])
                pool = Pooler.apply(features,
                                    proposal_bboxes.view(-1, 4),
                                    proposal_batch_indices.view(-1),
                                    mode=self._pooler_mode)
                pool = pool.view(pool.shape[0], -1)
                hidden = self.hidden[0](pool)
                hidden = self.hidden[1](hidden)
                hidden = self.hidden[3](hidden)
                hidden = self.hidden[4](hidden)
                #hidden = F.adaptive_max_pool2d(input=hidden, output_size=1)
                #hidden = hidden.view(hidden.shape[0], -1)
                proposal_transformers = self._proposal_transformer(hidden)

                if self.iteration:
                    detection_bboxes = self.create_bboxes(
                        proposal_bboxes, proposal_transformers.unsqueeze(0),
                        image_width, image_height, 1)
                    detection_bboxes = detection_bboxes.view(-1, 4)
                    pool = Pooler.apply(features,
                                        detection_bboxes.view(-1, 4),
                                        proposal_batch_indices.view(-1),
                                        mode=self._pooler_mode)
                    pool = pool.view(pool.shape[0], -1)

                    hidden = self.hidden[0](pool)
                    hidden = self.hidden[1](hidden)
                    hidden = self.hidden[3](hidden)
                    hidden = self.hidden[4](hidden)
                    proposal_transformers2 = self._proposal_transformer(hidden)
                    proposal_transformers2 = proposal_transformers2.view(
                        batch_size, -1, proposal_transformers.shape[-1])
                else:
                    proposal_transformers2 = None

                proposal_classes = self._proposal_class(hidden)
                proposal_vertices = self._proposal_vertices(hidden)

                proposal_classes = proposal_classes.view(
                    batch_size, -1, proposal_classes.shape[-1])
                proposal_transformers = proposal_transformers.view(
                    batch_size, -1, proposal_transformers.shape[-1])
                proposal_vertices = proposal_vertices.view(
                    batch_size, -1, proposal_vertices.shape[-1])
                return proposal_vertices, proposal_classes, proposal_transformers, proposal_transformers2
            else:
                labels = torch.full((batch_size, proposal_bboxes.shape[1]),
                                    -1,
                                    dtype=torch.long,
                                    device=proposal_bboxes.device)
                # print(proposal_bboxes.size(), gt_bboxes_batch.size())
                ious = BBox.iou(proposal_bboxes, gt_bboxes_batch)
                #print(proposal_bboxes.size(), gt_bboxes_batch.size(), ious.size())
                proposal_max_ious, proposal_assignments = ious.max(dim=2)
                labels[proposal_max_ious < 0.5] = 0
                fg_masks = proposal_max_ious >= 0.5
                if len(fg_masks.nonzero()) > 0:
                    labels[fg_masks] = gt_classes_batch[
                        fg_masks.nonzero()[:,
                                           0], proposal_assignments[fg_masks]]

                # select 128 x `batch_size` samples
                fg_indices = (labels > 0).nonzero()
                bg_indices = (labels == 0).nonzero()
                fg_indices = fg_indices[torch.randperm(
                    len(fg_indices))[:min(len(fg_indices), 32 * batch_size)]]
                bg_indices = bg_indices[torch.randperm(
                    len(bg_indices))[:128 * batch_size - len(fg_indices)]]
                selected_indices = torch.cat([fg_indices, bg_indices], dim=0)
                selected_indices = selected_indices[torch.randperm(
                    len(selected_indices))].unbind(dim=1)

                proposal_bboxes = proposal_bboxes[selected_indices]
                gt_bboxes = gt_bboxes_batch[
                    selected_indices[0],
                    proposal_assignments[selected_indices]]
                gt_vertices = gt_vertices_batch[
                    selected_indices[0],
                    proposal_assignments[selected_indices]]
                gt_proposal_classes = labels[selected_indices]
                gt_proposal_transformers = BBox.calc_transformer(
                    proposal_bboxes, gt_bboxes)
                batch_indices = selected_indices[0]

                #print('before', gt_proposal_classes)
                #print(gt_proposal_classes.size())

                pool = Pooler.apply(features,
                                    proposal_bboxes,
                                    proposal_batch_indices=batch_indices,
                                    mode=self._pooler_mode)

                #vgg16
                hidden = self.hidden(pool.view(pool.shape[0], -1))

                #resnet101
                # hidden = self.hidden(pool)
                # hidden = F.adaptive_max_pool2d(input=hidden, output_size=1)
                # hidden = hidden.view(hidden.shape[0], -1)

                if self.iteration:
                    proposal_transformers_first_iter = self._proposal_transformer(
                        hidden)
                    detection_bboxes = self.create_bboxes(
                        proposal_bboxes.unsqueeze(0),
                        proposal_transformers_first_iter.unsqueeze(0),
                        image_width, image_height, 1)
                    detection_bboxes = detection_bboxes.view(-1, 4)
                    pool = Pooler.apply(features,
                                        detection_bboxes,
                                        proposal_batch_indices=batch_indices,
                                        mode=self._pooler_mode)
                    hidden = self.hidden(pool.view(pool.shape[0], -1))

                    bboxes_centers = torch.stack(
                        ((detection_bboxes[:, 0] + detection_bboxes[:, 2]) / 2,
                         (detection_bboxes[:, 1] + detection_bboxes[:, 3]) /
                         2),
                        dim=1)
                    width = detection_bboxes[:, 2] - detection_bboxes[:, 0]
                    height = detection_bboxes[:, 3] - detection_bboxes[:, 1]

                    gt_proposal_transformers = BBox.calc_transformer(
                        detection_bboxes, gt_bboxes).detach()
                    for batch_index in range(batch_size):
                        selected_batch_indices = (
                            batch_indices == batch_index).nonzero().view(-1)
                        ious = BBox.iou(
                            detection_bboxes[selected_batch_indices].unsqueeze(
                                0), gt_bboxes_batch[batch_index].unsqueeze(
                                    0)).detach()
                        #print('iter', detection_bboxes.size(), gt_bboxes.size(), ious.size())
                        max_ious, _ = ious.max(dim=2)
                        # print(gt_proposal_classes.size(), max_ious.size())
                        gt_proposal_classes[selected_batch_indices][
                            max_ious[0] < 0.5] = 0
                        gt_proposal_classes[selected_batch_indices][
                            max_ious[0] >= 0.5] = 1
                    #print('after', gt_proposal_classes)
                    #print(gt_proposal_classes.size())

                    # #if fg_indices.nelement() > 0:
                    # infinites = torch.isinf(gt_proposal_transformers)
                    # if gt_bboxes[gt_bboxes > 0].nelement() > 0 and infinites[infinites == 1].nelement() > 0:
                    #     #print(infinites)
                    #     #print(gt_proposal_transformers)
                    #     # print(infinites.size())
                    #     indices = torch.max(infinites,1)[0]
                    #     #print(indices)
                    #     indices = indices.nonzero().view(-1)

                    #print(indices)
                    #print('gt_proposal_transformers', gt_proposal_transformers[indices])
                    #print('detection_bboxes', detection_bboxes[indices])
                    #print('gt_bboxes', gt_bboxes[indices])
                    #print('ious', ious[0,index], ious.size())
                    #print(ious.size())
                    #print('max_ious', max_ious[0,indices], max_ious.size())
                    #print('gt_proposal_classes', gt_proposal_classes[indices], gt_proposal_classes.size())
                    #     #yo = BBox.calc_transformer(detection_bboxes[index].unsqueeze(0), gt_bboxes[index].unsqueeze(0), print_it=True).detach()

                else:
                    bboxes_centers = torch.stack(
                        ((proposal_bboxes[:, 0] + proposal_bboxes[:, 2]) / 2,
                         (proposal_bboxes[:, 1] + proposal_bboxes[:, 3]) / 2),
                        dim=1)
                    width = proposal_bboxes[:, 2] - proposal_bboxes[:, 0]
                    height = proposal_bboxes[:, 3] - proposal_bboxes[:, 1]

                gt_vertices_norm = torch.empty(gt_vertices.size(),
                                               dtype=torch.float,
                                               device=gt_vertices.device)

                for i in range(gt_vertices_norm.size()[-1]):
                    gt_vertices_norm[:, :, i] = torch.stack(
                        ((gt_vertices[:, 0, i] - bboxes_centers[:, 0]) / width,
                         (gt_vertices[:, 1, i] - bboxes_centers[:, 1]) /
                         height),
                        dim=1)
                gt_vertices_norm = gt_vertices_norm.detach()

                proposal_classes = self._proposal_class(hidden)
                proposal_vertices = self._proposal_vertices(hidden)
                proposal_transformers = self._proposal_transformer(hidden)

                proposal_class_losses, proposal_transformer_losses, vertex_losses = self.loss(
                    proposal_vertices, proposal_classes, proposal_transformers,
                    gt_proposal_classes, gt_proposal_transformers,
                    gt_vertices_norm, batch_size, batch_indices)

                return proposal_vertices, proposal_classes, proposal_transformers, proposal_class_losses, proposal_transformer_losses, vertex_losses