【BEV 视图变换】MLP-based BEV view transformation(代码一键运行)

MLP-based BEV视图变换流程和代码

pipeline:
1.backbone提取32倍,64倍下采样特征:
img_s32 = self.bb(img) # backbone: resnet34
img_s64 = self.down(img_s32)
2.RV feature -> BEV feature
也就是,使用MLP将32倍,64倍下采样的featmap尺寸的图像特征映射到相同的BEV空间尺寸的BEV特征:

bev_32 = self.s32transformer(img_s32)
bev_64 = self.s64transformer(img_s64)
3.将两个BEV特征concat起来
bev = torch.cat([bev_64, bev_32], dim=1)

图像解释就是:
在这里插入图片描述

import torch
import torch.nn as nn
import torchvision

def naive_init_module(mod):
    for m in mod.modules():
        if isinstance(m, nn.Conv2d):
            nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
        elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):
            nn.init.constant_(m.weight, 1)
            nn.init.constant_(m.bias, 0)
    return mod

class Residual(nn.Module):
    def __init__(self, module, downsample=None):
        super(Residual, self).__init__()
        self.module = module
        self.downsample = downsample
        self.relu = nn.ReLU()

    def forward(self, x):
        identity = x
        out = self.module(x)

        if self.downsample is not None:
            identity = self.downsample(x)

        out += identity
        return self.relu(out)

class FCTransform_(nn.Module):
    def __init__(self, image_featmap_size, space_featmap_size):
        super(FCTransform_, self).__init__()
        ic, ih, iw = image_featmap_size  # (256, 16, 16)
        sc, sh, sw = space_featmap_size  # (128, 16, 32)
        self.image_featmap_size = image_featmap_size
        self.space_featmap_size = space_featmap_size
        self.fc_transform = nn.Sequential(
            nn.Linear(ih * iw, sh * sw),
            nn.ReLU(),
            nn.Linear(sh * sw, sh * sw),
            nn.ReLU()
        )
        self.conv1 = nn.Sequential(
            nn.Conv2d(in_channels=ic, out_channels=sc, kernel_size=1 * 1, stride=1, bias=False),
            nn.BatchNorm2d(sc),
            nn.ReLU(), )
        self.residual = Residual(
            module=nn.Sequential(
                nn.Conv2d(in_channels=sc, out_channels=sc, kernel_size=3, padding=1, stride=1, bias=False),
                nn.BatchNorm2d(sc),
            ))

    def forward(self, x):
        x = x.view(list(x.size()[:2]) + [self.image_featmap_size[1] * self.image_featmap_size[2], ])  # 这个 B,V,C,H*W
        bev_view = self.fc_transform(x)  # 拿出一个视角
        bev_view = bev_view.view(list(bev_view.size()[:2]) + [self.space_featmap_size[1], self.space_featmap_size[2]])
        bev_view = self.conv1(bev_view)
        bev_view = self.residual(bev_view)
        return bev_view


# model
# ResNet34 骨干网络 (self.bb),在 ImageNet 上进行预训练。
# 一个下采样层 (self.down),用于减小特征图的空间维度。
# 两个全连接变换层 (self.s32transformer 和 self.s64transformer),将 ResNet 骨干网络的特征图转换为 BEV 表示。
class VPN(nn.Module):  # BEV-LaneDet
    def __init__(self):
        super(VPN, self).__init__()

        # backbone: resnet34
        self.bb = nn.Sequential(*list(torchvision.models.resnet34(pretrained=True).children())[:-2])

        self.down = naive_init_module(
            Residual(
                module=nn.Sequential(
                    nn.Conv2d(512, 1024, kernel_size=3, stride=2, padding=1),  # S64
                    nn.BatchNorm2d(1024),
                    nn.ReLU(),
                    nn.Conv2d(1024, 1024, kernel_size=3, stride=1, padding=1),
                    nn.BatchNorm2d(1024)

                ),
                downsample=nn.Conv2d(512, 1024, kernel_size=3, stride=2, padding=1),
            )
        )

        self.s32transformer = FCTransform_((512, 20, 20), (256, 25, 5))
        self.s64transformer = FCTransform_((1024, 10, 10), (256, 25, 5))


    def forward(self, img):
        # backbone: resnet34
        img_s32 = self.bb(img)
        img_s64 = self.down(img_s32)
        bev_32 = self.s32transformer(img_s32)
        bev_64 = self.s64transformer(img_s64)
        bev = torch.cat([bev_64, bev_32], dim=1)


if __name__ == "__main__":
    vpn = VPN()
    input_img = torch.rand(1, 3,640,640)
    output = vpn(input_img)

以32倍下采样featiremap为例:
在这里插入图片描述

哪些model使用到了MLP-based的BEV视图变换方法

1 VPN(View Parsing Network)

Cross-view Semantic Segmentation for Sensing Surroundings
几乎上第一个探索BEV语义分割的任务
架构图
在这里插入图片描述

在这里插入图片描述

2 BEV-LaneDet

在这里插入图片描述

3 HDMapNet

在这里插入图片描述
在这里插入图片描述

一组使用IPM,LSS,MLP方法的效果对比图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

BILLY BILLY

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

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

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

打赏作者

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

抵扣说明:

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

余额充值