mobilenetv2_unet

mobileunet:

https://github.com/YZY-stack/UNet-MobileNet-Pytorch

mobilenetv2:

FootTrackingAR/ImgWrapNet.py at 87c73cc5b64d9a2227792334c479a51696a9d70b · crea9813/FootTrackingAR · GitHub

cpu 320*320需要3s
 

https://github.com/HCMUS-ROBOTICS/ssdf-nncore/blob/532c7b6521d35c8fcb6412c08766e286ad04ef27/nncore/segmentation/models/mobileunet.py

这个还稍微靠谱点:

import time
from collections import OrderedDict

import torch

from torch import nn

def _make_divisible(v, divisor, min_value=None):
    if min_value is None:
        min_value = divisor
    new_v = max(min_value, int(v + divisor / 2) // divisor * divisor)
    # Make sure that round down does not go down by more than 10%.
    if new_v < 0.9 * v:
        new_v += divisor
    return new_v


class ConvBNReLU(nn.Sequential):
    def __init__(self, in_planes, out_planes, kernel_size=3, stride=1, groups=1, norm_layer=None):
        padding = (kernel_size - 1) // 2
        if norm_layer is None:
            norm_layer = nn.BatchNorm2d
        super(ConvBNReLU, self).__init__(nn.Conv2d(in_planes, out_planes, kernel_size, stride, padding, groups=groups, bias=False), norm_layer(out_planes), nn.ReLU6(inplace=True))

class InvertedResidual(nn.Module):
    def __init__(self, inp, oup, stride, expand_ratio, norm_layer=None):
        super(InvertedResidual, self).__init__()
        self.stride = stride
        assert stride in [1, 2]

        if norm_layer is None:
            norm_layer = nn.BatchNorm2d

        hidden_dim = int(round(inp * expand_ratio))
        self.use_res_connect = self.stride == 1 and inp == oup

        layers = []
        if expand_ratio != 1:
            # pw
            layers.append(ConvBNReLU(inp, hidden_dim, kernel_size=1, norm_layer=norm_layer))
        layers.extend([# dw
            ConvBNReLU(hidden_dim, hidden_dim, stride=stride, groups=hidden_dim, norm_layer=norm_layer), # pw-linear
            nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False), norm_layer(oup), ])
        self.conv = nn.Sequential(*layers)

    def forward(self, x):
        if self.use_res_connect:
            return x + self.conv(x)
        else:
            return self.conv(x)


class MobileNetV2(nn.Module):
    def __init__(self, width_mult=1.0, inverted_residual_setting=None, round_nearest=8, block=InvertedResidual, norm_layer=nn.BatchNorm2d):
        super(MobileNetV2, self).__init__()

        input_channel = 32
        last_channel = 240

        if inverted_residual_setting is None:
            inverted_residual_setting = [# t, c, n, s
                [1, 16, 1, 1], [6, 24, 2, 2], [6, 32, 3, 2], [6, 64, 4, 2], [6, 96, 3, 1], [6, 160, 3, 2], [6, 240, 1, 1], ]

        # only check the first element, assuming user knows t,c,n,s are required
        if len(inverted_residual_setting) == 0 or len(inverted_residual_setting[0]) != 4:
            raise ValueError("inverted_residual_setting should be non-empty "
                             "or a 4-element list, got {}".format(inverted_residual_setting))

        # building first layer
        input_channel = _make_divisible(input_channel * width_mult, round_nearest)
        self.last_channel = _make_divisible(last_channel * max(1.0, width_mult), round_nearest)
        features = [ConvBNReLU(3, input_channel, stride=2, norm_layer=norm_layer)]
        # building inverted residual blocks
        for t, c, n, s in inverted_residual_setting:
            output_channel = _make_divisible(c * width_mult, round_nearest)
            for i in range(n):
                stride = s if i == 0 else 1
                features.append(block(input_channel, output_channel, stride, expand_ratio=t, norm_layer=norm_layer))
                input_channel = output_channel
        # building last several layers
        features.append(ConvBNReLU(input_channel, self.last_channel, kernel_size=1, norm_layer=norm_layer))
        # make it nn.Sequential
        self.features = nn.Sequential(*features)


        # weight initialization
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode='fan_out')
                if m.bias is not None:
                    nn.init.zeros_(m.bias)
            elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):
                nn.init.ones_(m.weight)
                nn.init.zeros_(m.bias)
            elif isinstance(m, nn.Linear):
                nn.init.normal_(m.weight, 0, 0.01)
                nn.init.zeros_(m.bias)

    def forward(self, x):
        x = self.features(x)
        return x


class InvertedResidual_a(nn.Module):
    def __init__(self, inp, oup, stride, expand_ratio):
        super(InvertedResidual_a, self).__init__()
        self.stride = stride
        assert stride in [1, 2]
        hidden_dim = round(inp * expand_ratio)
        self.use_res_connect = self.stride == 1 and inp == oup
        if expand_ratio == 1:
            self.conv = nn.Sequential(  # dw
                nn.Conv2d(hidden_dim, hidden_dim, 3, stride, 1, groups=hidden_dim, bias=False), nn.BatchNorm2d(hidden_dim), nn.ReLU6(inplace=True),  # pw-linear
                nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False), nn.BatchNorm2d(oup), )
        else:
            self.conv = nn.Sequential(  # pw
                nn.Conv2d(inp, hidden_dim, 1, 1, 0, bias=False), nn.BatchNorm2d(hidden_dim), nn.ReLU6(inplace=True),  # dw
                nn.Conv2d(hidden_dim, hidden_dim, 3, stride, 1, groups=hidden_dim, bias=False), nn.BatchNorm2d(hidden_dim), nn.ReLU6(inplace=True),  # pw-linear
                nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False), nn.BatchNorm2d(oup), )

    def forward(self, x):
        # if self.use_res_connect:
        #     return x + self.conv(x)
        # else:
        #     return self.conv(x)
        return self.conv(x)


class MobileUnet(nn.Module):
    def __init__(self):
        super(MobileUnet, self).__init__()
        mobilenet = MobileNetV2()

        self.down1 = nn.Sequential(*mobilenet.features[0:2])
        self.down2 = nn.Sequential(*mobilenet.features[2:4])
        self.down3 = nn.Sequential(*mobilenet.features[4:7])
        self.down4 = nn.Sequential(*mobilenet.features[7:14])
        self.down5 = nn.Sequential(*mobilenet.features[14:19])

        self.dconv1 = nn.ConvTranspose2d(240, 96, 4, padding=1, stride=2)
        self.invres1 = InvertedResidual_a(192, 96, 1, 6)

        self.dconv2 = nn.ConvTranspose2d(96, 32, 4, padding=1, stride=2)
        self.invres2 = InvertedResidual_a(64, 32, 1, 6)

        self.dconv3 = nn.ConvTranspose2d(32, 24, 4, padding=1, stride=2)
        self.invres3 = InvertedResidual_a(48, 24, 1, 6)

        self.dconv4 = nn.ConvTranspose2d(24, 16, 4, padding=1, stride=2)
        self.invres4 = InvertedResidual_a(32, 16, 1, 6)

        self.dconv5 = nn.ConvTranspose2d(16, 3, 4, padding=1, stride=2)
        self.invres5 = InvertedResidual_a(6, 3, 1, 6)

        self.conv_last = nn.Conv2d(3, 1, 1)

    def _init_weights(self):
        for module in self.modules():
            if isinstance(module, Up):
                module._init_weights()

    def forward(self, x):
        x0 = x
        x1 = x = self.down1(x)
        x2 = x = self.down2(x)
        # print((x2.shape, 'x2'))
        x3 = x = self.down3(x)
        x4 = x = self.down4(x)
        # print((x4.shape, 'x4'))
        x = self.down5(x)
        # print((x5.shape, 'x5'))

        up1 = torch.cat([x4, self.dconv1(x)], dim=1)
        up1 = self.invres1(up1)
        # print((up1.shape, 'up1'))

        up2 = torch.cat([x3, self.dconv2(up1)], dim=1)
        up2 = self.invres2(up2)
        # print((up2.shape, 'up2'))

        up3 = torch.cat([x2, self.dconv3(up2)], dim=1)
        up3 = self.invres3(up3)
        # print((up3.shape, 'up3'))

        up4 = torch.cat([x1, self.dconv4(up3)], dim=1)
        up4 = self.invres4(up4)
        # print((up4.shape, 'up4'))

        up5 = torch.cat([x0, self.dconv5(up4)], dim=1)
        up5 = self.invres5(up5)

        x = self.conv_last(up5)
        return x


class Up(nn.Module):
    def __init__(self, in_channels, in_concat_channels, out_channels):
        super(Up, self).__init__()
        self.in_channels = in_channels
        self.in_concat_channels = in_concat_channels
        self.out_channels = out_channels

        self.up_conv = UpConv(in_channels)
        self.double_conv = DoubleConv(self.in_channels + self.in_concat_channels, self.out_channels)

    def forward(self, x1, x2):
        """
        :param x1: feature from previous layer
        :param x2: feature to concat
        """
        x1 = self.up_conv(x1)
        x = torch.cat([x2, x1], dim=1)
        x = self.double_conv(x)
        return x


class UpConv(nn.Module):
    def __init__(self, in_channels):
        super().__init__()
        self.up_conv = nn.Sequential(OrderedDict([("up", nn.Upsample(scale_factor=2)), ("conv", nn.Conv2d(in_channels, in_channels // 2, kernel_size=3, padding=1),), ]))

    def forward(self, x):
        return self.up_conv(x)


class DoubleConv(nn.Module):
    """(convolution => [BN] => ReLU) * 2"""

    def __init__(self, in_channels, out_channels):
        super().__init__()
        self.double_conv = nn.Sequential(nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1), nn.BatchNorm2d(out_channels), nn.ReLU(inplace=True),
                                         nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1), nn.BatchNorm2d(out_channels), nn.ReLU(inplace=True), )

    def forward(self, x):
        return self.double_conv(x)


if __name__ == "__main__":

    model = MobileUnet().cuda()

    input = torch.randn(1, 3, 448, 448).cuda()

    for i in range(20):
        start = time.time()
        output = model(input)
        print('output.size ', output.size(), time.time() - start)
        del output

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
efficient_unet是一种高效的神经网络模型,它是对传统U-Net模型的改进和优化。U-Net是一种常用于图像分割任务的网络,但其在处理大型图像时存在计算和内存消耗较大的问题。而efficient_unet通过结合不同的技术和策略,提高了模型的计算效率和内存利用率。 efficient_unet的优化主要体现在以下几个方面:首先,它采用了轻量级的网络结构,降低了模型的复杂度和参数量,适合在资源有限的设备上使用,同时减少了计算和内存的开销。其次,它使用了深度可分离卷积(depthwise separable convolution)代替传统的卷积操作,减少了参数量和计算量,提高了模型的速度和效果。此外,efficient_unet还引入了注意力机制(attention mechanism)来引导网络关注重要的特征,进一步提高了分割结果的准确性。 在训练方面,efficient_unet通过引入增强技术,如数据增强和Dropout等,能够充分利用有限的训练数据,并防止过拟合问题的发生。同时,它还采用了有效的损失函数,如Dice损失函数,用于度量目标和预测之间的相似性,并指导网络的优化过程。 综上所述,efficient_unet是一种高效且优化的神经网络模型,在图像分割任务中具有较好的性能表现。它通过减少网络复杂度、使用轻量级结构、深度可分离卷积和注意力机制等技术来提高计算效率和内存利用率,并通过数据增强和有效的损失函数来提高模型的泛化能力。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

AI算法网奇

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

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

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

打赏作者

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

抵扣说明:

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

余额充值