Transformer实战-系列教程14:DETR 源码解读1(项目配置/CocoDetection类/ConvertCocoPolysToMask类)

🚩🚩🚩Transformer实战-系列教程总目录

有任何问题欢迎在下面留言
本篇文章的代码运行界面均在Pycharm中进行
本篇文章配套的代码资源已经上传
点我下载源码

DETR 算法解读
DETR 源码解读1(项目配置/CocoDetection类/ConvertCocoPolysToMask类)
DETR 源码解读2(DETR类)
DETR 源码解读3(位置编码:Joiner类/PositionEmbeddingSine类)
DETR 源码解读4(BackboneBase类/Backbone类)
DETR 源码解读5(Transformer类)
DETR 源码解读6(编码器:TransformerEncoder类/TransformerEncoderLayer类)
DETR 源码解读7(解码器:TransformerDecoder类/TransformerDecoderLayer类)
DETR 源码解读8(训练函数/损失函数)

1、项目配置

主要环境

install PyTorch 1.5+
pip install pycocotools 
pip install cython
pip install scipy

需要下载coco数据集,这个数据集比较大,训练集8w图像,验证集4w图像。数据包括coco-data,打开后三个文件夹,annotations、train2014、val2014。

作者表示,一个epoch需要28分钟,300个epoch花费了6天,在一台有8个V100的机器上。但是我们学习这个算法只需要跑一些小的demo,不需要这么大的配置资源

项目主要是两大模块,一个是数据的处理,一个是网络的构建

运行项目:main.py
配置参数:

--coco_path A:\CV\Transformer\DETR\coco-2014

只需要知道coco文件夹的位置

2、CocoDetection类

2.1 CocoDetection类

位置:datasets/coco.py/CocoDetection类

class CocoDetection(torchvision.datasets.CocoDetection):
    def __init__(self, img_folder, ann_file, transforms, return_masks):
        super(CocoDetection, self).__init__(img_folder, ann_file)
        self._transforms = transforms
        self.prepare = ConvertCocoPolysToMask(return_masks)

    def __getitem__(self, idx):
        img, target = super(CocoDetection, self).__getitem__(idx)
        image_id = self.ids[idx]
        target = {'image_id': image_id, 'annotations': target}
        img, target = self.prepare(img, target)
        if self._transforms is not None:
            img, target = self._transforms(img, target)
        return img, target
  1. CocoDetection类,继承torchvision.datasets.CocoDetection
  2. 构造函数,图像数据路径、标注数据路径、数据增强参数、是否要mask
  3. 初始化类
  4. 数据增强参数
  5. ConvertCocoPolysToMask是一个自定义的类,实例化这个类的对象,并且传入return_masks参数,主要是进行数据预处理的操作
  6. 定义一个迭代序列的函数,传入索引
  7. 获取索引为idx的图像(img)和标签(target),此时的标签数据包含了分割任务的标签,但是可以不用
  8. 获取当前图像的ID
  9. 把标签制作成包含图像id和原始标注数据的字典
  10. 调用 prepare 对象将标注数据转化为掩码
  11. 是否需要进行数据增强
  12. 调用make_coco_transforms函数进行数据增强,make_coco_transforms函数使用_transforms作为变量传入当前类、
  13. 返回处理后的图像和标签

这是一个coco数据集的读取类,而且还是继承torchvision.datasets.CocoDetection

2.1 make_coco_transforms()函数

位置:datasets/coco.py/make_coco_transforms函数
make_coco_transforms()函数是进行数据增强的函数

def make_coco_transforms(image_set):
    normalize = T.Compose([
        T.ToTensor(),
        T.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ])
    scales = [480, 512, 544, 576, 608, 640, 672, 704, 736, 768, 800]
    if image_set == 'train':
        return T.Compose([
            T.RandomHorizontalFlip(),
            T.RandomSelect(
                T.RandomResize(scales, max_size=1333),
                T.Compose([ T.RandomResize([400, 500, 600]),
                    T.RandomSizeCrop(384, 600), T.RandomResize(scales, max_size=1333), ])
            ),
            normalize,
        ])
    if image_set == 'val':
        return T.Compose([ T.RandomResize([800], max_size=1333), normalize,
        ])
    raise ValueError(f'unknown {image_set}')

数据增强比较简单,把数据转换为Tensor格式,进行归一化操作,随机水平翻转、从两个不同的缩放和裁剪策略中随机选择一个等

3、ConvertCocoPolysToMask类

位置:datasets/coco.py/ConvertCocoPolysToMask类

ConvertCocoPolysToMask类主要是进行数据预处理,主要在CocoDetection类中被调用

从的ConvertCocoPolysToMask类的代码来看,主要涉及到以下几种计算机视觉任务的数据预处理步骤:

  1. 物体检测(Object Detection)
    • 体现:通过处理bbox(边界框)信息。代码中提取和调整bbox坐标来适应物体检测任务的需求。
  2. 实例分割(Instance Segmentation)
    • 体现:如果return_masks为True,将COCO多边形标注(segmentation)转换为掩码(mask)。这对于实例分割任务来说是必要的,因为它需要精确地区分图像中各个对象的形状。
  3. 姿态估计(Pose Estimation)
    • 体现:通过处理keypoints信息。当标注中包含关键点数据时,代码会提取这些数据,这些数据对于识别和估计图像中人物的姿态非常有用。
class ConvertCocoPolysToMask(object):
    def __init__(self, return_masks=False):
        self.return_masks = return_masks
    def __call__(self, image, target):
        w, h = image.size
        image_id = target["image_id"]
        image_id = torch.tensor([image_id])
        anno = target["annotations"]
        anno = [obj for obj in anno if 'iscrowd' not in obj or obj['iscrowd'] == 0]
        boxes = [obj["bbox"] for obj in anno] # x y w h
        # guard against no boxes via resizing
        boxes = torch.as_tensor(boxes, dtype=torch.float32).reshape(-1, 4)
        boxes[:, 2:] += boxes[:, :2]
        boxes[:, 0::2].clamp_(min=0, max=w)
        boxes[:, 1::2].clamp_(min=0, max=h)
        classes = [obj["category_id"] for obj in anno]
        classes = torch.tensor(classes, dtype=torch.int64)
        if self.return_masks:
            segmentations = [obj["segmentation"] for obj in anno]
            masks = convert_coco_poly_to_mask(segmentations, h, w)
        keypoints = None
        if anno and "keypoints" in anno[0]:
            keypoints = [obj["keypoints"] for obj in anno]
            keypoints = torch.as_tensor(keypoints, dtype=torch.float32)
            num_keypoints = keypoints.shape[0]
            if num_keypoints:
                keypoints = keypoints.view(num_keypoints, -1, 3)

        keep = (boxes[:, 3] > boxes[:, 1]) & (boxes[:, 2] > boxes[:, 0])
        boxes = boxes[keep]
        classes = classes[keep]
        if self.return_masks:
            masks = masks[keep]
        if keypoints is not None:
            keypoints = keypoints[keep]
        target = {}
        target["boxes"] = boxes
        target["labels"] = classes
        if self.return_masks:
            target["masks"] = masks
        target["image_id"] = image_id
        if keypoints is not None:
            target["keypoints"] = keypoints
        area = torch.tensor([obj["area"] for obj in anno])
        iscrowd = torch.tensor([obj["iscrowd"] if "iscrowd" in obj else 0 for obj in anno])
        target["area"] = area[keep]
        target["iscrowd"] = iscrowd[keep]
        target["orig_size"] = torch.as_tensor([int(h), int(w)])
        target["size"] = torch.as_tensor([int(h), int(w)])
        return image, target
  1. 定义ConvertCocoPolysToMask类,用于处理COCO数据集的转换
  2. 类的初始化方法,参数return_masks用于控制是否返回标注的掩码信息
  3. return_masks
  4. 可调用方法,接收两个参数:image(PIL图像对象)和target(包含图像标注信息的字典)
  5. 图像w、h, 427 ∗ 640 427*640 427640,每张图片读进来的长宽都可能不一样
  6. 获取图像id,image id: 538686]
  7. 将id转化为Tensor,image id: tensor([538686])
  8. 获取标签的标注信息,包含面积、bbox框的长宽xy四个值、类别id、图像id、分割的标注信息
  9. 过滤标注信息,过滤掉有重叠框的,只保留对单个物体的框,包含重叠物体的不要,如果iscrowd为1,表示这个标注包含的是一个对象群,而不是单个对象
  10. 获取所有框,[[62.37, 135.48, 184.94, 364.52],…, [107.99, 46.17, 101.51, 157.66]]
  11. 框的数据转化为Tensor
  12. 将x、y、w、h
  13. 转化为
  14. x1、y1、x2、y2,tensor([[ 62.3700, 135.4800, 247.3100, 500.0000],…, [107.9900, 46.1700, 209.5000, 203.8300]])
  15. 获取当前图像的所有类别标签(可能对应有多个类别),[19, 21, 21, 1]
  16. 转化为Tensor,tensor([19, 21, 21, 1])
  17. 是否进行掩码转换
  18. 提取分割信息
  19. 调用函数将分割信息转化为掩码
  20. 初始化 keypoints (姿态估计任务使用)变量
  21. 判断标注信息中是否包含 keypoints 信息
  22. 提取所有标注的 keypoints 信息
  23. 将 keypoints 列表转换为PyTorch张量
  24. 获取 keypoints 的数量
  25. 判断是否存在 keypoints
  26. 重塑 keypoints 张量
  27. 过滤掉不合逻辑的边界框(即右下角坐标不大于左上角坐标的边界框),因为在标注数据的时候,外包人员如果没有按照标注说明去标,拉框不是从上面往下框住物体,而是从下往上,这会影响两个点的顺序判断
  28. 使用keep数组过滤边界框,保留有效的边界框
  29. 同样使用keep数组过滤类别ID,保留与有效边界框对应的类别ID
  30. 判断是否有掩码
  31. 使用keep数组过滤掩码,保留与有效边界框对应的掩码
  32. 如果 keypoints 信息存在
  33. 使用keep数组过滤 keypoints 信息
  34. 初始化一个新的字典target,用于存储处理后的标注信息
  35. 将过滤后的边界框信息添加到target字典
  36. 将过滤后的类别ID添加到target字典
  37. 判断是否有掩码
  38. 将过滤后的掩码添加到target字典
  39. 将图像ID添加到target字典
  40. 如果存在关键点信息
  41. 将过滤后的关键点信息添加到target字典
  42. 提取所有标注的面积信息,并转换为PyTorch张量
  43. 将过滤后的iscrowd信息添加到target字典,如果iscrowd为1,表示这个标注包含的是一个对象群,而不是单个对象
  44. 分别将原始图像的高度和宽度作为orig_size和size添加到target字典。这两个字段通常用于后续的处理或数据恢复步骤
  45. 返回处理后的图像和更新后的target字典

DETR 算法解读
DETR 源码解读1(项目配置/CocoDetection类/ConvertCocoPolysToMask类)
DETR 源码解读2(DETR类)
DETR 源码解读3(位置编码:Joiner类/PositionEmbeddingSine类)
DETR 源码解读4(BackboneBase类/Backbone类)
DETR 源码解读5(Transformer类)
DETR 源码解读6(编码器:TransformerEncoder类/TransformerEncoderLayer类)
DETR 源码解读7(解码器:TransformerDecoder类/TransformerDecoderLayer类)
DETR 源码解读8(训练函数/损失函数)

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Visual segmentation is one of the most important tasks in computer vision, which involves dividing an image into multiple segments, each of which corresponds to a different object or region of interest in the image. In recent years, transformer-based methods have emerged as a promising approach for visual segmentation, leveraging the self-attention mechanism to capture long-range dependencies in the image. This survey paper provides a comprehensive overview of transformer-based visual segmentation methods, covering their underlying principles, architecture, training strategies, and applications. The paper starts by introducing the basic concepts of visual segmentation and transformer-based models, followed by a discussion of the key challenges and opportunities in applying transformers to visual segmentation. The paper then reviews the state-of-the-art transformer-based segmentation methods, including both fully transformer-based approaches and hybrid approaches that combine transformers with other techniques such as convolutional neural networks (CNNs). For each method, the paper provides a detailed description of its architecture and training strategy, as well as its performance on benchmark datasets. Finally, the paper concludes with a discussion of the future directions of transformer-based visual segmentation, including potential improvements in model design, training methods, and applications. Overall, this survey paper provides a valuable resource for researchers and practitioners interested in the field of transformer-based visual segmentation.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

机器学习杨卓越

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值