【unbiased teacher for semi-supervised object detection复现】

  • Post author:
  • Post category:其他


unbiased teacher for semi-supervised object detection 配环境复现



配pytorch环境

  1. 搭建名为ubteachers的虚拟环境

    conda create -n ubteachers python=3.7
    
  2. 激活虚拟环境

    source activate ubteachers
    
  3. 安装符合要求的pytorch(按照自己的cuda版本进行选择,在可选的torch版本中找到可以匹配detectron的torch版本)

    按照下图选择torch版本:

    detectron官网


    在这里插入图片描述

    conda install pytorch==1.9.0 torchvision==0.10.0 torchaudio==0.9.0 cudatoolkit=10.2 -c pytorch
    



安装detectron2


  1. 首先安装一些支持包

    。因为我的服务器网络时好时坏,故而有些包只能下载到本地、上传服务器进行安装,如果你的服务器可以联网,可以使用其他安装方式。需要安装的包有

    opencv,fvcore,Cython,pycocotools

    pip install opencv-python
    
    conda install -c fvcore fvcore
    或
    pip install fvcore
    
    pip install -U Cython
    

    先下载

    pycocotools

    在本地,然后cd到cocoapi-master/PythonAPI下

    python setup.py build
    
    python setup.py install
    

    如果出现报错

    No module named 'pycocotools._mask'

    ,可参考

    https://blog.csdn.net/hesongzefairy/article/details/105343439

    ,执行make命令。


  2. 再来安装detectron2

    。先从官网把

    detectron2

    下载到本地,

    不用进入子文件夹

    python -m pip install -e detectron2
    


    到此为止,detectron和环境搭建基本完成。


    在输入上面detectron2命令的时候,我出现了报错 could not find a version that satisfies the requirement timm

    在这里插入图片描述

    解决方法:安装timm

    pip install timm
    



跑代码

  1. 下载官方代码和数据集coco2017,我的文件目录为

    在这里插入图片描述

  2. 输入命令:

    我只有一块GPU,故而

    num-gups 1

    python train_net.py \
          --num-gpus 8 \
          --config configs/coco_supervision/faster_rcnn_R_50_FPN_sup1_run1.yaml \
           SOLVER.IMG_PER_BATCH_LABEL 16 SOLVER.IMG_PER_BATCH_UNLABEL 16
    
  3. 出现报错及解决方案

    报错一:

    module 'distutuils' has no attribute 'version'


    在这里插入图片描述

    解决方法,


    pip uninstall setuptools



    pip install setuptools==59.5.0

报错二:

descriptors cannot not be created directly


在这里插入图片描述

解决方法:

pip install protobuf==3.19.0


报错三(常见)



cannot import name 'FastRCNNOutputs'


参考链接

ImportError: cannot import name ‘FastRCNNOutputs’ #44

  1. 将FastRCNNOutputs这个class复制到ubteacher/modeling/roi_heads/fast_rcnn.py

    class FastRCNNOutputs:
        """
        An internal implementation that stores information about outputs of a Fast R-CNN head,
        and provides methods that are used to decode the outputs of a Fast R-CNN head.
        """
    
        def __init__(
            self,
            box2box_transform,
            pred_class_logits,
            pred_proposal_deltas,
            proposals,
            smooth_l1_beta=0.0,
            box_reg_loss_type="smooth_l1",
        ):
            """
            Args:
                box2box_transform (Box2BoxTransform/Box2BoxTransformRotated):
                    box2box transform instance for proposal-to-detection transformations.
                pred_class_logits (Tensor): A tensor of shape (R, K + 1) storing the predicted class
                    logits for all R predicted object instances.
                    Each row corresponds to a predicted object instance.
                pred_proposal_deltas (Tensor): A tensor of shape (R, K * B) or (R, B) for
                    class-specific or class-agnostic regression. It stores the predicted deltas that
                    transform proposals into final box detections.
                    B is the box dimension (4 or 5).
                    When B is 4, each row is [dx, dy, dw, dh (, ....)].
                    When B is 5, each row is [dx, dy, dw, dh, da (, ....)].
                proposals (list[Instances]): A list of N Instances, where Instances i stores the
                    proposals for image i, in the field "proposal_boxes".
                    When training, each Instances must have ground-truth labels
                    stored in the field "gt_classes" and "gt_boxes".
                    The total number of all instances must be equal to R.
                smooth_l1_beta (float): The transition point between L1 and L2 loss in
                    the smooth L1 loss function. When set to 0, the loss becomes L1. When
                    set to +inf, the loss becomes constant 0.
                box_reg_loss_type (str): Box regression loss type. One of: "smooth_l1", "giou"
            """
            self.box2box_transform = box2box_transform
            self.num_preds_per_image = [len(p) for p in proposals]
            self.pred_class_logits = pred_class_logits
            self.pred_proposal_deltas = pred_proposal_deltas
            self.smooth_l1_beta = smooth_l1_beta
            self.box_reg_loss_type = box_reg_loss_type
    
            self.image_shapes = [x.image_size for x in proposals]
    
            if len(proposals):
                box_type = type(proposals[0].proposal_boxes)
                # cat(..., dim=0) concatenates over all images in the batch
                self.proposals = box_type.cat([p.proposal_boxes for p in proposals])
                assert (
                    not self.proposals.tensor.requires_grad
                ), "Proposals should not require gradients!"
    
                # "gt_classes" exists if and only if training. But other gt fields may
                # not necessarily exist in training for images that have no groundtruth.
                if proposals[0].has("gt_classes"):
                    self.gt_classes = cat([p.gt_classes for p in proposals], dim=0)
    
                    # If "gt_boxes" does not exist, the proposals must be all negative and
                    # should not be included in regression loss computation.
                    # Here we just use proposal_boxes as an arbitrary placeholder because its
                    # value won't be used in self.box_reg_loss().
                    gt_boxes = [
                        p.gt_boxes if p.has("gt_boxes") else p.proposal_boxes for p in proposals
                    ]
                    self.gt_boxes = box_type.cat(gt_boxes)
            else:
                self.proposals = Boxes(torch.zeros(0, 4, device=self.pred_proposal_deltas.device))
            self._no_instances = len(self.proposals) == 0  # no instances found
    
        def softmax_cross_entropy_loss(self):
            """
            Deprecated
            """
            _log_classification_stats(self.pred_class_logits, self.gt_classes)
            return cross_entropy(self.pred_class_logits, self.gt_classes, reduction="mean")
    
        def box_reg_loss(self):
            """
            Deprecated
            """
            if self._no_instances:
                return 0.0 * self.pred_proposal_deltas.sum()
    
            box_dim = self.proposals.tensor.size(1)  # 4 or 5
            cls_agnostic_bbox_reg = self.pred_proposal_deltas.size(1) == box_dim
            device = self.pred_proposal_deltas.device
    
            bg_class_ind = self.pred_class_logits.shape[1] - 1
            # Box delta loss is only computed between the prediction for the gt class k
            # (if 0 <= k < bg_class_ind) and the target; there is no loss defined on predictions
            # for non-gt classes and background.
            # Empty fg_inds should produce a valid loss of zero because reduction=sum.
            fg_inds = nonzero_tuple((self.gt_classes >= 0) & (self.gt_classes < bg_class_ind))[0]
    
            if cls_agnostic_bbox_reg:
                # pred_proposal_deltas only corresponds to foreground class for agnostic
                gt_class_cols = torch.arange(box_dim, device=device)
            else:
                # pred_proposal_deltas for class k are located in columns [b * k : b * k + b],
                # where b is the dimension of box representation (4 or 5)
                # Note that compared to Detectron1,
                # we do not perform bounding box regression for background classes.
                gt_class_cols = box_dim * self.gt_classes[fg_inds, None] + torch.arange(
                    box_dim, device=device
                )
    
            if self.box_reg_loss_type == "smooth_l1":
                gt_proposal_deltas = self.box2box_transform.get_deltas(
                    self.proposals.tensor, self.gt_boxes.tensor
                )
                loss_box_reg = smooth_l1_loss(
                    self.pred_proposal_deltas[fg_inds[:, None], gt_class_cols],
                    gt_proposal_deltas[fg_inds],
                    self.smooth_l1_beta,
                    reduction="sum",
                )
            elif self.box_reg_loss_type == "giou":
                fg_pred_boxes = self.box2box_transform.apply_deltas(
                    self.pred_proposal_deltas[fg_inds[:, None], gt_class_cols],
                    self.proposals.tensor[fg_inds],
                )
                loss_box_reg = giou_loss(
                    fg_pred_boxes,
                    self.gt_boxes.tensor[fg_inds],
                    reduction="sum",
                )
            else:
                raise ValueError(f"Invalid bbox reg loss type '{self.box_reg_loss_type}'")
    
            loss_box_reg = loss_box_reg / self.gt_classes.numel()
            return loss_box_reg
    
        def losses(self):
            """
            Deprecated
            """
            return {"loss_cls": self.softmax_cross_entropy_loss(), "loss_box_reg": self.box_reg_loss()}
    
        def predict_boxes(self):
            """
            Deprecated
            """
            pred = self.box2box_transform.apply_deltas(self.pred_proposal_deltas, self.proposals.tensor)
            return pred.split(self.num_preds_per_image, dim=0)
    
        def predict_probs(self):
            """
            Deprecated
            """
            probs = F.softmax(self.pred_class_logits, dim=-1)
            return probs.split(self.num_preds_per_image, dim=0)
    
    
  2. 在这个py文件里添加

    from detectron2.layers import ShapeSpec, batched_nms, cat, cross_entropy, nonzero_tuple
    from fvcore.nn import giou_loss, smooth_l1_loss
    from detectron2.modeling.box_regression import Box2BoxTransform
    from detectron2.structures import Boxes
    
  3. 注释掉py文件里的这里

    在这里插入图片描述

至此,程序可以跑通。希望该文章对您所有帮助!



版权声明:本文为weixin_44401589原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。