Spaces:
Sleeping
Sleeping
| from torch import nn | |
| import torch | |
| try: | |
| from torchvision.models.utils import load_state_dict_from_url # torchvision 0.4+ | |
| except ModuleNotFoundError: | |
| try: | |
| from torch.hub import load_state_dict_from_url # torch 1.x | |
| except ModuleNotFoundError: | |
| from torch.utils.model_zoo import load_url as load_state_dict_from_url # torch 0.4.1 | |
| model_urls = { | |
| 'mobilenet_v2': 'https://download.pytorch.org/models/mobilenet_v2-b0353104.pth', | |
| } | |
| class ConvBNReLU(nn.Sequential): | |
| def __init__(self, in_planes, out_planes, kernel_size=3, stride=1, groups=1, dilation=1): | |
| padding = (kernel_size - 1) // 2 | |
| if dilation != 1: | |
| padding = dilation | |
| super(ConvBNReLU, self).__init__( | |
| nn.Conv2d(in_planes, out_planes, kernel_size, stride, padding, groups=groups, dilation=dilation, | |
| bias=False), | |
| nn.BatchNorm2d(out_planes), | |
| nn.ReLU6(inplace=True) | |
| ) | |
| class InvertedResidual(nn.Module): | |
| def __init__(self, inp, oup, stride, expand_ratio, dilation=1): | |
| super(InvertedResidual, self).__init__() | |
| self.stride = stride | |
| assert stride in [1, 2] | |
| 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)) | |
| layers.extend([ | |
| # dw | |
| ConvBNReLU(hidden_dim, hidden_dim, stride=stride, groups=hidden_dim, dilation=dilation), | |
| # pw-linear | |
| nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False), | |
| nn.BatchNorm2d(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, pretrained=None, num_classes=1000, width_mult=1.0): | |
| super(MobileNetV2, self).__init__() | |
| block = InvertedResidual | |
| input_channel = 32 | |
| last_channel = 1280 | |
| inverted_residual_setting = [ | |
| # t, c, n, s, d | |
| [1, 16, 1, 1, 1], # conv1 112*112*16 | |
| [6, 24, 2, 2, 1], # conv2 56*56*24 | |
| [6, 32, 3, 2, 1], # conv3 28*28*32 | |
| [6, 64, 4, 2, 1], | |
| [6, 96, 3, 1, 1], # conv4 14*14*96 | |
| [6, 160, 3, 2, 1], | |
| [6, 320, 1, 1, 1], # conv5 7*7*320 | |
| ] | |
| # building first layer | |
| input_channel = int(input_channel * width_mult) | |
| self.last_channel = int(last_channel * max(1.0, width_mult)) | |
| features = [ConvBNReLU(3, input_channel, stride=2)] | |
| # building inverted residual blocks | |
| for t, c, n, s, d in inverted_residual_setting: | |
| output_channel = int(c * width_mult) | |
| for i in range(n): | |
| stride = s if i == 0 else 1 | |
| dilation = d if i == 0 else 1 | |
| features.append(block(input_channel, output_channel, stride, expand_ratio=t, dilation=d)) | |
| input_channel = output_channel | |
| # building last several layers | |
| features.append(ConvBNReLU(input_channel, self.last_channel, kernel_size=1)) | |
| # 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.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): | |
| res = [] | |
| for idx, m in enumerate(self.features): | |
| x = m(x) | |
| if idx in [1, 3, 6, 13, 17]: | |
| res.append(x) | |
| return res | |
| def mobilenet_v2(pretrained=True, progress=True, **kwargs): | |
| model = MobileNetV2(**kwargs) | |
| if pretrained: | |
| state_dict = load_state_dict_from_url(model_urls['mobilenet_v2'], | |
| progress=progress) | |
| print("loading imagenet pretrained mobilenetv2") | |
| model.load_state_dict(state_dict, strict=False) | |
| print("loaded imagenet pretrained mobilenetv2") | |
| return model |