diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/LICENSE b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..e53a92951d3b7ed1aea53f80500810e2f5498ad2 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/LICENSE @@ -0,0 +1,30 @@ +BSD 3-Clause License + +Copyright (c) 2017, Remi Cadene +All rights reserved. +Copyright 2021 Huawei Technologies Co., Ltd + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/README.md b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/README.md new file mode 100644 index 0000000000000000000000000000000000000000..933bc0095fcfeea6e94d21bddca3226845ab0592 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/README.md @@ -0,0 +1,178 @@ +# DPN68 for PyTorch + +- [概述](概述.md) +- [准备训练环境](准备训练环境.md) +- [开始训练](开始训练.md) +- [训练结果展示](训练结果展示.md) + + + +# 概述 + +## 简述 + +DPN是一种用于图像分类的简单、高效和模块化的双路径网络,它在内部呈现了一种新的连接路径拓扑。更深的 DPN 进一步推动了最先进的单模型性能,训练速度提高了约 2 倍。 + +- 参考实现: + + ``` + url=https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks + commit_id=8aae3d8f1135b6b13fed79c1d431e3449fdbf6e0 + code_path=pretrainedmodels/models/dpn.py + ``` + +- 适配昇腾 AI 处理器的实现: + + ``` + url=https://gitee.com/ascend/ModelZoo-PyTorch.git + code_path=PyTorch/contrib/cv/classification + ``` + +- 通过Git获取代码方法如下: + + ``` + git clone {url} # 克隆仓库的代码 + cd {code_path} # 切换到模型代码所在路径,若仓库下只有该模型,则无需切换 + ``` + +- 通过单击“立即下载”,下载源码包。 + +# 准备训练环境 + +## 准备环境 + +- 当前模型支持的固件与驱动、 CANN 以及 PyTorch 如下表所示。 + + **表 1** 版本配套表 + + | 配套 | 版本 | + | ---------- | ------------------------------------------------------------ | + | 固件与驱动 | [1.0.15](https://www.hiascend.com/hardware/firmware-drivers?tag=commercial) | + | CANN | [5.1.RC2](https://www.hiascend.com/software/cann/commercial?version=5.1.RC1) | + | PyTorch | [1.8.1](https://gitee.com/ascend/pytorch/tree/v1.8.1/) | + +- 环境准备指导。 + + 请参考《[Pytorch框架训练环境准备](https://www.hiascend.com/document/detail/zh/ModelZoo/pytorchframework/ptes)》。 + +- 安装依赖(根据模型需求,按需添加所需依赖)。 + + ``` + pip install -r requirements.txt + ``` + + +## 准备数据集 + +1. 获取数据集。 + + 以ImageNet-1K数据集为例,数据集目录结构参考如下所示。 + + ``` + ├── ImageNet-1K + ├──train + ├──类别1 + │──图片1 + │──图片2 + │ ... + ├──类别2 + │──图片1 + │──图片2 + │ ... + ├──... + ├──val + ├──类别1 + │──图片1 + │──图片2 + │ ... + ├──类别2 + │──图片1 + │──图片2 + │ ... + ``` + + > **说明:** + >该数据集的训练过程脚本只作为一种参考示例。 + +2. 数据预处理(按需处理所需要的数据集)。 + + +# 开始训练 + +## 训练模型 + +1. 进入解压后的源码包根目录。 + + ``` + cd ./DPN-68_for_PyTorch + ``` + +2. 运行训练脚本。 + + 该模型支持单机单卡训练和单机8卡训练。 + + - 1p training 1p + + ``` + bash ./test/train_full_1p.sh --data_path=xxx # training accuracy + + bash ./test/train_performance_1p.sh --data_path /forDocker/dataset/ImageNet # training 1p performance + ``` + + - 8p training 8p + + ``` + bash ./test/train_full_8p.sh --data_path=xxx # training accuracy + + bash ./test/train_performance_8p.sh --data_path=xxx # training performance + + ``` + + + --data\_path参数填写数据集路径。 + + 模型训练脚本参数说明如下。 + + ``` + 公共参数: + --data_path //数据集路径 + --addr //主机地址 + --workers //加载数据进程数 + --epochs //重复训练次数 + --batch-size //训练批次大小 + --lr //初始学习率,默认:0.01 + --momentum //动量,默认:0.9 + --weight_decay //权重衰减,默认:0.0001 + --amp //是否使用混合精度 + --loss-scale //混合精度lossscale大小 + --opt-level //混合精度类型 + --gpu //指定训练用卡编号 + --resume //中断重新开始模型参数路径 + --pretrained //预训练模型路径 + 多卡训练参数: + --multiprocessing-distributed //是否使用多卡训练 + --device-list '0,1,2,3,4,5,6,7' //多卡训练指定训练用卡 + ``` + + 训练完成后,权重文件保存在当前路径下,并输出模型训练精度和性能信息。 + +# 训练结果展示 + +**表 2** 训练结果展示表 + +| NAME | Acc@1 | FPS | Epochs | AMP_Type | +| ------- | ----- | ---: | ------ | -------: | +| 1p-竞品 | - | 438 | 1 | O2 | +| 1p-NPU | - | 613 | 1 | O2 | +| 8p-竞品 | 73.34 | 3064 | 90 | O2 | +| 8p-NPU | 73.35 | 4611 | 90 | O2 | + +# 版本说明 + +## 变更 + +2022.9.15:首次发布。 + +## 已知问题 + +无。 \ No newline at end of file diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/examples/dpn.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/examples/dpn.py new file mode 100644 index 0000000000000000000000000000000000000000..4d4a1e5042e93b97daa0181018dabd9bd74d200d --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/examples/dpn.py @@ -0,0 +1,473 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +""" PyTorch implementation of DualPathNetworks +Ported to PyTorch by [Ross Wightman](https://github.com/rwightman/pytorch-dpn-pretrained) + +Based on original MXNet implementation https://github.com/cypw/DPNs with +many ideas from another PyTorch implementation https://github.com/oyam/pytorch-DPNs. + +This implementation is compatible with the pretrained weights +from cypw's MXNet implementation. +""" +from __future__ import print_function, division, absolute_import +import os +import torch +import torch.nn as nn +import torch.nn.functional as F +import torch.utils.model_zoo as model_zoo +from collections import OrderedDict + +__all__ = ['DPN', 'dpn68', 'dpn68b', 'dpn92', 'dpn98', 'dpn131', 'dpn107'] + +pretrained_settings = { + 'dpn68': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/dpn68-4af7d88d2.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [124 / 255, 117 / 255, 104 / 255], + 'std': [1 / (.0167 * 255)] * 3, + 'num_classes': 1000 + } + }, + 'dpn68b': { + 'imagenet+5k': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/dpn68b_extra-363ab9c19.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [124 / 255, 117 / 255, 104 / 255], + 'std': [1 / (.0167 * 255)] * 3, + 'num_classes': 1000 + } + }, + 'dpn92': { + # 'imagenet': { + # 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/dpn68-66bebafa7.pth', + # 'input_space': 'RGB', + # 'input_size': [3, 224, 224], + # 'input_range': [0, 1], + # 'mean': [124 / 255, 117 / 255, 104 / 255], + # 'std': [1 / (.0167 * 255)] * 3, + # 'num_classes': 1000 + # }, + 'imagenet+5k': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/dpn92_extra-fda993c95.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [124 / 255, 117 / 255, 104 / 255], + 'std': [1 / (.0167 * 255)] * 3, + 'num_classes': 1000 + } + }, + 'dpn98': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/dpn98-722954780.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [124 / 255, 117 / 255, 104 / 255], + 'std': [1 / (.0167 * 255)] * 3, + 'num_classes': 1000 + } + }, + 'dpn131': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/dpn131-7af84be88.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [124 / 255, 117 / 255, 104 / 255], + 'std': [1 / (.0167 * 255)] * 3, + 'num_classes': 1000 + } + }, + 'dpn107': { + 'imagenet+5k': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/dpn107_extra-b7f9f4cc9.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [124 / 255, 117 / 255, 104 / 255], + 'std': [1 / (.0167 * 255)] * 3, + 'num_classes': 1000 + } + } +} + +def dpn68(num_classes=1000, pretrained='imagenet'): + model = DPN( + small=True, num_init_features=10, k_r=128, groups=32, + k_sec=(3, 4, 12, 3), inc_sec=(16, 32, 32, 64), + num_classes=num_classes, test_time_pool=True) + if pretrained: + settings = pretrained_settings['dpn68'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model + +def dpn68b(num_classes=1000, pretrained='imagenet+5k'): + model = DPN( + small=True, num_init_features=10, k_r=128, groups=32, + b=True, k_sec=(3, 4, 12, 3), inc_sec=(16, 32, 32, 64), + num_classes=num_classes, test_time_pool=True) + if pretrained: + settings = pretrained_settings['dpn68b'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model + +def dpn92(num_classes=1000, pretrained='imagenet+5k'): + model = DPN( + num_init_features=64, k_r=96, groups=32, + k_sec=(3, 4, 20, 3), inc_sec=(16, 32, 24, 128), + num_classes=num_classes, test_time_pool=True) + if pretrained: + settings = pretrained_settings['dpn92'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model + +def dpn98(num_classes=1000, pretrained='imagenet'): + model = DPN( + num_init_features=96, k_r=160, groups=40, + k_sec=(3, 6, 20, 3), inc_sec=(16, 32, 32, 128), + num_classes=num_classes, test_time_pool=True) + if pretrained: + settings = pretrained_settings['dpn98'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model + +def dpn131(num_classes=1000, pretrained='imagenet'): + model = DPN( + num_init_features=128, k_r=160, groups=40, + k_sec=(4, 8, 28, 3), inc_sec=(16, 32, 32, 128), + num_classes=num_classes, test_time_pool=True) + if pretrained: + settings = pretrained_settings['dpn131'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model + +def dpn107(num_classes=1000, pretrained='imagenet+5k'): + model = DPN( + num_init_features=128, k_r=200, groups=50, + k_sec=(4, 8, 20, 3), inc_sec=(20, 64, 64, 128), + num_classes=num_classes, test_time_pool=True) + if pretrained: + settings = pretrained_settings['dpn107'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model + + +class CatBnAct(nn.Module): + def __init__(self, in_chs, activation_fn=nn.ReLU(inplace=True)): + super(CatBnAct, self).__init__() + self.bn = nn.BatchNorm2d(in_chs, eps=0.001) + self.act = activation_fn + + def forward(self, x): + x = torch.cat(x, dim=1) if isinstance(x, tuple) else x + return self.act(self.bn(x)) + + +class BnActConv2d(nn.Module): + def __init__(self, in_chs, out_chs, kernel_size, stride, + padding=0, groups=1, activation_fn=nn.ReLU(inplace=True)): + super(BnActConv2d, self).__init__() + self.bn = nn.BatchNorm2d(in_chs, eps=0.001) + self.act = activation_fn + self.conv = nn.Conv2d(in_chs, out_chs, kernel_size, stride, padding, groups=groups, bias=False) + + def forward(self, x): + return self.conv(self.act(self.bn(x))) + + +class InputBlock(nn.Module): + def __init__(self, num_init_features, kernel_size=7, + padding=3, activation_fn=nn.ReLU(inplace=True)): + super(InputBlock, self).__init__() + self.conv = nn.Conv2d( + 3, num_init_features, kernel_size=kernel_size, stride=2, padding=padding, bias=False) + self.bn = nn.BatchNorm2d(num_init_features, eps=0.001) + self.act = activation_fn + self.pool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) + + def forward(self, x): + x = self.conv(x) + x = self.bn(x) + x = self.act(x) + x = self.pool(x) + return x + + +class DualPathBlock(nn.Module): + def __init__( + self, in_chs, num_1x1_a, num_3x3_b, num_1x1_c, inc, groups, block_type='normal', b=False): + super(DualPathBlock, self).__init__() + self.num_1x1_c = num_1x1_c + self.inc = inc + self.b = b + if block_type is 'proj': + self.key_stride = 1 + self.has_proj = True + elif block_type is 'down': + self.key_stride = 2 + self.has_proj = True + else: + assert block_type is 'normal' + self.key_stride = 1 + self.has_proj = False + + if self.has_proj: + # Using different member names here to allow easier parameter key matching for conversion + if self.key_stride == 2: + self.c1x1_w_s2 = BnActConv2d( + in_chs=in_chs, out_chs=num_1x1_c + 2 * inc, kernel_size=1, stride=2) + else: + self.c1x1_w_s1 = BnActConv2d( + in_chs=in_chs, out_chs=num_1x1_c + 2 * inc, kernel_size=1, stride=1) + self.c1x1_a = BnActConv2d(in_chs=in_chs, out_chs=num_1x1_a, kernel_size=1, stride=1) + self.c3x3_b = BnActConv2d( + in_chs=num_1x1_a, out_chs=num_3x3_b, kernel_size=3, + stride=self.key_stride, padding=1, groups=groups) + if b: + self.c1x1_c = CatBnAct(in_chs=num_3x3_b) + self.c1x1_c1 = nn.Conv2d(num_3x3_b, num_1x1_c, kernel_size=1, bias=False) + self.c1x1_c2 = nn.Conv2d(num_3x3_b, inc, kernel_size=1, bias=False) + else: + self.c1x1_c = BnActConv2d(in_chs=num_3x3_b, out_chs=num_1x1_c + inc, kernel_size=1, stride=1) + + def forward(self, x): + x_in = torch.cat(x, dim=1) if isinstance(x, tuple) else x + if self.has_proj: + if self.key_stride == 2: + x_s = self.c1x1_w_s2(x_in) + else: + x_s = self.c1x1_w_s1(x_in) + x_s1 = x_s[:, :self.num_1x1_c, :, :] + x_s2 = x_s[:, self.num_1x1_c:, :, :] + else: + x_s1 = x[0] + x_s2 = x[1] + x_in = self.c1x1_a(x_in) + x_in = self.c3x3_b(x_in) + if self.b: + x_in = self.c1x1_c(x_in) + out1 = self.c1x1_c1(x_in) + out2 = self.c1x1_c2(x_in) + else: + x_in = self.c1x1_c(x_in) + out1 = x_in[:, :self.num_1x1_c, :, :] + out2 = x_in[:, self.num_1x1_c:, :, :] + resid = x_s1 + out1 + dense = torch.cat([x_s2, out2], dim=1) + return resid, dense + + +class DPN(nn.Module): + def __init__(self, small=False, num_init_features=64, k_r=96, groups=32, + b=False, k_sec=(3, 4, 20, 3), inc_sec=(16, 32, 24, 128), + num_classes=1000, test_time_pool=False): + super(DPN, self).__init__() + self.test_time_pool = test_time_pool + self.b = b + bw_factor = 1 if small else 4 + + blocks = OrderedDict() + + # conv1 + if small: + blocks['conv1_1'] = InputBlock(num_init_features, kernel_size=3, padding=1) + else: + blocks['conv1_1'] = InputBlock(num_init_features, kernel_size=7, padding=3) + + # conv2 + bw = 64 * bw_factor + inc = inc_sec[0] + r = (k_r * bw) // (64 * bw_factor) + blocks['conv2_1'] = DualPathBlock(num_init_features, r, r, bw, inc, groups, 'proj', b) + in_chs = bw + 3 * inc + for i in range(2, k_sec[0] + 1): + blocks['conv2_' + str(i)] = DualPathBlock(in_chs, r, r, bw, inc, groups, 'normal', b) + in_chs += inc + + # conv3 + bw = 128 * bw_factor + inc = inc_sec[1] + r = (k_r * bw) // (64 * bw_factor) + blocks['conv3_1'] = DualPathBlock(in_chs, r, r, bw, inc, groups, 'down', b) + in_chs = bw + 3 * inc + for i in range(2, k_sec[1] + 1): + blocks['conv3_' + str(i)] = DualPathBlock(in_chs, r, r, bw, inc, groups, 'normal', b) + in_chs += inc + + # conv4 + bw = 256 * bw_factor + inc = inc_sec[2] + r = (k_r * bw) // (64 * bw_factor) + blocks['conv4_1'] = DualPathBlock(in_chs, r, r, bw, inc, groups, 'down', b) + in_chs = bw + 3 * inc + for i in range(2, k_sec[2] + 1): + blocks['conv4_' + str(i)] = DualPathBlock(in_chs, r, r, bw, inc, groups, 'normal', b) + in_chs += inc + + # conv5 + bw = 512 * bw_factor + inc = inc_sec[3] + r = (k_r * bw) // (64 * bw_factor) + blocks['conv5_1'] = DualPathBlock(in_chs, r, r, bw, inc, groups, 'down', b) + in_chs = bw + 3 * inc + for i in range(2, k_sec[3] + 1): + blocks['conv5_' + str(i)] = DualPathBlock(in_chs, r, r, bw, inc, groups, 'normal', b) + in_chs += inc + blocks['conv5_bn_ac'] = CatBnAct(in_chs) + + self.features = nn.Sequential(blocks) + + # Using 1x1 conv for the FC layer to allow the extra pooling scheme + self.last_linear = nn.Conv2d(in_chs, num_classes, kernel_size=1, bias=True) + + def logits(self, features): + if not self.training and self.test_time_pool: + x = F.avg_pool2d(features, kernel_size=7, stride=1) + out = self.last_linear(x) + # The extra test time pool should be pooling an img_size//32 - 6 size patch + out = adaptive_avgmax_pool2d(out, pool_type='avgmax') + else: + x = adaptive_avgmax_pool2d(features, pool_type='avg') + out = self.last_linear(x) + return out.view(out.size(0), -1) + + def forward(self, input): + x = self.features(input) + x = self.logits(x) + return x + +""" PyTorch selectable adaptive pooling +Adaptive pooling with the ability to select the type of pooling from: + * 'avg' - Average pooling + * 'max' - Max pooling + * 'avgmax' - Sum of average and max pooling re-scaled by 0.5 + * 'avgmaxc' - Concatenation of average and max pooling along feature dim, doubles feature dim + +Both a functional and a nn.Module version of the pooling is provided. + +Author: Ross Wightman (rwightman) +""" + +def pooling_factor(pool_type='avg'): + return 2 if pool_type == 'avgmaxc' else 1 + + +def adaptive_avgmax_pool2d(x, pool_type='avg', padding=0, count_include_pad=False): + """Selectable global pooling function with dynamic input kernel size + """ + if pool_type == 'avgmaxc': + x = torch.cat([ + F.avg_pool2d( + x, kernel_size=(x.size(2), x.size(3)), padding=padding, count_include_pad=count_include_pad), + F.max_pool2d(x, kernel_size=(x.size(2), x.size(3)), padding=padding) + ], dim=1) + elif pool_type == 'avgmax': + x_avg = F.avg_pool2d( + x, kernel_size=(x.size(2), x.size(3)), padding=padding, count_include_pad=count_include_pad) + x_max = F.max_pool2d(x, kernel_size=(x.size(2), x.size(3)), padding=padding) + x = 0.5 * (x_avg + x_max) + elif pool_type == 'max': + x = F.max_pool2d(x, kernel_size=(x.size(2), x.size(3)), padding=padding) + else: + if pool_type != 'avg': + print('Invalid pool type %s specified. Defaulting to average pooling.' % pool_type) + x = F.avg_pool2d( + x, kernel_size=(x.size(2), x.size(3)), padding=padding, count_include_pad=count_include_pad) + return x + + +class AdaptiveAvgMaxPool2d(torch.nn.Module): + """Selectable global pooling layer with dynamic input kernel size + """ + def __init__(self, output_size=1, pool_type='avg'): + super(AdaptiveAvgMaxPool2d, self).__init__() + self.output_size = output_size + self.pool_type = pool_type + if pool_type == 'avgmaxc' or pool_type == 'avgmax': + self.pool = nn.ModuleList([nn.AdaptiveAvgPool2d(output_size), nn.AdaptiveMaxPool2d(output_size)]) + elif pool_type == 'max': + self.pool = nn.AdaptiveMaxPool2d(output_size) + else: + if pool_type != 'avg': + print('Invalid pool type %s specified. Defaulting to average pooling.' % pool_type) + self.pool = nn.AdaptiveAvgPool2d(output_size) + + def forward(self, x): + if self.pool_type == 'avgmaxc': + x = torch.cat([p(x) for p in self.pool], dim=1) + elif self.pool_type == 'avgmax': + x = 0.5 * torch.sum(torch.stack([p(x) for p in self.pool]), 0).squeeze(dim=0) + else: + x = self.pool(x) + return x + + def factor(self): + return pooling_factor(self.pool_type) + + def __repr__(self): + return self.__class__.__name__ + ' (' \ + + 'output_size=' + str(self.output_size) \ + + ', pool_type=' + self.pool_type + ')' \ No newline at end of file diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/examples/dpn68.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/examples/dpn68.py new file mode 100644 index 0000000000000000000000000000000000000000..641dd3edaccbacbed635df4de71b548bd2b04326 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/examples/dpn68.py @@ -0,0 +1,666 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +from pickle import NONE +import warnings +import argparse +import os +import random +import shutil +import time +import json +import warnings +import torch +if torch.__version__ >= "1.8": + import torch_npu +print(torch.__version__) +import numpy as np +import apex +from apex import amp +import torch.nn as nn +import torch.nn.parallel +import torch.backends.cudnn as cudnn +import torch.distributed as dist +import torch.optim +import torch.multiprocessing as mp +import torch.utils.data +import torch.utils.data.distributed +import torchvision.transforms as transforms +import torchvision.datasets as datasets +from dpn import dpn68 + + +parser = argparse.ArgumentParser(description='PyTorch ImageNet Training') +parser.add_argument('--data_path', type=str, metavar='DIR', + help='path to dataset') +parser.add_argument('-j', '--workers', default=64, type=int, metavar='N', + help='number of data loading workers (default: 4)') +parser.add_argument('--epochs', default=90, type=int, metavar='N', + help='number of total epochs to run') +parser.add_argument('--start-epoch', default=0, type=int, metavar='N', + help='manual epoch number (useful on restarts)') +parser.add_argument('-b', '--batch-size', default=512, type=int, + metavar='N', + help='mini-batch size (default: 256), this is the total ' + 'batch size of all GPUs on the current node when ' + 'using Data Parallel or Distributed Data Parallel') +parser.add_argument('--lr', '--learning-rate', default=0.1, type=float, + metavar='LR', help='initial learning rate', dest='lr') +parser.add_argument('--momentum', default=0.9, type=float, metavar='M', + help='momentum') +parser.add_argument('--wd', '--weight-decay', default=1e-4, type=float, + metavar='W', help='weight decay (default: 1e-4)', + dest='weight_decay') +parser.add_argument('-p', '--print-freq', default=10, type=int, + metavar='N', help='print frequency (default: 10)') +parser.add_argument('--resume', default='', type=str, metavar='PATH', + help='path to latest checkpoint (default: none)') +parser.add_argument('-e', '--evaluate', dest='evaluate', action='store_true', + help='evaluate model on validation set') +parser.add_argument('--pretrained', dest='pretrained', action='store_true', + help='use pre-trained model') +parser.add_argument('--world-size', default=1, type=int, + help='number of nodes for distributed training') +parser.add_argument('--rank', default=0, type=int, + help='node rank for distributed training') +parser.add_argument('--dist-url', default='tcp://127.0.0.1:9266', type=str, + help='url used to set up distributed training') +parser.add_argument('--dist-backend', default='hccl', type=str, + help='distributed backend') +parser.add_argument('--seed', default=None, type=int, + help='seed for initializing training. ') +parser.add_argument('--gpu', default=None, type=int, + help='GPU id to use.') +parser.add_argument('--multiprocessing-distributed', action='store_true', + help='Use multi-processing distributed training to launch ' + 'N processes per node, which has N GPUs. This is the ' + 'fastest way to use PyTorch for either single node or ' + 'multi node data parallel training') +## for ascend 910 +parser.add_argument('--device', default='npu', type=str, help='npu or gpu') +parser.add_argument('--addr', default='127.0.0.1', + type=str, help='master addr') +parser.add_argument('--device_list', default='0,1,2,3,4,5,6,7', + type=str, help='device id list') +parser.add_argument('--amp', default=False, action='store_true', + help='use amp to train the model') +parser.add_argument('--loss-scale', default="dynamic", + help='loss scale using in amp, default -1 means dynamic') +parser.add_argument('--opt-level', default='O2', type=str, + help='loss scale using in amp, default -1 means dynamic') +parser.add_argument('--prof', default=False, action='store_true', + help='use profiling to evaluate the performance of model') +parser.add_argument('--warm_up_epochs', default=5, type=int, + help='warm up') +best_prec1 = 0 + + +def device_id_to_process_device_map(device_list): + devices = device_list.split(",") + devices = [int(x) for x in devices] + devices.sort() + + process_device_map = dict() + for process_id, device_id in enumerate(devices): + process_device_map[process_id] = device_id + + return process_device_map + + +def main(): + global args + args = parser.parse_args() + print(args.device_list) + + os.environ['MASTER_ADDR'] = args.addr + os.environ['MASTER_PORT'] = '29688' + os.environ['RANK'] = '0' + + if args.seed is not None: + random.seed(args.seed) + torch.manual_seed(args.seed) + cudnn.deterministic = True + warnings.warn('You have chosen to seed training. ' + 'This will turn on the CUDNN deterministic setting, ' + 'which can slow down your training considerably! ' + 'You may see unexpected behavior when restarting ' + 'from checkpoints.') + + if args.gpu is not None: + warnings.warn('You have chosen a specific GPU. This will completely ' + 'disable data parallelism.') + + if args.dist_url == "env://" and args.world_size == -1: + args.world_size = int(os.environ["WORLD_SIZE"]) + + args.distributed = args.world_size > 1 or args.multiprocessing_distributed + + args.process_device_map = device_id_to_process_device_map(args.device_list) + + if args.device == 'npu': + ngpus_per_node = len(args.process_device_map) + else: + if args.distributed: + ngpus_per_node = torch.cuda.device_count() + else: + ngpus_per_node = 1 + print('ngpus_per_node:', ngpus_per_node) + if args.multiprocessing_distributed: + # Since we have ngpus_per_node processes per node, the total world_size + # needs to be adjusted accordingly + args.world_size = ngpus_per_node * args.world_size + # Use torch.multiprocessing.spawn to launch distributed processes: the + # main_worker process function + mp.spawn(main_worker, nprocs=ngpus_per_node, + args=(ngpus_per_node, args)) + else: + # Simply call main_worker function + main_worker(args.gpu, ngpus_per_node, args) + + +def main_worker(gpu, ngpus_per_node, args): + print(args) + + global best_prec1 + args.gpu = args.process_device_map[gpu] + + if args.gpu is not None: + print("Use GPU: {} for training".format(args.gpu)) + + if args.distributed: + if args.dist_url == "env://" and args.rank == -1: + args.rank = int(os.environ["RANK"]) + if args.multiprocessing_distributed: + # For multiprocessing distributed training, rank needs to be the + # global rank among all the processes + args.rank = args.rank * ngpus_per_node + gpu + + if args.device == 'npu': + dist.init_process_group(backend=args.dist_backend, + world_size=args.world_size, rank=args.rank) + else: + dist.init_process_group(backend=args.dist_backend, init_method=args.dist_url, + world_size=args.world_size, rank=args.rank) + print('Rank[{}] init group success'.format(args.rank)) + # create model + + if args.pretrained: + model = dpn68(pretrained=False) + checkpoint = torch.load(args.resume, map_location='cpu') + if 'module.' in list(checkpoint['state_dict'].keys())[0]: + checkpoint['state_dict'] = {k.replace('module.', ''): v for k, v in checkpoint['state_dict'].items()} + model.load_state_dict(checkpoint['state_dict'], strict=False) + else: + model = dpn68(pretrained=False) + + if args.distributed: + # For multiprocessing distributed, DistributedDataParallel constructor + # should always set the single device scope, otherwise, + # DistributedDataParallel will use all available devices. + if args.gpu is not None: + if args.device == 'npu': + loc = 'npu:{}'.format(args.gpu) + torch.npu.set_device(loc) + print('Rank[{}] set device success'.format(args.rank)) + model = model.to(loc) + else: + torch.cuda.set_device(args.gpu) + model.cuda(args.gpu) + + # When using a single GPU per process and per + # DistributedDataParallel, we need to divide the batch size + # ourselves based on the total number of GPUs we have + args.batch_size = int(args.batch_size / args.world_size) + args.workers = int((args.workers + ngpus_per_node - 1) / ngpus_per_node) + else: + if args.device == 'npu': + loc = 'npu:{}'.format(args.gpu) + model = model.to(loc) + else: + model.cuda() + # DistributedDataParallel will divide and allocate batch_size to all + # available GPUs if device_ids are not set + print("[gpu id:", args.gpu, "]", + "============================test args.gpu is not None else==========================") + elif args.gpu is not None: + print("[gpu id:", args.gpu, "]", + "============================test elif args.gpu is not None:==========================") + if args.device == 'npu': + loc = 'npu:{}'.format(args.gpu) + torch.npu.set_device(args.gpu) + model = model.to(loc) + else: + torch.cuda.set_device(args.gpu) + model = model.cuda(args.gpu) + else: + # DataParallel will divide and allocate batch_size to all available GPUs + print("[gpu id:", args.gpu, "]", "============================test 1==========================") + print("[gpu id:", args.gpu, "]", "============================test 3==========================") + if args.device == 'npu': + loc = 'npu:{}'.format(args.gpu) + else: + print("before : model = torch.nn.DataParallel(model).cuda()") + + + + # define loss function (criterion) and optimizer + + optimizer = torch.optim.SGD(model.parameters(), args.lr, + momentum=args.momentum, + weight_decay=args.weight_decay) + model, optimizer = amp.initialize(model, optimizer, opt_level="O2", loss_scale=128.0)#add + + + if args.distributed: + if args.gpu is not None: + model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu], broadcast_buffers=False) + else: + print("[gpu id:", args.gpu, "]", + "============================test args.gpu is not None else==========================") + model = torch.nn.parallel.DistributedDataParallel(model) + elif args.gpu is not None: + print("[gpu id:", args.gpu, "]", + "============================test elif args.gpu is not None:==========================") + else: + # DataParallel will divide and allocate batch_size to all available GPUs + print("[gpu id:", args.gpu, "]", "============================test 1==========================") + print("[gpu id:", args.gpu, "]", "============================test 3==========================") + if args.device == 'npu': + loc = 'npu:{}'.format(args.gpu) + model = torch.nn.DataParallel(model).to(loc) + else: + model = torch.nn.DataParallel(model).cuda() + + if args.device == 'npu': + loc = 'npu:{}'.format(args.gpu) + criterion = nn.CrossEntropyLoss().to(loc) + else: + criterion = nn.CrossEntropyLoss().cuda(args.gpu) + #add + if args.resume: + if os.path.isfile(args.resume): + print("=> loading checkpoint '{}'".format(args.resume)) + if args.gpu is None: + checkpoint = torch.load(args.resume) + else: + if args.device == 'npu': + loc = 'npu:{}'.format(args.gpu) + else: + loc = 'cuda:{}'.format(args.gpu) + checkpoint = torch.load(args.resume, map_location=loc) + args.start_epoch = checkpoint['epoch'] + best_prec1 = checkpoint['best_prec1'] + if args.gpu is not None: + best_prec1 = best_prec1.to(args.gpu) + model.load_state_dict(checkpoint['state_dict']) + optimizer.load_state_dict(checkpoint['optimizer']) + amp.load_state_dict(checkpoint['amp']) + print("=> loaded checkpoint '{}' (epoch {})" + .format(args.resume, checkpoint['epoch'])) + else: + print("=> no checkpoint found at '{}'".format(args.resume)) + + cudnn.benchmark = True + + # Data loading code + traindir = os.path.join(args.data_path, 'train') + valdir = os.path.join(args.data_path, 'val') + normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]) + + train_dataset = datasets.ImageFolder( + traindir, + transforms.Compose([ + transforms.RandomResizedCrop(224), + transforms.RandomHorizontalFlip(), + transforms.ToTensor(), + normalize, + ])) + + if args.distributed: + train_sampler = torch.utils.data.distributed.DistributedSampler( + train_dataset) + else: + train_sampler = None + + print("load train data workers={}".format(args.workers)) + train_loader = torch.utils.data.DataLoader( + train_dataset, batch_size=args.batch_size, shuffle=( + train_sampler is None), + num_workers=args.workers, pin_memory=False, sampler=train_sampler, drop_last=True) + print("load val data") + val_loader = torch.utils.data.DataLoader( + datasets.ImageFolder(valdir, transforms.Compose([ + transforms.Resize(256), + transforms.CenterCrop(224), + transforms.ToTensor(), + normalize, + ])), + batch_size=args.batch_size, shuffle=True, + num_workers=args.workers, pin_memory=False, drop_last=True) + + if args.evaluate: + validate(val_loader, model, criterion, args, ngpus_per_node) + return + + if args.prof: + profiling(train_loader, model, criterion, optimizer, args) + return + + FPS = 0 + print("===> Training") + for epoch in range(args.epochs): + start_time = time.time() + + + if args.distributed: + train_sampler.set_epoch(epoch) + + adjust_learning_rate(optimizer, epoch, args) + + # train for one epoch + epoch_FPS = train(train_loader, model, criterion, optimizer, epoch, args, ngpus_per_node) + + # evaluate on validation set + acc1 = validate(val_loader, model, criterion, args, ngpus_per_node) + + # remember best acc@1 and save checkpoint + is_best = acc1 > best_prec1 + best_prec1 = max(acc1, best_prec1) + if args.device == 'npu' and args.gpu == 0 and epoch == 89: + print("Complete 90 epoch training, take time:{}h".format(round((time.time() - start_time) / 3600.0, 2))) + + if not args.multiprocessing_distributed or (args.multiprocessing_distributed + and args.rank % ngpus_per_node == 0): + + ############## npu modify begin ############# + if args.amp: + save_checkpoint({ + 'epoch': epoch + 1, + 'arch': 'dpn68', + 'state_dict': model.state_dict(), + 'best_acc1': best_prec1, + 'optimizer': optimizer.state_dict(), + 'amp': amp.state_dict(), + }, is_best) + else: + save_checkpoint({ + 'epoch': epoch + 1, + 'arch': 'dpn68', + 'state_dict': model.state_dict(), + 'best_acc1': best_prec1, + 'optimizer': optimizer.state_dict(), + }, is_best) + log_stats = {'epoch': epoch, + 'FPS': epoch_FPS} + FPS = FPS + epoch_FPS + end_time = time.time() + time_value = (end_time - start_time) / 3600 + print(time_value) + average_FPS = FPS / args.epochs + print("Average FPS {}\n".format(average_FPS)) + +def profiling(data_loader, model, criterion, optimizer, args): + # switch to train mode + model.train() + + def update(model, images, target, optimizer): + output = model(images) + loss = criterion(output, target) + optimizer.zero_grad() + if args.amp: + with amp.scale_loss(loss, optimizer) as scaled_loss: + scaled_loss.backward() + else: + loss.backward() + optimizer.step() + + for step, (images, target) in enumerate(data_loader): + if args.device == 'npu': + loc = 'npu:{}'.format(args.gpu) + images = images.to(loc, non_blocking=True).to(torch.float) + target = target.to(torch.int32).to(loc, non_blocking=True) + else: + images = images.cuda(args.gpu, non_blocking=True) + target = target.cuda(args.gpu, non_blocking=True) + + if step < 5: + update(model, images, target, optimizer) + else: + if args.device == 'npu': + with torch.autograd.profiler.profile(use_npu=True) as prof: + update(model, images, target, optimizer) + else: + with torch.autograd.profiler.profile(use_cuda=True) as prof: + update(model, images, target, optimizer) + break + + prof.export_chrome_trace("output.prof") + + +def train(train_loader, model, criterion, optimizer, epoch, args, ngpus_per_node): + batch_time = AverageMeter('Time', ':6.3f') + data_time = AverageMeter('Data', ':6.3f') + losses = AverageMeter('Loss', ':.4e') + top1 = AverageMeter('Acc@1', ':6.2f') + top5 = AverageMeter('Acc@5', ':6.2f') + progress = ProgressMeter( + len(train_loader), + [batch_time, data_time, losses, top1, top5], + prefix="Epoch: [{}]".format(epoch)) + + # switch to train mode + model.train() + + end = time.time() + for i, (images, target) in enumerate(train_loader): + # measure data loading time + data_time.update(time.time() - end) + if i == 5: + start_FPS = time.time() + + if args.device == 'npu': + loc = 'npu:{}'.format(args.gpu) + images = images.to(loc, non_blocking=True).to(torch.float) + target = target.to(torch.int32).to(loc, non_blocking=True) + else: + images = images.cuda(args.gpu, non_blocking=True) + target = target.cuda(args.gpu, non_blocking=True) + + # compute output + output = model(images) + loss = criterion(output, target) + + # measure accuracy and record loss + acc1, acc5 = accuracy(output, target, topk=(1, 5)) + losses.update(loss.item(), images.size(0)) + top1.update(acc1[0], images.size(0)) + top5.update(acc5[0], images.size(0)) + + # compute gradient and do SGD step + optimizer.zero_grad() + if args.amp: + with amp.scale_loss(loss, optimizer) as scaled_loss: + scaled_loss.backward() + else: + loss.backward() + optimizer.step() + if args.device == 'npu': + torch.npu.synchronize() + + # measure elapsed time + cost_time = time.time() - end + batch_time.update(cost_time) + end = time.time() + + if i % args.print_freq == 0: + if not args.multiprocessing_distributed or (args.multiprocessing_distributed + and args.rank % ngpus_per_node == 0): + progress.display(i) + + if not args.multiprocessing_distributed or (args.multiprocessing_distributed + and args.rank % ngpus_per_node == 0): + print("[npu id:", args.gpu, "]", "batch_size:", args.world_size * args.batch_size, + 'Time: {:.3f}'.format(batch_time.avg), '* FPS@all {:.3f}'.format( + args.batch_size * args.world_size / batch_time.avg)) + epoch_time = end - start_FPS + epoch_FPS = (len(train_loader) - 5) * args.batch_size * args.world_size / float(epoch_time) + print(f"train_one_epoch FPS: {epoch_FPS}") + return epoch_FPS + +def validate(val_loader, model, criterion, args, ngpus_per_node): + batch_time = AverageMeter('Time', ':6.3f') + losses = AverageMeter('Loss', ':.4e') + top1 = AverageMeter('Acc@1', ':6.2f') + top5 = AverageMeter('Acc@5', ':6.2f') + progress = ProgressMeter( + len(val_loader), + [batch_time, losses, top1, top5], + prefix='Test: ') + + # switch to evaluate mode + model.eval() + + with torch.no_grad(): + end = time.time() + for i, (images, target) in enumerate(val_loader): + if args.gpu is not None: + if args.device == 'npu': + loc = 'npu:{}'.format(args.gpu) + images = images.to(loc).to(torch.float) + else: + images = images.cuda(args.gpu, non_blocking=True) + if args.device == 'npu': + loc = 'npu:{}'.format(args.gpu) + target = target.to(torch.int32).to(loc, non_blocking=True) + else: + target = target.cuda(args.gpu, non_blocking=True) + + # compute output + output = model(images) + loss = criterion(output, target) + + # measure accuracy and record loss + acc1, acc5 = accuracy(output, target, topk=(1, 5)) + losses.update(loss.item(), images.size(0)) + top1.update(acc1[0], images.size(0)) + top5.update(acc5[0], images.size(0)) + + # measure elapsed time + cost_time = time.time() - end + batch_time.update(cost_time) + end = time.time() + + if i % args.print_freq == 0: + if not args.multiprocessing_distributed or (args.multiprocessing_distributed + and args.rank % ngpus_per_node == 0): + progress.display(i) + + if i % args.print_freq == 0: + + print("[gpu id:", args.gpu, "]", '[AVG-ACC] * Acc@1 {top1.avg:.3f} Acc@5 {top5.avg:.3f}' + .format(top1=top1, top5=top5)) + + return top1.avg + + +def save_checkpoint(state, is_best, filename='checkpoint.pth.tar'): + torch.save(state, filename) + if is_best: + shutil.copyfile(filename, 'model_best.pth.tar') + + +class AverageMeter(object): + """Computes and stores the average and current value""" + + def __init__(self, name, fmt=':f', start_count_index=2): + self.name = name + self.fmt = fmt + self.reset() + self.start_count_index = start_count_index + + def reset(self): + self.val = 0 + self.avg = 0 + self.sum = 0 + self.count = 0 + + def update(self, val, n=1): + if self.count == 0: + self.N = n + + self.val = val + self.count += n + if self.count > (self.start_count_index * self.N): + self.sum += val * n + self.avg = self.sum / (self.count - self.start_count_index * self.N) + + def __str__(self): + fmtstr = '{name} {val' + self.fmt + '} ({avg' + self.fmt + '})' + return fmtstr.format(**self.__dict__) + + +class ProgressMeter(object): + + def __init__(self, num_batches, meters, prefix=""): + self.batch_fmtstr = self._get_batch_fmtstr(num_batches) + self.meters = meters + self.prefix = prefix + + def display(self, batch): + entries = [self.prefix + self.batch_fmtstr.format(batch)] + entries += [str(meter) for meter in self.meters] + print('\t'.join(entries)) + + def _get_batch_fmtstr(self, num_batches): + num_digits = len(str(num_batches // 1)) + fmt = '{:' + str(num_digits) + 'd}' + return '[' + fmt + '/' + fmt.format(num_batches) + ']' + + +def adjust_learning_rate(optimizer, epoch, args): + """Sets the learning rate to the initial LR decayed by 10 every 30 epochs""" + # lr = args.lr * (0.1 ** (epoch // (args.epochs//3 - 3))) + + if args.warm_up_epochs > 0 and epoch < args.warm_up_epochs: + lr = args.lr * ((epoch + 1) / (args.warm_up_epochs + 1)) + else: + alpha = 0 + cosine_decay = 0.5 * ( + 1 + np.cos(np.pi * (epoch - args.warm_up_epochs) / (args.epochs - args.warm_up_epochs))) + decayed = (1 - alpha) * cosine_decay + alpha + lr = args.lr * decayed + + print("=> Epoch[%d] Setting lr: %.4f" % (epoch, lr)) + for param_group in optimizer.param_groups: + param_group['lr'] = lr + + +def accuracy(output, target, topk=(1,)): + """Computes the accuracy over the k top predictions for the specified values of k""" + with torch.no_grad(): + maxk = max(topk) + batch_size = target.size(0) + + _, pred = output.topk(maxk, 1, True, True) + pred = pred.t() + correct = pred.eq(target.view(1, -1).expand_as(pred)) + + res = [] + for k in topk: + correct_k = correct[:k].reshape(-1).float().sum(0, keepdim=True) + res.append(correct_k.mul_(100.0 / batch_size)) + return res + + +if __name__ == '__main__': + main() + diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/examples/visu_arch.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/examples/visu_arch.py new file mode 100644 index 0000000000000000000000000000000000000000..8a64f4c2cdac23fa94b4c471b766c06d9665ca53 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/examples/visu_arch.py @@ -0,0 +1,238 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +from __future__ import print_function, division, absolute_import +import os + +import torch # http://pytorch.org/about/ +from torch.autograd import Variable +from torch.utils import model_zoo + +import torchvision # https://github.com/pytorch/vision +import torchvision.models as models +import torchvision.transforms as transforms + +from lib.voc import Voc2007Classification +from lib.util import load_imagenet_classes + +model_urls = { + # Alexnet + # Paper: https://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks.pdf + # https://github.com/pytorch/vision/blob/master/torchvision/models/alexnet.py + 'alexnet': 'https://download.pytorch.org/models/alexnet-owt-4df8aa71.pth', + # VGG + # Paper: https://arxiv.org/abs/1409.1556 + # https://github.com/pytorch/vision/blob/master/torchvision/models/vgg.py + 'vgg16': 'https://download.pytorch.org/models/vgg16-397923af.pth', + # VGG BatchNorm + # Paper: https://arxiv.org/abs/1502.03167 + # https://github.com/pytorch/vision/blob/master/torchvision/models/vgg.py + 'vgg16_bn': 'https://download.pytorch.org/models/vgg16_bn-6c64b313.pth', + # Inception + # Paper: https://arxiv.org/abs/1602.07261 + # https://github.com/pytorch/vision/blob/master/torchvision/models/inception.py + 'inception_v3': 'https://download.pytorch.org/models/inception_v3_google-1a9a5a14.pth', + # Resnet + # Paper: https://arxiv.org/abs/1512.03385 + # https://github.com/pytorch/vision/blob/master/torchvision/models/resnet.py + 'resnet18': 'https://download.pytorch.org/models/resnet18-5c106cde.pth', + 'resnet50': 'https://download.pytorch.org/models/resnet50-19c8e357.pth', + 'resnet152': 'https://download.pytorch.org/models/resnet152-b121ed2d.pth' +} + +if __name__ == '__main__': + + model_name = 'alexnet' + + dir_datasets = '/home/sasl/shared/EI-SE5-CS/datasets' # '/tmp/torch/datasets' + dir_models = '/home/sasl/shared/EI-SE5-CS/models' # '/tmp/torch/models' + dir_outputs = '/tmp/outputs/' + model_name + + print('Create network') + model = models.__dict__[model_name]() # https://stackoverflow.com/questions/19907442/python-explain-dict-attribute + model.eval() # http://pytorch.org/docs/master/nn.html?highlight=eval#torch.nn.Module.eval + print('') + + ########################################################################## + + print('Display modules') + print(model) + print('') + + ########################################################################## + + print('Display parameters') + state_dict = model.state_dict() # http://pytorch.org/docs/master/_modules/torch/nn/modules/module.html#Module.state_dict + for key, value in state_dict.items(): + print(key, value.size()) + print('') + + print('Display features.0.weight') + print(state_dict['features.0.weight']) + print('') + + ########################################################################## + + print('Display inputs/outputs') + + def print_info(self, input, output): + print('Inside '+ self.__class__.__name__+ ' forward') + print('input size', input[0].size()) + print('output size', output.data.size()) + print('') + + handles = [] + for m in model.features: + handles.append(m.register_forward_hook(print_info)) # http://pytorch.org/docs/master/_modules/torch/nn/modules/module.html#Module.register_forward_pre_hook + + for m in model.classifier: + handles.append(m.register_forward_hook(print_info)) + + input = Variable(torch.randn(1,3,224,224).float(), requires_grad=False) # http://pytorch.org/tutorials/beginner/blitz/autograd_tutorial.html#sphx-glr-beginner-blitz-autograd-tutorial-py + output = model(input) # model(input) calls model.__call__(input) which calls model.forward(hook) and then calls the hooks + + for h in handles: + h.remove() # to remove the hooks + + print('') + + ########################################################################## + + print('Load dataset Voc2007') + + train_data = Voc2007Classification(dir_datasets, 'train') # or val, test, trainval + + print('Voc2007 trainset has {} images'.format(len(train_data))) + + print('Voc2007 has {} classes'.format(len(train_data.classes))) + print(train_data.classes) + + item = train_data[0] # train_data contains a list of items (image, name, target) + img_data = item[0] # PIL.Image.Image + img_name = item[1] # string + target = item[2] # torch.Tensor of size=20 (=nb_classes), contains 3 values: -1 (absence of class), 1 (presence of class), 0 (hard example) + + os.system('mkdir -p ' + dir_outputs) # create a directory + path_img = os.path.join(dir_outputs, img_name+'.png') + img_data.save(path_img) # save image using PIL + + print('Write image to ' + path_img) + for class_id, has_class in enumerate(target): + if has_class == 1: + print('image {} has object of class {}'.format(img_name, train_data.classes[class_id])) + + ########################################################################## + + print('Load pretrained model on Imagenet') + model.load_state_dict(model_zoo.load_url(model_urls[model_name], + model_dir=dir_models)) + + print('Display predictions') + + tf = transforms.Compose([ + transforms.Scale(224), # rescale an RGB image to size 224^ (not a square) + transforms.CenterCrop(224), # extract a square of size 224 at the center of the image + transforms.ToTensor(), # convert the PIL.Image into a torch.Tensor + transforms.Normalize( + mean=[0.485, 0.456, 0.406], # mean pixel value per channel + std=[0.229, 0.224, 0.225] # standard deviation value per channel + ) + ]) + + input_data = tf(img_data) + input_data = input_data.unsqueeze(0) # (3,224,224) -> (1,3,224,224) + print('input size', input_data.size()) + print(input_data) + + input = Variable(input_data, requires_grad=False) + output = model(input) + + print('output size', output.data.size()) + print(output.data) + + # Load Imagenet Synsets + imagenet_classes = load_imagenet_classes() + print('Imagenet has {} classes'.format(imagenet_classes)) + + max, argmax = output.data.squeeze().max(0) + class_id = argmax[0] + print('Image {} is of class "{}"'.format(img_name, imagenet_classes[class_id])) + + ############################################################################# + + print('Save normalized input as RGB image') + + dir_activations = os.path.join(dir_outputs,'activations') + os.system('mkdir -p ' + dir_activations) + + path_img_input = os.path.join(dir_activations, 'input.png') + print('save input activation to ' + path_img_input) + transforms.ToPILImage()(input_data[0]).save(path_img_input) # save image using PIL + + print('') + + ############################################################################# + + print('Save activations as Gray images') + + layer_id = 0 + + def save_activation(self, input, output): + global layer_id + + for i in range(10):#output.data.size(1)): + path_img_output = os.path.join(dir_activations, 'layer{}_{}_channel{}.png'.format(layer_id, self.__class__.__name__, i)) + print('save output activation to ' + path_img_output) + torchvision.utils.save_image(output.data.squeeze(0)[i], path_img_output) # save image (of type Tensor) using torchvision + + layer_id += 1 + + handles = [] + for m in model.features: + handles.append(m.register_forward_hook(save_activation)) + + input = Variable(input_data, requires_grad=False) + output = model(input) + + for h in handles: + h.remove() + + print('') + + ############################################################################# + + dir_parameters = os.path.join(dir_outputs, 'parameters') + os.system('mkdir -p ' + dir_parameters) + state_dict = model.state_dict() + + print('Save first layer parameters as RGB images') + + weight = state_dict['features.0.weight'] + for filter_id in range(weight.size(0)): + path_param = os.path.join(dir_parameters, 'features.0.weight_filter{}.png'.format(filter_id)) + print('save ' + path_param) + torchvision.utils.save_image(weight[filter_id], path_param) + + print('') + + + print('Save other layer parameters as Gray images') + + for key in state_dict: + if 'features' in key and 'weight' in key: + for filter_id in range(3): + for channel_id in range(3): + path_param = os.path.join(dir_parameters, '{}_filter{}_channel{}.png'.format(key, filter_id, channel_id)) + print('save ' + path_param) + torchvision.utils.save_image(state_dict[key][filter_id][channel_id], path_param) + + print('') + diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/examples/voc2007_extract.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/examples/voc2007_extract.py new file mode 100644 index 0000000000000000000000000000000000000000..d085c1e6607a6ed7346cf6692425a88797592d6e --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/examples/voc2007_extract.py @@ -0,0 +1,196 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +from __future__ import print_function, division, absolute_import +import os +import argparse +from tqdm import tqdm + +import torch +from torch.autograd import Variable +from torch.utils import model_zoo + +# http://scikit-learn.org +from sklearn.metrics import accuracy_score +from sklearn.metrics import average_precision_score +from sklearn.svm import LinearSVC +from sklearn.svm import SVC + +import sys +sys.path.append('.') +import pretrainedmodels +import pretrainedmodels.utils +import pretrainedmodels.datasets + +model_names = sorted(name for name in pretrainedmodels.__dict__ + if not name.startswith("__") + and name.islower() + and callable(pretrainedmodels.__dict__[name])) + +def extract_features_targets(model, features_size, loader, path_data, cuda=False): + if os.path.isfile(path_data): + print('Load features from {}'.format(path_data)) + return torch.load(path_data) + + print('\nExtract features on {}set'.format(loader.dataset.set)) + + features = torch.Tensor(len(loader.dataset), features_size) + targets = torch.Tensor(len(loader.dataset), len(loader.dataset.classes)) + + for batch_id, batch in enumerate(tqdm(loader)): + img = batch[0] + target = batch[2] + current_bsize = img.size(0) + from_ = int(batch_id * loader.batch_size) + to_ = int(from_ + current_bsize) + + if cuda: + img = img.cuda(async=True) + + input = Variable(img, requires_grad=False) + output = model(input) + + features[from_:to_] = output.data.cpu() + targets[from_:to_] = target + + os.system('mkdir -p {}'.format(os.path.dirname(path_data))) + print('save ' + path_data) + torch.save((features, targets), path_data) + print('') + return features, targets + +def train_multilabel(features, targets, classes, train_split, test_split, C=1.0, ignore_hard_examples=True, after_ReLU=False, normalize_L2=False): + print('\nHyperparameters:\n - C: {}\n - after_ReLU: {}\n - normL2: {}'.format(C, after_ReLU, normalize_L2)) + train_APs = [] + test_APs = [] + for class_id in range(len(classes)): + + classifier = SVC(C=C, kernel='linear') # http://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html + + if ignore_hard_examples: + train_masks = (targets[train_split][:,class_id] != 0).view(-1, 1) + train_features = torch.masked_select(features[train_split], train_masks.expand_as(features[train_split])).view(-1,features[train_split].size(1)) + train_targets = torch.masked_select(targets[train_split], train_masks.expand_as(targets[train_split])).view(-1,targets[train_split].size(1)) + test_masks = (targets[test_split][:,class_id] != 0).view(-1, 1) + test_features = torch.masked_select(features[test_split], test_masks.expand_as(features[test_split])).view(-1,features[test_split].size(1)) + test_targets = torch.masked_select(targets[test_split], test_masks.expand_as(targets[test_split])).view(-1,targets[test_split].size(1)) + else: + train_features = features[train_split] + train_targets = targets[train_split] + test_features = features[test_split] + test_targets = features[test_split] + + if after_ReLU: + train_features[train_features < 0] = 0 + test_features[test_features < 0] = 0 + + if normalize_L2: + train_norm = torch.norm(train_features, p=2, dim=1).unsqueeze(1) + train_features = train_features.div(train_norm.expand_as(train_features)) + test_norm = torch.norm(test_features, p=2, dim=1).unsqueeze(1) + test_features = test_features.div(test_norm.expand_as(test_features)) + + train_X = train_features.numpy() + train_y = (train_targets[:,class_id] != -1).numpy() # uses hard examples if not ignored + + test_X = test_features.numpy() + test_y = (test_targets[:,class_id] != -1).numpy() + + classifier.fit(train_X, train_y) # train parameters of the classifier + + train_preds = classifier.predict(train_X) + train_acc = accuracy_score(train_y, train_preds) * 100 + train_AP = average_precision_score(train_y, train_preds) * 100 + train_APs.append(train_AP) + + test_preds = classifier.predict(test_X) + test_acc = accuracy_score(test_y, test_preds) * 100 + test_AP = average_precision_score(test_y, test_preds) * 100 + test_APs.append(test_AP) + + print('class "{}" ({}/{}):'.format(classes[class_id], test_y.sum(), test_y.shape[0])) + print(' - {:8}: acc {:.2f}, AP {:.2f}'.format(train_split, train_acc, train_AP)) + print(' - {:8}: acc {:.2f}, AP {:.2f}'.format(test_split, test_acc, test_AP)) + + print('all classes:') + print(' - {:8}: mAP {:.4f}'.format(train_split, sum(train_APs)/len(classes))) + print(' - {:8}: mAP {:.4f}'.format(test_split, sum(test_APs)/len(classes))) + +########################################################################## +# main +########################################################################## + +parser = argparse.ArgumentParser( + description='Train/Evaluate models', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) +parser.add_argument('--dir_outputs', default='/tmp/outputs', type=str, help='') +parser.add_argument('--dir_datasets', default='/tmp/datasets', type=str, help='') +parser.add_argument('--C', default=1, type=float, help='') +parser.add_argument('-b', '--batch_size', default=50, type=float, help='') +parser.add_argument('-a', '--arch', default='alexnet', choices=model_names, + help='model architecture: ' + + ' | '.join(model_names) + + ' (default: alexnet)') +parser.add_argument('--train_split', default='train', type=str, help='') +parser.add_argument('--test_split', default='val', type=str, help='') +parser.add_argument('--cuda', const=True, nargs='?', type=bool, help='') + +def main (): + global args + args = parser.parse_args() + print('\nCUDA status: {}'.format(args.cuda)) + + print('\nLoad pretrained model on Imagenet') + model = pretrainedmodels.__dict__[args.arch](num_classes=1000, pretrained='imagenet') + model.eval() + if args.cuda: + model.cuda() + + features_size = model.last_linear.in_features + model.last_linear = pretrainedmodels.utils.Identity() # Trick to get inputs (features) from last_linear + + print('\nLoad datasets') + tf_img = pretrainedmodels.utils.TransformImage(model) + train_set = pretrainedmodels.datasets.Voc2007Classification(args.dir_datasets, 'train', transform=tf_img) + val_set = pretrainedmodels.datasets.Voc2007Classification(args.dir_datasets, 'val', transform=tf_img) + test_set = pretrainedmodels.datasets.Voc2007Classification(args.dir_datasets, 'test', transform=tf_img) + + train_loader = torch.utils.data.DataLoader(train_set, batch_size=args.batch_size, shuffle=False, num_workers=2) + val_loader = torch.utils.data.DataLoader(val_set, batch_size=args.batch_size, shuffle=False, num_workers=2) + test_loader = torch.utils.data.DataLoader(test_set, batch_size=args.batch_size, shuffle=False, num_workers=2) + + print('\nLoad features') + dir_features = os.path.join(args.dir_outputs, 'data/{}'.format(args.arch)) + path_train_data = '{}/{}set.pth'.format(dir_features, 'train') + path_val_data = '{}/{}set.pth'.format(dir_features, 'val') + path_test_data = '{}/{}set.pth'.format(dir_features, 'test') + + features = {} + targets = {} + features['train'], targets['train'] = extract_features_targets(model, features_size, train_loader, path_train_data, args.cuda) + features['val'], targets['val'] = extract_features_targets(model, features_size, val_loader, path_val_data, args.cuda) + features['test'], targets['test'] = extract_features_targets(model, features_size, test_loader, path_test_data, args.cuda) + features['trainval'] = torch.cat([features['train'], features['val']], 0) + targets['trainval'] = torch.cat([targets['train'], targets['val']], 0) + + print('\nTrain Support Vector Machines') + if args.train_split == 'train' and args.test_split == 'val': + print('\nHyperparameters search: train multilabel classifiers (on-versus-all) on train/val') + elif args.train_split == 'trainval' and args.test_split == 'test': + print('\nEvaluation: train a multilabel classifier on trainval/test') + else: + raise ValueError('Trying to train on {} and eval on {}'.format(args.train_split, args.test_split)) + + train_multilabel(features, targets, train_set.classes, args.train_split, args.test_split, C=args.C) + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/__init__.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0187e4b331774220e999cb6620fbdd8eddb5effd --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/__init__.py @@ -0,0 +1,55 @@ +from .version import __version__ + +from . import models +from . import datasets + +from .models.utils import pretrained_settings +from .models.utils import model_names + +# to support pretrainedmodels.__dict__['nasnetalarge'] +# but depreciated +from .models.fbresnet import fbresnet152 +from .models.cafferesnet import cafferesnet101 +from .models.bninception import bninception +from .models.resnext import resnext101_32x4d +from .models.resnext import resnext101_64x4d +from .models.inceptionv4 import inceptionv4 +from .models.inceptionresnetv2 import inceptionresnetv2 +from .models.nasnet import nasnetalarge +from .models.nasnet_mobile import nasnetamobile +from .models.torchvision_models import alexnet +from .models.torchvision_models import densenet121 +from .models.torchvision_models import densenet169 +from .models.torchvision_models import densenet201 +from .models.torchvision_models import densenet161 +from .models.torchvision_models import resnet18 +from .models.torchvision_models import resnet34 +from .models.torchvision_models import resnet50 +from .models.torchvision_models import resnet101 +from .models.torchvision_models import resnet152 +from .models.torchvision_models import inceptionv3 +from .models.torchvision_models import squeezenet1_0 +from .models.torchvision_models import squeezenet1_1 +from .models.torchvision_models import vgg11 +from .models.torchvision_models import vgg11_bn +from .models.torchvision_models import vgg13 +from .models.torchvision_models import vgg13_bn +from .models.torchvision_models import vgg16 +from .models.torchvision_models import vgg16_bn +from .models.torchvision_models import vgg19_bn +from .models.torchvision_models import vgg19 +from .models.dpn import dpn68 +from .models.dpn import dpn68b +from .models.dpn import dpn92 +from .models.dpn import dpn98 +from .models.dpn import dpn131 +from .models.dpn import dpn107 +from .models.xception import xception +from .models.senet import senet154 +from .models.senet import se_resnet50 +from .models.senet import se_resnet101 +from .models.senet import se_resnet152 +from .models.senet import se_resnext50_32x4d +from .models.senet import se_resnext101_32x4d +from .models.pnasnet import pnasnet5large +from .models.polynet import polynet diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/datasets/__init__.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/datasets/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..14e02a054c26d825f72422d13e19ba693344ce21 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/datasets/__init__.py @@ -0,0 +1,2 @@ +from __future__ import print_function, division, absolute_import +from .voc import Voc2007Classification \ No newline at end of file diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/datasets/utils.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/datasets/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..59f8bf44295632ce9defcbe64caefdc258d738cd --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/datasets/utils.py @@ -0,0 +1,210 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +from __future__ import print_function, division, absolute_import +import math +from six.moves.urllib.request import urlretrieve + +import torch +from PIL import Image +from tqdm import tqdm + +def load_imagenet_classes(path_synsets='data/imagenet_synsets.txt', + path_classes='data/imagenet_classes.txt'): + with open(path_synsets, 'r') as f: + synsets = f.readlines() + + synsets = [x.strip() for x in synsets] + splits = [line.split(' ') for line in synsets] + key_to_classname = {spl[0]:' '.join(spl[1:]) for spl in splits} + + with open(path_classes, 'r') as f: + class_id_to_key = f.readlines() + + class_id_to_key = [x.strip() for x in class_id_to_key] + + cid_to_cname = [] + for i in range(len(class_id_to_key)): + key = class_id_to_key[i] + cname = key_to_classname[key] + cid_to_cname.append(cname) + + return cid_to_cname + + +class Warp(object): + def __init__(self, size, interpolation=Image.BILINEAR): + self.size = int(size) + self.interpolation = interpolation + + def __call__(self, img): + return img.resize((self.size, self.size), self.interpolation) + + def __str__(self): + return self.__class__.__name__ + ' (size={size}, interpolation={interpolation})'.format(size=self.size, + interpolation=self.interpolation) + + +def download_url(url, destination=None, progress_bar=True): + """Download a URL to a local file. + + Parameters + ---------- + url : str + The URL to download. + destination : str, None + The destination of the file. If None is given the file is saved to a temporary directory. + progress_bar : bool + Whether to show a command-line progress bar while downloading. + + Returns + ------- + filename : str + The location of the downloaded file. + + Notes + ----- + Progress bar use/example adapted from tqdm documentation: https://github.com/tqdm/tqdm + """ + + def my_hook(t): + last_b = [0] + + def inner(b=1, bsize=1, tsize=None): + if tsize is not None: + t.total = tsize + if b > 0: + t.update((b - last_b[0]) * bsize) + last_b[0] = b + + return inner + + if progress_bar: + with tqdm(unit='B', unit_scale=True, miniters=1, desc=url.split('/')[-1]) as t: + filename, _ = urlretrieve(url, filename=destination, reporthook=my_hook(t)) + else: + filename, _ = urlretrieve(url, filename=destination) + + +class AveragePrecisionMeter(object): + """ + The APMeter measures the average precision per class. + The APMeter is designed to operate on `NxK` Tensors `output` and + `target`, and optionally a `Nx1` Tensor weight where (1) the `output` + contains model output scores for `N` examples and `K` classes that ought to + be higher when the model is more convinced that the example should be + positively labeled, and smaller when the model believes the example should + be negatively labeled (for instance, the output of a sigmoid function); (2) + the `target` contains only values 0 (for negative examples) and 1 + (for positive examples); and (3) the `weight` ( > 0) represents weight for + each sample. + """ + + def __init__(self, difficult_examples=False): + super(AveragePrecisionMeter, self).__init__() + self.reset() + self.difficult_examples = difficult_examples + + def reset(self): + """Resets the meter with empty member variables""" + self.scores = torch.FloatTensor(torch.FloatStorage()) + self.targets = torch.LongTensor(torch.LongStorage()) + + def add(self, output, target): + """ + Args: + output (Tensor): NxK tensor that for each of the N examples + indicates the probability of the example belonging to each of + the K classes, according to the model. The probabilities should + sum to one over all classes + target (Tensor): binary NxK tensort that encodes which of the K + classes are associated with the N-th input + (eg: a row [0, 1, 0, 1] indicates that the example is + associated with classes 2 and 4) + weight (optional, Tensor): Nx1 tensor representing the weight for + each example (each weight > 0) + """ + if not torch.is_tensor(output): + output = torch.from_numpy(output) + if not torch.is_tensor(target): + target = torch.from_numpy(target) + + if output.dim() == 1: + output = output.view(-1, 1) + else: + assert output.dim() == 2, \ + 'wrong output size (should be 1D or 2D with one column \ + per class)' + if target.dim() == 1: + target = target.view(-1, 1) + else: + assert target.dim() == 2, \ + 'wrong target size (should be 1D or 2D with one column \ + per class)' + if self.scores.numel() > 0: + assert target.size(1) == self.targets.size(1), \ + 'dimensions for output should match previously added examples.' + + # make sure storage is of sufficient size + if self.scores.storage().size() < self.scores.numel() + output.numel(): + new_size = math.ceil(self.scores.storage().size() * 1.5) + self.scores.storage().resize_(int(new_size + output.numel())) + self.targets.storage().resize_(int(new_size + output.numel())) + + # store scores and targets + offset = self.scores.size(0) if self.scores.dim() > 0 else 0 + self.scores.resize_(offset + output.size(0), output.size(1)) + self.targets.resize_(offset + target.size(0), target.size(1)) + self.scores.narrow(0, offset, output.size(0)).copy_(output) + self.targets.narrow(0, offset, target.size(0)).copy_(target) + + def value(self): + """Returns the model's average precision for each class + Return: + ap (FloatTensor): 1xK tensor, with avg precision for each class k + """ + + if self.scores.numel() == 0: + return 0 + ap = torch.zeros(self.scores.size(1)) + rg = torch.arange(1, self.scores.size(0)).float() + + # compute average precision for each class + for k in range(self.scores.size(1)): + # sort scores + scores = self.scores[:, k] + targets = self.targets[:, k] + + # compute average precision + ap[k] = AveragePrecisionMeter.average_precision(scores, targets, self.difficult_examples) + return ap + + @staticmethod + def average_precision(output, target, difficult_examples=True): + + # sort examples + sorted, indices = torch.sort(output, dim=0, descending=True) + + # Computes prec@i + pos_count = 0. + total_count = 0. + precision_at_i = 0. + for i in indices: + label = target[i] + if difficult_examples and label == 0: + continue + if label == 1: + pos_count += 1 + total_count += 1 + if label == 1: + precision_at_i += pos_count / total_count + precision_at_i /= pos_count + return precision_at_i \ No newline at end of file diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/datasets/voc.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/datasets/voc.py new file mode 100644 index 0000000000000000000000000000000000000000..bbaee5c48e2794de9a57637a3724e87c0b59573a --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/datasets/voc.py @@ -0,0 +1,272 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +from __future__ import print_function, division, absolute_import +import csv +import os +import os.path +import tarfile +from six.moves.urllib.parse import urlparse + +import numpy as np +import torch +import torch.utils.data as data +from PIL import Image + +from . import utils + +object_categories = ['aeroplane', 'bicycle', 'bird', 'boat', + 'bottle', 'bus', 'car', 'cat', 'chair', + 'cow', 'diningtable', 'dog', 'horse', + 'motorbike', 'person', 'pottedplant', + 'sheep', 'sofa', 'train', 'tvmonitor'] + +urls = { + 'devkit': 'http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCdevkit_18-May-2011.tar', + 'trainval_2007': 'http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtrainval_06-Nov-2007.tar', + 'test_images_2007': 'http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtest_06-Nov-2007.tar', + 'test_anno_2007': 'http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtestnoimgs_06-Nov-2007.tar', +} + + +def read_image_label(file): + print('[dataset] read ' + file) + data = dict() + with open(file, 'r') as f: + for line in f: + tmp = line.split(' ') + name = tmp[0] + label = int(tmp[-1]) + data[name] = label + # data.append([name, label]) + # print('%s %d' % (name, label)) + return data + + +def read_object_labels(root, dataset, set): + path_labels = os.path.join(root, 'VOCdevkit', dataset, 'ImageSets', 'Main') + labeled_data = dict() + num_classes = len(object_categories) + + for i in range(num_classes): + file = os.path.join(path_labels, object_categories[i] + '_' + set + '.txt') + data = read_image_label(file) + + if i == 0: + for (name, label) in data.items(): + labels = np.zeros(num_classes) + labels[i] = label + labeled_data[name] = labels + else: + for (name, label) in data.items(): + labeled_data[name][i] = label + + return labeled_data + + +def write_object_labels_csv(file, labeled_data): + # write a csv file + print('[dataset] write file %s' % file) + with open(file, 'w') as csvfile: + fieldnames = ['name'] + fieldnames.extend(object_categories) + writer = csv.DictWriter(csvfile, fieldnames=fieldnames) + + writer.writeheader() + for (name, labels) in labeled_data.items(): + example = {'name': name} + for i in range(20): + example[fieldnames[i + 1]] = int(labels[i]) + writer.writerow(example) + + csvfile.close() + + +def read_object_labels_csv(file, header=True): + images = [] + num_categories = 0 + print('[dataset] read', file) + with open(file, 'r') as f: + reader = csv.reader(f) + rownum = 0 + for row in reader: + if header and rownum == 0: + header = row + else: + if num_categories == 0: + num_categories = len(row) - 1 + name = row[0] + labels = (np.asarray(row[1:num_categories + 1])).astype(np.float32) + labels = torch.from_numpy(labels) + item = (name, labels) + images.append(item) + rownum += 1 + return images + + +def find_images_classification(root, dataset, set): + path_labels = os.path.join(root, 'VOCdevkit', dataset, 'ImageSets', 'Main') + images = [] + file = os.path.join(path_labels, set + '.txt') + with open(file, 'r') as f: + for line in f: + images.append(line) + return images + + +def download_voc2007(root): + path_devkit = os.path.join(root, 'VOCdevkit') + path_images = os.path.join(root, 'VOCdevkit', 'VOC2007', 'JPEGImages') + tmpdir = os.path.join(root, 'tmp') + + # create directory + if not os.path.exists(root): + os.makedirs(root) + + if not os.path.exists(path_devkit): + + if not os.path.exists(tmpdir): + os.makedirs(tmpdir) + + parts = urlparse(urls['devkit']) + filename = os.path.basename(parts.path) + cached_file = os.path.join(tmpdir, filename) + + if not os.path.exists(cached_file): + print('Downloading: "{}" to {}\n'.format(urls['devkit'], cached_file)) + utils.download_url(urls['devkit'], cached_file) + + # extract file + print('[dataset] Extracting tar file {file} to {path}'.format(file=cached_file, path=root)) + cwd = os.getcwd() + tar = tarfile.open(cached_file, "r") + os.chdir(root) + tar.extractall() + tar.close() + os.chdir(cwd) + print('[dataset] Done!') + + # train/val images/annotations + if not os.path.exists(path_images): + + # download train/val images/annotations + parts = urlparse(urls['trainval_2007']) + filename = os.path.basename(parts.path) + cached_file = os.path.join(tmpdir, filename) + + if not os.path.exists(cached_file): + print('Downloading: "{}" to {}\n'.format(urls['trainval_2007'], cached_file)) + utils.download_url(urls['trainval_2007'], cached_file) + + # extract file + print('[dataset] Extracting tar file {file} to {path}'.format(file=cached_file, path=root)) + cwd = os.getcwd() + tar = tarfile.open(cached_file, "r") + os.chdir(root) + tar.extractall() + tar.close() + os.chdir(cwd) + print('[dataset] Done!') + + # test annotations + test_anno = os.path.join(path_devkit, 'VOC2007/ImageSets/Main/aeroplane_test.txt') + if not os.path.exists(test_anno): + + # download test annotations + parts = urlparse(urls['test_images_2007']) + filename = os.path.basename(parts.path) + cached_file = os.path.join(tmpdir, filename) + + if not os.path.exists(cached_file): + print('Downloading: "{}" to {}\n'.format(urls['test_images_2007'], cached_file)) + utils.download_url(urls['test_images_2007'], cached_file) + + # extract file + print('[dataset] Extracting tar file {file} to {path}'.format(file=cached_file, path=root)) + cwd = os.getcwd() + tar = tarfile.open(cached_file, "r") + os.chdir(root) + tar.extractall() + tar.close() + os.chdir(cwd) + print('[dataset] Done!') + + # test images + test_image = os.path.join(path_devkit, 'VOC2007/JPEGImages/000001.jpg') + if not os.path.exists(test_image): + + # download test images + parts = urlparse(urls['test_anno_2007']) + filename = os.path.basename(parts.path) + cached_file = os.path.join(tmpdir, filename) + + if not os.path.exists(cached_file): + print('Downloading: "{}" to {}\n'.format(urls['test_anno_2007'], cached_file)) + utils.download_url(urls['test_anno_2007'], cached_file) + + # extract file + print('[dataset] Extracting tar file {file} to {path}'.format(file=cached_file, path=root)) + cwd = os.getcwd() + tar = tarfile.open(cached_file, "r") + os.chdir(root) + tar.extractall() + tar.close() + os.chdir(cwd) + print('[dataset] Done!') + + +class Voc2007Classification(data.Dataset): + + def __init__(self, root, set, transform=None, target_transform=None): + self.root = root + self.path_devkit = os.path.join(root, 'VOCdevkit') + self.path_images = os.path.join(root, 'VOCdevkit', 'VOC2007', 'JPEGImages') + self.set = set + self.transform = transform + self.target_transform = target_transform + + # download dataset + download_voc2007(self.root) + + # define path of csv file + path_csv = os.path.join(self.root, 'files', 'VOC2007') + # define filename of csv file + file_csv = os.path.join(path_csv, 'classification_' + set + '.csv') + + # create the csv file if necessary + if not os.path.exists(file_csv): + if not os.path.exists(path_csv): # create dir if necessary + os.makedirs(path_csv) + # generate csv file + labeled_data = read_object_labels(self.root, 'VOC2007', self.set) + # write csv file + write_object_labels_csv(file_csv, labeled_data) + + self.classes = object_categories + self.images = read_object_labels_csv(file_csv) + + print('[dataset] VOC 2007 classification set=%s number of classes=%d number of images=%d' % ( + set, len(self.classes), len(self.images))) + + def __getitem__(self, index): + path, target = self.images[index] + img = Image.open(os.path.join(self.path_images, path + '.jpg')).convert('RGB') + if self.transform is not None: + img = self.transform(img) + if self.target_transform is not None: + target = self.target_transform(target) + return img, path, target + + def __len__(self): + return len(self.images) + + def get_number_classes(self): + return len(self.classes) diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/dpn.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/dpn.py new file mode 100644 index 0000000000000000000000000000000000000000..4d4a1e5042e93b97daa0181018dabd9bd74d200d --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/dpn.py @@ -0,0 +1,473 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +""" PyTorch implementation of DualPathNetworks +Ported to PyTorch by [Ross Wightman](https://github.com/rwightman/pytorch-dpn-pretrained) + +Based on original MXNet implementation https://github.com/cypw/DPNs with +many ideas from another PyTorch implementation https://github.com/oyam/pytorch-DPNs. + +This implementation is compatible with the pretrained weights +from cypw's MXNet implementation. +""" +from __future__ import print_function, division, absolute_import +import os +import torch +import torch.nn as nn +import torch.nn.functional as F +import torch.utils.model_zoo as model_zoo +from collections import OrderedDict + +__all__ = ['DPN', 'dpn68', 'dpn68b', 'dpn92', 'dpn98', 'dpn131', 'dpn107'] + +pretrained_settings = { + 'dpn68': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/dpn68-4af7d88d2.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [124 / 255, 117 / 255, 104 / 255], + 'std': [1 / (.0167 * 255)] * 3, + 'num_classes': 1000 + } + }, + 'dpn68b': { + 'imagenet+5k': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/dpn68b_extra-363ab9c19.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [124 / 255, 117 / 255, 104 / 255], + 'std': [1 / (.0167 * 255)] * 3, + 'num_classes': 1000 + } + }, + 'dpn92': { + # 'imagenet': { + # 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/dpn68-66bebafa7.pth', + # 'input_space': 'RGB', + # 'input_size': [3, 224, 224], + # 'input_range': [0, 1], + # 'mean': [124 / 255, 117 / 255, 104 / 255], + # 'std': [1 / (.0167 * 255)] * 3, + # 'num_classes': 1000 + # }, + 'imagenet+5k': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/dpn92_extra-fda993c95.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [124 / 255, 117 / 255, 104 / 255], + 'std': [1 / (.0167 * 255)] * 3, + 'num_classes': 1000 + } + }, + 'dpn98': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/dpn98-722954780.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [124 / 255, 117 / 255, 104 / 255], + 'std': [1 / (.0167 * 255)] * 3, + 'num_classes': 1000 + } + }, + 'dpn131': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/dpn131-7af84be88.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [124 / 255, 117 / 255, 104 / 255], + 'std': [1 / (.0167 * 255)] * 3, + 'num_classes': 1000 + } + }, + 'dpn107': { + 'imagenet+5k': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/dpn107_extra-b7f9f4cc9.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [124 / 255, 117 / 255, 104 / 255], + 'std': [1 / (.0167 * 255)] * 3, + 'num_classes': 1000 + } + } +} + +def dpn68(num_classes=1000, pretrained='imagenet'): + model = DPN( + small=True, num_init_features=10, k_r=128, groups=32, + k_sec=(3, 4, 12, 3), inc_sec=(16, 32, 32, 64), + num_classes=num_classes, test_time_pool=True) + if pretrained: + settings = pretrained_settings['dpn68'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model + +def dpn68b(num_classes=1000, pretrained='imagenet+5k'): + model = DPN( + small=True, num_init_features=10, k_r=128, groups=32, + b=True, k_sec=(3, 4, 12, 3), inc_sec=(16, 32, 32, 64), + num_classes=num_classes, test_time_pool=True) + if pretrained: + settings = pretrained_settings['dpn68b'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model + +def dpn92(num_classes=1000, pretrained='imagenet+5k'): + model = DPN( + num_init_features=64, k_r=96, groups=32, + k_sec=(3, 4, 20, 3), inc_sec=(16, 32, 24, 128), + num_classes=num_classes, test_time_pool=True) + if pretrained: + settings = pretrained_settings['dpn92'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model + +def dpn98(num_classes=1000, pretrained='imagenet'): + model = DPN( + num_init_features=96, k_r=160, groups=40, + k_sec=(3, 6, 20, 3), inc_sec=(16, 32, 32, 128), + num_classes=num_classes, test_time_pool=True) + if pretrained: + settings = pretrained_settings['dpn98'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model + +def dpn131(num_classes=1000, pretrained='imagenet'): + model = DPN( + num_init_features=128, k_r=160, groups=40, + k_sec=(4, 8, 28, 3), inc_sec=(16, 32, 32, 128), + num_classes=num_classes, test_time_pool=True) + if pretrained: + settings = pretrained_settings['dpn131'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model + +def dpn107(num_classes=1000, pretrained='imagenet+5k'): + model = DPN( + num_init_features=128, k_r=200, groups=50, + k_sec=(4, 8, 20, 3), inc_sec=(20, 64, 64, 128), + num_classes=num_classes, test_time_pool=True) + if pretrained: + settings = pretrained_settings['dpn107'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model + + +class CatBnAct(nn.Module): + def __init__(self, in_chs, activation_fn=nn.ReLU(inplace=True)): + super(CatBnAct, self).__init__() + self.bn = nn.BatchNorm2d(in_chs, eps=0.001) + self.act = activation_fn + + def forward(self, x): + x = torch.cat(x, dim=1) if isinstance(x, tuple) else x + return self.act(self.bn(x)) + + +class BnActConv2d(nn.Module): + def __init__(self, in_chs, out_chs, kernel_size, stride, + padding=0, groups=1, activation_fn=nn.ReLU(inplace=True)): + super(BnActConv2d, self).__init__() + self.bn = nn.BatchNorm2d(in_chs, eps=0.001) + self.act = activation_fn + self.conv = nn.Conv2d(in_chs, out_chs, kernel_size, stride, padding, groups=groups, bias=False) + + def forward(self, x): + return self.conv(self.act(self.bn(x))) + + +class InputBlock(nn.Module): + def __init__(self, num_init_features, kernel_size=7, + padding=3, activation_fn=nn.ReLU(inplace=True)): + super(InputBlock, self).__init__() + self.conv = nn.Conv2d( + 3, num_init_features, kernel_size=kernel_size, stride=2, padding=padding, bias=False) + self.bn = nn.BatchNorm2d(num_init_features, eps=0.001) + self.act = activation_fn + self.pool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) + + def forward(self, x): + x = self.conv(x) + x = self.bn(x) + x = self.act(x) + x = self.pool(x) + return x + + +class DualPathBlock(nn.Module): + def __init__( + self, in_chs, num_1x1_a, num_3x3_b, num_1x1_c, inc, groups, block_type='normal', b=False): + super(DualPathBlock, self).__init__() + self.num_1x1_c = num_1x1_c + self.inc = inc + self.b = b + if block_type is 'proj': + self.key_stride = 1 + self.has_proj = True + elif block_type is 'down': + self.key_stride = 2 + self.has_proj = True + else: + assert block_type is 'normal' + self.key_stride = 1 + self.has_proj = False + + if self.has_proj: + # Using different member names here to allow easier parameter key matching for conversion + if self.key_stride == 2: + self.c1x1_w_s2 = BnActConv2d( + in_chs=in_chs, out_chs=num_1x1_c + 2 * inc, kernel_size=1, stride=2) + else: + self.c1x1_w_s1 = BnActConv2d( + in_chs=in_chs, out_chs=num_1x1_c + 2 * inc, kernel_size=1, stride=1) + self.c1x1_a = BnActConv2d(in_chs=in_chs, out_chs=num_1x1_a, kernel_size=1, stride=1) + self.c3x3_b = BnActConv2d( + in_chs=num_1x1_a, out_chs=num_3x3_b, kernel_size=3, + stride=self.key_stride, padding=1, groups=groups) + if b: + self.c1x1_c = CatBnAct(in_chs=num_3x3_b) + self.c1x1_c1 = nn.Conv2d(num_3x3_b, num_1x1_c, kernel_size=1, bias=False) + self.c1x1_c2 = nn.Conv2d(num_3x3_b, inc, kernel_size=1, bias=False) + else: + self.c1x1_c = BnActConv2d(in_chs=num_3x3_b, out_chs=num_1x1_c + inc, kernel_size=1, stride=1) + + def forward(self, x): + x_in = torch.cat(x, dim=1) if isinstance(x, tuple) else x + if self.has_proj: + if self.key_stride == 2: + x_s = self.c1x1_w_s2(x_in) + else: + x_s = self.c1x1_w_s1(x_in) + x_s1 = x_s[:, :self.num_1x1_c, :, :] + x_s2 = x_s[:, self.num_1x1_c:, :, :] + else: + x_s1 = x[0] + x_s2 = x[1] + x_in = self.c1x1_a(x_in) + x_in = self.c3x3_b(x_in) + if self.b: + x_in = self.c1x1_c(x_in) + out1 = self.c1x1_c1(x_in) + out2 = self.c1x1_c2(x_in) + else: + x_in = self.c1x1_c(x_in) + out1 = x_in[:, :self.num_1x1_c, :, :] + out2 = x_in[:, self.num_1x1_c:, :, :] + resid = x_s1 + out1 + dense = torch.cat([x_s2, out2], dim=1) + return resid, dense + + +class DPN(nn.Module): + def __init__(self, small=False, num_init_features=64, k_r=96, groups=32, + b=False, k_sec=(3, 4, 20, 3), inc_sec=(16, 32, 24, 128), + num_classes=1000, test_time_pool=False): + super(DPN, self).__init__() + self.test_time_pool = test_time_pool + self.b = b + bw_factor = 1 if small else 4 + + blocks = OrderedDict() + + # conv1 + if small: + blocks['conv1_1'] = InputBlock(num_init_features, kernel_size=3, padding=1) + else: + blocks['conv1_1'] = InputBlock(num_init_features, kernel_size=7, padding=3) + + # conv2 + bw = 64 * bw_factor + inc = inc_sec[0] + r = (k_r * bw) // (64 * bw_factor) + blocks['conv2_1'] = DualPathBlock(num_init_features, r, r, bw, inc, groups, 'proj', b) + in_chs = bw + 3 * inc + for i in range(2, k_sec[0] + 1): + blocks['conv2_' + str(i)] = DualPathBlock(in_chs, r, r, bw, inc, groups, 'normal', b) + in_chs += inc + + # conv3 + bw = 128 * bw_factor + inc = inc_sec[1] + r = (k_r * bw) // (64 * bw_factor) + blocks['conv3_1'] = DualPathBlock(in_chs, r, r, bw, inc, groups, 'down', b) + in_chs = bw + 3 * inc + for i in range(2, k_sec[1] + 1): + blocks['conv3_' + str(i)] = DualPathBlock(in_chs, r, r, bw, inc, groups, 'normal', b) + in_chs += inc + + # conv4 + bw = 256 * bw_factor + inc = inc_sec[2] + r = (k_r * bw) // (64 * bw_factor) + blocks['conv4_1'] = DualPathBlock(in_chs, r, r, bw, inc, groups, 'down', b) + in_chs = bw + 3 * inc + for i in range(2, k_sec[2] + 1): + blocks['conv4_' + str(i)] = DualPathBlock(in_chs, r, r, bw, inc, groups, 'normal', b) + in_chs += inc + + # conv5 + bw = 512 * bw_factor + inc = inc_sec[3] + r = (k_r * bw) // (64 * bw_factor) + blocks['conv5_1'] = DualPathBlock(in_chs, r, r, bw, inc, groups, 'down', b) + in_chs = bw + 3 * inc + for i in range(2, k_sec[3] + 1): + blocks['conv5_' + str(i)] = DualPathBlock(in_chs, r, r, bw, inc, groups, 'normal', b) + in_chs += inc + blocks['conv5_bn_ac'] = CatBnAct(in_chs) + + self.features = nn.Sequential(blocks) + + # Using 1x1 conv for the FC layer to allow the extra pooling scheme + self.last_linear = nn.Conv2d(in_chs, num_classes, kernel_size=1, bias=True) + + def logits(self, features): + if not self.training and self.test_time_pool: + x = F.avg_pool2d(features, kernel_size=7, stride=1) + out = self.last_linear(x) + # The extra test time pool should be pooling an img_size//32 - 6 size patch + out = adaptive_avgmax_pool2d(out, pool_type='avgmax') + else: + x = adaptive_avgmax_pool2d(features, pool_type='avg') + out = self.last_linear(x) + return out.view(out.size(0), -1) + + def forward(self, input): + x = self.features(input) + x = self.logits(x) + return x + +""" PyTorch selectable adaptive pooling +Adaptive pooling with the ability to select the type of pooling from: + * 'avg' - Average pooling + * 'max' - Max pooling + * 'avgmax' - Sum of average and max pooling re-scaled by 0.5 + * 'avgmaxc' - Concatenation of average and max pooling along feature dim, doubles feature dim + +Both a functional and a nn.Module version of the pooling is provided. + +Author: Ross Wightman (rwightman) +""" + +def pooling_factor(pool_type='avg'): + return 2 if pool_type == 'avgmaxc' else 1 + + +def adaptive_avgmax_pool2d(x, pool_type='avg', padding=0, count_include_pad=False): + """Selectable global pooling function with dynamic input kernel size + """ + if pool_type == 'avgmaxc': + x = torch.cat([ + F.avg_pool2d( + x, kernel_size=(x.size(2), x.size(3)), padding=padding, count_include_pad=count_include_pad), + F.max_pool2d(x, kernel_size=(x.size(2), x.size(3)), padding=padding) + ], dim=1) + elif pool_type == 'avgmax': + x_avg = F.avg_pool2d( + x, kernel_size=(x.size(2), x.size(3)), padding=padding, count_include_pad=count_include_pad) + x_max = F.max_pool2d(x, kernel_size=(x.size(2), x.size(3)), padding=padding) + x = 0.5 * (x_avg + x_max) + elif pool_type == 'max': + x = F.max_pool2d(x, kernel_size=(x.size(2), x.size(3)), padding=padding) + else: + if pool_type != 'avg': + print('Invalid pool type %s specified. Defaulting to average pooling.' % pool_type) + x = F.avg_pool2d( + x, kernel_size=(x.size(2), x.size(3)), padding=padding, count_include_pad=count_include_pad) + return x + + +class AdaptiveAvgMaxPool2d(torch.nn.Module): + """Selectable global pooling layer with dynamic input kernel size + """ + def __init__(self, output_size=1, pool_type='avg'): + super(AdaptiveAvgMaxPool2d, self).__init__() + self.output_size = output_size + self.pool_type = pool_type + if pool_type == 'avgmaxc' or pool_type == 'avgmax': + self.pool = nn.ModuleList([nn.AdaptiveAvgPool2d(output_size), nn.AdaptiveMaxPool2d(output_size)]) + elif pool_type == 'max': + self.pool = nn.AdaptiveMaxPool2d(output_size) + else: + if pool_type != 'avg': + print('Invalid pool type %s specified. Defaulting to average pooling.' % pool_type) + self.pool = nn.AdaptiveAvgPool2d(output_size) + + def forward(self, x): + if self.pool_type == 'avgmaxc': + x = torch.cat([p(x) for p in self.pool], dim=1) + elif self.pool_type == 'avgmax': + x = 0.5 * torch.sum(torch.stack([p(x) for p in self.pool]), 0).squeeze(dim=0) + else: + x = self.pool(x) + return x + + def factor(self): + return pooling_factor(self.pool_type) + + def __repr__(self): + return self.__class__.__name__ + ' (' \ + + 'output_size=' + str(self.output_size) \ + + ', pool_type=' + self.pool_type + ')' \ No newline at end of file diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/__init__.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..83c2392d25f9a1712560feeca181bf2969cdcf7e --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/__init__.py @@ -0,0 +1,58 @@ +from __future__ import print_function, division, absolute_import +from .fbresnet import fbresnet152 + +from .cafferesnet import cafferesnet101 + +from .bninception import bninception + +from .resnext import resnext101_32x4d +from .resnext import resnext101_64x4d + +from .inceptionv4 import inceptionv4 + +from .inceptionresnetv2 import inceptionresnetv2 + +from .nasnet import nasnetalarge + +from .nasnet_mobile import nasnetamobile + +from .torchvision_models import alexnet +from .torchvision_models import densenet121 +from .torchvision_models import densenet169 +from .torchvision_models import densenet201 +from .torchvision_models import densenet161 +from .torchvision_models import resnet18 +from .torchvision_models import resnet34 +from .torchvision_models import resnet50 +from .torchvision_models import resnet101 +from .torchvision_models import resnet152 +from .torchvision_models import inceptionv3 +from .torchvision_models import squeezenet1_0 +from .torchvision_models import squeezenet1_1 +from .torchvision_models import vgg11 +from .torchvision_models import vgg11_bn +from .torchvision_models import vgg13 +from .torchvision_models import vgg13_bn +from .torchvision_models import vgg16 +from .torchvision_models import vgg16_bn +from .torchvision_models import vgg19_bn +from .torchvision_models import vgg19 + +from .dpn import dpn68 +from .dpn import dpn68b +from .dpn import dpn92 +from .dpn import dpn98 +from .dpn import dpn131 +from .dpn import dpn107 + +from .xception import xception + +from .senet import senet154 +from .senet import se_resnet50 +from .senet import se_resnet101 +from .senet import se_resnet152 +from .senet import se_resnext50_32x4d +from .senet import se_resnext101_32x4d + +from .pnasnet import pnasnet5large +from .polynet import polynet diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/bninception.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/bninception.py new file mode 100644 index 0000000000000000000000000000000000000000..f6d65f5486e2b86fff6b99a65e1e6756217b0e40 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/bninception.py @@ -0,0 +1,527 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +from __future__ import print_function, division, absolute_import +import torch +import torch.nn as nn +import torch.nn.functional as F +import torch.utils.model_zoo as model_zoo +import os +import sys + +__all__ = ['BNInception', 'bninception'] + +pretrained_settings = { + 'bninception': { + 'imagenet': { + # Was ported using python2 (may trigger warning) + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/bn_inception-52deb4733.pth', + # 'url': 'http://yjxiong.me/others/bn_inception-9f5701afb96c8044.pth', + 'input_space': 'BGR', + 'input_size': [3, 224, 224], + 'input_range': [0, 255], + 'mean': [104, 117, 128], + 'std': [1, 1, 1], + 'num_classes': 1000 + } + } +} + +class BNInception(nn.Module): + + def __init__(self, num_classes=1000): + super(BNInception, self).__init__() + inplace = True + self.conv1_7x7_s2 = nn.Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3)) + self.conv1_7x7_s2_bn = nn.BatchNorm2d(64, affine=True) + self.conv1_relu_7x7 = nn.ReLU (inplace) + self.pool1_3x3_s2 = nn.MaxPool2d ((3, 3), stride=(2, 2), dilation=(1, 1), ceil_mode=True) + self.conv2_3x3_reduce = nn.Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1)) + self.conv2_3x3_reduce_bn = nn.BatchNorm2d(64, affine=True) + self.conv2_relu_3x3_reduce = nn.ReLU (inplace) + self.conv2_3x3 = nn.Conv2d(64, 192, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.conv2_3x3_bn = nn.BatchNorm2d(192, affine=True) + self.conv2_relu_3x3 = nn.ReLU (inplace) + self.pool2_3x3_s2 = nn.MaxPool2d ((3, 3), stride=(2, 2), dilation=(1, 1), ceil_mode=True) + self.inception_3a_1x1 = nn.Conv2d(192, 64, kernel_size=(1, 1), stride=(1, 1)) + self.inception_3a_1x1_bn = nn.BatchNorm2d(64, affine=True) + self.inception_3a_relu_1x1 = nn.ReLU (inplace) + self.inception_3a_3x3_reduce = nn.Conv2d(192, 64, kernel_size=(1, 1), stride=(1, 1)) + self.inception_3a_3x3_reduce_bn = nn.BatchNorm2d(64, affine=True) + self.inception_3a_relu_3x3_reduce = nn.ReLU (inplace) + self.inception_3a_3x3 = nn.Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_3a_3x3_bn = nn.BatchNorm2d(64, affine=True) + self.inception_3a_relu_3x3 = nn.ReLU (inplace) + self.inception_3a_double_3x3_reduce = nn.Conv2d(192, 64, kernel_size=(1, 1), stride=(1, 1)) + self.inception_3a_double_3x3_reduce_bn = nn.BatchNorm2d(64, affine=True) + self.inception_3a_relu_double_3x3_reduce = nn.ReLU (inplace) + self.inception_3a_double_3x3_1 = nn.Conv2d(64, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_3a_double_3x3_1_bn = nn.BatchNorm2d(96, affine=True) + self.inception_3a_relu_double_3x3_1 = nn.ReLU (inplace) + self.inception_3a_double_3x3_2 = nn.Conv2d(96, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_3a_double_3x3_2_bn = nn.BatchNorm2d(96, affine=True) + self.inception_3a_relu_double_3x3_2 = nn.ReLU (inplace) + self.inception_3a_pool = nn.AvgPool2d (3, stride=1, padding=1, ceil_mode=True, count_include_pad=True) + self.inception_3a_pool_proj = nn.Conv2d(192, 32, kernel_size=(1, 1), stride=(1, 1)) + self.inception_3a_pool_proj_bn = nn.BatchNorm2d(32, affine=True) + self.inception_3a_relu_pool_proj = nn.ReLU (inplace) + self.inception_3b_1x1 = nn.Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1)) + self.inception_3b_1x1_bn = nn.BatchNorm2d(64, affine=True) + self.inception_3b_relu_1x1 = nn.ReLU (inplace) + self.inception_3b_3x3_reduce = nn.Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1)) + self.inception_3b_3x3_reduce_bn = nn.BatchNorm2d(64, affine=True) + self.inception_3b_relu_3x3_reduce = nn.ReLU (inplace) + self.inception_3b_3x3 = nn.Conv2d(64, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_3b_3x3_bn = nn.BatchNorm2d(96, affine=True) + self.inception_3b_relu_3x3 = nn.ReLU (inplace) + self.inception_3b_double_3x3_reduce = nn.Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1)) + self.inception_3b_double_3x3_reduce_bn = nn.BatchNorm2d(64, affine=True) + self.inception_3b_relu_double_3x3_reduce = nn.ReLU (inplace) + self.inception_3b_double_3x3_1 = nn.Conv2d(64, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_3b_double_3x3_1_bn = nn.BatchNorm2d(96, affine=True) + self.inception_3b_relu_double_3x3_1 = nn.ReLU (inplace) + self.inception_3b_double_3x3_2 = nn.Conv2d(96, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_3b_double_3x3_2_bn = nn.BatchNorm2d(96, affine=True) + self.inception_3b_relu_double_3x3_2 = nn.ReLU (inplace) + self.inception_3b_pool = nn.AvgPool2d (3, stride=1, padding=1, ceil_mode=True, count_include_pad=True) + self.inception_3b_pool_proj = nn.Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1)) + self.inception_3b_pool_proj_bn = nn.BatchNorm2d(64, affine=True) + self.inception_3b_relu_pool_proj = nn.ReLU (inplace) + self.inception_3c_3x3_reduce = nn.Conv2d(320, 128, kernel_size=(1, 1), stride=(1, 1)) + self.inception_3c_3x3_reduce_bn = nn.BatchNorm2d(128, affine=True) + self.inception_3c_relu_3x3_reduce = nn.ReLU (inplace) + self.inception_3c_3x3 = nn.Conv2d(128, 160, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1)) + self.inception_3c_3x3_bn = nn.BatchNorm2d(160, affine=True) + self.inception_3c_relu_3x3 = nn.ReLU (inplace) + self.inception_3c_double_3x3_reduce = nn.Conv2d(320, 64, kernel_size=(1, 1), stride=(1, 1)) + self.inception_3c_double_3x3_reduce_bn = nn.BatchNorm2d(64, affine=True) + self.inception_3c_relu_double_3x3_reduce = nn.ReLU (inplace) + self.inception_3c_double_3x3_1 = nn.Conv2d(64, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_3c_double_3x3_1_bn = nn.BatchNorm2d(96, affine=True) + self.inception_3c_relu_double_3x3_1 = nn.ReLU (inplace) + self.inception_3c_double_3x3_2 = nn.Conv2d(96, 96, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1)) + self.inception_3c_double_3x3_2_bn = nn.BatchNorm2d(96, affine=True) + self.inception_3c_relu_double_3x3_2 = nn.ReLU (inplace) + self.inception_3c_pool = nn.MaxPool2d ((3, 3), stride=(2, 2), dilation=(1, 1), ceil_mode=True) + self.inception_4a_1x1 = nn.Conv2d(576, 224, kernel_size=(1, 1), stride=(1, 1)) + self.inception_4a_1x1_bn = nn.BatchNorm2d(224, affine=True) + self.inception_4a_relu_1x1 = nn.ReLU (inplace) + self.inception_4a_3x3_reduce = nn.Conv2d(576, 64, kernel_size=(1, 1), stride=(1, 1)) + self.inception_4a_3x3_reduce_bn = nn.BatchNorm2d(64, affine=True) + self.inception_4a_relu_3x3_reduce = nn.ReLU (inplace) + self.inception_4a_3x3 = nn.Conv2d(64, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_4a_3x3_bn = nn.BatchNorm2d(96, affine=True) + self.inception_4a_relu_3x3 = nn.ReLU (inplace) + self.inception_4a_double_3x3_reduce = nn.Conv2d(576, 96, kernel_size=(1, 1), stride=(1, 1)) + self.inception_4a_double_3x3_reduce_bn = nn.BatchNorm2d(96, affine=True) + self.inception_4a_relu_double_3x3_reduce = nn.ReLU (inplace) + self.inception_4a_double_3x3_1 = nn.Conv2d(96, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_4a_double_3x3_1_bn = nn.BatchNorm2d(128, affine=True) + self.inception_4a_relu_double_3x3_1 = nn.ReLU (inplace) + self.inception_4a_double_3x3_2 = nn.Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_4a_double_3x3_2_bn = nn.BatchNorm2d(128, affine=True) + self.inception_4a_relu_double_3x3_2 = nn.ReLU (inplace) + self.inception_4a_pool = nn.AvgPool2d (3, stride=1, padding=1, ceil_mode=True, count_include_pad=True) + self.inception_4a_pool_proj = nn.Conv2d(576, 128, kernel_size=(1, 1), stride=(1, 1)) + self.inception_4a_pool_proj_bn = nn.BatchNorm2d(128, affine=True) + self.inception_4a_relu_pool_proj = nn.ReLU (inplace) + self.inception_4b_1x1 = nn.Conv2d(576, 192, kernel_size=(1, 1), stride=(1, 1)) + self.inception_4b_1x1_bn = nn.BatchNorm2d(192, affine=True) + self.inception_4b_relu_1x1 = nn.ReLU (inplace) + self.inception_4b_3x3_reduce = nn.Conv2d(576, 96, kernel_size=(1, 1), stride=(1, 1)) + self.inception_4b_3x3_reduce_bn = nn.BatchNorm2d(96, affine=True) + self.inception_4b_relu_3x3_reduce = nn.ReLU (inplace) + self.inception_4b_3x3 = nn.Conv2d(96, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_4b_3x3_bn = nn.BatchNorm2d(128, affine=True) + self.inception_4b_relu_3x3 = nn.ReLU (inplace) + self.inception_4b_double_3x3_reduce = nn.Conv2d(576, 96, kernel_size=(1, 1), stride=(1, 1)) + self.inception_4b_double_3x3_reduce_bn = nn.BatchNorm2d(96, affine=True) + self.inception_4b_relu_double_3x3_reduce = nn.ReLU (inplace) + self.inception_4b_double_3x3_1 = nn.Conv2d(96, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_4b_double_3x3_1_bn = nn.BatchNorm2d(128, affine=True) + self.inception_4b_relu_double_3x3_1 = nn.ReLU (inplace) + self.inception_4b_double_3x3_2 = nn.Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_4b_double_3x3_2_bn = nn.BatchNorm2d(128, affine=True) + self.inception_4b_relu_double_3x3_2 = nn.ReLU (inplace) + self.inception_4b_pool = nn.AvgPool2d (3, stride=1, padding=1, ceil_mode=True, count_include_pad=True) + self.inception_4b_pool_proj = nn.Conv2d(576, 128, kernel_size=(1, 1), stride=(1, 1)) + self.inception_4b_pool_proj_bn = nn.BatchNorm2d(128, affine=True) + self.inception_4b_relu_pool_proj = nn.ReLU (inplace) + self.inception_4c_1x1 = nn.Conv2d(576, 160, kernel_size=(1, 1), stride=(1, 1)) + self.inception_4c_1x1_bn = nn.BatchNorm2d(160, affine=True) + self.inception_4c_relu_1x1 = nn.ReLU (inplace) + self.inception_4c_3x3_reduce = nn.Conv2d(576, 128, kernel_size=(1, 1), stride=(1, 1)) + self.inception_4c_3x3_reduce_bn = nn.BatchNorm2d(128, affine=True) + self.inception_4c_relu_3x3_reduce = nn.ReLU (inplace) + self.inception_4c_3x3 = nn.Conv2d(128, 160, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_4c_3x3_bn = nn.BatchNorm2d(160, affine=True) + self.inception_4c_relu_3x3 = nn.ReLU (inplace) + self.inception_4c_double_3x3_reduce = nn.Conv2d(576, 128, kernel_size=(1, 1), stride=(1, 1)) + self.inception_4c_double_3x3_reduce_bn = nn.BatchNorm2d(128, affine=True) + self.inception_4c_relu_double_3x3_reduce = nn.ReLU (inplace) + self.inception_4c_double_3x3_1 = nn.Conv2d(128, 160, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_4c_double_3x3_1_bn = nn.BatchNorm2d(160, affine=True) + self.inception_4c_relu_double_3x3_1 = nn.ReLU (inplace) + self.inception_4c_double_3x3_2 = nn.Conv2d(160, 160, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_4c_double_3x3_2_bn = nn.BatchNorm2d(160, affine=True) + self.inception_4c_relu_double_3x3_2 = nn.ReLU (inplace) + self.inception_4c_pool = nn.AvgPool2d (3, stride=1, padding=1, ceil_mode=True, count_include_pad=True) + self.inception_4c_pool_proj = nn.Conv2d(576, 128, kernel_size=(1, 1), stride=(1, 1)) + self.inception_4c_pool_proj_bn = nn.BatchNorm2d(128, affine=True) + self.inception_4c_relu_pool_proj = nn.ReLU (inplace) + self.inception_4d_1x1 = nn.Conv2d(608, 96, kernel_size=(1, 1), stride=(1, 1)) + self.inception_4d_1x1_bn = nn.BatchNorm2d(96, affine=True) + self.inception_4d_relu_1x1 = nn.ReLU (inplace) + self.inception_4d_3x3_reduce = nn.Conv2d(608, 128, kernel_size=(1, 1), stride=(1, 1)) + self.inception_4d_3x3_reduce_bn = nn.BatchNorm2d(128, affine=True) + self.inception_4d_relu_3x3_reduce = nn.ReLU (inplace) + self.inception_4d_3x3 = nn.Conv2d(128, 192, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_4d_3x3_bn = nn.BatchNorm2d(192, affine=True) + self.inception_4d_relu_3x3 = nn.ReLU (inplace) + self.inception_4d_double_3x3_reduce = nn.Conv2d(608, 160, kernel_size=(1, 1), stride=(1, 1)) + self.inception_4d_double_3x3_reduce_bn = nn.BatchNorm2d(160, affine=True) + self.inception_4d_relu_double_3x3_reduce = nn.ReLU (inplace) + self.inception_4d_double_3x3_1 = nn.Conv2d(160, 192, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_4d_double_3x3_1_bn = nn.BatchNorm2d(192, affine=True) + self.inception_4d_relu_double_3x3_1 = nn.ReLU (inplace) + self.inception_4d_double_3x3_2 = nn.Conv2d(192, 192, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_4d_double_3x3_2_bn = nn.BatchNorm2d(192, affine=True) + self.inception_4d_relu_double_3x3_2 = nn.ReLU (inplace) + self.inception_4d_pool = nn.AvgPool2d (3, stride=1, padding=1, ceil_mode=True, count_include_pad=True) + self.inception_4d_pool_proj = nn.Conv2d(608, 128, kernel_size=(1, 1), stride=(1, 1)) + self.inception_4d_pool_proj_bn = nn.BatchNorm2d(128, affine=True) + self.inception_4d_relu_pool_proj = nn.ReLU (inplace) + self.inception_4e_3x3_reduce = nn.Conv2d(608, 128, kernel_size=(1, 1), stride=(1, 1)) + self.inception_4e_3x3_reduce_bn = nn.BatchNorm2d(128, affine=True) + self.inception_4e_relu_3x3_reduce = nn.ReLU (inplace) + self.inception_4e_3x3 = nn.Conv2d(128, 192, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1)) + self.inception_4e_3x3_bn = nn.BatchNorm2d(192, affine=True) + self.inception_4e_relu_3x3 = nn.ReLU (inplace) + self.inception_4e_double_3x3_reduce = nn.Conv2d(608, 192, kernel_size=(1, 1), stride=(1, 1)) + self.inception_4e_double_3x3_reduce_bn = nn.BatchNorm2d(192, affine=True) + self.inception_4e_relu_double_3x3_reduce = nn.ReLU (inplace) + self.inception_4e_double_3x3_1 = nn.Conv2d(192, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_4e_double_3x3_1_bn = nn.BatchNorm2d(256, affine=True) + self.inception_4e_relu_double_3x3_1 = nn.ReLU (inplace) + self.inception_4e_double_3x3_2 = nn.Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1)) + self.inception_4e_double_3x3_2_bn = nn.BatchNorm2d(256, affine=True) + self.inception_4e_relu_double_3x3_2 = nn.ReLU (inplace) + self.inception_4e_pool = nn.MaxPool2d ((3, 3), stride=(2, 2), dilation=(1, 1), ceil_mode=True) + self.inception_5a_1x1 = nn.Conv2d(1056, 352, kernel_size=(1, 1), stride=(1, 1)) + self.inception_5a_1x1_bn = nn.BatchNorm2d(352, affine=True) + self.inception_5a_relu_1x1 = nn.ReLU (inplace) + self.inception_5a_3x3_reduce = nn.Conv2d(1056, 192, kernel_size=(1, 1), stride=(1, 1)) + self.inception_5a_3x3_reduce_bn = nn.BatchNorm2d(192, affine=True) + self.inception_5a_relu_3x3_reduce = nn.ReLU (inplace) + self.inception_5a_3x3 = nn.Conv2d(192, 320, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_5a_3x3_bn = nn.BatchNorm2d(320, affine=True) + self.inception_5a_relu_3x3 = nn.ReLU (inplace) + self.inception_5a_double_3x3_reduce = nn.Conv2d(1056, 160, kernel_size=(1, 1), stride=(1, 1)) + self.inception_5a_double_3x3_reduce_bn = nn.BatchNorm2d(160, affine=True) + self.inception_5a_relu_double_3x3_reduce = nn.ReLU (inplace) + self.inception_5a_double_3x3_1 = nn.Conv2d(160, 224, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_5a_double_3x3_1_bn = nn.BatchNorm2d(224, affine=True) + self.inception_5a_relu_double_3x3_1 = nn.ReLU (inplace) + self.inception_5a_double_3x3_2 = nn.Conv2d(224, 224, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_5a_double_3x3_2_bn = nn.BatchNorm2d(224, affine=True) + self.inception_5a_relu_double_3x3_2 = nn.ReLU (inplace) + self.inception_5a_pool = nn.AvgPool2d (3, stride=1, padding=1, ceil_mode=True, count_include_pad=True) + self.inception_5a_pool_proj = nn.Conv2d(1056, 128, kernel_size=(1, 1), stride=(1, 1)) + self.inception_5a_pool_proj_bn = nn.BatchNorm2d(128, affine=True) + self.inception_5a_relu_pool_proj = nn.ReLU (inplace) + self.inception_5b_1x1 = nn.Conv2d(1024, 352, kernel_size=(1, 1), stride=(1, 1)) + self.inception_5b_1x1_bn = nn.BatchNorm2d(352, affine=True) + self.inception_5b_relu_1x1 = nn.ReLU (inplace) + self.inception_5b_3x3_reduce = nn.Conv2d(1024, 192, kernel_size=(1, 1), stride=(1, 1)) + self.inception_5b_3x3_reduce_bn = nn.BatchNorm2d(192, affine=True) + self.inception_5b_relu_3x3_reduce = nn.ReLU (inplace) + self.inception_5b_3x3 = nn.Conv2d(192, 320, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_5b_3x3_bn = nn.BatchNorm2d(320, affine=True) + self.inception_5b_relu_3x3 = nn.ReLU (inplace) + self.inception_5b_double_3x3_reduce = nn.Conv2d(1024, 192, kernel_size=(1, 1), stride=(1, 1)) + self.inception_5b_double_3x3_reduce_bn = nn.BatchNorm2d(192, affine=True) + self.inception_5b_relu_double_3x3_reduce = nn.ReLU (inplace) + self.inception_5b_double_3x3_1 = nn.Conv2d(192, 224, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_5b_double_3x3_1_bn = nn.BatchNorm2d(224, affine=True) + self.inception_5b_relu_double_3x3_1 = nn.ReLU (inplace) + self.inception_5b_double_3x3_2 = nn.Conv2d(224, 224, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) + self.inception_5b_double_3x3_2_bn = nn.BatchNorm2d(224, affine=True) + self.inception_5b_relu_double_3x3_2 = nn.ReLU (inplace) + self.inception_5b_pool = nn.MaxPool2d ((3, 3), stride=(1, 1), padding=(1, 1), dilation=(1, 1), ceil_mode=True) + self.inception_5b_pool_proj = nn.Conv2d(1024, 128, kernel_size=(1, 1), stride=(1, 1)) + self.inception_5b_pool_proj_bn = nn.BatchNorm2d(128, affine=True) + self.inception_5b_relu_pool_proj = nn.ReLU (inplace) + self.last_linear = nn.Linear (1024, num_classes) + + def features(self, input): + conv1_7x7_s2_out = self.conv1_7x7_s2(input) + conv1_7x7_s2_bn_out = self.conv1_7x7_s2_bn(conv1_7x7_s2_out) + conv1_relu_7x7_out = self.conv1_relu_7x7(conv1_7x7_s2_bn_out) + pool1_3x3_s2_out = self.pool1_3x3_s2(conv1_relu_7x7_out) + conv2_3x3_reduce_out = self.conv2_3x3_reduce(pool1_3x3_s2_out) + conv2_3x3_reduce_bn_out = self.conv2_3x3_reduce_bn(conv2_3x3_reduce_out) + conv2_relu_3x3_reduce_out = self.conv2_relu_3x3_reduce(conv2_3x3_reduce_bn_out) + conv2_3x3_out = self.conv2_3x3(conv2_relu_3x3_reduce_out) + conv2_3x3_bn_out = self.conv2_3x3_bn(conv2_3x3_out) + conv2_relu_3x3_out = self.conv2_relu_3x3(conv2_3x3_bn_out) + pool2_3x3_s2_out = self.pool2_3x3_s2(conv2_relu_3x3_out) + inception_3a_1x1_out = self.inception_3a_1x1(pool2_3x3_s2_out) + inception_3a_1x1_bn_out = self.inception_3a_1x1_bn(inception_3a_1x1_out) + inception_3a_relu_1x1_out = self.inception_3a_relu_1x1(inception_3a_1x1_bn_out) + inception_3a_3x3_reduce_out = self.inception_3a_3x3_reduce(pool2_3x3_s2_out) + inception_3a_3x3_reduce_bn_out = self.inception_3a_3x3_reduce_bn(inception_3a_3x3_reduce_out) + inception_3a_relu_3x3_reduce_out = self.inception_3a_relu_3x3_reduce(inception_3a_3x3_reduce_bn_out) + inception_3a_3x3_out = self.inception_3a_3x3(inception_3a_relu_3x3_reduce_out) + inception_3a_3x3_bn_out = self.inception_3a_3x3_bn(inception_3a_3x3_out) + inception_3a_relu_3x3_out = self.inception_3a_relu_3x3(inception_3a_3x3_bn_out) + inception_3a_double_3x3_reduce_out = self.inception_3a_double_3x3_reduce(pool2_3x3_s2_out) + inception_3a_double_3x3_reduce_bn_out = self.inception_3a_double_3x3_reduce_bn(inception_3a_double_3x3_reduce_out) + inception_3a_relu_double_3x3_reduce_out = self.inception_3a_relu_double_3x3_reduce(inception_3a_double_3x3_reduce_bn_out) + inception_3a_double_3x3_1_out = self.inception_3a_double_3x3_1(inception_3a_relu_double_3x3_reduce_out) + inception_3a_double_3x3_1_bn_out = self.inception_3a_double_3x3_1_bn(inception_3a_double_3x3_1_out) + inception_3a_relu_double_3x3_1_out = self.inception_3a_relu_double_3x3_1(inception_3a_double_3x3_1_bn_out) + inception_3a_double_3x3_2_out = self.inception_3a_double_3x3_2(inception_3a_relu_double_3x3_1_out) + inception_3a_double_3x3_2_bn_out = self.inception_3a_double_3x3_2_bn(inception_3a_double_3x3_2_out) + inception_3a_relu_double_3x3_2_out = self.inception_3a_relu_double_3x3_2(inception_3a_double_3x3_2_bn_out) + inception_3a_pool_out = self.inception_3a_pool(pool2_3x3_s2_out) + inception_3a_pool_proj_out = self.inception_3a_pool_proj(inception_3a_pool_out) + inception_3a_pool_proj_bn_out = self.inception_3a_pool_proj_bn(inception_3a_pool_proj_out) + inception_3a_relu_pool_proj_out = self.inception_3a_relu_pool_proj(inception_3a_pool_proj_bn_out) + inception_3a_output_out = torch.cat([inception_3a_relu_1x1_out,inception_3a_relu_3x3_out,inception_3a_relu_double_3x3_2_out ,inception_3a_relu_pool_proj_out], 1) + inception_3b_1x1_out = self.inception_3b_1x1(inception_3a_output_out) + inception_3b_1x1_bn_out = self.inception_3b_1x1_bn(inception_3b_1x1_out) + inception_3b_relu_1x1_out = self.inception_3b_relu_1x1(inception_3b_1x1_bn_out) + inception_3b_3x3_reduce_out = self.inception_3b_3x3_reduce(inception_3a_output_out) + inception_3b_3x3_reduce_bn_out = self.inception_3b_3x3_reduce_bn(inception_3b_3x3_reduce_out) + inception_3b_relu_3x3_reduce_out = self.inception_3b_relu_3x3_reduce(inception_3b_3x3_reduce_bn_out) + inception_3b_3x3_out = self.inception_3b_3x3(inception_3b_relu_3x3_reduce_out) + inception_3b_3x3_bn_out = self.inception_3b_3x3_bn(inception_3b_3x3_out) + inception_3b_relu_3x3_out = self.inception_3b_relu_3x3(inception_3b_3x3_bn_out) + inception_3b_double_3x3_reduce_out = self.inception_3b_double_3x3_reduce(inception_3a_output_out) + inception_3b_double_3x3_reduce_bn_out = self.inception_3b_double_3x3_reduce_bn(inception_3b_double_3x3_reduce_out) + inception_3b_relu_double_3x3_reduce_out = self.inception_3b_relu_double_3x3_reduce(inception_3b_double_3x3_reduce_bn_out) + inception_3b_double_3x3_1_out = self.inception_3b_double_3x3_1(inception_3b_relu_double_3x3_reduce_out) + inception_3b_double_3x3_1_bn_out = self.inception_3b_double_3x3_1_bn(inception_3b_double_3x3_1_out) + inception_3b_relu_double_3x3_1_out = self.inception_3b_relu_double_3x3_1(inception_3b_double_3x3_1_bn_out) + inception_3b_double_3x3_2_out = self.inception_3b_double_3x3_2(inception_3b_relu_double_3x3_1_out) + inception_3b_double_3x3_2_bn_out = self.inception_3b_double_3x3_2_bn(inception_3b_double_3x3_2_out) + inception_3b_relu_double_3x3_2_out = self.inception_3b_relu_double_3x3_2(inception_3b_double_3x3_2_bn_out) + inception_3b_pool_out = self.inception_3b_pool(inception_3a_output_out) + inception_3b_pool_proj_out = self.inception_3b_pool_proj(inception_3b_pool_out) + inception_3b_pool_proj_bn_out = self.inception_3b_pool_proj_bn(inception_3b_pool_proj_out) + inception_3b_relu_pool_proj_out = self.inception_3b_relu_pool_proj(inception_3b_pool_proj_bn_out) + inception_3b_output_out = torch.cat([inception_3b_relu_1x1_out,inception_3b_relu_3x3_out,inception_3b_relu_double_3x3_2_out,inception_3b_relu_pool_proj_out], 1) + inception_3c_3x3_reduce_out = self.inception_3c_3x3_reduce(inception_3b_output_out) + inception_3c_3x3_reduce_bn_out = self.inception_3c_3x3_reduce_bn(inception_3c_3x3_reduce_out) + inception_3c_relu_3x3_reduce_out = self.inception_3c_relu_3x3_reduce(inception_3c_3x3_reduce_bn_out) + inception_3c_3x3_out = self.inception_3c_3x3(inception_3c_relu_3x3_reduce_out) + inception_3c_3x3_bn_out = self.inception_3c_3x3_bn(inception_3c_3x3_out) + inception_3c_relu_3x3_out = self.inception_3c_relu_3x3(inception_3c_3x3_bn_out) + inception_3c_double_3x3_reduce_out = self.inception_3c_double_3x3_reduce(inception_3b_output_out) + inception_3c_double_3x3_reduce_bn_out = self.inception_3c_double_3x3_reduce_bn(inception_3c_double_3x3_reduce_out) + inception_3c_relu_double_3x3_reduce_out = self.inception_3c_relu_double_3x3_reduce(inception_3c_double_3x3_reduce_bn_out) + inception_3c_double_3x3_1_out = self.inception_3c_double_3x3_1(inception_3c_relu_double_3x3_reduce_out) + inception_3c_double_3x3_1_bn_out = self.inception_3c_double_3x3_1_bn(inception_3c_double_3x3_1_out) + inception_3c_relu_double_3x3_1_out = self.inception_3c_relu_double_3x3_1(inception_3c_double_3x3_1_bn_out) + inception_3c_double_3x3_2_out = self.inception_3c_double_3x3_2(inception_3c_relu_double_3x3_1_out) + inception_3c_double_3x3_2_bn_out = self.inception_3c_double_3x3_2_bn(inception_3c_double_3x3_2_out) + inception_3c_relu_double_3x3_2_out = self.inception_3c_relu_double_3x3_2(inception_3c_double_3x3_2_bn_out) + inception_3c_pool_out = self.inception_3c_pool(inception_3b_output_out) + inception_3c_output_out = torch.cat([inception_3c_relu_3x3_out,inception_3c_relu_double_3x3_2_out,inception_3c_pool_out], 1) + inception_4a_1x1_out = self.inception_4a_1x1(inception_3c_output_out) + inception_4a_1x1_bn_out = self.inception_4a_1x1_bn(inception_4a_1x1_out) + inception_4a_relu_1x1_out = self.inception_4a_relu_1x1(inception_4a_1x1_bn_out) + inception_4a_3x3_reduce_out = self.inception_4a_3x3_reduce(inception_3c_output_out) + inception_4a_3x3_reduce_bn_out = self.inception_4a_3x3_reduce_bn(inception_4a_3x3_reduce_out) + inception_4a_relu_3x3_reduce_out = self.inception_4a_relu_3x3_reduce(inception_4a_3x3_reduce_bn_out) + inception_4a_3x3_out = self.inception_4a_3x3(inception_4a_relu_3x3_reduce_out) + inception_4a_3x3_bn_out = self.inception_4a_3x3_bn(inception_4a_3x3_out) + inception_4a_relu_3x3_out = self.inception_4a_relu_3x3(inception_4a_3x3_bn_out) + inception_4a_double_3x3_reduce_out = self.inception_4a_double_3x3_reduce(inception_3c_output_out) + inception_4a_double_3x3_reduce_bn_out = self.inception_4a_double_3x3_reduce_bn(inception_4a_double_3x3_reduce_out) + inception_4a_relu_double_3x3_reduce_out = self.inception_4a_relu_double_3x3_reduce(inception_4a_double_3x3_reduce_bn_out) + inception_4a_double_3x3_1_out = self.inception_4a_double_3x3_1(inception_4a_relu_double_3x3_reduce_out) + inception_4a_double_3x3_1_bn_out = self.inception_4a_double_3x3_1_bn(inception_4a_double_3x3_1_out) + inception_4a_relu_double_3x3_1_out = self.inception_4a_relu_double_3x3_1(inception_4a_double_3x3_1_bn_out) + inception_4a_double_3x3_2_out = self.inception_4a_double_3x3_2(inception_4a_relu_double_3x3_1_out) + inception_4a_double_3x3_2_bn_out = self.inception_4a_double_3x3_2_bn(inception_4a_double_3x3_2_out) + inception_4a_relu_double_3x3_2_out = self.inception_4a_relu_double_3x3_2(inception_4a_double_3x3_2_bn_out) + inception_4a_pool_out = self.inception_4a_pool(inception_3c_output_out) + inception_4a_pool_proj_out = self.inception_4a_pool_proj(inception_4a_pool_out) + inception_4a_pool_proj_bn_out = self.inception_4a_pool_proj_bn(inception_4a_pool_proj_out) + inception_4a_relu_pool_proj_out = self.inception_4a_relu_pool_proj(inception_4a_pool_proj_bn_out) + inception_4a_output_out = torch.cat([inception_4a_relu_1x1_out,inception_4a_relu_3x3_out,inception_4a_relu_double_3x3_2_out,inception_4a_relu_pool_proj_out], 1) + inception_4b_1x1_out = self.inception_4b_1x1(inception_4a_output_out) + inception_4b_1x1_bn_out = self.inception_4b_1x1_bn(inception_4b_1x1_out) + inception_4b_relu_1x1_out = self.inception_4b_relu_1x1(inception_4b_1x1_bn_out) + inception_4b_3x3_reduce_out = self.inception_4b_3x3_reduce(inception_4a_output_out) + inception_4b_3x3_reduce_bn_out = self.inception_4b_3x3_reduce_bn(inception_4b_3x3_reduce_out) + inception_4b_relu_3x3_reduce_out = self.inception_4b_relu_3x3_reduce(inception_4b_3x3_reduce_bn_out) + inception_4b_3x3_out = self.inception_4b_3x3(inception_4b_relu_3x3_reduce_out) + inception_4b_3x3_bn_out = self.inception_4b_3x3_bn(inception_4b_3x3_out) + inception_4b_relu_3x3_out = self.inception_4b_relu_3x3(inception_4b_3x3_bn_out) + inception_4b_double_3x3_reduce_out = self.inception_4b_double_3x3_reduce(inception_4a_output_out) + inception_4b_double_3x3_reduce_bn_out = self.inception_4b_double_3x3_reduce_bn(inception_4b_double_3x3_reduce_out) + inception_4b_relu_double_3x3_reduce_out = self.inception_4b_relu_double_3x3_reduce(inception_4b_double_3x3_reduce_bn_out) + inception_4b_double_3x3_1_out = self.inception_4b_double_3x3_1(inception_4b_relu_double_3x3_reduce_out) + inception_4b_double_3x3_1_bn_out = self.inception_4b_double_3x3_1_bn(inception_4b_double_3x3_1_out) + inception_4b_relu_double_3x3_1_out = self.inception_4b_relu_double_3x3_1(inception_4b_double_3x3_1_bn_out) + inception_4b_double_3x3_2_out = self.inception_4b_double_3x3_2(inception_4b_relu_double_3x3_1_out) + inception_4b_double_3x3_2_bn_out = self.inception_4b_double_3x3_2_bn(inception_4b_double_3x3_2_out) + inception_4b_relu_double_3x3_2_out = self.inception_4b_relu_double_3x3_2(inception_4b_double_3x3_2_bn_out) + inception_4b_pool_out = self.inception_4b_pool(inception_4a_output_out) + inception_4b_pool_proj_out = self.inception_4b_pool_proj(inception_4b_pool_out) + inception_4b_pool_proj_bn_out = self.inception_4b_pool_proj_bn(inception_4b_pool_proj_out) + inception_4b_relu_pool_proj_out = self.inception_4b_relu_pool_proj(inception_4b_pool_proj_bn_out) + inception_4b_output_out = torch.cat([inception_4b_relu_1x1_out,inception_4b_relu_3x3_out,inception_4b_relu_double_3x3_2_out,inception_4b_relu_pool_proj_out], 1) + inception_4c_1x1_out = self.inception_4c_1x1(inception_4b_output_out) + inception_4c_1x1_bn_out = self.inception_4c_1x1_bn(inception_4c_1x1_out) + inception_4c_relu_1x1_out = self.inception_4c_relu_1x1(inception_4c_1x1_bn_out) + inception_4c_3x3_reduce_out = self.inception_4c_3x3_reduce(inception_4b_output_out) + inception_4c_3x3_reduce_bn_out = self.inception_4c_3x3_reduce_bn(inception_4c_3x3_reduce_out) + inception_4c_relu_3x3_reduce_out = self.inception_4c_relu_3x3_reduce(inception_4c_3x3_reduce_bn_out) + inception_4c_3x3_out = self.inception_4c_3x3(inception_4c_relu_3x3_reduce_out) + inception_4c_3x3_bn_out = self.inception_4c_3x3_bn(inception_4c_3x3_out) + inception_4c_relu_3x3_out = self.inception_4c_relu_3x3(inception_4c_3x3_bn_out) + inception_4c_double_3x3_reduce_out = self.inception_4c_double_3x3_reduce(inception_4b_output_out) + inception_4c_double_3x3_reduce_bn_out = self.inception_4c_double_3x3_reduce_bn(inception_4c_double_3x3_reduce_out) + inception_4c_relu_double_3x3_reduce_out = self.inception_4c_relu_double_3x3_reduce(inception_4c_double_3x3_reduce_bn_out) + inception_4c_double_3x3_1_out = self.inception_4c_double_3x3_1(inception_4c_relu_double_3x3_reduce_out) + inception_4c_double_3x3_1_bn_out = self.inception_4c_double_3x3_1_bn(inception_4c_double_3x3_1_out) + inception_4c_relu_double_3x3_1_out = self.inception_4c_relu_double_3x3_1(inception_4c_double_3x3_1_bn_out) + inception_4c_double_3x3_2_out = self.inception_4c_double_3x3_2(inception_4c_relu_double_3x3_1_out) + inception_4c_double_3x3_2_bn_out = self.inception_4c_double_3x3_2_bn(inception_4c_double_3x3_2_out) + inception_4c_relu_double_3x3_2_out = self.inception_4c_relu_double_3x3_2(inception_4c_double_3x3_2_bn_out) + inception_4c_pool_out = self.inception_4c_pool(inception_4b_output_out) + inception_4c_pool_proj_out = self.inception_4c_pool_proj(inception_4c_pool_out) + inception_4c_pool_proj_bn_out = self.inception_4c_pool_proj_bn(inception_4c_pool_proj_out) + inception_4c_relu_pool_proj_out = self.inception_4c_relu_pool_proj(inception_4c_pool_proj_bn_out) + inception_4c_output_out = torch.cat([inception_4c_relu_1x1_out,inception_4c_relu_3x3_out,inception_4c_relu_double_3x3_2_out,inception_4c_relu_pool_proj_out], 1) + inception_4d_1x1_out = self.inception_4d_1x1(inception_4c_output_out) + inception_4d_1x1_bn_out = self.inception_4d_1x1_bn(inception_4d_1x1_out) + inception_4d_relu_1x1_out = self.inception_4d_relu_1x1(inception_4d_1x1_bn_out) + inception_4d_3x3_reduce_out = self.inception_4d_3x3_reduce(inception_4c_output_out) + inception_4d_3x3_reduce_bn_out = self.inception_4d_3x3_reduce_bn(inception_4d_3x3_reduce_out) + inception_4d_relu_3x3_reduce_out = self.inception_4d_relu_3x3_reduce(inception_4d_3x3_reduce_bn_out) + inception_4d_3x3_out = self.inception_4d_3x3(inception_4d_relu_3x3_reduce_out) + inception_4d_3x3_bn_out = self.inception_4d_3x3_bn(inception_4d_3x3_out) + inception_4d_relu_3x3_out = self.inception_4d_relu_3x3(inception_4d_3x3_bn_out) + inception_4d_double_3x3_reduce_out = self.inception_4d_double_3x3_reduce(inception_4c_output_out) + inception_4d_double_3x3_reduce_bn_out = self.inception_4d_double_3x3_reduce_bn(inception_4d_double_3x3_reduce_out) + inception_4d_relu_double_3x3_reduce_out = self.inception_4d_relu_double_3x3_reduce(inception_4d_double_3x3_reduce_bn_out) + inception_4d_double_3x3_1_out = self.inception_4d_double_3x3_1(inception_4d_relu_double_3x3_reduce_out) + inception_4d_double_3x3_1_bn_out = self.inception_4d_double_3x3_1_bn(inception_4d_double_3x3_1_out) + inception_4d_relu_double_3x3_1_out = self.inception_4d_relu_double_3x3_1(inception_4d_double_3x3_1_bn_out) + inception_4d_double_3x3_2_out = self.inception_4d_double_3x3_2(inception_4d_relu_double_3x3_1_out) + inception_4d_double_3x3_2_bn_out = self.inception_4d_double_3x3_2_bn(inception_4d_double_3x3_2_out) + inception_4d_relu_double_3x3_2_out = self.inception_4d_relu_double_3x3_2(inception_4d_double_3x3_2_bn_out) + inception_4d_pool_out = self.inception_4d_pool(inception_4c_output_out) + inception_4d_pool_proj_out = self.inception_4d_pool_proj(inception_4d_pool_out) + inception_4d_pool_proj_bn_out = self.inception_4d_pool_proj_bn(inception_4d_pool_proj_out) + inception_4d_relu_pool_proj_out = self.inception_4d_relu_pool_proj(inception_4d_pool_proj_bn_out) + inception_4d_output_out = torch.cat([inception_4d_relu_1x1_out,inception_4d_relu_3x3_out,inception_4d_relu_double_3x3_2_out,inception_4d_relu_pool_proj_out], 1) + inception_4e_3x3_reduce_out = self.inception_4e_3x3_reduce(inception_4d_output_out) + inception_4e_3x3_reduce_bn_out = self.inception_4e_3x3_reduce_bn(inception_4e_3x3_reduce_out) + inception_4e_relu_3x3_reduce_out = self.inception_4e_relu_3x3_reduce(inception_4e_3x3_reduce_bn_out) + inception_4e_3x3_out = self.inception_4e_3x3(inception_4e_relu_3x3_reduce_out) + inception_4e_3x3_bn_out = self.inception_4e_3x3_bn(inception_4e_3x3_out) + inception_4e_relu_3x3_out = self.inception_4e_relu_3x3(inception_4e_3x3_bn_out) + inception_4e_double_3x3_reduce_out = self.inception_4e_double_3x3_reduce(inception_4d_output_out) + inception_4e_double_3x3_reduce_bn_out = self.inception_4e_double_3x3_reduce_bn(inception_4e_double_3x3_reduce_out) + inception_4e_relu_double_3x3_reduce_out = self.inception_4e_relu_double_3x3_reduce(inception_4e_double_3x3_reduce_bn_out) + inception_4e_double_3x3_1_out = self.inception_4e_double_3x3_1(inception_4e_relu_double_3x3_reduce_out) + inception_4e_double_3x3_1_bn_out = self.inception_4e_double_3x3_1_bn(inception_4e_double_3x3_1_out) + inception_4e_relu_double_3x3_1_out = self.inception_4e_relu_double_3x3_1(inception_4e_double_3x3_1_bn_out) + inception_4e_double_3x3_2_out = self.inception_4e_double_3x3_2(inception_4e_relu_double_3x3_1_out) + inception_4e_double_3x3_2_bn_out = self.inception_4e_double_3x3_2_bn(inception_4e_double_3x3_2_out) + inception_4e_relu_double_3x3_2_out = self.inception_4e_relu_double_3x3_2(inception_4e_double_3x3_2_bn_out) + inception_4e_pool_out = self.inception_4e_pool(inception_4d_output_out) + inception_4e_output_out = torch.cat([inception_4e_relu_3x3_out,inception_4e_relu_double_3x3_2_out,inception_4e_pool_out], 1) + inception_5a_1x1_out = self.inception_5a_1x1(inception_4e_output_out) + inception_5a_1x1_bn_out = self.inception_5a_1x1_bn(inception_5a_1x1_out) + inception_5a_relu_1x1_out = self.inception_5a_relu_1x1(inception_5a_1x1_bn_out) + inception_5a_3x3_reduce_out = self.inception_5a_3x3_reduce(inception_4e_output_out) + inception_5a_3x3_reduce_bn_out = self.inception_5a_3x3_reduce_bn(inception_5a_3x3_reduce_out) + inception_5a_relu_3x3_reduce_out = self.inception_5a_relu_3x3_reduce(inception_5a_3x3_reduce_bn_out) + inception_5a_3x3_out = self.inception_5a_3x3(inception_5a_relu_3x3_reduce_out) + inception_5a_3x3_bn_out = self.inception_5a_3x3_bn(inception_5a_3x3_out) + inception_5a_relu_3x3_out = self.inception_5a_relu_3x3(inception_5a_3x3_bn_out) + inception_5a_double_3x3_reduce_out = self.inception_5a_double_3x3_reduce(inception_4e_output_out) + inception_5a_double_3x3_reduce_bn_out = self.inception_5a_double_3x3_reduce_bn(inception_5a_double_3x3_reduce_out) + inception_5a_relu_double_3x3_reduce_out = self.inception_5a_relu_double_3x3_reduce(inception_5a_double_3x3_reduce_bn_out) + inception_5a_double_3x3_1_out = self.inception_5a_double_3x3_1(inception_5a_relu_double_3x3_reduce_out) + inception_5a_double_3x3_1_bn_out = self.inception_5a_double_3x3_1_bn(inception_5a_double_3x3_1_out) + inception_5a_relu_double_3x3_1_out = self.inception_5a_relu_double_3x3_1(inception_5a_double_3x3_1_bn_out) + inception_5a_double_3x3_2_out = self.inception_5a_double_3x3_2(inception_5a_relu_double_3x3_1_out) + inception_5a_double_3x3_2_bn_out = self.inception_5a_double_3x3_2_bn(inception_5a_double_3x3_2_out) + inception_5a_relu_double_3x3_2_out = self.inception_5a_relu_double_3x3_2(inception_5a_double_3x3_2_bn_out) + inception_5a_pool_out = self.inception_5a_pool(inception_4e_output_out) + inception_5a_pool_proj_out = self.inception_5a_pool_proj(inception_5a_pool_out) + inception_5a_pool_proj_bn_out = self.inception_5a_pool_proj_bn(inception_5a_pool_proj_out) + inception_5a_relu_pool_proj_out = self.inception_5a_relu_pool_proj(inception_5a_pool_proj_bn_out) + inception_5a_output_out = torch.cat([inception_5a_relu_1x1_out,inception_5a_relu_3x3_out,inception_5a_relu_double_3x3_2_out,inception_5a_relu_pool_proj_out], 1) + inception_5b_1x1_out = self.inception_5b_1x1(inception_5a_output_out) + inception_5b_1x1_bn_out = self.inception_5b_1x1_bn(inception_5b_1x1_out) + inception_5b_relu_1x1_out = self.inception_5b_relu_1x1(inception_5b_1x1_bn_out) + inception_5b_3x3_reduce_out = self.inception_5b_3x3_reduce(inception_5a_output_out) + inception_5b_3x3_reduce_bn_out = self.inception_5b_3x3_reduce_bn(inception_5b_3x3_reduce_out) + inception_5b_relu_3x3_reduce_out = self.inception_5b_relu_3x3_reduce(inception_5b_3x3_reduce_bn_out) + inception_5b_3x3_out = self.inception_5b_3x3(inception_5b_relu_3x3_reduce_out) + inception_5b_3x3_bn_out = self.inception_5b_3x3_bn(inception_5b_3x3_out) + inception_5b_relu_3x3_out = self.inception_5b_relu_3x3(inception_5b_3x3_bn_out) + inception_5b_double_3x3_reduce_out = self.inception_5b_double_3x3_reduce(inception_5a_output_out) + inception_5b_double_3x3_reduce_bn_out = self.inception_5b_double_3x3_reduce_bn(inception_5b_double_3x3_reduce_out) + inception_5b_relu_double_3x3_reduce_out = self.inception_5b_relu_double_3x3_reduce(inception_5b_double_3x3_reduce_bn_out) + inception_5b_double_3x3_1_out = self.inception_5b_double_3x3_1(inception_5b_relu_double_3x3_reduce_out) + inception_5b_double_3x3_1_bn_out = self.inception_5b_double_3x3_1_bn(inception_5b_double_3x3_1_out) + inception_5b_relu_double_3x3_1_out = self.inception_5b_relu_double_3x3_1(inception_5b_double_3x3_1_bn_out) + inception_5b_double_3x3_2_out = self.inception_5b_double_3x3_2(inception_5b_relu_double_3x3_1_out) + inception_5b_double_3x3_2_bn_out = self.inception_5b_double_3x3_2_bn(inception_5b_double_3x3_2_out) + inception_5b_relu_double_3x3_2_out = self.inception_5b_relu_double_3x3_2(inception_5b_double_3x3_2_bn_out) + inception_5b_pool_out = self.inception_5b_pool(inception_5a_output_out) + inception_5b_pool_proj_out = self.inception_5b_pool_proj(inception_5b_pool_out) + inception_5b_pool_proj_bn_out = self.inception_5b_pool_proj_bn(inception_5b_pool_proj_out) + inception_5b_relu_pool_proj_out = self.inception_5b_relu_pool_proj(inception_5b_pool_proj_bn_out) + inception_5b_output_out = torch.cat([inception_5b_relu_1x1_out,inception_5b_relu_3x3_out,inception_5b_relu_double_3x3_2_out,inception_5b_relu_pool_proj_out], 1) + return inception_5b_output_out + + def logits(self, features): + adaptiveAvgPoolWidth = features.shape[2] + x = F.avg_pool2d(features, kernel_size=adaptiveAvgPoolWidth) + x = x.view(x.size(0), -1) + x = self.last_linear(x) + return x + + def forward(self, input): + x = self.features(input) + x = self.logits(x) + return x + +def bninception(num_classes=1000, pretrained='imagenet'): + r"""BNInception model architecture from `_ paper. + """ + model = BNInception(num_classes=num_classes) + if pretrained is not None: + settings = pretrained_settings['bninception'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model + + +if __name__ == '__main__': + + model = bninception() diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/cafferesnet.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/cafferesnet.py new file mode 100644 index 0000000000000000000000000000000000000000..8038d98fc47f05cf684ae9b8c03bde1b2b2c60e9 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/cafferesnet.py @@ -0,0 +1,195 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +from __future__ import print_function, division, absolute_import +import math +import torch +import torch.nn as nn +import torch.nn.functional as F +import torch.utils.model_zoo as model_zoo + +pretrained_settings = { + 'cafferesnet101': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/cafferesnet101-9d633cc0.pth', + 'input_space': 'BGR', + 'input_size': [3, 224, 224], + 'input_range': [0, 255], + 'mean': [102.9801, 115.9465, 122.7717], + 'std': [1, 1, 1], + 'num_classes': 1000 + } + } +} + + +def conv3x3(in_planes, out_planes, stride=1): + "3x3 convolution with padding" + return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride, + padding=1, bias=False) + + +class BasicBlock(nn.Module): + expansion = 1 + + def __init__(self, inplanes, planes, stride=1, downsample=None): + super(BasicBlock, self).__init__() + self.conv1 = conv3x3(inplanes, planes, stride) + self.bn1 = nn.BatchNorm2d(planes) + self.relu = nn.ReLU(inplace=True) + self.conv2 = conv3x3(planes, planes) + self.bn2 = nn.BatchNorm2d(planes) + self.downsample = downsample + self.stride = stride + + def forward(self, x): + residual = x + + out = self.conv1(x) + out = self.bn1(out) + out = self.relu(out) + + out = self.conv2(out) + out = self.bn2(out) + + if self.downsample is not None: + residual = self.downsample(x) + + out += residual + out = self.relu(out) + + return out + + +class Bottleneck(nn.Module): + expansion = 4 + + def __init__(self, inplanes, planes, stride=1, downsample=None): + super(Bottleneck, self).__init__() + self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, stride=stride, bias=False) # change + self.bn1 = nn.BatchNorm2d(planes) + self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=1, # change + padding=1, bias=False) + self.bn2 = nn.BatchNorm2d(planes) + self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=False) + self.bn3 = nn.BatchNorm2d(planes * 4) + self.relu = nn.ReLU(inplace=True) + self.downsample = downsample + self.stride = stride + + def forward(self, x): + residual = x + + out = self.conv1(x) + out = self.bn1(out) + out = self.relu(out) + + out = self.conv2(out) + out = self.bn2(out) + out = self.relu(out) + + out = self.conv3(out) + out = self.bn3(out) + + if self.downsample is not None: + residual = self.downsample(x) + + out += residual + out = self.relu(out) + + return out + + +class ResNet(nn.Module): + + def __init__(self, block, layers, num_classes=1000): + self.inplanes = 64 + super(ResNet, self).__init__() + self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, + bias=False) + self.bn1 = nn.BatchNorm2d(64) + self.relu = nn.ReLU(inplace=True) + self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=0, ceil_mode=True) # change + self.layer1 = self._make_layer(block, 64, layers[0]) + self.layer2 = self._make_layer(block, 128, layers[1], stride=2) + self.layer3 = self._make_layer(block, 256, layers[2], stride=2) + self.layer4 = self._make_layer(block, 512, layers[3], stride=2) + # it is slightly better whereas slower to set stride = 1 + # self.layer4 = self._make_layer(block, 512, layers[3], stride=1) + self.avgpool = nn.AvgPool2d(7) + self.last_linear = nn.Linear(512 * block.expansion, num_classes) + + for m in self.modules(): + if isinstance(m, nn.Conv2d): + n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels + m.weight.data.normal_(0, math.sqrt(2. / n)) + elif isinstance(m, nn.BatchNorm2d): + m.weight.data.fill_(1) + m.bias.data.zero_() + + def _make_layer(self, block, planes, blocks, stride=1): + downsample = None + if stride != 1 or self.inplanes != planes * block.expansion: + downsample = nn.Sequential( + nn.Conv2d(self.inplanes, planes * block.expansion, + kernel_size=1, stride=stride, bias=False), + nn.BatchNorm2d(planes * block.expansion), + ) + + layers = [] + layers.append(block(self.inplanes, planes, stride, downsample)) + self.inplanes = planes * block.expansion + for i in range(1, blocks): + layers.append(block(self.inplanes, planes)) + + return nn.Sequential(*layers) + + def features(self, x): + x = self.conv1(x) + x = self.bn1(x) + x = self.relu(x) + x = self.maxpool(x) + + x = self.layer1(x) + x = self.layer2(x) + x = self.layer3(x) + x = self.layer4(x) + return x + + def logits(self, x): + x = self.avgpool(x) + x = x.view(x.size(0), -1) + x = self.last_linear(x) + return x + + def forward(self, x): + x = self.features(x) + x = self.logits(x) + return x + + +def cafferesnet101(num_classes=1000, pretrained='imagenet'): + """Constructs a ResNet-101 model. + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + """ + model = ResNet(Bottleneck, [3, 4, 23, 3], num_classes=num_classes) + if pretrained is not None: + settings = pretrained_settings['cafferesnet101'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model \ No newline at end of file diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/dpn.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/dpn.py new file mode 100644 index 0000000000000000000000000000000000000000..4d4a1e5042e93b97daa0181018dabd9bd74d200d --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/dpn.py @@ -0,0 +1,473 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +""" PyTorch implementation of DualPathNetworks +Ported to PyTorch by [Ross Wightman](https://github.com/rwightman/pytorch-dpn-pretrained) + +Based on original MXNet implementation https://github.com/cypw/DPNs with +many ideas from another PyTorch implementation https://github.com/oyam/pytorch-DPNs. + +This implementation is compatible with the pretrained weights +from cypw's MXNet implementation. +""" +from __future__ import print_function, division, absolute_import +import os +import torch +import torch.nn as nn +import torch.nn.functional as F +import torch.utils.model_zoo as model_zoo +from collections import OrderedDict + +__all__ = ['DPN', 'dpn68', 'dpn68b', 'dpn92', 'dpn98', 'dpn131', 'dpn107'] + +pretrained_settings = { + 'dpn68': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/dpn68-4af7d88d2.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [124 / 255, 117 / 255, 104 / 255], + 'std': [1 / (.0167 * 255)] * 3, + 'num_classes': 1000 + } + }, + 'dpn68b': { + 'imagenet+5k': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/dpn68b_extra-363ab9c19.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [124 / 255, 117 / 255, 104 / 255], + 'std': [1 / (.0167 * 255)] * 3, + 'num_classes': 1000 + } + }, + 'dpn92': { + # 'imagenet': { + # 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/dpn68-66bebafa7.pth', + # 'input_space': 'RGB', + # 'input_size': [3, 224, 224], + # 'input_range': [0, 1], + # 'mean': [124 / 255, 117 / 255, 104 / 255], + # 'std': [1 / (.0167 * 255)] * 3, + # 'num_classes': 1000 + # }, + 'imagenet+5k': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/dpn92_extra-fda993c95.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [124 / 255, 117 / 255, 104 / 255], + 'std': [1 / (.0167 * 255)] * 3, + 'num_classes': 1000 + } + }, + 'dpn98': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/dpn98-722954780.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [124 / 255, 117 / 255, 104 / 255], + 'std': [1 / (.0167 * 255)] * 3, + 'num_classes': 1000 + } + }, + 'dpn131': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/dpn131-7af84be88.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [124 / 255, 117 / 255, 104 / 255], + 'std': [1 / (.0167 * 255)] * 3, + 'num_classes': 1000 + } + }, + 'dpn107': { + 'imagenet+5k': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/dpn107_extra-b7f9f4cc9.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [124 / 255, 117 / 255, 104 / 255], + 'std': [1 / (.0167 * 255)] * 3, + 'num_classes': 1000 + } + } +} + +def dpn68(num_classes=1000, pretrained='imagenet'): + model = DPN( + small=True, num_init_features=10, k_r=128, groups=32, + k_sec=(3, 4, 12, 3), inc_sec=(16, 32, 32, 64), + num_classes=num_classes, test_time_pool=True) + if pretrained: + settings = pretrained_settings['dpn68'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model + +def dpn68b(num_classes=1000, pretrained='imagenet+5k'): + model = DPN( + small=True, num_init_features=10, k_r=128, groups=32, + b=True, k_sec=(3, 4, 12, 3), inc_sec=(16, 32, 32, 64), + num_classes=num_classes, test_time_pool=True) + if pretrained: + settings = pretrained_settings['dpn68b'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model + +def dpn92(num_classes=1000, pretrained='imagenet+5k'): + model = DPN( + num_init_features=64, k_r=96, groups=32, + k_sec=(3, 4, 20, 3), inc_sec=(16, 32, 24, 128), + num_classes=num_classes, test_time_pool=True) + if pretrained: + settings = pretrained_settings['dpn92'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model + +def dpn98(num_classes=1000, pretrained='imagenet'): + model = DPN( + num_init_features=96, k_r=160, groups=40, + k_sec=(3, 6, 20, 3), inc_sec=(16, 32, 32, 128), + num_classes=num_classes, test_time_pool=True) + if pretrained: + settings = pretrained_settings['dpn98'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model + +def dpn131(num_classes=1000, pretrained='imagenet'): + model = DPN( + num_init_features=128, k_r=160, groups=40, + k_sec=(4, 8, 28, 3), inc_sec=(16, 32, 32, 128), + num_classes=num_classes, test_time_pool=True) + if pretrained: + settings = pretrained_settings['dpn131'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model + +def dpn107(num_classes=1000, pretrained='imagenet+5k'): + model = DPN( + num_init_features=128, k_r=200, groups=50, + k_sec=(4, 8, 20, 3), inc_sec=(20, 64, 64, 128), + num_classes=num_classes, test_time_pool=True) + if pretrained: + settings = pretrained_settings['dpn107'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model + + +class CatBnAct(nn.Module): + def __init__(self, in_chs, activation_fn=nn.ReLU(inplace=True)): + super(CatBnAct, self).__init__() + self.bn = nn.BatchNorm2d(in_chs, eps=0.001) + self.act = activation_fn + + def forward(self, x): + x = torch.cat(x, dim=1) if isinstance(x, tuple) else x + return self.act(self.bn(x)) + + +class BnActConv2d(nn.Module): + def __init__(self, in_chs, out_chs, kernel_size, stride, + padding=0, groups=1, activation_fn=nn.ReLU(inplace=True)): + super(BnActConv2d, self).__init__() + self.bn = nn.BatchNorm2d(in_chs, eps=0.001) + self.act = activation_fn + self.conv = nn.Conv2d(in_chs, out_chs, kernel_size, stride, padding, groups=groups, bias=False) + + def forward(self, x): + return self.conv(self.act(self.bn(x))) + + +class InputBlock(nn.Module): + def __init__(self, num_init_features, kernel_size=7, + padding=3, activation_fn=nn.ReLU(inplace=True)): + super(InputBlock, self).__init__() + self.conv = nn.Conv2d( + 3, num_init_features, kernel_size=kernel_size, stride=2, padding=padding, bias=False) + self.bn = nn.BatchNorm2d(num_init_features, eps=0.001) + self.act = activation_fn + self.pool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) + + def forward(self, x): + x = self.conv(x) + x = self.bn(x) + x = self.act(x) + x = self.pool(x) + return x + + +class DualPathBlock(nn.Module): + def __init__( + self, in_chs, num_1x1_a, num_3x3_b, num_1x1_c, inc, groups, block_type='normal', b=False): + super(DualPathBlock, self).__init__() + self.num_1x1_c = num_1x1_c + self.inc = inc + self.b = b + if block_type is 'proj': + self.key_stride = 1 + self.has_proj = True + elif block_type is 'down': + self.key_stride = 2 + self.has_proj = True + else: + assert block_type is 'normal' + self.key_stride = 1 + self.has_proj = False + + if self.has_proj: + # Using different member names here to allow easier parameter key matching for conversion + if self.key_stride == 2: + self.c1x1_w_s2 = BnActConv2d( + in_chs=in_chs, out_chs=num_1x1_c + 2 * inc, kernel_size=1, stride=2) + else: + self.c1x1_w_s1 = BnActConv2d( + in_chs=in_chs, out_chs=num_1x1_c + 2 * inc, kernel_size=1, stride=1) + self.c1x1_a = BnActConv2d(in_chs=in_chs, out_chs=num_1x1_a, kernel_size=1, stride=1) + self.c3x3_b = BnActConv2d( + in_chs=num_1x1_a, out_chs=num_3x3_b, kernel_size=3, + stride=self.key_stride, padding=1, groups=groups) + if b: + self.c1x1_c = CatBnAct(in_chs=num_3x3_b) + self.c1x1_c1 = nn.Conv2d(num_3x3_b, num_1x1_c, kernel_size=1, bias=False) + self.c1x1_c2 = nn.Conv2d(num_3x3_b, inc, kernel_size=1, bias=False) + else: + self.c1x1_c = BnActConv2d(in_chs=num_3x3_b, out_chs=num_1x1_c + inc, kernel_size=1, stride=1) + + def forward(self, x): + x_in = torch.cat(x, dim=1) if isinstance(x, tuple) else x + if self.has_proj: + if self.key_stride == 2: + x_s = self.c1x1_w_s2(x_in) + else: + x_s = self.c1x1_w_s1(x_in) + x_s1 = x_s[:, :self.num_1x1_c, :, :] + x_s2 = x_s[:, self.num_1x1_c:, :, :] + else: + x_s1 = x[0] + x_s2 = x[1] + x_in = self.c1x1_a(x_in) + x_in = self.c3x3_b(x_in) + if self.b: + x_in = self.c1x1_c(x_in) + out1 = self.c1x1_c1(x_in) + out2 = self.c1x1_c2(x_in) + else: + x_in = self.c1x1_c(x_in) + out1 = x_in[:, :self.num_1x1_c, :, :] + out2 = x_in[:, self.num_1x1_c:, :, :] + resid = x_s1 + out1 + dense = torch.cat([x_s2, out2], dim=1) + return resid, dense + + +class DPN(nn.Module): + def __init__(self, small=False, num_init_features=64, k_r=96, groups=32, + b=False, k_sec=(3, 4, 20, 3), inc_sec=(16, 32, 24, 128), + num_classes=1000, test_time_pool=False): + super(DPN, self).__init__() + self.test_time_pool = test_time_pool + self.b = b + bw_factor = 1 if small else 4 + + blocks = OrderedDict() + + # conv1 + if small: + blocks['conv1_1'] = InputBlock(num_init_features, kernel_size=3, padding=1) + else: + blocks['conv1_1'] = InputBlock(num_init_features, kernel_size=7, padding=3) + + # conv2 + bw = 64 * bw_factor + inc = inc_sec[0] + r = (k_r * bw) // (64 * bw_factor) + blocks['conv2_1'] = DualPathBlock(num_init_features, r, r, bw, inc, groups, 'proj', b) + in_chs = bw + 3 * inc + for i in range(2, k_sec[0] + 1): + blocks['conv2_' + str(i)] = DualPathBlock(in_chs, r, r, bw, inc, groups, 'normal', b) + in_chs += inc + + # conv3 + bw = 128 * bw_factor + inc = inc_sec[1] + r = (k_r * bw) // (64 * bw_factor) + blocks['conv3_1'] = DualPathBlock(in_chs, r, r, bw, inc, groups, 'down', b) + in_chs = bw + 3 * inc + for i in range(2, k_sec[1] + 1): + blocks['conv3_' + str(i)] = DualPathBlock(in_chs, r, r, bw, inc, groups, 'normal', b) + in_chs += inc + + # conv4 + bw = 256 * bw_factor + inc = inc_sec[2] + r = (k_r * bw) // (64 * bw_factor) + blocks['conv4_1'] = DualPathBlock(in_chs, r, r, bw, inc, groups, 'down', b) + in_chs = bw + 3 * inc + for i in range(2, k_sec[2] + 1): + blocks['conv4_' + str(i)] = DualPathBlock(in_chs, r, r, bw, inc, groups, 'normal', b) + in_chs += inc + + # conv5 + bw = 512 * bw_factor + inc = inc_sec[3] + r = (k_r * bw) // (64 * bw_factor) + blocks['conv5_1'] = DualPathBlock(in_chs, r, r, bw, inc, groups, 'down', b) + in_chs = bw + 3 * inc + for i in range(2, k_sec[3] + 1): + blocks['conv5_' + str(i)] = DualPathBlock(in_chs, r, r, bw, inc, groups, 'normal', b) + in_chs += inc + blocks['conv5_bn_ac'] = CatBnAct(in_chs) + + self.features = nn.Sequential(blocks) + + # Using 1x1 conv for the FC layer to allow the extra pooling scheme + self.last_linear = nn.Conv2d(in_chs, num_classes, kernel_size=1, bias=True) + + def logits(self, features): + if not self.training and self.test_time_pool: + x = F.avg_pool2d(features, kernel_size=7, stride=1) + out = self.last_linear(x) + # The extra test time pool should be pooling an img_size//32 - 6 size patch + out = adaptive_avgmax_pool2d(out, pool_type='avgmax') + else: + x = adaptive_avgmax_pool2d(features, pool_type='avg') + out = self.last_linear(x) + return out.view(out.size(0), -1) + + def forward(self, input): + x = self.features(input) + x = self.logits(x) + return x + +""" PyTorch selectable adaptive pooling +Adaptive pooling with the ability to select the type of pooling from: + * 'avg' - Average pooling + * 'max' - Max pooling + * 'avgmax' - Sum of average and max pooling re-scaled by 0.5 + * 'avgmaxc' - Concatenation of average and max pooling along feature dim, doubles feature dim + +Both a functional and a nn.Module version of the pooling is provided. + +Author: Ross Wightman (rwightman) +""" + +def pooling_factor(pool_type='avg'): + return 2 if pool_type == 'avgmaxc' else 1 + + +def adaptive_avgmax_pool2d(x, pool_type='avg', padding=0, count_include_pad=False): + """Selectable global pooling function with dynamic input kernel size + """ + if pool_type == 'avgmaxc': + x = torch.cat([ + F.avg_pool2d( + x, kernel_size=(x.size(2), x.size(3)), padding=padding, count_include_pad=count_include_pad), + F.max_pool2d(x, kernel_size=(x.size(2), x.size(3)), padding=padding) + ], dim=1) + elif pool_type == 'avgmax': + x_avg = F.avg_pool2d( + x, kernel_size=(x.size(2), x.size(3)), padding=padding, count_include_pad=count_include_pad) + x_max = F.max_pool2d(x, kernel_size=(x.size(2), x.size(3)), padding=padding) + x = 0.5 * (x_avg + x_max) + elif pool_type == 'max': + x = F.max_pool2d(x, kernel_size=(x.size(2), x.size(3)), padding=padding) + else: + if pool_type != 'avg': + print('Invalid pool type %s specified. Defaulting to average pooling.' % pool_type) + x = F.avg_pool2d( + x, kernel_size=(x.size(2), x.size(3)), padding=padding, count_include_pad=count_include_pad) + return x + + +class AdaptiveAvgMaxPool2d(torch.nn.Module): + """Selectable global pooling layer with dynamic input kernel size + """ + def __init__(self, output_size=1, pool_type='avg'): + super(AdaptiveAvgMaxPool2d, self).__init__() + self.output_size = output_size + self.pool_type = pool_type + if pool_type == 'avgmaxc' or pool_type == 'avgmax': + self.pool = nn.ModuleList([nn.AdaptiveAvgPool2d(output_size), nn.AdaptiveMaxPool2d(output_size)]) + elif pool_type == 'max': + self.pool = nn.AdaptiveMaxPool2d(output_size) + else: + if pool_type != 'avg': + print('Invalid pool type %s specified. Defaulting to average pooling.' % pool_type) + self.pool = nn.AdaptiveAvgPool2d(output_size) + + def forward(self, x): + if self.pool_type == 'avgmaxc': + x = torch.cat([p(x) for p in self.pool], dim=1) + elif self.pool_type == 'avgmax': + x = 0.5 * torch.sum(torch.stack([p(x) for p in self.pool]), 0).squeeze(dim=0) + else: + x = self.pool(x) + return x + + def factor(self): + return pooling_factor(self.pool_type) + + def __repr__(self): + return self.__class__.__name__ + ' (' \ + + 'output_size=' + str(self.output_size) \ + + ', pool_type=' + self.pool_type + ')' \ No newline at end of file diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/fbresnet.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/fbresnet.py new file mode 100644 index 0000000000000000000000000000000000000000..d271c74917177a80e2101c21dd8404f99cda6f78 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/fbresnet.py @@ -0,0 +1,246 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +from __future__ import print_function, division, absolute_import +import torch.nn as nn +import torch.nn.functional as F +import math +import torch.utils.model_zoo as model_zoo + + +__all__ = ['FBResNet', + #'fbresnet18', 'fbresnet34', 'fbresnet50', 'fbresnet101', + 'fbresnet152'] + +pretrained_settings = { + 'fbresnet152': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/fbresnet152-2e20f6b4.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [0.485, 0.456, 0.406], + 'std': [0.229, 0.224, 0.225], + 'num_classes': 1000 + } + } +} + + +def conv3x3(in_planes, out_planes, stride=1): + "3x3 convolution with padding" + return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride, + padding=1, bias=True) + + +class BasicBlock(nn.Module): + expansion = 1 + + def __init__(self, inplanes, planes, stride=1, downsample=None): + super(BasicBlock, self).__init__() + self.conv1 = conv3x3(inplanes, planes, stride) + self.bn1 = nn.BatchNorm2d(planes) + self.relu = nn.ReLU(inplace=True) + self.conv2 = conv3x3(planes, planes) + self.bn2 = nn.BatchNorm2d(planes) + self.downsample = downsample + self.stride = stride + + def forward(self, x): + residual = x + + out = self.conv1(x) + out = self.bn1(out) + out = self.relu(out) + + out = self.conv2(out) + out = self.bn2(out) + + if self.downsample is not None: + residual = self.downsample(x) + + out += residual + out = self.relu(out) + + return out + + +class Bottleneck(nn.Module): + expansion = 4 + + def __init__(self, inplanes, planes, stride=1, downsample=None): + super(Bottleneck, self).__init__() + self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=True) + self.bn1 = nn.BatchNorm2d(planes) + self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride, + padding=1, bias=True) + self.bn2 = nn.BatchNorm2d(planes) + self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=True) + self.bn3 = nn.BatchNorm2d(planes * 4) + self.relu = nn.ReLU(inplace=True) + self.downsample = downsample + self.stride = stride + + def forward(self, x): + residual = x + + out = self.conv1(x) + out = self.bn1(out) + out = self.relu(out) + + out = self.conv2(out) + out = self.bn2(out) + out = self.relu(out) + + out = self.conv3(out) + out = self.bn3(out) + + if self.downsample is not None: + residual = self.downsample(x) + + out += residual + out = self.relu(out) + + return out + +class FBResNet(nn.Module): + + def __init__(self, block, layers, num_classes=1000): + self.inplanes = 64 + # Special attributs + self.input_space = None + self.input_size = (299, 299, 3) + self.mean = None + self.std = None + super(FBResNet, self).__init__() + # Modules + self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, + bias=True) + self.bn1 = nn.BatchNorm2d(64) + self.relu = nn.ReLU(inplace=True) + self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) + self.layer1 = self._make_layer(block, 64, layers[0]) + self.layer2 = self._make_layer(block, 128, layers[1], stride=2) + self.layer3 = self._make_layer(block, 256, layers[2], stride=2) + self.layer4 = self._make_layer(block, 512, layers[3], stride=2) + self.last_linear = nn.Linear(512 * block.expansion, num_classes) + + for m in self.modules(): + if isinstance(m, nn.Conv2d): + n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels + m.weight.data.normal_(0, math.sqrt(2. / n)) + elif isinstance(m, nn.BatchNorm2d): + m.weight.data.fill_(1) + m.bias.data.zero_() + + def _make_layer(self, block, planes, blocks, stride=1): + downsample = None + if stride != 1 or self.inplanes != planes * block.expansion: + downsample = nn.Sequential( + nn.Conv2d(self.inplanes, planes * block.expansion, + kernel_size=1, stride=stride, bias=True), + nn.BatchNorm2d(planes * block.expansion), + ) + + layers = [] + layers.append(block(self.inplanes, planes, stride, downsample)) + self.inplanes = planes * block.expansion + for i in range(1, blocks): + layers.append(block(self.inplanes, planes)) + + return nn.Sequential(*layers) + + def features(self, input): + x = self.conv1(input) + self.conv1_input = x.clone() + x = self.bn1(x) + x = self.relu(x) + x = self.maxpool(x) + + x = self.layer1(x) + x = self.layer2(x) + x = self.layer3(x) + x = self.layer4(x) + return x + + def logits(self, features): + adaptiveAvgPoolWidth = features.shape[2] + x = F.avg_pool2d(features, kernel_size=adaptiveAvgPoolWidth) + x = x.view(x.size(0), -1) + x = self.last_linear(x) + return x + + def forward(self, input): + x = self.features(input) + x = self.logits(x) + return x + + +def fbresnet18(num_classes=1000): + """Constructs a ResNet-18 model. + + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + """ + model = FBResNet(BasicBlock, [2, 2, 2, 2], num_classes=num_classes) + return model + + +def fbresnet34(num_classes=1000): + """Constructs a ResNet-34 model. + + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + """ + model = FBResNet(BasicBlock, [3, 4, 6, 3], num_classes=num_classes) + return model + + +def fbresnet50(num_classes=1000): + """Constructs a ResNet-50 model. + + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + """ + model = FBResNet(Bottleneck, [3, 4, 6, 3], num_classes=num_classes) + return model + + +def fbresnet101(num_classes=1000): + """Constructs a ResNet-101 model. + + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + """ + model = FBResNet(Bottleneck, [3, 4, 23, 3], num_classes=num_classes) + return model + + +def fbresnet152(num_classes=1000, pretrained='imagenet'): + """Constructs a ResNet-152 model. + + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + """ + model = FBResNet(Bottleneck, [3, 8, 36, 3], num_classes=num_classes) + if pretrained is not None: + settings = pretrained_settings['fbresnet152'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model + + diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/fbresnet/resnet152_dump.lua b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/fbresnet/resnet152_dump.lua new file mode 100644 index 0000000000000000000000000000000000000000..9b92686617cb38062e801b80b9926080dafef0a4 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/fbresnet/resnet152_dump.lua @@ -0,0 +1,42 @@ +require 'cutorch' +require 'cunn' +require 'cudnn' +require 'image' +vision=require 'torchnet-vision' + +net=vision.models.resnet.load{filename='data/resnet152/net.t7',length=152} +print(net) + +require 'nn' +nn.Module.parameters = function(self) + if self.weight and self.bias and self.running_mean and self.running_var then + return {self.weight, self.bias, self.running_mean, self.running_var}, {self.gradWeight, self.gradBias} + + elseif self.weight and self.bias then + return {self.weight, self.bias}, {self.gradWeight, self.gradBias} + elseif self.weight then + return {self.weight}, {self.gradWeight} + elseif self.bias then + return {self.bias}, {self.gradBias} + else + return + end +end + +netparams, _ = net:parameters() +print(#netparams) +torch.save('data/resnet152/netparams.t7', netparams) + +net=net:cuda() +net:evaluate() +--p, gp = net:getParameters() +input = torch.ones(1,3,224,224) +input[{1,1,1,1}] = -1 +input[1] = image.load('data/cat_224.png') +print(input:sum()) +input = input:cuda() +output=net:forward(input) + +for i=1, 11 do + torch.save('data/resnet152/output'..i..'.t7', net:get(i).output:float()) +end diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/fbresnet/resnet152_load.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/fbresnet/resnet152_load.py new file mode 100644 index 0000000000000000000000000000000000000000..beef96a5bd86257e1b8c1edbbfd76966ad30215a --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/fbresnet/resnet152_load.py @@ -0,0 +1,295 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +from __future__ import print_function, division, absolute_import +import torch.nn as nn +import math +import torch.utils.model_zoo as model_zoo + + +__all__ = ['ResNet', 'resnet18', 'resnet34', 'resnet50', 'resnet101', + 'resnet152'] + + +model_urls = { + 'resnet18': 'https://download.pytorch.org/models/resnet18-5c106cde.pth', + 'resnet34': 'https://download.pytorch.org/models/resnet34-333f7ec4.pth', + 'resnet50': 'https://download.pytorch.org/models/resnet50-19c8e357.pth', + 'resnet101': 'https://download.pytorch.org/models/resnet101-5d3b4d8f.pth', + 'resnet152': 'https://download.pytorch.org/models/resnet152-b121ed2d.pth', +} + + +def conv3x3(in_planes, out_planes, stride=1): + "3x3 convolution with padding" + return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride, + padding=1, bias=True) + + +class BasicBlock(nn.Module): + expansion = 1 + + def __init__(self, inplanes, planes, stride=1, downsample=None): + super(BasicBlock, self).__init__() + self.conv1 = conv3x3(inplanes, planes, stride) + self.bn1 = nn.BatchNorm2d(planes) + self.relu = nn.ReLU(inplace=True) + self.conv2 = conv3x3(planes, planes) + self.bn2 = nn.BatchNorm2d(planes) + self.downsample = downsample + self.stride = stride + + def forward(self, x): + residual = x + + out = self.conv1(x) + out = self.bn1(out) + out = self.relu(out) + + out = self.conv2(out) + out = self.bn2(out) + + if self.downsample is not None: + residual = self.downsample(x) + + out += residual + out = self.relu(out) + + return out + + +class Bottleneck(nn.Module): + expansion = 4 + + def __init__(self, inplanes, planes, stride=1, downsample=None): + super(Bottleneck, self).__init__() + self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=True) + self.bn1 = nn.BatchNorm2d(planes) + self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride, + padding=1, bias=True) + self.bn2 = nn.BatchNorm2d(planes) + self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=True) + self.bn3 = nn.BatchNorm2d(planes * 4) + self.relu = nn.ReLU(inplace=True) + self.downsample = downsample + self.stride = stride + + def forward(self, x): + residual = x + + out = self.conv1(x) + out = self.bn1(out) + out = self.relu(out) + + out = self.conv2(out) + out = self.bn2(out) + out = self.relu(out) + + out = self.conv3(out) + out = self.bn3(out) + + if self.downsample is not None: + residual = self.downsample(x) + + out += residual + out = self.relu(out) + + return out + +from torch.legacy import nn as nnl + +class ResNet(nn.Module): + + def __init__(self, block, layers, num_classes=1000): + self.inplanes = 64 + super(ResNet, self).__init__() + self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, + bias=True) + #self.conv1 = nnl.SpatialConvolution(3, 64, 7, 7, 2, 2, 3, 3) + self.bn1 = nn.BatchNorm2d(64) + self.relu = nn.ReLU(inplace=True) + self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) + self.layer1 = self._make_layer(block, 64, layers[0]) + self.layer2 = self._make_layer(block, 128, layers[1], stride=2) + self.layer3 = self._make_layer(block, 256, layers[2], stride=2) + self.layer4 = self._make_layer(block, 512, layers[3], stride=2) + self.avgpool = nn.AvgPool2d(7) + self.fc = nn.Linear(512 * block.expansion, num_classes) + + for m in self.modules(): + if isinstance(m, nn.Conv2d): + n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels + m.weight.data.normal_(0, math.sqrt(2. / n)) + elif isinstance(m, nn.BatchNorm2d): + m.weight.data.fill_(1) + m.bias.data.zero_() + + def _make_layer(self, block, planes, blocks, stride=1): + downsample = None + if stride != 1 or self.inplanes != planes * block.expansion: + downsample = nn.Sequential( + nn.Conv2d(self.inplanes, planes * block.expansion, + kernel_size=1, stride=stride, bias=True), + nn.BatchNorm2d(planes * block.expansion), + ) + + layers = [] + layers.append(block(self.inplanes, planes, stride, downsample)) + self.inplanes = planes * block.expansion + for i in range(1, blocks): + layers.append(block(self.inplanes, planes)) + + return nn.Sequential(*layers) + + def forward(self, x): + x = self.conv1(x) + self.conv1_input = x.clone() + x = self.bn1(x) + x = self.relu(x) + x = self.maxpool(x) + + x = self.layer1(x) + x = self.layer2(x) + x = self.layer3(x) + x = self.layer4(x) + + x = self.avgpool(x) + x = x.view(x.size(0), -1) + x = self.fc(x) + + return x + + +def resnet18(pretrained=False, **kwargs): + """Constructs a ResNet-18 model. + + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + """ + model = ResNet(BasicBlock, [2, 2, 2, 2], **kwargs) + if pretrained: + model.load_state_dict(model_zoo.load_url(model_urls['resnet18'])) + return model + + +def resnet34(pretrained=False, **kwargs): + """Constructs a ResNet-34 model. + + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + """ + model = ResNet(BasicBlock, [3, 4, 6, 3], **kwargs) + if pretrained: + model.load_state_dict(model_zoo.load_url(model_urls['resnet34'])) + return model + + +def resnet50(pretrained=False, **kwargs): + """Constructs a ResNet-50 model. + + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + """ + model = ResNet(Bottleneck, [3, 4, 6, 3], **kwargs) + if pretrained: + model.load_state_dict(model_zoo.load_url(model_urls['resnet50'])) + return model + + +def resnet101(pretrained=False, **kwargs): + """Constructs a ResNet-101 model. + + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + """ + model = ResNet(Bottleneck, [3, 4, 23, 3], **kwargs) + if pretrained: + model.load_state_dict(model_zoo.load_url(model_urls['resnet101'])) + return model + + +def resnet152(pretrained=False, **kwargs): + """Constructs a ResNet-152 model. + + Args: + pretrained (bool): If True, returns a model pre-trained on ImageNet + """ + model = ResNet(Bottleneck, [3, 8, 36, 3], **kwargs) + if pretrained: + model.load_state_dict(model_zoo.load_url(model_urls['resnet152'])) + return model + +import torchfile +from torch.utils.serialization import load_lua +import torch +netparams = torchfile.load('data/resnet152/netparams.t7') +#netparams2 = load_lua('data/resnet152/netparams.t7') +#import ipdb; ipdb.set_trace() +netoutputs = [] +for i in range(1, 12): + path = 'data/resnet152/output{}.t7'.format(i) + out = load_lua(path) + #print(out.size()) + if out.dim()==4: + pass#out.transpose_(2, 3) + netoutputs.append(out) + +net = resnet152() +state_dict = net.state_dict() + +import collections +s = collections.OrderedDict() + + +i=0 +for key in state_dict.keys(): + new = torch.from_numpy(netparams[i]) + s[key] = new + if s[key].dim() == 4: + pass#s[key].transpose_(2,3) + i += 1 + +net.load_state_dict(s) + +net.conv1.register_forward_hook(lambda self, input, output: \ + print('conv1', torch.dist(output.data, netoutputs[0]))) +net.bn1.register_forward_hook(lambda self, input, output: \ + print('bn1', torch.dist(output.data, netoutputs[1]))) +net.relu.register_forward_hook(lambda self, input, output: \ + print('relu', torch.dist(output.data, netoutputs[2]))) +net.maxpool.register_forward_hook(lambda self, input, output: \ + print('maxpool', torch.dist(output.data, netoutputs[3]))) +net.layer1.register_forward_hook(lambda self, input, output: \ + print('layer1', torch.dist(output.data, netoutputs[4]))) +net.layer2.register_forward_hook(lambda self, input, output: \ + print('layer2', torch.dist(output.data, netoutputs[5]))) +net.layer3.register_forward_hook(lambda self, input, output: \ + print('layer3', torch.dist(output.data, netoutputs[6]))) +net.layer4.register_forward_hook(lambda self, input, output: \ + print('layer4', torch.dist(output.data, netoutputs[7]))) +net.avgpool.register_forward_hook(lambda self, input, output: \ + print('avgpool', torch.dist(output.data, netoutputs[8]))) +net.fc.register_forward_hook(lambda self, input, output: \ + print('fc', torch.dist(output.data, netoutputs[10]))) + +net.eval() +input_data = torch.ones(1,3,224,224) +input_data[0][0][0][0] = -1 +from PIL import Image +import torchvision.transforms as transforms +input_data[0] = transforms.ToTensor()(Image.open('data/cat_224.png')) +print('cat sum', input_data.sum()) +input = torch.autograd.Variable(input_data) +output = net.forward(input) + +torch.save(s, 'data/resnet152.pth') + + diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/inceptionresnetv2.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/inceptionresnetv2.py new file mode 100644 index 0000000000000000000000000000000000000000..77257883d0e8ce31788d3f59727ecbd95e4de646 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/inceptionresnetv2.py @@ -0,0 +1,391 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +from __future__ import print_function, division, absolute_import +import torch +import torch.nn as nn +import torch.utils.model_zoo as model_zoo +import os +import sys + +__all__ = ['InceptionResNetV2', 'inceptionresnetv2'] + +pretrained_settings = { + 'inceptionresnetv2': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/inceptionresnetv2-520b38e4.pth', + 'input_space': 'RGB', + 'input_size': [3, 299, 299], + 'input_range': [0, 1], + 'mean': [0.5, 0.5, 0.5], + 'std': [0.5, 0.5, 0.5], + 'num_classes': 1000 + }, + 'imagenet+background': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/inceptionresnetv2-520b38e4.pth', + 'input_space': 'RGB', + 'input_size': [3, 299, 299], + 'input_range': [0, 1], + 'mean': [0.5, 0.5, 0.5], + 'std': [0.5, 0.5, 0.5], + 'num_classes': 1001 + } + } +} + + +class BasicConv2d(nn.Module): + + def __init__(self, in_planes, out_planes, kernel_size, stride, padding=0): + super(BasicConv2d, self).__init__() + self.conv = nn.Conv2d(in_planes, out_planes, + kernel_size=kernel_size, stride=stride, + padding=padding, bias=False) # verify bias false + self.bn = nn.BatchNorm2d(out_planes, + eps=0.001, # value found in tensorflow + momentum=0.1, # default pytorch value + affine=True) + self.relu = nn.ReLU(inplace=False) + + def forward(self, x): + x = self.conv(x) + x = self.bn(x) + x = self.relu(x) + return x + + +class Mixed_5b(nn.Module): + + def __init__(self): + super(Mixed_5b, self).__init__() + + self.branch0 = BasicConv2d(192, 96, kernel_size=1, stride=1) + + self.branch1 = nn.Sequential( + BasicConv2d(192, 48, kernel_size=1, stride=1), + BasicConv2d(48, 64, kernel_size=5, stride=1, padding=2) + ) + + self.branch2 = nn.Sequential( + BasicConv2d(192, 64, kernel_size=1, stride=1), + BasicConv2d(64, 96, kernel_size=3, stride=1, padding=1), + BasicConv2d(96, 96, kernel_size=3, stride=1, padding=1) + ) + + self.branch3 = nn.Sequential( + nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False), + BasicConv2d(192, 64, kernel_size=1, stride=1) + ) + + def forward(self, x): + x0 = self.branch0(x) + x1 = self.branch1(x) + x2 = self.branch2(x) + x3 = self.branch3(x) + out = torch.cat((x0, x1, x2, x3), 1) + return out + + +class Block35(nn.Module): + + def __init__(self, scale=1.0): + super(Block35, self).__init__() + + self.scale = scale + + self.branch0 = BasicConv2d(320, 32, kernel_size=1, stride=1) + + self.branch1 = nn.Sequential( + BasicConv2d(320, 32, kernel_size=1, stride=1), + BasicConv2d(32, 32, kernel_size=3, stride=1, padding=1) + ) + + self.branch2 = nn.Sequential( + BasicConv2d(320, 32, kernel_size=1, stride=1), + BasicConv2d(32, 48, kernel_size=3, stride=1, padding=1), + BasicConv2d(48, 64, kernel_size=3, stride=1, padding=1) + ) + + self.conv2d = nn.Conv2d(128, 320, kernel_size=1, stride=1) + self.relu = nn.ReLU(inplace=False) + + def forward(self, x): + x0 = self.branch0(x) + x1 = self.branch1(x) + x2 = self.branch2(x) + out = torch.cat((x0, x1, x2), 1) + out = self.conv2d(out) + out = out * self.scale + x + out = self.relu(out) + return out + + +class Mixed_6a(nn.Module): + + def __init__(self): + super(Mixed_6a, self).__init__() + + self.branch0 = BasicConv2d(320, 384, kernel_size=3, stride=2) + + self.branch1 = nn.Sequential( + BasicConv2d(320, 256, kernel_size=1, stride=1), + BasicConv2d(256, 256, kernel_size=3, stride=1, padding=1), + BasicConv2d(256, 384, kernel_size=3, stride=2) + ) + + self.branch2 = nn.MaxPool2d(3, stride=2) + + def forward(self, x): + x0 = self.branch0(x) + x1 = self.branch1(x) + x2 = self.branch2(x) + out = torch.cat((x0, x1, x2), 1) + return out + + +class Block17(nn.Module): + + def __init__(self, scale=1.0): + super(Block17, self).__init__() + + self.scale = scale + + self.branch0 = BasicConv2d(1088, 192, kernel_size=1, stride=1) + + self.branch1 = nn.Sequential( + BasicConv2d(1088, 128, kernel_size=1, stride=1), + BasicConv2d(128, 160, kernel_size=(1,7), stride=1, padding=(0,3)), + BasicConv2d(160, 192, kernel_size=(7,1), stride=1, padding=(3,0)) + ) + + self.conv2d = nn.Conv2d(384, 1088, kernel_size=1, stride=1) + self.relu = nn.ReLU(inplace=False) + + def forward(self, x): + x0 = self.branch0(x) + x1 = self.branch1(x) + out = torch.cat((x0, x1), 1) + out = self.conv2d(out) + out = out * self.scale + x + out = self.relu(out) + return out + + +class Mixed_7a(nn.Module): + + def __init__(self): + super(Mixed_7a, self).__init__() + + self.branch0 = nn.Sequential( + BasicConv2d(1088, 256, kernel_size=1, stride=1), + BasicConv2d(256, 384, kernel_size=3, stride=2) + ) + + self.branch1 = nn.Sequential( + BasicConv2d(1088, 256, kernel_size=1, stride=1), + BasicConv2d(256, 288, kernel_size=3, stride=2) + ) + + self.branch2 = nn.Sequential( + BasicConv2d(1088, 256, kernel_size=1, stride=1), + BasicConv2d(256, 288, kernel_size=3, stride=1, padding=1), + BasicConv2d(288, 320, kernel_size=3, stride=2) + ) + + self.branch3 = nn.MaxPool2d(3, stride=2) + + def forward(self, x): + x0 = self.branch0(x) + x1 = self.branch1(x) + x2 = self.branch2(x) + x3 = self.branch3(x) + out = torch.cat((x0, x1, x2, x3), 1) + return out + + +class Block8(nn.Module): + + def __init__(self, scale=1.0, noReLU=False): + super(Block8, self).__init__() + + self.scale = scale + self.noReLU = noReLU + + self.branch0 = BasicConv2d(2080, 192, kernel_size=1, stride=1) + + self.branch1 = nn.Sequential( + BasicConv2d(2080, 192, kernel_size=1, stride=1), + BasicConv2d(192, 224, kernel_size=(1,3), stride=1, padding=(0,1)), + BasicConv2d(224, 256, kernel_size=(3,1), stride=1, padding=(1,0)) + ) + + self.conv2d = nn.Conv2d(448, 2080, kernel_size=1, stride=1) + if not self.noReLU: + self.relu = nn.ReLU(inplace=False) + + def forward(self, x): + x0 = self.branch0(x) + x1 = self.branch1(x) + out = torch.cat((x0, x1), 1) + out = self.conv2d(out) + out = out * self.scale + x + if not self.noReLU: + out = self.relu(out) + return out + + +class InceptionResNetV2(nn.Module): + + def __init__(self, num_classes=1001): + super(InceptionResNetV2, self).__init__() + # Special attributs + self.input_space = None + self.input_size = (299, 299, 3) + self.mean = None + self.std = None + # Modules + self.conv2d_1a = BasicConv2d(3, 32, kernel_size=3, stride=2) + self.conv2d_2a = BasicConv2d(32, 32, kernel_size=3, stride=1) + self.conv2d_2b = BasicConv2d(32, 64, kernel_size=3, stride=1, padding=1) + self.maxpool_3a = nn.MaxPool2d(3, stride=2) + self.conv2d_3b = BasicConv2d(64, 80, kernel_size=1, stride=1) + self.conv2d_4a = BasicConv2d(80, 192, kernel_size=3, stride=1) + self.maxpool_5a = nn.MaxPool2d(3, stride=2) + self.mixed_5b = Mixed_5b() + self.repeat = nn.Sequential( + Block35(scale=0.17), + Block35(scale=0.17), + Block35(scale=0.17), + Block35(scale=0.17), + Block35(scale=0.17), + Block35(scale=0.17), + Block35(scale=0.17), + Block35(scale=0.17), + Block35(scale=0.17), + Block35(scale=0.17) + ) + self.mixed_6a = Mixed_6a() + self.repeat_1 = nn.Sequential( + Block17(scale=0.10), + Block17(scale=0.10), + Block17(scale=0.10), + Block17(scale=0.10), + Block17(scale=0.10), + Block17(scale=0.10), + Block17(scale=0.10), + Block17(scale=0.10), + Block17(scale=0.10), + Block17(scale=0.10), + Block17(scale=0.10), + Block17(scale=0.10), + Block17(scale=0.10), + Block17(scale=0.10), + Block17(scale=0.10), + Block17(scale=0.10), + Block17(scale=0.10), + Block17(scale=0.10), + Block17(scale=0.10), + Block17(scale=0.10) + ) + self.mixed_7a = Mixed_7a() + self.repeat_2 = nn.Sequential( + Block8(scale=0.20), + Block8(scale=0.20), + Block8(scale=0.20), + Block8(scale=0.20), + Block8(scale=0.20), + Block8(scale=0.20), + Block8(scale=0.20), + Block8(scale=0.20), + Block8(scale=0.20) + ) + self.block8 = Block8(noReLU=True) + self.conv2d_7b = BasicConv2d(2080, 1536, kernel_size=1, stride=1) + self.avgpool_1a = nn.AvgPool2d(8, count_include_pad=False) + self.last_linear = nn.Linear(1536, num_classes) + + def features(self, input): + x = self.conv2d_1a(input) + x = self.conv2d_2a(x) + x = self.conv2d_2b(x) + x = self.maxpool_3a(x) + x = self.conv2d_3b(x) + x = self.conv2d_4a(x) + x = self.maxpool_5a(x) + x = self.mixed_5b(x) + x = self.repeat(x) + x = self.mixed_6a(x) + x = self.repeat_1(x) + x = self.mixed_7a(x) + x = self.repeat_2(x) + x = self.block8(x) + x = self.conv2d_7b(x) + return x + + def logits(self, features): + x = self.avgpool_1a(features) + x = x.view(x.size(0), -1) + x = self.last_linear(x) + return x + + def forward(self, input): + x = self.features(input) + x = self.logits(x) + return x + +def inceptionresnetv2(num_classes=1000, pretrained='imagenet'): + r"""InceptionResNetV2 model architecture from the + `"InceptionV4, Inception-ResNet..." `_ paper. + """ + if pretrained: + settings = pretrained_settings['inceptionresnetv2'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + # both 'imagenet'&'imagenet+background' are loaded from same parameters + model = InceptionResNetV2(num_classes=1001) + model.load_state_dict(model_zoo.load_url(settings['url'])) + + if pretrained == 'imagenet': + new_last_linear = nn.Linear(1536, 1000) + new_last_linear.weight.data = model.last_linear.weight.data[1:] + new_last_linear.bias.data = model.last_linear.bias.data[1:] + model.last_linear = new_last_linear + + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + + model.mean = settings['mean'] + model.std = settings['std'] + else: + model = InceptionResNetV2(num_classes=num_classes) + return model + +''' +TEST +Run this code with: +``` +cd $HOME/pretrained-models.pytorch +python -m pretrainedmodels.inceptionresnetv2 +``` +''' +if __name__ == '__main__': + + assert inceptionresnetv2(num_classes=10, pretrained=None) + print('success') + assert inceptionresnetv2(num_classes=1000, pretrained='imagenet') + print('success') + assert inceptionresnetv2(num_classes=1001, pretrained='imagenet+background') + print('success') + + # fail + assert inceptionresnetv2(num_classes=1001, pretrained='imagenet') \ No newline at end of file diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/inceptionv4.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/inceptionv4.py new file mode 100644 index 0000000000000000000000000000000000000000..c9af9da2b55aa76c7ff5c8b36b626ffdd4278097 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/inceptionv4.py @@ -0,0 +1,369 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +from __future__ import print_function, division, absolute_import +import torch +import torch.nn as nn +import torch.nn.functional as F +import torch.utils.model_zoo as model_zoo +import os +import sys + +__all__ = ['InceptionV4', 'inceptionv4'] + +pretrained_settings = { + 'inceptionv4': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/inceptionv4-8e4777a0.pth', + 'input_space': 'RGB', + 'input_size': [3, 299, 299], + 'input_range': [0, 1], + 'mean': [0.5, 0.5, 0.5], + 'std': [0.5, 0.5, 0.5], + 'num_classes': 1000 + }, + 'imagenet+background': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/inceptionv4-8e4777a0.pth', + 'input_space': 'RGB', + 'input_size': [3, 299, 299], + 'input_range': [0, 1], + 'mean': [0.5, 0.5, 0.5], + 'std': [0.5, 0.5, 0.5], + 'num_classes': 1001 + } + } +} + + +class BasicConv2d(nn.Module): + + def __init__(self, in_planes, out_planes, kernel_size, stride, padding=0): + super(BasicConv2d, self).__init__() + self.conv = nn.Conv2d(in_planes, out_planes, + kernel_size=kernel_size, stride=stride, + padding=padding, bias=False) # verify bias false + self.bn = nn.BatchNorm2d(out_planes, + eps=0.001, # value found in tensorflow + momentum=0.1, # default pytorch value + affine=True) + self.relu = nn.ReLU(inplace=True) + + def forward(self, x): + x = self.conv(x) + x = self.bn(x) + x = self.relu(x) + return x + + +class Mixed_3a(nn.Module): + + def __init__(self): + super(Mixed_3a, self).__init__() + self.maxpool = nn.MaxPool2d(3, stride=2) + self.conv = BasicConv2d(64, 96, kernel_size=3, stride=2) + + def forward(self, x): + x0 = self.maxpool(x) + x1 = self.conv(x) + out = torch.cat((x0, x1), 1) + return out + + +class Mixed_4a(nn.Module): + + def __init__(self): + super(Mixed_4a, self).__init__() + + self.branch0 = nn.Sequential( + BasicConv2d(160, 64, kernel_size=1, stride=1), + BasicConv2d(64, 96, kernel_size=3, stride=1) + ) + + self.branch1 = nn.Sequential( + BasicConv2d(160, 64, kernel_size=1, stride=1), + BasicConv2d(64, 64, kernel_size=(1,7), stride=1, padding=(0,3)), + BasicConv2d(64, 64, kernel_size=(7,1), stride=1, padding=(3,0)), + BasicConv2d(64, 96, kernel_size=(3,3), stride=1) + ) + + def forward(self, x): + x0 = self.branch0(x) + x1 = self.branch1(x) + out = torch.cat((x0, x1), 1) + return out + + +class Mixed_5a(nn.Module): + + def __init__(self): + super(Mixed_5a, self).__init__() + self.conv = BasicConv2d(192, 192, kernel_size=3, stride=2) + self.maxpool = nn.MaxPool2d(3, stride=2) + + def forward(self, x): + x0 = self.conv(x) + x1 = self.maxpool(x) + out = torch.cat((x0, x1), 1) + return out + + +class Inception_A(nn.Module): + + def __init__(self): + super(Inception_A, self).__init__() + self.branch0 = BasicConv2d(384, 96, kernel_size=1, stride=1) + + self.branch1 = nn.Sequential( + BasicConv2d(384, 64, kernel_size=1, stride=1), + BasicConv2d(64, 96, kernel_size=3, stride=1, padding=1) + ) + + self.branch2 = nn.Sequential( + BasicConv2d(384, 64, kernel_size=1, stride=1), + BasicConv2d(64, 96, kernel_size=3, stride=1, padding=1), + BasicConv2d(96, 96, kernel_size=3, stride=1, padding=1) + ) + + self.branch3 = nn.Sequential( + nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False), + BasicConv2d(384, 96, kernel_size=1, stride=1) + ) + + def forward(self, x): + x0 = self.branch0(x) + x1 = self.branch1(x) + x2 = self.branch2(x) + x3 = self.branch3(x) + out = torch.cat((x0, x1, x2, x3), 1) + return out + + +class Reduction_A(nn.Module): + + def __init__(self): + super(Reduction_A, self).__init__() + self.branch0 = BasicConv2d(384, 384, kernel_size=3, stride=2) + + self.branch1 = nn.Sequential( + BasicConv2d(384, 192, kernel_size=1, stride=1), + BasicConv2d(192, 224, kernel_size=3, stride=1, padding=1), + BasicConv2d(224, 256, kernel_size=3, stride=2) + ) + + self.branch2 = nn.MaxPool2d(3, stride=2) + + def forward(self, x): + x0 = self.branch0(x) + x1 = self.branch1(x) + x2 = self.branch2(x) + out = torch.cat((x0, x1, x2), 1) + return out + + +class Inception_B(nn.Module): + + def __init__(self): + super(Inception_B, self).__init__() + self.branch0 = BasicConv2d(1024, 384, kernel_size=1, stride=1) + + self.branch1 = nn.Sequential( + BasicConv2d(1024, 192, kernel_size=1, stride=1), + BasicConv2d(192, 224, kernel_size=(1,7), stride=1, padding=(0,3)), + BasicConv2d(224, 256, kernel_size=(7,1), stride=1, padding=(3,0)) + ) + + self.branch2 = nn.Sequential( + BasicConv2d(1024, 192, kernel_size=1, stride=1), + BasicConv2d(192, 192, kernel_size=(7,1), stride=1, padding=(3,0)), + BasicConv2d(192, 224, kernel_size=(1,7), stride=1, padding=(0,3)), + BasicConv2d(224, 224, kernel_size=(7,1), stride=1, padding=(3,0)), + BasicConv2d(224, 256, kernel_size=(1,7), stride=1, padding=(0,3)) + ) + + self.branch3 = nn.Sequential( + nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False), + BasicConv2d(1024, 128, kernel_size=1, stride=1) + ) + + def forward(self, x): + x0 = self.branch0(x) + x1 = self.branch1(x) + x2 = self.branch2(x) + x3 = self.branch3(x) + out = torch.cat((x0, x1, x2, x3), 1) + return out + + +class Reduction_B(nn.Module): + + def __init__(self): + super(Reduction_B, self).__init__() + + self.branch0 = nn.Sequential( + BasicConv2d(1024, 192, kernel_size=1, stride=1), + BasicConv2d(192, 192, kernel_size=3, stride=2) + ) + + self.branch1 = nn.Sequential( + BasicConv2d(1024, 256, kernel_size=1, stride=1), + BasicConv2d(256, 256, kernel_size=(1,7), stride=1, padding=(0,3)), + BasicConv2d(256, 320, kernel_size=(7,1), stride=1, padding=(3,0)), + BasicConv2d(320, 320, kernel_size=3, stride=2) + ) + + self.branch2 = nn.MaxPool2d(3, stride=2) + + def forward(self, x): + x0 = self.branch0(x) + x1 = self.branch1(x) + x2 = self.branch2(x) + out = torch.cat((x0, x1, x2), 1) + return out + + +class Inception_C(nn.Module): + + def __init__(self): + super(Inception_C, self).__init__() + + self.branch0 = BasicConv2d(1536, 256, kernel_size=1, stride=1) + + self.branch1_0 = BasicConv2d(1536, 384, kernel_size=1, stride=1) + self.branch1_1a = BasicConv2d(384, 256, kernel_size=(1,3), stride=1, padding=(0,1)) + self.branch1_1b = BasicConv2d(384, 256, kernel_size=(3,1), stride=1, padding=(1,0)) + + self.branch2_0 = BasicConv2d(1536, 384, kernel_size=1, stride=1) + self.branch2_1 = BasicConv2d(384, 448, kernel_size=(3,1), stride=1, padding=(1,0)) + self.branch2_2 = BasicConv2d(448, 512, kernel_size=(1,3), stride=1, padding=(0,1)) + self.branch2_3a = BasicConv2d(512, 256, kernel_size=(1,3), stride=1, padding=(0,1)) + self.branch2_3b = BasicConv2d(512, 256, kernel_size=(3,1), stride=1, padding=(1,0)) + + self.branch3 = nn.Sequential( + nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False), + BasicConv2d(1536, 256, kernel_size=1, stride=1) + ) + + def forward(self, x): + x0 = self.branch0(x) + + x1_0 = self.branch1_0(x) + x1_1a = self.branch1_1a(x1_0) + x1_1b = self.branch1_1b(x1_0) + x1 = torch.cat((x1_1a, x1_1b), 1) + + x2_0 = self.branch2_0(x) + x2_1 = self.branch2_1(x2_0) + x2_2 = self.branch2_2(x2_1) + x2_3a = self.branch2_3a(x2_2) + x2_3b = self.branch2_3b(x2_2) + x2 = torch.cat((x2_3a, x2_3b), 1) + + x3 = self.branch3(x) + + out = torch.cat((x0, x1, x2, x3), 1) + return out + + +class InceptionV4(nn.Module): + + def __init__(self, num_classes=1001): + super(InceptionV4, self).__init__() + # Special attributs + self.input_space = None + self.input_size = (299, 299, 3) + self.mean = None + self.std = None + # Modules + self.features = nn.Sequential( + BasicConv2d(3, 32, kernel_size=3, stride=2), + BasicConv2d(32, 32, kernel_size=3, stride=1), + BasicConv2d(32, 64, kernel_size=3, stride=1, padding=1), + Mixed_3a(), + Mixed_4a(), + Mixed_5a(), + Inception_A(), + Inception_A(), + Inception_A(), + Inception_A(), + Reduction_A(), # Mixed_6a + Inception_B(), + Inception_B(), + Inception_B(), + Inception_B(), + Inception_B(), + Inception_B(), + Inception_B(), + Reduction_B(), # Mixed_7a + Inception_C(), + Inception_C(), + Inception_C() + ) + self.last_linear = nn.Linear(1536, num_classes) + + def logits(self, features): + #Allows image of any size to be processed + adaptiveAvgPoolWidth = features.shape[2] + x = F.avg_pool2d(features, kernel_size=adaptiveAvgPoolWidth) + x = x.view(x.size(0), -1) + x = self.last_linear(x) + return x + + def forward(self, input): + x = self.features(input) + x = self.logits(x) + return x + + +def inceptionv4(num_classes=1000, pretrained='imagenet'): + if pretrained: + settings = pretrained_settings['inceptionv4'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + # both 'imagenet'&'imagenet+background' are loaded from same parameters + model = InceptionV4(num_classes=1001) + model.load_state_dict(model_zoo.load_url(settings['url'])) + + if pretrained == 'imagenet': + new_last_linear = nn.Linear(1536, 1000) + new_last_linear.weight.data = model.last_linear.weight.data[1:] + new_last_linear.bias.data = model.last_linear.bias.data[1:] + model.last_linear = new_last_linear + + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + else: + model = InceptionV4(num_classes=num_classes) + return model + + +''' +TEST +Run this code with: +``` +cd $HOME/pretrained-models.pytorch +python -m pretrainedmodels.inceptionv4 +``` +''' +if __name__ == '__main__': + + assert inceptionv4(num_classes=10, pretrained=None) + print('success') + assert inceptionv4(num_classes=1000, pretrained='imagenet') + print('success') + assert inceptionv4(num_classes=1001, pretrained='imagenet+background') + print('success') + + # fail + assert inceptionv4(num_classes=1001, pretrained='imagenet') diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/nasnet.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/nasnet.py new file mode 100644 index 0000000000000000000000000000000000000000..53f3e787f4929c222f0ac689daa9a9f89fb96791 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/nasnet.py @@ -0,0 +1,657 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +from __future__ import print_function, division, absolute_import +import torch +import torch.nn as nn +import torch.nn.functional as F +import torch.utils.model_zoo as model_zoo +from torch.autograd import Variable + +pretrained_settings = { + 'nasnetalarge': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/nasnetalarge-a1897284.pth', + 'input_space': 'RGB', + 'input_size': [3, 331, 331], # resize 354 + 'input_range': [0, 1], + 'mean': [0.5, 0.5, 0.5], + 'std': [0.5, 0.5, 0.5], + 'num_classes': 1000 + }, + 'imagenet+background': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/nasnetalarge-a1897284.pth', + 'input_space': 'RGB', + 'input_size': [3, 331, 331], # resize 354 + 'input_range': [0, 1], + 'mean': [0.5, 0.5, 0.5], + 'std': [0.5, 0.5, 0.5], + 'num_classes': 1001 + } + } +} + + +class MaxPoolPad(nn.Module): + + def __init__(self): + super(MaxPoolPad, self).__init__() + self.pad = nn.ZeroPad2d((1, 0, 1, 0)) + self.pool = nn.MaxPool2d(3, stride=2, padding=1) + + def forward(self, x): + x = self.pad(x) + x = self.pool(x) + x = x[:, :, 1:, 1:] + return x + + +class AvgPoolPad(nn.Module): + + def __init__(self, stride=2, padding=1): + super(AvgPoolPad, self).__init__() + self.pad = nn.ZeroPad2d((1, 0, 1, 0)) + self.pool = nn.AvgPool2d(3, stride=stride, padding=padding, count_include_pad=False) + + def forward(self, x): + x = self.pad(x) + x = self.pool(x) + x = x[:, :, 1:, 1:] + return x + + +class SeparableConv2d(nn.Module): + + def __init__(self, in_channels, out_channels, dw_kernel, dw_stride, dw_padding, bias=False): + super(SeparableConv2d, self).__init__() + self.depthwise_conv2d = nn.Conv2d(in_channels, in_channels, dw_kernel, + stride=dw_stride, + padding=dw_padding, + bias=bias, + groups=in_channels) + self.pointwise_conv2d = nn.Conv2d(in_channels, out_channels, 1, stride=1, bias=bias) + + def forward(self, x): + x = self.depthwise_conv2d(x) + x = self.pointwise_conv2d(x) + return x + + +class BranchSeparables(nn.Module): + + def __init__(self, in_channels, out_channels, kernel_size, stride, padding, bias=False): + super(BranchSeparables, self).__init__() + self.relu = nn.ReLU() + self.separable_1 = SeparableConv2d(in_channels, in_channels, kernel_size, stride, padding, bias=bias) + self.bn_sep_1 = nn.BatchNorm2d(in_channels, eps=0.001, momentum=0.1, affine=True) + self.relu1 = nn.ReLU() + self.separable_2 = SeparableConv2d(in_channels, out_channels, kernel_size, 1, padding, bias=bias) + self.bn_sep_2 = nn.BatchNorm2d(out_channels, eps=0.001, momentum=0.1, affine=True) + + def forward(self, x): + x = self.relu(x) + x = self.separable_1(x) + x = self.bn_sep_1(x) + x = self.relu1(x) + x = self.separable_2(x) + x = self.bn_sep_2(x) + return x + + +class BranchSeparablesStem(nn.Module): + + def __init__(self, in_channels, out_channels, kernel_size, stride, padding, bias=False): + super(BranchSeparablesStem, self).__init__() + self.relu = nn.ReLU() + self.separable_1 = SeparableConv2d(in_channels, out_channels, kernel_size, stride, padding, bias=bias) + self.bn_sep_1 = nn.BatchNorm2d(out_channels, eps=0.001, momentum=0.1, affine=True) + self.relu1 = nn.ReLU() + self.separable_2 = SeparableConv2d(out_channels, out_channels, kernel_size, 1, padding, bias=bias) + self.bn_sep_2 = nn.BatchNorm2d(out_channels, eps=0.001, momentum=0.1, affine=True) + + def forward(self, x): + x = self.relu(x) + x = self.separable_1(x) + x = self.bn_sep_1(x) + x = self.relu1(x) + x = self.separable_2(x) + x = self.bn_sep_2(x) + return x + + +class BranchSeparablesReduction(BranchSeparables): + + def __init__(self, in_channels, out_channels, kernel_size, stride, padding, z_padding=1, bias=False): + BranchSeparables.__init__(self, in_channels, out_channels, kernel_size, stride, padding, bias) + self.padding = nn.ZeroPad2d((z_padding, 0, z_padding, 0)) + + def forward(self, x): + x = self.relu(x) + x = self.padding(x) + x = self.separable_1(x) + x = x[:, :, 1:, 1:].contiguous() + x = self.bn_sep_1(x) + x = self.relu1(x) + x = self.separable_2(x) + x = self.bn_sep_2(x) + return x + + +class CellStem0(nn.Module): + def __init__(self, stem_filters, num_filters=42): + super(CellStem0, self).__init__() + self.num_filters = num_filters + self.stem_filters = stem_filters + self.conv_1x1 = nn.Sequential() + self.conv_1x1.add_module('relu', nn.ReLU()) + self.conv_1x1.add_module('conv', nn.Conv2d(self.stem_filters, self.num_filters, 1, stride=1, bias=False)) + self.conv_1x1.add_module('bn', nn.BatchNorm2d(self.num_filters, eps=0.001, momentum=0.1, affine=True)) + + self.comb_iter_0_left = BranchSeparables(self.num_filters, self.num_filters, 5, 2, 2) + self.comb_iter_0_right = BranchSeparablesStem(self.stem_filters, self.num_filters, 7, 2, 3, bias=False) + + self.comb_iter_1_left = nn.MaxPool2d(3, stride=2, padding=1) + self.comb_iter_1_right = BranchSeparablesStem(self.stem_filters, self.num_filters, 7, 2, 3, bias=False) + + self.comb_iter_2_left = nn.AvgPool2d(3, stride=2, padding=1, count_include_pad=False) + self.comb_iter_2_right = BranchSeparablesStem(self.stem_filters, self.num_filters, 5, 2, 2, bias=False) + + self.comb_iter_3_right = nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False) + + self.comb_iter_4_left = BranchSeparables(self.num_filters, self.num_filters, 3, 1, 1, bias=False) + self.comb_iter_4_right = nn.MaxPool2d(3, stride=2, padding=1) + + def forward(self, x): + x1 = self.conv_1x1(x) + + x_comb_iter_0_left = self.comb_iter_0_left(x1) + x_comb_iter_0_right = self.comb_iter_0_right(x) + x_comb_iter_0 = x_comb_iter_0_left + x_comb_iter_0_right + + x_comb_iter_1_left = self.comb_iter_1_left(x1) + x_comb_iter_1_right = self.comb_iter_1_right(x) + x_comb_iter_1 = x_comb_iter_1_left + x_comb_iter_1_right + + x_comb_iter_2_left = self.comb_iter_2_left(x1) + x_comb_iter_2_right = self.comb_iter_2_right(x) + x_comb_iter_2 = x_comb_iter_2_left + x_comb_iter_2_right + + x_comb_iter_3_right = self.comb_iter_3_right(x_comb_iter_0) + x_comb_iter_3 = x_comb_iter_3_right + x_comb_iter_1 + + x_comb_iter_4_left = self.comb_iter_4_left(x_comb_iter_0) + x_comb_iter_4_right = self.comb_iter_4_right(x1) + x_comb_iter_4 = x_comb_iter_4_left + x_comb_iter_4_right + + x_out = torch.cat([x_comb_iter_1, x_comb_iter_2, x_comb_iter_3, x_comb_iter_4], 1) + return x_out + + +class CellStem1(nn.Module): + + def __init__(self, stem_filters, num_filters): + super(CellStem1, self).__init__() + self.num_filters = num_filters + self.stem_filters = stem_filters + self.conv_1x1 = nn.Sequential() + self.conv_1x1.add_module('relu', nn.ReLU()) + self.conv_1x1.add_module('conv', nn.Conv2d(2*self.num_filters, self.num_filters, 1, stride=1, bias=False)) + self.conv_1x1.add_module('bn', nn.BatchNorm2d(self.num_filters, eps=0.001, momentum=0.1, affine=True)) + + self.relu = nn.ReLU() + self.path_1 = nn.Sequential() + self.path_1.add_module('avgpool', nn.AvgPool2d(1, stride=2, count_include_pad=False)) + self.path_1.add_module('conv', nn.Conv2d(self.stem_filters, self.num_filters//2, 1, stride=1, bias=False)) + self.path_2 = nn.ModuleList() + self.path_2.add_module('pad', nn.ZeroPad2d((0, 1, 0, 1))) + self.path_2.add_module('avgpool', nn.AvgPool2d(1, stride=2, count_include_pad=False)) + self.path_2.add_module('conv', nn.Conv2d(self.stem_filters, self.num_filters//2, 1, stride=1, bias=False)) + + self.final_path_bn = nn.BatchNorm2d(self.num_filters, eps=0.001, momentum=0.1, affine=True) + + self.comb_iter_0_left = BranchSeparables(self.num_filters, self.num_filters, 5, 2, 2, bias=False) + self.comb_iter_0_right = BranchSeparables(self.num_filters, self.num_filters, 7, 2, 3, bias=False) + + self.comb_iter_1_left = nn.MaxPool2d(3, stride=2, padding=1) + self.comb_iter_1_right = BranchSeparables(self.num_filters, self.num_filters, 7, 2, 3, bias=False) + + self.comb_iter_2_left = nn.AvgPool2d(3, stride=2, padding=1, count_include_pad=False) + self.comb_iter_2_right = BranchSeparables(self.num_filters, self.num_filters, 5, 2, 2, bias=False) + + self.comb_iter_3_right = nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False) + + self.comb_iter_4_left = BranchSeparables(self.num_filters, self.num_filters, 3, 1, 1, bias=False) + self.comb_iter_4_right = nn.MaxPool2d(3, stride=2, padding=1) + + def forward(self, x_conv0, x_stem_0): + x_left = self.conv_1x1(x_stem_0) + + x_relu = self.relu(x_conv0) + # path 1 + x_path1 = self.path_1(x_relu) + # path 2 + x_path2 = self.path_2.pad(x_relu) + x_path2 = x_path2[:, :, 1:, 1:] + x_path2 = self.path_2.avgpool(x_path2) + x_path2 = self.path_2.conv(x_path2) + # final path + x_right = self.final_path_bn(torch.cat([x_path1, x_path2], 1)) + + x_comb_iter_0_left = self.comb_iter_0_left(x_left) + x_comb_iter_0_right = self.comb_iter_0_right(x_right) + x_comb_iter_0 = x_comb_iter_0_left + x_comb_iter_0_right + + x_comb_iter_1_left = self.comb_iter_1_left(x_left) + x_comb_iter_1_right = self.comb_iter_1_right(x_right) + x_comb_iter_1 = x_comb_iter_1_left + x_comb_iter_1_right + + x_comb_iter_2_left = self.comb_iter_2_left(x_left) + x_comb_iter_2_right = self.comb_iter_2_right(x_right) + x_comb_iter_2 = x_comb_iter_2_left + x_comb_iter_2_right + + x_comb_iter_3_right = self.comb_iter_3_right(x_comb_iter_0) + x_comb_iter_3 = x_comb_iter_3_right + x_comb_iter_1 + + x_comb_iter_4_left = self.comb_iter_4_left(x_comb_iter_0) + x_comb_iter_4_right = self.comb_iter_4_right(x_left) + x_comb_iter_4 = x_comb_iter_4_left + x_comb_iter_4_right + + x_out = torch.cat([x_comb_iter_1, x_comb_iter_2, x_comb_iter_3, x_comb_iter_4], 1) + return x_out + + +class FirstCell(nn.Module): + + def __init__(self, in_channels_left, out_channels_left, in_channels_right, out_channels_right): + super(FirstCell, self).__init__() + self.conv_1x1 = nn.Sequential() + self.conv_1x1.add_module('relu', nn.ReLU()) + self.conv_1x1.add_module('conv', nn.Conv2d(in_channels_right, out_channels_right, 1, stride=1, bias=False)) + self.conv_1x1.add_module('bn', nn.BatchNorm2d(out_channels_right, eps=0.001, momentum=0.1, affine=True)) + + self.relu = nn.ReLU() + self.path_1 = nn.Sequential() + self.path_1.add_module('avgpool', nn.AvgPool2d(1, stride=2, count_include_pad=False)) + self.path_1.add_module('conv', nn.Conv2d(in_channels_left, out_channels_left, 1, stride=1, bias=False)) + self.path_2 = nn.ModuleList() + self.path_2.add_module('pad', nn.ZeroPad2d((0, 1, 0, 1))) + self.path_2.add_module('avgpool', nn.AvgPool2d(1, stride=2, count_include_pad=False)) + self.path_2.add_module('conv', nn.Conv2d(in_channels_left, out_channels_left, 1, stride=1, bias=False)) + + self.final_path_bn = nn.BatchNorm2d(out_channels_left * 2, eps=0.001, momentum=0.1, affine=True) + + self.comb_iter_0_left = BranchSeparables(out_channels_right, out_channels_right, 5, 1, 2, bias=False) + self.comb_iter_0_right = BranchSeparables(out_channels_right, out_channels_right, 3, 1, 1, bias=False) + + self.comb_iter_1_left = BranchSeparables(out_channels_right, out_channels_right, 5, 1, 2, bias=False) + self.comb_iter_1_right = BranchSeparables(out_channels_right, out_channels_right, 3, 1, 1, bias=False) + + self.comb_iter_2_left = nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False) + + self.comb_iter_3_left = nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False) + self.comb_iter_3_right = nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False) + + self.comb_iter_4_left = BranchSeparables(out_channels_right, out_channels_right, 3, 1, 1, bias=False) + + def forward(self, x, x_prev): + x_relu = self.relu(x_prev) + # path 1 + x_path1 = self.path_1(x_relu) + # path 2 + x_path2 = self.path_2.pad(x_relu) + x_path2 = x_path2[:, :, 1:, 1:] + x_path2 = self.path_2.avgpool(x_path2) + x_path2 = self.path_2.conv(x_path2) + # final path + x_left = self.final_path_bn(torch.cat([x_path1, x_path2], 1)) + + x_right = self.conv_1x1(x) + + x_comb_iter_0_left = self.comb_iter_0_left(x_right) + x_comb_iter_0_right = self.comb_iter_0_right(x_left) + x_comb_iter_0 = x_comb_iter_0_left + x_comb_iter_0_right + + x_comb_iter_1_left = self.comb_iter_1_left(x_left) + x_comb_iter_1_right = self.comb_iter_1_right(x_left) + x_comb_iter_1 = x_comb_iter_1_left + x_comb_iter_1_right + + x_comb_iter_2_left = self.comb_iter_2_left(x_right) + x_comb_iter_2 = x_comb_iter_2_left + x_left + + x_comb_iter_3_left = self.comb_iter_3_left(x_left) + x_comb_iter_3_right = self.comb_iter_3_right(x_left) + x_comb_iter_3 = x_comb_iter_3_left + x_comb_iter_3_right + + x_comb_iter_4_left = self.comb_iter_4_left(x_right) + x_comb_iter_4 = x_comb_iter_4_left + x_right + + x_out = torch.cat([x_left, x_comb_iter_0, x_comb_iter_1, x_comb_iter_2, x_comb_iter_3, x_comb_iter_4], 1) + return x_out + + +class NormalCell(nn.Module): + + def __init__(self, in_channels_left, out_channels_left, in_channels_right, out_channels_right): + super(NormalCell, self).__init__() + self.conv_prev_1x1 = nn.Sequential() + self.conv_prev_1x1.add_module('relu', nn.ReLU()) + self.conv_prev_1x1.add_module('conv', nn.Conv2d(in_channels_left, out_channels_left, 1, stride=1, bias=False)) + self.conv_prev_1x1.add_module('bn', nn.BatchNorm2d(out_channels_left, eps=0.001, momentum=0.1, affine=True)) + + self.conv_1x1 = nn.Sequential() + self.conv_1x1.add_module('relu', nn.ReLU()) + self.conv_1x1.add_module('conv', nn.Conv2d(in_channels_right, out_channels_right, 1, stride=1, bias=False)) + self.conv_1x1.add_module('bn', nn.BatchNorm2d(out_channels_right, eps=0.001, momentum=0.1, affine=True)) + + self.comb_iter_0_left = BranchSeparables(out_channels_right, out_channels_right, 5, 1, 2, bias=False) + self.comb_iter_0_right = BranchSeparables(out_channels_left, out_channels_left, 3, 1, 1, bias=False) + + self.comb_iter_1_left = BranchSeparables(out_channels_left, out_channels_left, 5, 1, 2, bias=False) + self.comb_iter_1_right = BranchSeparables(out_channels_left, out_channels_left, 3, 1, 1, bias=False) + + self.comb_iter_2_left = nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False) + + self.comb_iter_3_left = nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False) + self.comb_iter_3_right = nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False) + + self.comb_iter_4_left = BranchSeparables(out_channels_right, out_channels_right, 3, 1, 1, bias=False) + + def forward(self, x, x_prev): + x_left = self.conv_prev_1x1(x_prev) + x_right = self.conv_1x1(x) + + x_comb_iter_0_left = self.comb_iter_0_left(x_right) + x_comb_iter_0_right = self.comb_iter_0_right(x_left) + x_comb_iter_0 = x_comb_iter_0_left + x_comb_iter_0_right + + x_comb_iter_1_left = self.comb_iter_1_left(x_left) + x_comb_iter_1_right = self.comb_iter_1_right(x_left) + x_comb_iter_1 = x_comb_iter_1_left + x_comb_iter_1_right + + x_comb_iter_2_left = self.comb_iter_2_left(x_right) + x_comb_iter_2 = x_comb_iter_2_left + x_left + + x_comb_iter_3_left = self.comb_iter_3_left(x_left) + x_comb_iter_3_right = self.comb_iter_3_right(x_left) + x_comb_iter_3 = x_comb_iter_3_left + x_comb_iter_3_right + + x_comb_iter_4_left = self.comb_iter_4_left(x_right) + x_comb_iter_4 = x_comb_iter_4_left + x_right + + x_out = torch.cat([x_left, x_comb_iter_0, x_comb_iter_1, x_comb_iter_2, x_comb_iter_3, x_comb_iter_4], 1) + return x_out + + +class ReductionCell0(nn.Module): + + def __init__(self, in_channels_left, out_channels_left, in_channels_right, out_channels_right): + super(ReductionCell0, self).__init__() + self.conv_prev_1x1 = nn.Sequential() + self.conv_prev_1x1.add_module('relu', nn.ReLU()) + self.conv_prev_1x1.add_module('conv', nn.Conv2d(in_channels_left, out_channels_left, 1, stride=1, bias=False)) + self.conv_prev_1x1.add_module('bn', nn.BatchNorm2d(out_channels_left, eps=0.001, momentum=0.1, affine=True)) + + self.conv_1x1 = nn.Sequential() + self.conv_1x1.add_module('relu', nn.ReLU()) + self.conv_1x1.add_module('conv', nn.Conv2d(in_channels_right, out_channels_right, 1, stride=1, bias=False)) + self.conv_1x1.add_module('bn', nn.BatchNorm2d(out_channels_right, eps=0.001, momentum=0.1, affine=True)) + + self.comb_iter_0_left = BranchSeparablesReduction(out_channels_right, out_channels_right, 5, 2, 2, bias=False) + self.comb_iter_0_right = BranchSeparablesReduction(out_channels_right, out_channels_right, 7, 2, 3, bias=False) + + self.comb_iter_1_left = MaxPoolPad() + self.comb_iter_1_right = BranchSeparablesReduction(out_channels_right, out_channels_right, 7, 2, 3, bias=False) + + self.comb_iter_2_left = AvgPoolPad() + self.comb_iter_2_right = BranchSeparablesReduction(out_channels_right, out_channels_right, 5, 2, 2, bias=False) + + self.comb_iter_3_right = nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False) + + self.comb_iter_4_left = BranchSeparablesReduction(out_channels_right, out_channels_right, 3, 1, 1, bias=False) + self.comb_iter_4_right = MaxPoolPad() + + def forward(self, x, x_prev): + x_left = self.conv_prev_1x1(x_prev) + x_right = self.conv_1x1(x) + + x_comb_iter_0_left = self.comb_iter_0_left(x_right) + x_comb_iter_0_right = self.comb_iter_0_right(x_left) + x_comb_iter_0 = x_comb_iter_0_left + x_comb_iter_0_right + + x_comb_iter_1_left = self.comb_iter_1_left(x_right) + x_comb_iter_1_right = self.comb_iter_1_right(x_left) + x_comb_iter_1 = x_comb_iter_1_left + x_comb_iter_1_right + + x_comb_iter_2_left = self.comb_iter_2_left(x_right) + x_comb_iter_2_right = self.comb_iter_2_right(x_left) + x_comb_iter_2 = x_comb_iter_2_left + x_comb_iter_2_right + + x_comb_iter_3_right = self.comb_iter_3_right(x_comb_iter_0) + x_comb_iter_3 = x_comb_iter_3_right + x_comb_iter_1 + + x_comb_iter_4_left = self.comb_iter_4_left(x_comb_iter_0) + x_comb_iter_4_right = self.comb_iter_4_right(x_right) + x_comb_iter_4 = x_comb_iter_4_left + x_comb_iter_4_right + + x_out = torch.cat([x_comb_iter_1, x_comb_iter_2, x_comb_iter_3, x_comb_iter_4], 1) + return x_out + + +class ReductionCell1(nn.Module): + + def __init__(self, in_channels_left, out_channels_left, in_channels_right, out_channels_right): + super(ReductionCell1, self).__init__() + self.conv_prev_1x1 = nn.Sequential() + self.conv_prev_1x1.add_module('relu', nn.ReLU()) + self.conv_prev_1x1.add_module('conv', nn.Conv2d(in_channels_left, out_channels_left, 1, stride=1, bias=False)) + self.conv_prev_1x1.add_module('bn', nn.BatchNorm2d(out_channels_left, eps=0.001, momentum=0.1, affine=True)) + + self.conv_1x1 = nn.Sequential() + self.conv_1x1.add_module('relu', nn.ReLU()) + self.conv_1x1.add_module('conv', nn.Conv2d(in_channels_right, out_channels_right, 1, stride=1, bias=False)) + self.conv_1x1.add_module('bn', nn.BatchNorm2d(out_channels_right, eps=0.001, momentum=0.1, affine=True)) + + self.comb_iter_0_left = BranchSeparables(out_channels_right, out_channels_right, 5, 2, 2, bias=False) + self.comb_iter_0_right = BranchSeparables(out_channels_right, out_channels_right, 7, 2, 3, bias=False) + + self.comb_iter_1_left = nn.MaxPool2d(3, stride=2, padding=1) + self.comb_iter_1_right = BranchSeparables(out_channels_right, out_channels_right, 7, 2, 3, bias=False) + + self.comb_iter_2_left = nn.AvgPool2d(3, stride=2, padding=1, count_include_pad=False) + self.comb_iter_2_right = BranchSeparables(out_channels_right, out_channels_right, 5, 2, 2, bias=False) + + self.comb_iter_3_right = nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False) + + self.comb_iter_4_left = BranchSeparables(out_channels_right, out_channels_right, 3, 1, 1, bias=False) + self.comb_iter_4_right = nn.MaxPool2d(3, stride=2, padding=1) + + def forward(self, x, x_prev): + x_left = self.conv_prev_1x1(x_prev) + x_right = self.conv_1x1(x) + + x_comb_iter_0_left = self.comb_iter_0_left(x_right) + x_comb_iter_0_right = self.comb_iter_0_right(x_left) + x_comb_iter_0 = x_comb_iter_0_left + x_comb_iter_0_right + + x_comb_iter_1_left = self.comb_iter_1_left(x_right) + x_comb_iter_1_right = self.comb_iter_1_right(x_left) + x_comb_iter_1 = x_comb_iter_1_left + x_comb_iter_1_right + + x_comb_iter_2_left = self.comb_iter_2_left(x_right) + x_comb_iter_2_right = self.comb_iter_2_right(x_left) + x_comb_iter_2 = x_comb_iter_2_left + x_comb_iter_2_right + + x_comb_iter_3_right = self.comb_iter_3_right(x_comb_iter_0) + x_comb_iter_3 = x_comb_iter_3_right + x_comb_iter_1 + + x_comb_iter_4_left = self.comb_iter_4_left(x_comb_iter_0) + x_comb_iter_4_right = self.comb_iter_4_right(x_right) + x_comb_iter_4 = x_comb_iter_4_left + x_comb_iter_4_right + + x_out = torch.cat([x_comb_iter_1, x_comb_iter_2, x_comb_iter_3, x_comb_iter_4], 1) + return x_out + + +class NASNetALarge(nn.Module): + """NASNetALarge (6 @ 4032) """ + + def __init__(self, num_classes=1001, stem_filters=96, penultimate_filters=4032, filters_multiplier=2): + super(NASNetALarge, self).__init__() + self.num_classes = num_classes + self.stem_filters = stem_filters + self.penultimate_filters = penultimate_filters + self.filters_multiplier = filters_multiplier + + filters = self.penultimate_filters // 24 + # 24 is default value for the architecture + + self.conv0 = nn.Sequential() + self.conv0.add_module('conv', nn.Conv2d(in_channels=3, out_channels=self.stem_filters, kernel_size=3, padding=0, stride=2, + bias=False)) + self.conv0.add_module('bn', nn.BatchNorm2d(self.stem_filters, eps=0.001, momentum=0.1, affine=True)) + + self.cell_stem_0 = CellStem0(self.stem_filters, num_filters=filters // (filters_multiplier ** 2)) + self.cell_stem_1 = CellStem1(self.stem_filters, num_filters=filters // filters_multiplier) + + self.cell_0 = FirstCell(in_channels_left=filters, out_channels_left=filters//2, + in_channels_right=2*filters, out_channels_right=filters) + self.cell_1 = NormalCell(in_channels_left=2*filters, out_channels_left=filters, + in_channels_right=6*filters, out_channels_right=filters) + self.cell_2 = NormalCell(in_channels_left=6*filters, out_channels_left=filters, + in_channels_right=6*filters, out_channels_right=filters) + self.cell_3 = NormalCell(in_channels_left=6*filters, out_channels_left=filters, + in_channels_right=6*filters, out_channels_right=filters) + self.cell_4 = NormalCell(in_channels_left=6*filters, out_channels_left=filters, + in_channels_right=6*filters, out_channels_right=filters) + self.cell_5 = NormalCell(in_channels_left=6*filters, out_channels_left=filters, + in_channels_right=6*filters, out_channels_right=filters) + + self.reduction_cell_0 = ReductionCell0(in_channels_left=6*filters, out_channels_left=2*filters, + in_channels_right=6*filters, out_channels_right=2*filters) + + self.cell_6 = FirstCell(in_channels_left=6*filters, out_channels_left=filters, + in_channels_right=8*filters, out_channels_right=2*filters) + self.cell_7 = NormalCell(in_channels_left=8*filters, out_channels_left=2*filters, + in_channels_right=12*filters, out_channels_right=2*filters) + self.cell_8 = NormalCell(in_channels_left=12*filters, out_channels_left=2*filters, + in_channels_right=12*filters, out_channels_right=2*filters) + self.cell_9 = NormalCell(in_channels_left=12*filters, out_channels_left=2*filters, + in_channels_right=12*filters, out_channels_right=2*filters) + self.cell_10 = NormalCell(in_channels_left=12*filters, out_channels_left=2*filters, + in_channels_right=12*filters, out_channels_right=2*filters) + self.cell_11 = NormalCell(in_channels_left=12*filters, out_channels_left=2*filters, + in_channels_right=12*filters, out_channels_right=2*filters) + + self.reduction_cell_1 = ReductionCell1(in_channels_left=12*filters, out_channels_left=4*filters, + in_channels_right=12*filters, out_channels_right=4*filters) + + self.cell_12 = FirstCell(in_channels_left=12*filters, out_channels_left=2*filters, + in_channels_right=16*filters, out_channels_right=4*filters) + self.cell_13 = NormalCell(in_channels_left=16*filters, out_channels_left=4*filters, + in_channels_right=24*filters, out_channels_right=4*filters) + self.cell_14 = NormalCell(in_channels_left=24*filters, out_channels_left=4*filters, + in_channels_right=24*filters, out_channels_right=4*filters) + self.cell_15 = NormalCell(in_channels_left=24*filters, out_channels_left=4*filters, + in_channels_right=24*filters, out_channels_right=4*filters) + self.cell_16 = NormalCell(in_channels_left=24*filters, out_channels_left=4*filters, + in_channels_right=24*filters, out_channels_right=4*filters) + self.cell_17 = NormalCell(in_channels_left=24*filters, out_channels_left=4*filters, + in_channels_right=24*filters, out_channels_right=4*filters) + + self.relu = nn.ReLU() + self.avg_pool = nn.AvgPool2d(11, stride=1, padding=0) + self.dropout = nn.Dropout() + self.last_linear = nn.Linear(24*filters, self.num_classes) + + def features(self, input): + x_conv0 = self.conv0(input) + x_stem_0 = self.cell_stem_0(x_conv0) + x_stem_1 = self.cell_stem_1(x_conv0, x_stem_0) + + x_cell_0 = self.cell_0(x_stem_1, x_stem_0) + x_cell_1 = self.cell_1(x_cell_0, x_stem_1) + x_cell_2 = self.cell_2(x_cell_1, x_cell_0) + x_cell_3 = self.cell_3(x_cell_2, x_cell_1) + x_cell_4 = self.cell_4(x_cell_3, x_cell_2) + x_cell_5 = self.cell_5(x_cell_4, x_cell_3) + + x_reduction_cell_0 = self.reduction_cell_0(x_cell_5, x_cell_4) + + x_cell_6 = self.cell_6(x_reduction_cell_0, x_cell_4) + x_cell_7 = self.cell_7(x_cell_6, x_reduction_cell_0) + x_cell_8 = self.cell_8(x_cell_7, x_cell_6) + x_cell_9 = self.cell_9(x_cell_8, x_cell_7) + x_cell_10 = self.cell_10(x_cell_9, x_cell_8) + x_cell_11 = self.cell_11(x_cell_10, x_cell_9) + + x_reduction_cell_1 = self.reduction_cell_1(x_cell_11, x_cell_10) + + x_cell_12 = self.cell_12(x_reduction_cell_1, x_cell_10) + x_cell_13 = self.cell_13(x_cell_12, x_reduction_cell_1) + x_cell_14 = self.cell_14(x_cell_13, x_cell_12) + x_cell_15 = self.cell_15(x_cell_14, x_cell_13) + x_cell_16 = self.cell_16(x_cell_15, x_cell_14) + x_cell_17 = self.cell_17(x_cell_16, x_cell_15) + return x_cell_17 + + def logits(self, features): + x = self.relu(features) + x = self.avg_pool(x) + x = x.view(x.size(0), -1) + x = self.dropout(x) + x = self.last_linear(x) + return x + + def forward(self, input): + x = self.features(input) + x = self.logits(x) + return x + + +def nasnetalarge(num_classes=1001, pretrained='imagenet'): + r"""NASNetALarge model architecture from the + `"NASNet" `_ paper. + """ + if pretrained: + settings = pretrained_settings['nasnetalarge'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + # both 'imagenet'&'imagenet+background' are loaded from same parameters + model = NASNetALarge(num_classes=1001) + model.load_state_dict(model_zoo.load_url(settings['url'])) + + if pretrained == 'imagenet': + new_last_linear = nn.Linear(model.last_linear.in_features, 1000) + new_last_linear.weight.data = model.last_linear.weight.data[1:] + new_last_linear.bias.data = model.last_linear.bias.data[1:] + model.last_linear = new_last_linear + + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + + model.mean = settings['mean'] + model.std = settings['std'] + else: + model = NASNetALarge(num_classes=num_classes) + return model + + +if __name__ == "__main__": + + model = NASNetALarge() + input = Variable(torch.randn(2, 3, 331, 331)) + + output = model(input) + print(output.size()) + + diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/nasnet_mobile.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/nasnet_mobile.py new file mode 100644 index 0000000000000000000000000000000000000000..03cd194193ca2be0961024a867b3a7c978eea29a --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/nasnet_mobile.py @@ -0,0 +1,672 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +""" +NASNet Mobile +Thanks to Anastasiia (https://github.com/DagnyT) for the great help, support and motivation! + + +------------------------------------------------------------------------------------ + Architecture | Top-1 Acc | Top-5 Acc | Multiply-Adds | Params (M) +------------------------------------------------------------------------------------ +| NASNet-A (4 @ 1056) | 74.08% | 91.74% | 564 M | 5.3 | +------------------------------------------------------------------------------------ +# References: + - [Learning Transferable Architectures for Scalable Image Recognition] + (https://arxiv.org/abs/1707.07012) +""" +from __future__ import print_function, division, absolute_import +import torch +import torch.nn as nn +import torch.nn.functional as F +import torch.utils.model_zoo as model_zoo +from torch.autograd import Variable +import numpy as np + +pretrained_settings = { + 'nasnetamobile': { + 'imagenet': { + #'url': 'https://github.com/veronikayurchuk/pretrained-models.pytorch/releases/download/v1.0/nasnetmobile-7e03cead.pth.tar', + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/nasnetamobile-7e03cead.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], # resize 256 + 'input_range': [0, 1], + 'mean': [0.5, 0.5, 0.5], + 'std': [0.5, 0.5, 0.5], + 'num_classes': 1000 + }, + # 'imagenet+background': { + # # 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/nasnetalarge-a1897284.pth', + # 'input_space': 'RGB', + # 'input_size': [3, 224, 224], # resize 256 + # 'input_range': [0, 1], + # 'mean': [0.5, 0.5, 0.5], + # 'std': [0.5, 0.5, 0.5], + # 'num_classes': 1001 + # } + } +} + + +class MaxPoolPad(nn.Module): + + def __init__(self): + super(MaxPoolPad, self).__init__() + self.pad = nn.ZeroPad2d((1, 0, 1, 0)) + self.pool = nn.MaxPool2d(3, stride=2, padding=1) + + def forward(self, x): + x = self.pad(x) + x = self.pool(x) + x = x[:, :, 1:, 1:].contiguous() + return x + + +class AvgPoolPad(nn.Module): + + def __init__(self, stride=2, padding=1): + super(AvgPoolPad, self).__init__() + self.pad = nn.ZeroPad2d((1, 0, 1, 0)) + self.pool = nn.AvgPool2d(3, stride=stride, padding=padding, count_include_pad=False) + + def forward(self, x): + x = self.pad(x) + x = self.pool(x) + x = x[:, :, 1:, 1:].contiguous() + return x + + +class SeparableConv2d(nn.Module): + + def __init__(self, in_channels, out_channels, dw_kernel, dw_stride, dw_padding, bias=False): + super(SeparableConv2d, self).__init__() + self.depthwise_conv2d = nn.Conv2d(in_channels, in_channels, dw_kernel, + stride=dw_stride, + padding=dw_padding, + bias=bias, + groups=in_channels) + self.pointwise_conv2d = nn.Conv2d(in_channels, out_channels, 1, stride=1, bias=bias) + + def forward(self, x): + x = self.depthwise_conv2d(x) + x = self.pointwise_conv2d(x) + return x + + +class BranchSeparables(nn.Module): + + def __init__(self, in_channels, out_channels, kernel_size, stride, padding, name=None, bias=False): + super(BranchSeparables, self).__init__() + self.relu = nn.ReLU() + self.separable_1 = SeparableConv2d(in_channels, in_channels, kernel_size, stride, padding, bias=bias) + self.bn_sep_1 = nn.BatchNorm2d(in_channels, eps=0.001, momentum=0.1, affine=True) + self.relu1 = nn.ReLU() + self.separable_2 = SeparableConv2d(in_channels, out_channels, kernel_size, 1, padding, bias=bias) + self.bn_sep_2 = nn.BatchNorm2d(out_channels, eps=0.001, momentum=0.1, affine=True) + self.name = name + + def forward(self, x): + x = self.relu(x) + if self.name == 'specific': + x = nn.ZeroPad2d((1, 0, 1, 0))(x) + x = self.separable_1(x) + if self.name == 'specific': + x = x[:, :, 1:, 1:].contiguous() + + x = self.bn_sep_1(x) + x = self.relu1(x) + x = self.separable_2(x) + x = self.bn_sep_2(x) + return x + + +class BranchSeparablesStem(nn.Module): + + def __init__(self, in_channels, out_channels, kernel_size, stride, padding, bias=False): + super(BranchSeparablesStem, self).__init__() + self.relu = nn.ReLU() + self.separable_1 = SeparableConv2d(in_channels, out_channels, kernel_size, stride, padding, bias=bias) + self.bn_sep_1 = nn.BatchNorm2d(out_channels, eps=0.001, momentum=0.1, affine=True) + self.relu1 = nn.ReLU() + self.separable_2 = SeparableConv2d(out_channels, out_channels, kernel_size, 1, padding, bias=bias) + self.bn_sep_2 = nn.BatchNorm2d(out_channels, eps=0.001, momentum=0.1, affine=True) + + def forward(self, x): + x = self.relu(x) + x = self.separable_1(x) + x = self.bn_sep_1(x) + x = self.relu1(x) + x = self.separable_2(x) + x = self.bn_sep_2(x) + return x + + +class BranchSeparablesReduction(BranchSeparables): + + def __init__(self, in_channels, out_channels, kernel_size, stride, padding, z_padding=1, bias=False): + BranchSeparables.__init__(self, in_channels, out_channels, kernel_size, stride, padding, bias) + self.padding = nn.ZeroPad2d((z_padding, 0, z_padding, 0)) + + def forward(self, x): + x = self.relu(x) + x = self.padding(x) + x = self.separable_1(x) + x = x[:, :, 1:, 1:].contiguous() + x = self.bn_sep_1(x) + x = self.relu1(x) + x = self.separable_2(x) + x = self.bn_sep_2(x) + return x + + +class CellStem0(nn.Module): + def __init__(self, stem_filters, num_filters=42): + super(CellStem0, self).__init__() + self.num_filters = num_filters + self.stem_filters = stem_filters + self.conv_1x1 = nn.Sequential() + self.conv_1x1.add_module('relu', nn.ReLU()) + self.conv_1x1.add_module('conv', nn.Conv2d(self.stem_filters, self.num_filters, 1, stride=1, bias=False)) + self.conv_1x1.add_module('bn', nn.BatchNorm2d(self.num_filters, eps=0.001, momentum=0.1, affine=True)) + + self.comb_iter_0_left = BranchSeparables(self.num_filters, self.num_filters, 5, 2, 2) + self.comb_iter_0_right = BranchSeparablesStem(self.stem_filters, self.num_filters, 7, 2, 3, bias=False) + + self.comb_iter_1_left = nn.MaxPool2d(3, stride=2, padding=1) + self.comb_iter_1_right = BranchSeparablesStem(self.stem_filters, self.num_filters, 7, 2, 3, bias=False) + + self.comb_iter_2_left = nn.AvgPool2d(3, stride=2, padding=1, count_include_pad=False) + self.comb_iter_2_right = BranchSeparablesStem(self.stem_filters, self.num_filters, 5, 2, 2, bias=False) + + self.comb_iter_3_right = nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False) + + self.comb_iter_4_left = BranchSeparables(self.num_filters, self.num_filters, 3, 1, 1, bias=False) + self.comb_iter_4_right = nn.MaxPool2d(3, stride=2, padding=1) + + def forward(self, x): + x1 = self.conv_1x1(x) + + x_comb_iter_0_left = self.comb_iter_0_left(x1) + x_comb_iter_0_right = self.comb_iter_0_right(x) + x_comb_iter_0 = x_comb_iter_0_left + x_comb_iter_0_right + + x_comb_iter_1_left = self.comb_iter_1_left(x1) + x_comb_iter_1_right = self.comb_iter_1_right(x) + x_comb_iter_1 = x_comb_iter_1_left + x_comb_iter_1_right + + x_comb_iter_2_left = self.comb_iter_2_left(x1) + x_comb_iter_2_right = self.comb_iter_2_right(x) + x_comb_iter_2 = x_comb_iter_2_left + x_comb_iter_2_right + + x_comb_iter_3_right = self.comb_iter_3_right(x_comb_iter_0) + x_comb_iter_3 = x_comb_iter_3_right + x_comb_iter_1 + + x_comb_iter_4_left = self.comb_iter_4_left(x_comb_iter_0) + x_comb_iter_4_right = self.comb_iter_4_right(x1) + x_comb_iter_4 = x_comb_iter_4_left + x_comb_iter_4_right + + x_out = torch.cat([x_comb_iter_1, x_comb_iter_2, x_comb_iter_3, x_comb_iter_4], 1) + return x_out + + +class CellStem1(nn.Module): + + def __init__(self, stem_filters, num_filters): + super(CellStem1, self).__init__() + self.num_filters = num_filters + self.stem_filters = stem_filters + self.conv_1x1 = nn.Sequential() + self.conv_1x1.add_module('relu', nn.ReLU()) + self.conv_1x1.add_module('conv', nn.Conv2d(2*self.num_filters, self.num_filters, 1, stride=1, bias=False)) + self.conv_1x1.add_module('bn', nn.BatchNorm2d(self.num_filters, eps=0.001, momentum=0.1, affine=True)) + + self.relu = nn.ReLU() + self.path_1 = nn.Sequential() + self.path_1.add_module('avgpool', nn.AvgPool2d(1, stride=2, count_include_pad=False)) + self.path_1.add_module('conv', nn.Conv2d(self.stem_filters, self.num_filters//2, 1, stride=1, bias=False)) + self.path_2 = nn.ModuleList() + self.path_2.add_module('pad', nn.ZeroPad2d((0, 1, 0, 1))) + self.path_2.add_module('avgpool', nn.AvgPool2d(1, stride=2, count_include_pad=False)) + self.path_2.add_module('conv', nn.Conv2d(self.stem_filters, self.num_filters//2, 1, stride=1, bias=False)) + + self.final_path_bn = nn.BatchNorm2d(self.num_filters, eps=0.001, momentum=0.1, affine=True) + + self.comb_iter_0_left = BranchSeparables(self.num_filters, self.num_filters, 5, 2, 2, name='specific', bias=False) + self.comb_iter_0_right = BranchSeparables(self.num_filters, self.num_filters, 7, 2, 3, name='specific', bias=False) + + # self.comb_iter_1_left = nn.MaxPool2d(3, stride=2, padding=1) + self.comb_iter_1_left = MaxPoolPad() + self.comb_iter_1_right = BranchSeparables(self.num_filters, self.num_filters, 7, 2, 3, name='specific', bias=False) + + # self.comb_iter_2_left = nn.AvgPool2d(3, stride=2, padding=1, count_include_pad=False) + self.comb_iter_2_left = AvgPoolPad() + self.comb_iter_2_right = BranchSeparables(self.num_filters, self.num_filters, 5, 2, 2, name='specific', bias=False) + + self.comb_iter_3_right = nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False) + + self.comb_iter_4_left = BranchSeparables(self.num_filters, self.num_filters, 3, 1, 1, name='specific', bias=False) + # self.comb_iter_4_right = nn.MaxPool2d(3, stride=2, padding=1) + self.comb_iter_4_right = MaxPoolPad() + + def forward(self, x_conv0, x_stem_0): + x_left = self.conv_1x1(x_stem_0) + + x_relu = self.relu(x_conv0) + # path 1 + x_path1 = self.path_1(x_relu) + # path 2 + x_path2 = self.path_2.pad(x_relu) + x_path2 = x_path2[:, :, 1:, 1:] + x_path2 = self.path_2.avgpool(x_path2) + x_path2 = self.path_2.conv(x_path2) + # final path + x_right = self.final_path_bn(torch.cat([x_path1, x_path2], 1)) + + x_comb_iter_0_left = self.comb_iter_0_left(x_left) + x_comb_iter_0_right = self.comb_iter_0_right(x_right) + x_comb_iter_0 = x_comb_iter_0_left + x_comb_iter_0_right + + x_comb_iter_1_left = self.comb_iter_1_left(x_left) + x_comb_iter_1_right = self.comb_iter_1_right(x_right) + x_comb_iter_1 = x_comb_iter_1_left + x_comb_iter_1_right + + x_comb_iter_2_left = self.comb_iter_2_left(x_left) + x_comb_iter_2_right = self.comb_iter_2_right(x_right) + x_comb_iter_2 = x_comb_iter_2_left + x_comb_iter_2_right + + x_comb_iter_3_right = self.comb_iter_3_right(x_comb_iter_0) + x_comb_iter_3 = x_comb_iter_3_right + x_comb_iter_1 + + x_comb_iter_4_left = self.comb_iter_4_left(x_comb_iter_0) + x_comb_iter_4_right = self.comb_iter_4_right(x_left) + x_comb_iter_4 = x_comb_iter_4_left + x_comb_iter_4_right + + x_out = torch.cat([x_comb_iter_1, x_comb_iter_2, x_comb_iter_3, x_comb_iter_4], 1) + return x_out + + +class FirstCell(nn.Module): + + def __init__(self, in_channels_left, out_channels_left, in_channels_right, out_channels_right): + super(FirstCell, self).__init__() + self.conv_1x1 = nn.Sequential() + self.conv_1x1.add_module('relu', nn.ReLU()) + self.conv_1x1.add_module('conv', nn.Conv2d(in_channels_right, out_channels_right, 1, stride=1, bias=False)) + self.conv_1x1.add_module('bn', nn.BatchNorm2d(out_channels_right, eps=0.001, momentum=0.1, affine=True)) + + self.relu = nn.ReLU() + self.path_1 = nn.Sequential() + self.path_1.add_module('avgpool', nn.AvgPool2d(1, stride=2, count_include_pad=False)) + self.path_1.add_module('conv', nn.Conv2d(in_channels_left, out_channels_left, 1, stride=1, bias=False)) + self.path_2 = nn.ModuleList() + self.path_2.add_module('pad', nn.ZeroPad2d((0, 1, 0, 1))) + self.path_2.add_module('avgpool', nn.AvgPool2d(1, stride=2, count_include_pad=False)) + self.path_2.add_module('conv', nn.Conv2d(in_channels_left, out_channels_left, 1, stride=1, bias=False)) + + self.final_path_bn = nn.BatchNorm2d(out_channels_left * 2, eps=0.001, momentum=0.1, affine=True) + + self.comb_iter_0_left = BranchSeparables(out_channels_right, out_channels_right, 5, 1, 2, bias=False) + self.comb_iter_0_right = BranchSeparables(out_channels_right, out_channels_right, 3, 1, 1, bias=False) + + self.comb_iter_1_left = BranchSeparables(out_channels_right, out_channels_right, 5, 1, 2, bias=False) + self.comb_iter_1_right = BranchSeparables(out_channels_right, out_channels_right, 3, 1, 1, bias=False) + + self.comb_iter_2_left = nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False) + + self.comb_iter_3_left = nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False) + self.comb_iter_3_right = nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False) + + self.comb_iter_4_left = BranchSeparables(out_channels_right, out_channels_right, 3, 1, 1, bias=False) + + def forward(self, x, x_prev): + x_relu = self.relu(x_prev) + # path 1 + x_path1 = self.path_1(x_relu) + # path 2 + x_path2 = self.path_2.pad(x_relu) + x_path2 = x_path2[:, :, 1:, 1:] + x_path2 = self.path_2.avgpool(x_path2) + x_path2 = self.path_2.conv(x_path2) + # final path + x_left = self.final_path_bn(torch.cat([x_path1, x_path2], 1)) + + x_right = self.conv_1x1(x) + + x_comb_iter_0_left = self.comb_iter_0_left(x_right) + x_comb_iter_0_right = self.comb_iter_0_right(x_left) + x_comb_iter_0 = x_comb_iter_0_left + x_comb_iter_0_right + + x_comb_iter_1_left = self.comb_iter_1_left(x_left) + x_comb_iter_1_right = self.comb_iter_1_right(x_left) + x_comb_iter_1 = x_comb_iter_1_left + x_comb_iter_1_right + + x_comb_iter_2_left = self.comb_iter_2_left(x_right) + x_comb_iter_2 = x_comb_iter_2_left + x_left + + x_comb_iter_3_left = self.comb_iter_3_left(x_left) + x_comb_iter_3_right = self.comb_iter_3_right(x_left) + x_comb_iter_3 = x_comb_iter_3_left + x_comb_iter_3_right + + x_comb_iter_4_left = self.comb_iter_4_left(x_right) + x_comb_iter_4 = x_comb_iter_4_left + x_right + + x_out = torch.cat([x_left, x_comb_iter_0, x_comb_iter_1, x_comb_iter_2, x_comb_iter_3, x_comb_iter_4], 1) + return x_out + + +class NormalCell(nn.Module): + + def __init__(self, in_channels_left, out_channels_left, in_channels_right, out_channels_right): + super(NormalCell, self).__init__() + self.conv_prev_1x1 = nn.Sequential() + self.conv_prev_1x1.add_module('relu', nn.ReLU()) + self.conv_prev_1x1.add_module('conv', nn.Conv2d(in_channels_left, out_channels_left, 1, stride=1, bias=False)) + self.conv_prev_1x1.add_module('bn', nn.BatchNorm2d(out_channels_left, eps=0.001, momentum=0.1, affine=True)) + + self.conv_1x1 = nn.Sequential() + self.conv_1x1.add_module('relu', nn.ReLU()) + self.conv_1x1.add_module('conv', nn.Conv2d(in_channels_right, out_channels_right, 1, stride=1, bias=False)) + self.conv_1x1.add_module('bn', nn.BatchNorm2d(out_channels_right, eps=0.001, momentum=0.1, affine=True)) + + self.comb_iter_0_left = BranchSeparables(out_channels_right, out_channels_right, 5, 1, 2, bias=False) + self.comb_iter_0_right = BranchSeparables(out_channels_left, out_channels_left, 3, 1, 1, bias=False) + + self.comb_iter_1_left = BranchSeparables(out_channels_left, out_channels_left, 5, 1, 2, bias=False) + self.comb_iter_1_right = BranchSeparables(out_channels_left, out_channels_left, 3, 1, 1, bias=False) + + self.comb_iter_2_left = nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False) + + self.comb_iter_3_left = nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False) + self.comb_iter_3_right = nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False) + + self.comb_iter_4_left = BranchSeparables(out_channels_right, out_channels_right, 3, 1, 1, bias=False) + + def forward(self, x, x_prev): + x_left = self.conv_prev_1x1(x_prev) + x_right = self.conv_1x1(x) + + x_comb_iter_0_left = self.comb_iter_0_left(x_right) + x_comb_iter_0_right = self.comb_iter_0_right(x_left) + x_comb_iter_0 = x_comb_iter_0_left + x_comb_iter_0_right + + x_comb_iter_1_left = self.comb_iter_1_left(x_left) + x_comb_iter_1_right = self.comb_iter_1_right(x_left) + x_comb_iter_1 = x_comb_iter_1_left + x_comb_iter_1_right + + x_comb_iter_2_left = self.comb_iter_2_left(x_right) + x_comb_iter_2 = x_comb_iter_2_left + x_left + + x_comb_iter_3_left = self.comb_iter_3_left(x_left) + x_comb_iter_3_right = self.comb_iter_3_right(x_left) + x_comb_iter_3 = x_comb_iter_3_left + x_comb_iter_3_right + + x_comb_iter_4_left = self.comb_iter_4_left(x_right) + x_comb_iter_4 = x_comb_iter_4_left + x_right + + x_out = torch.cat([x_left, x_comb_iter_0, x_comb_iter_1, x_comb_iter_2, x_comb_iter_3, x_comb_iter_4], 1) + return x_out + + +class ReductionCell0(nn.Module): + + def __init__(self, in_channels_left, out_channels_left, in_channels_right, out_channels_right): + super(ReductionCell0, self).__init__() + self.conv_prev_1x1 = nn.Sequential() + self.conv_prev_1x1.add_module('relu', nn.ReLU()) + self.conv_prev_1x1.add_module('conv', nn.Conv2d(in_channels_left, out_channels_left, 1, stride=1, bias=False)) + self.conv_prev_1x1.add_module('bn', nn.BatchNorm2d(out_channels_left, eps=0.001, momentum=0.1, affine=True)) + + self.conv_1x1 = nn.Sequential() + self.conv_1x1.add_module('relu', nn.ReLU()) + self.conv_1x1.add_module('conv', nn.Conv2d(in_channels_right, out_channels_right, 1, stride=1, bias=False)) + self.conv_1x1.add_module('bn', nn.BatchNorm2d(out_channels_right, eps=0.001, momentum=0.1, affine=True)) + + self.comb_iter_0_left = BranchSeparablesReduction(out_channels_right, out_channels_right, 5, 2, 2, bias=False) + self.comb_iter_0_right = BranchSeparablesReduction(out_channels_right, out_channels_right, 7, 2, 3, bias=False) + + self.comb_iter_1_left = MaxPoolPad() + self.comb_iter_1_right = BranchSeparablesReduction(out_channels_right, out_channels_right, 7, 2, 3, bias=False) + + self.comb_iter_2_left = AvgPoolPad() + self.comb_iter_2_right = BranchSeparablesReduction(out_channels_right, out_channels_right, 5, 2, 2, bias=False) + + self.comb_iter_3_right = nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False) + + self.comb_iter_4_left = BranchSeparablesReduction(out_channels_right, out_channels_right, 3, 1, 1, bias=False) + self.comb_iter_4_right = MaxPoolPad() + + def forward(self, x, x_prev): + x_left = self.conv_prev_1x1(x_prev) + x_right = self.conv_1x1(x) + + x_comb_iter_0_left = self.comb_iter_0_left(x_right) + x_comb_iter_0_right = self.comb_iter_0_right(x_left) + x_comb_iter_0 = x_comb_iter_0_left + x_comb_iter_0_right + + x_comb_iter_1_left = self.comb_iter_1_left(x_right) + x_comb_iter_1_right = self.comb_iter_1_right(x_left) + x_comb_iter_1 = x_comb_iter_1_left + x_comb_iter_1_right + + x_comb_iter_2_left = self.comb_iter_2_left(x_right) + x_comb_iter_2_right = self.comb_iter_2_right(x_left) + x_comb_iter_2 = x_comb_iter_2_left + x_comb_iter_2_right + + x_comb_iter_3_right = self.comb_iter_3_right(x_comb_iter_0) + x_comb_iter_3 = x_comb_iter_3_right + x_comb_iter_1 + + x_comb_iter_4_left = self.comb_iter_4_left(x_comb_iter_0) + x_comb_iter_4_right = self.comb_iter_4_right(x_right) + x_comb_iter_4 = x_comb_iter_4_left + x_comb_iter_4_right + + x_out = torch.cat([x_comb_iter_1, x_comb_iter_2, x_comb_iter_3, x_comb_iter_4], 1) + return x_out + + +class ReductionCell1(nn.Module): + + def __init__(self, in_channels_left, out_channels_left, in_channels_right, out_channels_right): + super(ReductionCell1, self).__init__() + self.conv_prev_1x1 = nn.Sequential() + self.conv_prev_1x1.add_module('relu', nn.ReLU()) + self.conv_prev_1x1.add_module('conv', nn.Conv2d(in_channels_left, out_channels_left, 1, stride=1, bias=False)) + self.conv_prev_1x1.add_module('bn', nn.BatchNorm2d(out_channels_left, eps=0.001, momentum=0.1, affine=True)) + + self.conv_1x1 = nn.Sequential() + self.conv_1x1.add_module('relu', nn.ReLU()) + self.conv_1x1.add_module('conv', nn.Conv2d(in_channels_right, out_channels_right, 1, stride=1, bias=False)) + self.conv_1x1.add_module('bn', nn.BatchNorm2d(out_channels_right, eps=0.001, momentum=0.1, affine=True)) + + self.comb_iter_0_left = BranchSeparables(out_channels_right, out_channels_right, 5, 2, 2, name='specific', bias=False) + self.comb_iter_0_right = BranchSeparables(out_channels_right, out_channels_right, 7, 2, 3, name='specific', bias=False) + + # self.comb_iter_1_left = nn.MaxPool2d(3, stride=2, padding=1) + self.comb_iter_1_left = MaxPoolPad() + self.comb_iter_1_right = BranchSeparables(out_channels_right, out_channels_right, 7, 2, 3, name='specific', bias=False) + + # self.comb_iter_2_left = nn.AvgPool2d(3, stride=2, padding=1, count_include_pad=False) + self.comb_iter_2_left = AvgPoolPad() + self.comb_iter_2_right = BranchSeparables(out_channels_right, out_channels_right, 5, 2, 2, name='specific', bias=False) + + self.comb_iter_3_right = nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False) + + self.comb_iter_4_left = BranchSeparables(out_channels_right, out_channels_right, 3, 1, 1, name='specific', bias=False) + # self.comb_iter_4_right = nn.MaxPool2d(3, stride=2, padding=1) + self.comb_iter_4_right =MaxPoolPad() + + def forward(self, x, x_prev): + x_left = self.conv_prev_1x1(x_prev) + x_right = self.conv_1x1(x) + + x_comb_iter_0_left = self.comb_iter_0_left(x_right) + x_comb_iter_0_right = self.comb_iter_0_right(x_left) + x_comb_iter_0 = x_comb_iter_0_left + x_comb_iter_0_right + + x_comb_iter_1_left = self.comb_iter_1_left(x_right) + x_comb_iter_1_right = self.comb_iter_1_right(x_left) + x_comb_iter_1 = x_comb_iter_1_left + x_comb_iter_1_right + + x_comb_iter_2_left = self.comb_iter_2_left(x_right) + x_comb_iter_2_right = self.comb_iter_2_right(x_left) + x_comb_iter_2 = x_comb_iter_2_left + x_comb_iter_2_right + + x_comb_iter_3_right = self.comb_iter_3_right(x_comb_iter_0) + x_comb_iter_3 = x_comb_iter_3_right + x_comb_iter_1 + + x_comb_iter_4_left = self.comb_iter_4_left(x_comb_iter_0) + x_comb_iter_4_right = self.comb_iter_4_right(x_right) + x_comb_iter_4 = x_comb_iter_4_left + x_comb_iter_4_right + + x_out = torch.cat([x_comb_iter_1, x_comb_iter_2, x_comb_iter_3, x_comb_iter_4], 1) + return x_out + + +class NASNetAMobile(nn.Module): + """NASNetAMobile (4 @ 1056) """ + + def __init__(self, num_classes=1000, stem_filters=32, penultimate_filters=1056, filters_multiplier=2): + super(NASNetAMobile, self).__init__() + self.num_classes = num_classes + self.stem_filters = stem_filters + self.penultimate_filters = penultimate_filters + self.filters_multiplier = filters_multiplier + + filters = self.penultimate_filters // 24 + # 24 is default value for the architecture + + self.conv0 = nn.Sequential() + self.conv0.add_module('conv', nn.Conv2d(in_channels=3, out_channels=self.stem_filters, kernel_size=3, padding=0, stride=2, + bias=False)) + self.conv0.add_module('bn', nn.BatchNorm2d(self.stem_filters, eps=0.001, momentum=0.1, affine=True)) + + self.cell_stem_0 = CellStem0(self.stem_filters, num_filters=filters // (filters_multiplier ** 2)) + self.cell_stem_1 = CellStem1(self.stem_filters, num_filters=filters // filters_multiplier) + + self.cell_0 = FirstCell(in_channels_left=filters, out_channels_left=filters//2, # 1, 0.5 + in_channels_right=2*filters, out_channels_right=filters) # 2, 1 + self.cell_1 = NormalCell(in_channels_left=2*filters, out_channels_left=filters, # 2, 1 + in_channels_right=6*filters, out_channels_right=filters) # 6, 1 + self.cell_2 = NormalCell(in_channels_left=6*filters, out_channels_left=filters, # 6, 1 + in_channels_right=6*filters, out_channels_right=filters) # 6, 1 + self.cell_3 = NormalCell(in_channels_left=6*filters, out_channels_left=filters, # 6, 1 + in_channels_right=6*filters, out_channels_right=filters) # 6, 1 + + self.reduction_cell_0 = ReductionCell0(in_channels_left=6*filters, out_channels_left=2*filters, # 6, 2 + in_channels_right=6*filters, out_channels_right=2*filters) # 6, 2 + + self.cell_6 = FirstCell(in_channels_left=6*filters, out_channels_left=filters, # 6, 1 + in_channels_right=8*filters, out_channels_right=2*filters) # 8, 2 + self.cell_7 = NormalCell(in_channels_left=8*filters, out_channels_left=2*filters, # 8, 2 + in_channels_right=12*filters, out_channels_right=2*filters) # 12, 2 + self.cell_8 = NormalCell(in_channels_left=12*filters, out_channels_left=2*filters, # 12, 2 + in_channels_right=12*filters, out_channels_right=2*filters) # 12, 2 + self.cell_9 = NormalCell(in_channels_left=12*filters, out_channels_left=2*filters, # 12, 2 + in_channels_right=12*filters, out_channels_right=2*filters) # 12, 2 + + self.reduction_cell_1 = ReductionCell1(in_channels_left=12*filters, out_channels_left=4*filters, # 12, 4 + in_channels_right=12*filters, out_channels_right=4*filters) # 12, 4 + + self.cell_12 = FirstCell(in_channels_left=12*filters, out_channels_left=2*filters, # 12, 2 + in_channels_right=16*filters, out_channels_right=4*filters) # 16, 4 + self.cell_13 = NormalCell(in_channels_left=16*filters, out_channels_left=4*filters, # 16, 4 + in_channels_right=24*filters, out_channels_right=4*filters) # 24, 4 + self.cell_14 = NormalCell(in_channels_left=24*filters, out_channels_left=4*filters, # 24, 4 + in_channels_right=24*filters, out_channels_right=4*filters) # 24, 4 + self.cell_15 = NormalCell(in_channels_left=24*filters, out_channels_left=4*filters, # 24, 4 + in_channels_right=24*filters, out_channels_right=4*filters) # 24, 4 + + self.relu = nn.ReLU() + self.avg_pool = nn.AvgPool2d(7, stride=1, padding=0) + self.dropout = nn.Dropout() + self.last_linear = nn.Linear(24*filters, self.num_classes) + + def features(self, input): + x_conv0 = self.conv0(input) + x_stem_0 = self.cell_stem_0(x_conv0) + x_stem_1 = self.cell_stem_1(x_conv0, x_stem_0) + + x_cell_0 = self.cell_0(x_stem_1, x_stem_0) + x_cell_1 = self.cell_1(x_cell_0, x_stem_1) + x_cell_2 = self.cell_2(x_cell_1, x_cell_0) + x_cell_3 = self.cell_3(x_cell_2, x_cell_1) + + x_reduction_cell_0 = self.reduction_cell_0(x_cell_3, x_cell_2) + + x_cell_6 = self.cell_6(x_reduction_cell_0, x_cell_3) + x_cell_7 = self.cell_7(x_cell_6, x_reduction_cell_0) + x_cell_8 = self.cell_8(x_cell_7, x_cell_6) + x_cell_9 = self.cell_9(x_cell_8, x_cell_7) + + x_reduction_cell_1 = self.reduction_cell_1(x_cell_9, x_cell_8) + + x_cell_12 = self.cell_12(x_reduction_cell_1, x_cell_9) + x_cell_13 = self.cell_13(x_cell_12, x_reduction_cell_1) + x_cell_14 = self.cell_14(x_cell_13, x_cell_12) + x_cell_15 = self.cell_15(x_cell_14, x_cell_13) + return x_cell_15 + + def logits(self, features): + x = self.relu(features) + x = self.avg_pool(x) + x = x.view(x.size(0), -1) + x = self.dropout(x) + x = self.last_linear(x) + return x + + def forward(self, input): + x = self.features(input) + x = self.logits(x) + return x + + +def nasnetamobile(num_classes=1000, pretrained='imagenet'): + r"""NASNetALarge model architecture from the + `"NASNet" `_ paper. + """ + if pretrained: + settings = pretrained_settings['nasnetamobile'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + # both 'imagenet'&'imagenet+background' are loaded from same parameters + model = NASNetAMobile(num_classes=num_classes) + model.load_state_dict(model_zoo.load_url(settings['url'], map_location=None)) + + # if pretrained == 'imagenet': + # new_last_linear = nn.Linear(model.last_linear.in_features, 1000) + # new_last_linear.weight.data = model.last_linear.weight.data[1:] + # new_last_linear.bias.data = model.last_linear.bias.data[1:] + # model.last_linear = new_last_linear + + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + + model.mean = settings['mean'] + model.std = settings['std'] + else: + settings = pretrained_settings['nasnetamobile']['imagenet'] + model = NASNetAMobile(num_classes=num_classes) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + + model.mean = settings['mean'] + model.std = settings['std'] + return model + + +if __name__ == "__main__": + + model = NASNetAMobile() + input = Variable(torch.randn(2, 3, 224, 224)) + output = model(input) + + print(output.size()) diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/pnasnet.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/pnasnet.py new file mode 100644 index 0000000000000000000000000000000000000000..cbcf2d5454cdee389cb187e744fe10d870c09c9e --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/pnasnet.py @@ -0,0 +1,412 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +from __future__ import print_function, division, absolute_import +from collections import OrderedDict + +import torch +import torch.nn as nn +import torch.utils.model_zoo as model_zoo + + +pretrained_settings = { + 'pnasnet5large': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/pnasnet5large-bf079911.pth', + 'input_space': 'RGB', + 'input_size': [3, 331, 331], + 'input_range': [0, 1], + 'mean': [0.5, 0.5, 0.5], + 'std': [0.5, 0.5, 0.5], + 'num_classes': 1000 + }, + 'imagenet+background': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/pnasnet5large-bf079911.pth', + 'input_space': 'RGB', + 'input_size': [3, 331, 331], + 'input_range': [0, 1], + 'mean': [0.5, 0.5, 0.5], + 'std': [0.5, 0.5, 0.5], + 'num_classes': 1001 + } + } +} + + +class MaxPool(nn.Module): + + def __init__(self, kernel_size, stride=1, padding=1, zero_pad=False): + super(MaxPool, self).__init__() + self.zero_pad = nn.ZeroPad2d((1, 0, 1, 0)) if zero_pad else None + self.pool = nn.MaxPool2d(kernel_size, stride=stride, padding=padding) + + def forward(self, x): + if self.zero_pad: + x = self.zero_pad(x) + x = self.pool(x) + if self.zero_pad: + x = x[:, :, 1:, 1:] + return x + + +class SeparableConv2d(nn.Module): + + def __init__(self, in_channels, out_channels, dw_kernel_size, dw_stride, + dw_padding): + super(SeparableConv2d, self).__init__() + self.depthwise_conv2d = nn.Conv2d(in_channels, in_channels, + kernel_size=dw_kernel_size, + stride=dw_stride, padding=dw_padding, + groups=in_channels, bias=False) + self.pointwise_conv2d = nn.Conv2d(in_channels, out_channels, + kernel_size=1, bias=False) + + def forward(self, x): + x = self.depthwise_conv2d(x) + x = self.pointwise_conv2d(x) + return x + + +class BranchSeparables(nn.Module): + + def __init__(self, in_channels, out_channels, kernel_size, stride=1, + stem_cell=False, zero_pad=False): + super(BranchSeparables, self).__init__() + padding = kernel_size // 2 + middle_channels = out_channels if stem_cell else in_channels + self.zero_pad = nn.ZeroPad2d((1, 0, 1, 0)) if zero_pad else None + self.relu_1 = nn.ReLU() + self.separable_1 = SeparableConv2d(in_channels, middle_channels, + kernel_size, dw_stride=stride, + dw_padding=padding) + self.bn_sep_1 = nn.BatchNorm2d(middle_channels, eps=0.001) + self.relu_2 = nn.ReLU() + self.separable_2 = SeparableConv2d(middle_channels, out_channels, + kernel_size, dw_stride=1, + dw_padding=padding) + self.bn_sep_2 = nn.BatchNorm2d(out_channels, eps=0.001) + + def forward(self, x): + x = self.relu_1(x) + if self.zero_pad: + x = self.zero_pad(x) + x = self.separable_1(x) + if self.zero_pad: + x = x[:, :, 1:, 1:].contiguous() + x = self.bn_sep_1(x) + x = self.relu_2(x) + x = self.separable_2(x) + x = self.bn_sep_2(x) + return x + + +class ReluConvBn(nn.Module): + + def __init__(self, in_channels, out_channels, kernel_size, stride=1): + super(ReluConvBn, self).__init__() + self.relu = nn.ReLU() + self.conv = nn.Conv2d(in_channels, out_channels, + kernel_size=kernel_size, stride=stride, + bias=False) + self.bn = nn.BatchNorm2d(out_channels, eps=0.001) + + def forward(self, x): + x = self.relu(x) + x = self.conv(x) + x = self.bn(x) + return x + + +class FactorizedReduction(nn.Module): + + def __init__(self, in_channels, out_channels): + super(FactorizedReduction, self).__init__() + self.relu = nn.ReLU() + self.path_1 = nn.Sequential(OrderedDict([ + ('avgpool', nn.AvgPool2d(1, stride=2, count_include_pad=False)), + ('conv', nn.Conv2d(in_channels, out_channels // 2, + kernel_size=1, bias=False)), + ])) + self.path_2 = nn.Sequential(OrderedDict([ + ('pad', nn.ZeroPad2d((0, 1, 0, 1))), + ('avgpool', nn.AvgPool2d(1, stride=2, count_include_pad=False)), + ('conv', nn.Conv2d(in_channels, out_channels // 2, + kernel_size=1, bias=False)), + ])) + self.final_path_bn = nn.BatchNorm2d(out_channels, eps=0.001) + + def forward(self, x): + x = self.relu(x) + + x_path1 = self.path_1(x) + + x_path2 = self.path_2.pad(x) + x_path2 = x_path2[:, :, 1:, 1:] + x_path2 = self.path_2.avgpool(x_path2) + x_path2 = self.path_2.conv(x_path2) + + out = self.final_path_bn(torch.cat([x_path1, x_path2], 1)) + return out + + +class CellBase(nn.Module): + + def cell_forward(self, x_left, x_right): + x_comb_iter_0_left = self.comb_iter_0_left(x_left) + x_comb_iter_0_right = self.comb_iter_0_right(x_left) + x_comb_iter_0 = x_comb_iter_0_left + x_comb_iter_0_right + + x_comb_iter_1_left = self.comb_iter_1_left(x_right) + x_comb_iter_1_right = self.comb_iter_1_right(x_right) + x_comb_iter_1 = x_comb_iter_1_left + x_comb_iter_1_right + + x_comb_iter_2_left = self.comb_iter_2_left(x_right) + x_comb_iter_2_right = self.comb_iter_2_right(x_right) + x_comb_iter_2 = x_comb_iter_2_left + x_comb_iter_2_right + + x_comb_iter_3_left = self.comb_iter_3_left(x_comb_iter_2) + x_comb_iter_3_right = self.comb_iter_3_right(x_right) + x_comb_iter_3 = x_comb_iter_3_left + x_comb_iter_3_right + + x_comb_iter_4_left = self.comb_iter_4_left(x_left) + if self.comb_iter_4_right: + x_comb_iter_4_right = self.comb_iter_4_right(x_right) + else: + x_comb_iter_4_right = x_right + x_comb_iter_4 = x_comb_iter_4_left + x_comb_iter_4_right + + x_out = torch.cat( + [x_comb_iter_0, x_comb_iter_1, x_comb_iter_2, x_comb_iter_3, + x_comb_iter_4], 1) + return x_out + + +class CellStem0(CellBase): + + def __init__(self, in_channels_left, out_channels_left, in_channels_right, + out_channels_right): + super(CellStem0, self).__init__() + self.conv_1x1 = ReluConvBn(in_channels_right, out_channels_right, + kernel_size=1) + self.comb_iter_0_left = BranchSeparables(in_channels_left, + out_channels_left, + kernel_size=5, stride=2, + stem_cell=True) + self.comb_iter_0_right = nn.Sequential(OrderedDict([ + ('max_pool', MaxPool(3, stride=2)), + ('conv', nn.Conv2d(in_channels_left, out_channels_left, + kernel_size=1, bias=False)), + ('bn', nn.BatchNorm2d(out_channels_left, eps=0.001)), + ])) + self.comb_iter_1_left = BranchSeparables(out_channels_right, + out_channels_right, + kernel_size=7, stride=2) + self.comb_iter_1_right = MaxPool(3, stride=2) + self.comb_iter_2_left = BranchSeparables(out_channels_right, + out_channels_right, + kernel_size=5, stride=2) + self.comb_iter_2_right = BranchSeparables(out_channels_right, + out_channels_right, + kernel_size=3, stride=2) + self.comb_iter_3_left = BranchSeparables(out_channels_right, + out_channels_right, + kernel_size=3) + self.comb_iter_3_right = MaxPool(3, stride=2) + self.comb_iter_4_left = BranchSeparables(in_channels_right, + out_channels_right, + kernel_size=3, stride=2, + stem_cell=True) + self.comb_iter_4_right = ReluConvBn(out_channels_right, + out_channels_right, + kernel_size=1, stride=2) + + def forward(self, x_left): + x_right = self.conv_1x1(x_left) + x_out = self.cell_forward(x_left, x_right) + return x_out + + +class Cell(CellBase): + + def __init__(self, in_channels_left, out_channels_left, in_channels_right, + out_channels_right, is_reduction=False, zero_pad=False, + match_prev_layer_dimensions=False): + super(Cell, self).__init__() + + # If `is_reduction` is set to `True` stride 2 is used for + # convolutional and pooling layers to reduce the spatial size of + # the output of a cell approximately by a factor of 2. + stride = 2 if is_reduction else 1 + + # If `match_prev_layer_dimensions` is set to `True` + # `FactorizedReduction` is used to reduce the spatial size + # of the left input of a cell approximately by a factor of 2. + self.match_prev_layer_dimensions = match_prev_layer_dimensions + if match_prev_layer_dimensions: + self.conv_prev_1x1 = FactorizedReduction(in_channels_left, + out_channels_left) + else: + self.conv_prev_1x1 = ReluConvBn(in_channels_left, + out_channels_left, kernel_size=1) + + self.conv_1x1 = ReluConvBn(in_channels_right, out_channels_right, + kernel_size=1) + self.comb_iter_0_left = BranchSeparables(out_channels_left, + out_channels_left, + kernel_size=5, stride=stride, + zero_pad=zero_pad) + self.comb_iter_0_right = MaxPool(3, stride=stride, zero_pad=zero_pad) + self.comb_iter_1_left = BranchSeparables(out_channels_right, + out_channels_right, + kernel_size=7, stride=stride, + zero_pad=zero_pad) + self.comb_iter_1_right = MaxPool(3, stride=stride, zero_pad=zero_pad) + self.comb_iter_2_left = BranchSeparables(out_channels_right, + out_channels_right, + kernel_size=5, stride=stride, + zero_pad=zero_pad) + self.comb_iter_2_right = BranchSeparables(out_channels_right, + out_channels_right, + kernel_size=3, stride=stride, + zero_pad=zero_pad) + self.comb_iter_3_left = BranchSeparables(out_channels_right, + out_channels_right, + kernel_size=3) + self.comb_iter_3_right = MaxPool(3, stride=stride, zero_pad=zero_pad) + self.comb_iter_4_left = BranchSeparables(out_channels_left, + out_channels_left, + kernel_size=3, stride=stride, + zero_pad=zero_pad) + if is_reduction: + self.comb_iter_4_right = ReluConvBn(out_channels_right, + out_channels_right, + kernel_size=1, stride=stride) + else: + self.comb_iter_4_right = None + + def forward(self, x_left, x_right): + x_left = self.conv_prev_1x1(x_left) + x_right = self.conv_1x1(x_right) + x_out = self.cell_forward(x_left, x_right) + return x_out + + +class PNASNet5Large(nn.Module): + def __init__(self, num_classes=1001): + super(PNASNet5Large, self).__init__() + self.num_classes = num_classes + self.conv_0 = nn.Sequential(OrderedDict([ + ('conv', nn.Conv2d(3, 96, kernel_size=3, stride=2, bias=False)), + ('bn', nn.BatchNorm2d(96, eps=0.001)) + ])) + self.cell_stem_0 = CellStem0(in_channels_left=96, out_channels_left=54, + in_channels_right=96, + out_channels_right=54) + self.cell_stem_1 = Cell(in_channels_left=96, out_channels_left=108, + in_channels_right=270, out_channels_right=108, + match_prev_layer_dimensions=True, + is_reduction=True) + self.cell_0 = Cell(in_channels_left=270, out_channels_left=216, + in_channels_right=540, out_channels_right=216, + match_prev_layer_dimensions=True) + self.cell_1 = Cell(in_channels_left=540, out_channels_left=216, + in_channels_right=1080, out_channels_right=216) + self.cell_2 = Cell(in_channels_left=1080, out_channels_left=216, + in_channels_right=1080, out_channels_right=216) + self.cell_3 = Cell(in_channels_left=1080, out_channels_left=216, + in_channels_right=1080, out_channels_right=216) + self.cell_4 = Cell(in_channels_left=1080, out_channels_left=432, + in_channels_right=1080, out_channels_right=432, + is_reduction=True, zero_pad=True) + self.cell_5 = Cell(in_channels_left=1080, out_channels_left=432, + in_channels_right=2160, out_channels_right=432, + match_prev_layer_dimensions=True) + self.cell_6 = Cell(in_channels_left=2160, out_channels_left=432, + in_channels_right=2160, out_channels_right=432) + self.cell_7 = Cell(in_channels_left=2160, out_channels_left=432, + in_channels_right=2160, out_channels_right=432) + self.cell_8 = Cell(in_channels_left=2160, out_channels_left=864, + in_channels_right=2160, out_channels_right=864, + is_reduction=True) + self.cell_9 = Cell(in_channels_left=2160, out_channels_left=864, + in_channels_right=4320, out_channels_right=864, + match_prev_layer_dimensions=True) + self.cell_10 = Cell(in_channels_left=4320, out_channels_left=864, + in_channels_right=4320, out_channels_right=864) + self.cell_11 = Cell(in_channels_left=4320, out_channels_left=864, + in_channels_right=4320, out_channels_right=864) + self.relu = nn.ReLU() + self.avg_pool = nn.AvgPool2d(11, stride=1, padding=0) + self.dropout = nn.Dropout(0.5) + self.last_linear = nn.Linear(4320, num_classes) + + def features(self, x): + x_conv_0 = self.conv_0(x) + x_stem_0 = self.cell_stem_0(x_conv_0) + x_stem_1 = self.cell_stem_1(x_conv_0, x_stem_0) + x_cell_0 = self.cell_0(x_stem_0, x_stem_1) + x_cell_1 = self.cell_1(x_stem_1, x_cell_0) + x_cell_2 = self.cell_2(x_cell_0, x_cell_1) + x_cell_3 = self.cell_3(x_cell_1, x_cell_2) + x_cell_4 = self.cell_4(x_cell_2, x_cell_3) + x_cell_5 = self.cell_5(x_cell_3, x_cell_4) + x_cell_6 = self.cell_6(x_cell_4, x_cell_5) + x_cell_7 = self.cell_7(x_cell_5, x_cell_6) + x_cell_8 = self.cell_8(x_cell_6, x_cell_7) + x_cell_9 = self.cell_9(x_cell_7, x_cell_8) + x_cell_10 = self.cell_10(x_cell_8, x_cell_9) + x_cell_11 = self.cell_11(x_cell_9, x_cell_10) + return x_cell_11 + + def logits(self, features): + x = self.relu(features) + x = self.avg_pool(x) + x = x.view(x.size(0), -1) + x = self.dropout(x) + x = self.last_linear(x) + return x + + def forward(self, input): + x = self.features(input) + x = self.logits(x) + return x + + +def pnasnet5large(num_classes=1001, pretrained='imagenet'): + r"""PNASNet-5 model architecture from the + `"Progressive Neural Architecture Search" + `_ paper. + """ + if pretrained: + settings = pretrained_settings['pnasnet5large'][pretrained] + assert num_classes == settings[ + 'num_classes'], 'num_classes should be {}, but is {}'.format( + settings['num_classes'], num_classes) + + # both 'imagenet'&'imagenet+background' are loaded from same parameters + model = PNASNet5Large(num_classes=1001) + model.load_state_dict(model_zoo.load_url(settings['url'])) + + if pretrained == 'imagenet': + new_last_linear = nn.Linear(model.last_linear.in_features, 1000) + new_last_linear.weight.data = model.last_linear.weight.data[1:] + new_last_linear.bias.data = model.last_linear.bias.data[1:] + model.last_linear = new_last_linear + + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + + model.mean = settings['mean'] + model.std = settings['std'] + else: + model = PNASNet5Large(num_classes=num_classes) + return model diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/polynet.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/polynet.py new file mode 100644 index 0000000000000000000000000000000000000000..1a9b611178e36b3cc0e9506e4f5c2e37b396a5c6 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/polynet.py @@ -0,0 +1,491 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +from __future__ import print_function, division, absolute_import +import torch +import torch.nn as nn +from torch.utils import model_zoo + +__all__ = ['PolyNet', 'polynet'] + +pretrained_settings = { + 'polynet': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/polynet-f71d82a5.pth', + 'input_space': 'RGB', + 'input_size': [3, 331, 331], + 'input_range': [0, 1], + 'mean': [0.485, 0.456, 0.406], + 'std': [0.229, 0.224, 0.225], + 'num_classes': 1000 + }, + } +} + + +class BasicConv2d(nn.Module): + + def __init__(self, in_planes, out_planes, kernel_size, stride=1, padding=0, + output_relu=True): + super(BasicConv2d, self).__init__() + self.conv = nn.Conv2d(in_planes, out_planes, kernel_size=kernel_size, + stride=stride, padding=padding, bias=False) + self.bn = nn.BatchNorm2d(out_planes) + self.relu = nn.ReLU() if output_relu else None + + def forward(self, x): + x = self.conv(x) + x = self.bn(x) + if self.relu: + x = self.relu(x) + return x + + +class PolyConv2d(nn.Module): + """A block that is used inside poly-N (poly-2, poly-3, and so on) modules. + The Convolution layer is shared between all Inception blocks inside + a poly-N module. BatchNorm layers are not shared between Inception blocks + and therefore the number of BatchNorm layers is equal to the number of + Inception blocks inside a poly-N module. + """ + + def __init__(self, in_planes, out_planes, kernel_size, num_blocks, + stride=1, padding=0): + super(PolyConv2d, self).__init__() + self.conv = nn.Conv2d(in_planes, out_planes, kernel_size=kernel_size, + stride=stride, padding=padding, bias=False) + self.bn_blocks = nn.ModuleList([ + nn.BatchNorm2d(out_planes) for _ in range(num_blocks) + ]) + self.relu = nn.ReLU() + + def forward(self, x, block_index): + x = self.conv(x) + bn = self.bn_blocks[block_index] + x = bn(x) + x = self.relu(x) + return x + + +class Stem(nn.Module): + + def __init__(self): + super(Stem, self).__init__() + self.conv1 = nn.Sequential( + BasicConv2d(3, 32, kernel_size=3, stride=2), + BasicConv2d(32, 32, kernel_size=3), + BasicConv2d(32, 64, kernel_size=3, padding=1), + ) + self.conv1_pool_branch = nn.MaxPool2d(3, stride=2) + self.conv1_branch = BasicConv2d(64, 96, kernel_size=3, stride=2) + self.conv2_short = nn.Sequential( + BasicConv2d(160, 64, kernel_size=1), + BasicConv2d(64, 96, kernel_size=3), + ) + self.conv2_long = nn.Sequential( + BasicConv2d(160, 64, kernel_size=1), + BasicConv2d(64, 64, kernel_size=(7, 1), padding=(3, 0)), + BasicConv2d(64, 64, kernel_size=(1, 7), padding=(0, 3)), + BasicConv2d(64, 96, kernel_size=3), + ) + self.conv2_pool_branch = nn.MaxPool2d(3, stride=2) + self.conv2_branch = BasicConv2d(192, 192, kernel_size=3, stride=2) + + def forward(self, x): + x = self.conv1(x) + + x0 = self.conv1_pool_branch(x) + x1 = self.conv1_branch(x) + x = torch.cat((x0, x1), 1) + + x0 = self.conv2_short(x) + x1 = self.conv2_long(x) + x = torch.cat((x0, x1), 1) + + x0 = self.conv2_pool_branch(x) + x1 = self.conv2_branch(x) + out = torch.cat((x0, x1), 1) + return out + + +class BlockA(nn.Module): + """Inception-ResNet-A block.""" + + def __init__(self): + super(BlockA, self).__init__() + self.path0 = nn.Sequential( + BasicConv2d(384, 32, kernel_size=1), + BasicConv2d(32, 48, kernel_size=3, padding=1), + BasicConv2d(48, 64, kernel_size=3, padding=1), + ) + self.path1 = nn.Sequential( + BasicConv2d(384, 32, kernel_size=1), + BasicConv2d(32, 32, kernel_size=3, padding=1), + ) + self.path2 = BasicConv2d(384, 32, kernel_size=1) + self.conv2d = BasicConv2d(128, 384, kernel_size=1, output_relu=False) + + def forward(self, x): + x0 = self.path0(x) + x1 = self.path1(x) + x2 = self.path2(x) + out = torch.cat((x0, x1, x2), 1) + out = self.conv2d(out) + return out + + +class BlockB(nn.Module): + """Inception-ResNet-B block.""" + + def __init__(self): + super(BlockB, self).__init__() + self.path0 = nn.Sequential( + BasicConv2d(1152, 128, kernel_size=1), + BasicConv2d(128, 160, kernel_size=(1, 7), padding=(0, 3)), + BasicConv2d(160, 192, kernel_size=(7, 1), padding=(3, 0)), + ) + self.path1 = BasicConv2d(1152, 192, kernel_size=1) + self.conv2d = BasicConv2d(384, 1152, kernel_size=1, output_relu=False) + + def forward(self, x): + x0 = self.path0(x) + x1 = self.path1(x) + out = torch.cat((x0, x1), 1) + out = self.conv2d(out) + return out + + +class BlockC(nn.Module): + """Inception-ResNet-C block.""" + + def __init__(self): + super(BlockC, self).__init__() + self.path0 = nn.Sequential( + BasicConv2d(2048, 192, kernel_size=1), + BasicConv2d(192, 224, kernel_size=(1, 3), padding=(0, 1)), + BasicConv2d(224, 256, kernel_size=(3, 1), padding=(1, 0)), + ) + self.path1 = BasicConv2d(2048, 192, kernel_size=1) + self.conv2d = BasicConv2d(448, 2048, kernel_size=1, output_relu=False) + + def forward(self, x): + x0 = self.path0(x) + x1 = self.path1(x) + out = torch.cat((x0, x1), 1) + out = self.conv2d(out) + return out + + +class ReductionA(nn.Module): + """A dimensionality reduction block that is placed after stage-a + Inception-ResNet blocks. + """ + + def __init__(self): + super(ReductionA, self).__init__() + self.path0 = nn.Sequential( + BasicConv2d(384, 256, kernel_size=1), + BasicConv2d(256, 256, kernel_size=3, padding=1), + BasicConv2d(256, 384, kernel_size=3, stride=2), + ) + self.path1 = BasicConv2d(384, 384, kernel_size=3, stride=2) + self.path2 = nn.MaxPool2d(3, stride=2) + + def forward(self, x): + x0 = self.path0(x) + x1 = self.path1(x) + x2 = self.path2(x) + out = torch.cat((x0, x1, x2), 1) + return out + + +class ReductionB(nn.Module): + """A dimensionality reduction block that is placed after stage-b + Inception-ResNet blocks. + """ + def __init__(self): + super(ReductionB, self).__init__() + self.path0 = nn.Sequential( + BasicConv2d(1152, 256, kernel_size=1), + BasicConv2d(256, 256, kernel_size=3, padding=1), + BasicConv2d(256, 256, kernel_size=3, stride=2), + ) + self.path1 = nn.Sequential( + BasicConv2d(1152, 256, kernel_size=1), + BasicConv2d(256, 256, kernel_size=3, stride=2), + ) + self.path2 = nn.Sequential( + BasicConv2d(1152, 256, kernel_size=1), + BasicConv2d(256, 384, kernel_size=3, stride=2), + ) + self.path3 = nn.MaxPool2d(3, stride=2) + + def forward(self, x): + x0 = self.path0(x) + x1 = self.path1(x) + x2 = self.path2(x) + x3 = self.path3(x) + out = torch.cat((x0, x1, x2, x3), 1) + return out + + +class InceptionResNetBPoly(nn.Module): + """Base class for constructing poly-N Inception-ResNet-B modules. + When `num_blocks` is equal to 1, a module will have only a first-order path + and will be equal to a standard Inception-ResNet-B block. + When `num_blocks` is equal to 2, a module will have first-order and + second-order paths and will be called Inception-ResNet-B poly-2 module. + Increasing value of the `num_blocks` parameter will produce a higher order + Inception-ResNet-B poly-N modules. + """ + + def __init__(self, scale, num_blocks): + super(InceptionResNetBPoly, self).__init__() + assert num_blocks >= 1, 'num_blocks should be greater or equal to 1' + self.scale = scale + self.num_blocks = num_blocks + self.path0_1x1 = PolyConv2d(1152, 128, kernel_size=1, + num_blocks=self.num_blocks) + self.path0_1x7 = PolyConv2d(128, 160, kernel_size=(1, 7), + num_blocks=self.num_blocks, padding=(0, 3)) + self.path0_7x1 = PolyConv2d(160, 192, kernel_size=(7, 1), + num_blocks=self.num_blocks, padding=(3, 0)) + self.path1 = PolyConv2d(1152, 192, kernel_size=1, + num_blocks=self.num_blocks) + # conv2d blocks are not shared between Inception-ResNet-B blocks + self.conv2d_blocks = nn.ModuleList([ + BasicConv2d(384, 1152, kernel_size=1, output_relu=False) + for _ in range(self.num_blocks) + ]) + self.relu = nn.ReLU() + + def forward_block(self, x, block_index): + x0 = self.path0_1x1(x, block_index) + x0 = self.path0_1x7(x0, block_index) + x0 = self.path0_7x1(x0, block_index) + x1 = self.path1(x, block_index) + out = torch.cat((x0, x1), 1) + conv2d_block = self.conv2d_blocks[block_index] + out = conv2d_block(out) + return out + + def forward(self, x): + out = x + for block_index in range(self.num_blocks): + x = self.forward_block(x, block_index) + out = out + x * self.scale + x = self.relu(x) + out = self.relu(out) + return out + + +class InceptionResNetCPoly(nn.Module): + """Base class for constructing poly-N Inception-ResNet-C modules. + When `num_blocks` is equal to 1, a module will have only a first-order path + and will be equal to a standard Inception-ResNet-C block. + When `num_blocks` is equal to 2, a module will have first-order and + second-order paths and will be called Inception-ResNet-C poly-2 module. + Increasing value of the `num_blocks` parameter will produce a higher order + Inception-ResNet-C poly-N modules. + """ + + def __init__(self, scale, num_blocks): + super(InceptionResNetCPoly, self).__init__() + assert num_blocks >= 1, 'num_blocks should be greater or equal to 1' + self.scale = scale + self.num_blocks = num_blocks + self.path0_1x1 = PolyConv2d(2048, 192, kernel_size=1, + num_blocks=self.num_blocks) + self.path0_1x3 = PolyConv2d(192, 224, kernel_size=(1, 3), + num_blocks=self.num_blocks, padding=(0, 1)) + self.path0_3x1 = PolyConv2d(224, 256, kernel_size=(3, 1), + num_blocks=self.num_blocks, padding=(1, 0)) + self.path1 = PolyConv2d(2048, 192, kernel_size=1, + num_blocks=self.num_blocks) + # conv2d blocks are not shared between Inception-ResNet-C blocks + self.conv2d_blocks = nn.ModuleList([ + BasicConv2d(448, 2048, kernel_size=1, output_relu=False) + for _ in range(self.num_blocks) + ]) + self.relu = nn.ReLU() + + def forward_block(self, x, block_index): + x0 = self.path0_1x1(x, block_index) + x0 = self.path0_1x3(x0, block_index) + x0 = self.path0_3x1(x0, block_index) + x1 = self.path1(x, block_index) + out = torch.cat((x0, x1), 1) + conv2d_block = self.conv2d_blocks[block_index] + out = conv2d_block(out) + return out + + def forward(self, x): + out = x + for block_index in range(self.num_blocks): + x = self.forward_block(x, block_index) + out = out + x * self.scale + x = self.relu(x) + out = self.relu(out) + return out + + +class MultiWay(nn.Module): + """Base class for constructing N-way modules (2-way, 3-way, and so on).""" + + def __init__(self, scale, block_cls, num_blocks): + super(MultiWay, self).__init__() + assert num_blocks >= 1, 'num_blocks should be greater or equal to 1' + self.scale = scale + self.blocks = nn.ModuleList([block_cls() for _ in range(num_blocks)]) + self.relu = nn.ReLU() + + def forward(self, x): + out = x + for block in self.blocks: + out = out + block(x) * self.scale + out = self.relu(out) + return out + + +# Some helper classes to simplify the construction of PolyNet + +class InceptionResNetA2Way(MultiWay): + + def __init__(self, scale): + super(InceptionResNetA2Way, self).__init__(scale, block_cls=BlockA, + num_blocks=2) + + +class InceptionResNetB2Way(MultiWay): + + def __init__(self, scale): + super(InceptionResNetB2Way, self).__init__(scale, block_cls=BlockB, + num_blocks=2) + + +class InceptionResNetC2Way(MultiWay): + + def __init__(self, scale): + super(InceptionResNetC2Way, self).__init__(scale, block_cls=BlockC, + num_blocks=2) + + +class InceptionResNetBPoly3(InceptionResNetBPoly): + + def __init__(self, scale): + super(InceptionResNetBPoly3, self).__init__(scale, num_blocks=3) + + +class InceptionResNetCPoly3(InceptionResNetCPoly): + + def __init__(self, scale): + super(InceptionResNetCPoly3, self).__init__(scale, num_blocks=3) + + +class PolyNet(nn.Module): + + def __init__(self, num_classes=1000): + super(PolyNet, self).__init__() + self.stem = Stem() + self.stage_a = nn.Sequential( + InceptionResNetA2Way(scale=1), + InceptionResNetA2Way(scale=0.992308), + InceptionResNetA2Way(scale=0.984615), + InceptionResNetA2Way(scale=0.976923), + InceptionResNetA2Way(scale=0.969231), + InceptionResNetA2Way(scale=0.961538), + InceptionResNetA2Way(scale=0.953846), + InceptionResNetA2Way(scale=0.946154), + InceptionResNetA2Way(scale=0.938462), + InceptionResNetA2Way(scale=0.930769), + ) + self.reduction_a = ReductionA() + self.stage_b = nn.Sequential( + InceptionResNetBPoly3(scale=0.923077), + InceptionResNetB2Way(scale=0.915385), + InceptionResNetBPoly3(scale=0.907692), + InceptionResNetB2Way(scale=0.9), + InceptionResNetBPoly3(scale=0.892308), + InceptionResNetB2Way(scale=0.884615), + InceptionResNetBPoly3(scale=0.876923), + InceptionResNetB2Way(scale=0.869231), + InceptionResNetBPoly3(scale=0.861538), + InceptionResNetB2Way(scale=0.853846), + InceptionResNetBPoly3(scale=0.846154), + InceptionResNetB2Way(scale=0.838462), + InceptionResNetBPoly3(scale=0.830769), + InceptionResNetB2Way(scale=0.823077), + InceptionResNetBPoly3(scale=0.815385), + InceptionResNetB2Way(scale=0.807692), + InceptionResNetBPoly3(scale=0.8), + InceptionResNetB2Way(scale=0.792308), + InceptionResNetBPoly3(scale=0.784615), + InceptionResNetB2Way(scale=0.776923), + ) + self.reduction_b = ReductionB() + self.stage_c = nn.Sequential( + InceptionResNetCPoly3(scale=0.769231), + InceptionResNetC2Way(scale=0.761538), + InceptionResNetCPoly3(scale=0.753846), + InceptionResNetC2Way(scale=0.746154), + InceptionResNetCPoly3(scale=0.738462), + InceptionResNetC2Way(scale=0.730769), + InceptionResNetCPoly3(scale=0.723077), + InceptionResNetC2Way(scale=0.715385), + InceptionResNetCPoly3(scale=0.707692), + InceptionResNetC2Way(scale=0.7), + ) + self.avg_pool = nn.AvgPool2d(9, stride=1) + self.dropout = nn.Dropout(0.2) + self.last_linear = nn.Linear(2048, num_classes) + + def features(self, x): + x = self.stem(x) + x = self.stage_a(x) + x = self.reduction_a(x) + x = self.stage_b(x) + x = self.reduction_b(x) + x = self.stage_c(x) + return x + + def logits(self, x): + x = self.avg_pool(x) + x = self.dropout(x) + x = x.view(x.size(0), -1) + x = self.last_linear(x) + return x + + def forward(self, x): + x = self.features(x) + x = self.logits(x) + return x + + +def polynet(num_classes=1000, pretrained='imagenet'): + """PolyNet architecture from the paper + 'PolyNet: A Pursuit of Structural Diversity in Very Deep Networks' + https://arxiv.org/abs/1611.05725 + """ + if pretrained: + settings = pretrained_settings['polynet'][pretrained] + assert num_classes == settings['num_classes'], \ + 'num_classes should be {}, but is {}'.format( + settings['num_classes'], num_classes) + model = PolyNet(num_classes=num_classes) + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + else: + model = PolyNet(num_classes=num_classes) + return model diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/resnet_features/__init__.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/resnet_features/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..87af356fe42c97fa8379aedb708498a05f1f36b6 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/resnet_features/__init__.py @@ -0,0 +1,3 @@ +from __future__ import print_function, division, absolute_import +from .resnext101_32x4d_features import resnext101_32x4d_features +from .resnext101_64x4d_features import resnext101_64x4d_features \ No newline at end of file diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/resnet_features/resnext101_32x4d_features.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/resnet_features/resnext101_32x4d_features.py new file mode 100644 index 0000000000000000000000000000000000000000..29148aef7e17dca0874b8a79895b9328dba708a4 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/resnet_features/resnext101_32x4d_features.py @@ -0,0 +1,708 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +from __future__ import print_function, division, absolute_import +import torch +import torch.nn as nn +from torch.autograd import Variable +from functools import reduce + +class LambdaBase(nn.Sequential): + def __init__(self, *args): + super(LambdaBase, self).__init__(*args) + + def forward_prepare(self, input): + output = [] + for module in self._modules.values(): + output.append(module(input)) + return output if output else input + +class Lambda(LambdaBase): + def __init__(self, *args): + super(Lambda, self).__init__(*args) + self.lambda_func = identity + + def forward(self, input): + return self.lambda_func(self.forward_prepare(input)) + +class LambdaMap(LambdaBase): + def __init__(self, *args): + super(LambdaMap, self).__init__(*args) + self.lambda_func = identity + + def forward(self, input): + return list(map(self.lambda_func,self.forward_prepare(input))) + +class LambdaReduce(LambdaBase): + def __init__(self, *args): + super(LambdaReduce, self).__init__(*args) + self.lambda_func = add + + def forward(self, input): + return reduce(self.lambda_func,self.forward_prepare(input)) + +def identity(x): return x + +def add(x, y): return x + y + +resnext101_32x4d_features = nn.Sequential( # Sequential, + nn.Conv2d(3,64,(7, 7),(2, 2),(3, 3),1,1,bias=False), + nn.BatchNorm2d(64), + nn.ReLU(), + nn.MaxPool2d((3, 3),(2, 2),(1, 1)), + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(64,128,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(128), + nn.ReLU(), + nn.Conv2d(128,128,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(128), + nn.ReLU(), + ), + nn.Conv2d(128,256,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(256), + ), + nn.Sequential( # Sequential, + nn.Conv2d(64,256,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(256), + ), + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(256,128,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(128), + nn.ReLU(), + nn.Conv2d(128,128,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(128), + nn.ReLU(), + ), + nn.Conv2d(128,256,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(256), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(256,128,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(128), + nn.ReLU(), + nn.Conv2d(128,128,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(128), + nn.ReLU(), + ), + nn.Conv2d(128,256,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(256), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + ), + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(256,256,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(256), + nn.ReLU(), + nn.Conv2d(256,256,(3, 3),(2, 2),(1, 1),1,32,bias=False), + nn.BatchNorm2d(256), + nn.ReLU(), + ), + nn.Conv2d(256,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + ), + nn.Sequential( # Sequential, + nn.Conv2d(256,512,(1, 1),(2, 2),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + ), + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(512,256,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(256), + nn.ReLU(), + nn.Conv2d(256,256,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(256), + nn.ReLU(), + ), + nn.Conv2d(256,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(512,256,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(256), + nn.ReLU(), + nn.Conv2d(256,256,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(256), + nn.ReLU(), + ), + nn.Conv2d(256,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(512,256,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(256), + nn.ReLU(), + nn.Conv2d(256,256,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(256), + nn.ReLU(), + ), + nn.Conv2d(256,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + ), + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(512,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(2, 2),(1, 1),1,32,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + nn.Sequential( # Sequential, + nn.Conv2d(512,1024,(1, 1),(2, 2),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(1024,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(1024,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(1024,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(1024,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(1024,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(1024,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(1024,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(1024,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(1024,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(1024,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(1024,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(1024,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(1024,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(1024,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(1024,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(1024,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(1024,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(1024,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(1024,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(1024,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(1024,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(1024,512,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + ), + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(1024,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024,1024,(3, 3),(2, 2),(1, 1),1,32,bias=False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024,2048,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(2048), + ), + nn.Sequential( # Sequential, + nn.Conv2d(1024,2048,(1, 1),(2, 2),(0, 0),1,1,bias=False), + nn.BatchNorm2d(2048), + ), + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(2048,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024,1024,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024,2048,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(2048), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + nn.Sequential( # Sequential, + LambdaMap( # ConcatTable, + nn.Sequential( # Sequential, + nn.Sequential( # Sequential, + nn.Conv2d(2048,1024,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024,1024,(3, 3),(1, 1),(1, 1),1,32,bias=False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024,2048,(1, 1),(1, 1),(0, 0),1,1,bias=False), + nn.BatchNorm2d(2048), + ), + Lambda(), # Identity, + ), + LambdaReduce(), # CAddTable, + nn.ReLU(), + ), + ) +) \ No newline at end of file diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/resnet_features/resnext101_64x4d_features.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/resnet_features/resnext101_64x4d_features.py new file mode 100644 index 0000000000000000000000000000000000000000..063cca10153f033ffa1a25eb89fe7eea8774af28 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/resnet_features/resnext101_64x4d_features.py @@ -0,0 +1,708 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +from __future__ import print_function, division, absolute_import +import torch +import torch.nn as nn +from torch.autograd import Variable +from functools import reduce + +class LambdaBase(nn.Sequential): + def __init__(self, *args): + super(LambdaBase, self).__init__(*args) + + def forward_prepare(self, input): + output = [] + for module in self._modules.values(): + output.append(module(input)) + return output if output else input + +class Lambda(LambdaBase): + def __init__(self, *args): + super(Lambda, self).__init__(*args) + self.lambda_func = identity + + def forward(self, input): + return self.lambda_func(self.forward_prepare(input)) + +class LambdaMap(LambdaBase): + def __init__(self, *args): + super(LambdaMap, self).__init__(*args) + self.lambda_func = identity + + def forward(self, input): + return list(map(self.lambda_func,self.forward_prepare(input))) + +class LambdaReduce(LambdaBase): + def __init__(self, *args): + super(LambdaReduce, self).__init__(*args) + self.lambda_func = add + + def forward(self, input): + return reduce(self.lambda_func,self.forward_prepare(input)) + +def identity(x): return x + +def add(x, y): return x + y + +resnext101_64x4d_features = nn.Sequential(#Sequential, + nn.Conv2d(3, 64, (7, 7), (2, 2), (3, 3), 1, 1, bias = False), + nn.BatchNorm2d(64), + nn.ReLU(), + nn.MaxPool2d((3, 3), (2, 2), (1, 1)), + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(64, 256, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(256), + nn.ReLU(), + nn.Conv2d(256, 256, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(256), + nn.ReLU(), + ), + nn.Conv2d(256, 256, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(256), + ), + nn.Sequential(#Sequential, + nn.Conv2d(64, 256, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(256), + ), + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(256, 256, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(256), + nn.ReLU(), + nn.Conv2d(256, 256, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(256), + nn.ReLU(), + ), + nn.Conv2d(256, 256, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(256), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(256, 256, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(256), + nn.ReLU(), + nn.Conv2d(256, 256, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(256), + nn.ReLU(), + ), + nn.Conv2d(256, 256, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(256), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + ), + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(256, 512, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512, 512, (3, 3), (2, 2), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512, 512, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(512), + ), + nn.Sequential(#Sequential, + nn.Conv2d(256, 512, (1, 1), (2, 2), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(512), + ), + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(512, 512, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512, 512, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512, 512, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(512), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(512, 512, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512, 512, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512, 512, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(512), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(512, 512, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(512), + nn.ReLU(), + nn.Conv2d(512, 512, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(512), + nn.ReLU(), + ), + nn.Conv2d(512, 512, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(512), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + ), + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(512, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024, 1024, (3, 3), (2, 2), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + nn.Sequential(#Sequential, + nn.Conv2d(512, 1024, (1, 1), (2, 2), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024, 1024, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024, 1024, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024, 1024, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024, 1024, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024, 1024, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024, 1024, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024, 1024, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024, 1024, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024, 1024, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024, 1024, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024, 1024, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024, 1024, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024, 1024, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024, 1024, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024, 1024, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024, 1024, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024, 1024, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024, 1024, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024, 1024, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024, 1024, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024, 1024, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + nn.Conv2d(1024, 1024, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(1024), + nn.ReLU(), + ), + nn.Conv2d(1024, 1024, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(1024), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + ), + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(1024, 2048, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(2048), + nn.ReLU(), + nn.Conv2d(2048, 2048, (3, 3), (2, 2), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(2048), + nn.ReLU(), + ), + nn.Conv2d(2048, 2048, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(2048), + ), + nn.Sequential(#Sequential, + nn.Conv2d(1024, 2048, (1, 1), (2, 2), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(2048), + ), + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(2048, 2048, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(2048), + nn.ReLU(), + nn.Conv2d(2048, 2048, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(2048), + nn.ReLU(), + ), + nn.Conv2d(2048, 2048, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(2048), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + nn.Sequential(#Sequential, + LambdaMap( #ConcatTable, + nn.Sequential(#Sequential, + nn.Sequential(#Sequential, + nn.Conv2d(2048, 2048, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(2048), + nn.ReLU(), + nn.Conv2d(2048, 2048, (3, 3), (1, 1), (1, 1), 1, 64, bias = False), + nn.BatchNorm2d(2048), + nn.ReLU(), + ), + nn.Conv2d(2048, 2048, (1, 1), (1, 1), (0, 0), 1, 1, bias = False), + nn.BatchNorm2d(2048), + ), + Lambda(), #Identity, + ), + LambdaReduce(), #CAddTable, + nn.ReLU(), + ), + ) +) \ No newline at end of file diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/resnext.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/resnext.py new file mode 100644 index 0000000000000000000000000000000000000000..4a12d143df77a67dec5248591443d91ed9e7e166 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/resnext.py @@ -0,0 +1,116 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +from __future__ import print_function, division, absolute_import +import os +import torch +import torch.nn as nn +import torch.utils.model_zoo as model_zoo +from .resnext_features import resnext101_32x4d_features +from .resnext_features import resnext101_64x4d_features + +__all__ = ['ResNeXt101_32x4d', 'resnext101_32x4d', + 'ResNeXt101_64x4d', 'resnext101_64x4d'] + +pretrained_settings = { + 'resnext101_32x4d': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/resnext101_32x4d-29e315fa.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [0.485, 0.456, 0.406], + 'std': [0.229, 0.224, 0.225], + 'num_classes': 1000 + } + }, + 'resnext101_64x4d': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/resnext101_64x4d-e77a0586.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [0.485, 0.456, 0.406], + 'std': [0.229, 0.224, 0.225], + 'num_classes': 1000 + } + } +} + +class ResNeXt101_32x4d(nn.Module): + + def __init__(self, num_classes=1000): + super(ResNeXt101_32x4d, self).__init__() + self.num_classes = num_classes + self.features = resnext101_32x4d_features + self.avg_pool = nn.AvgPool2d((7, 7), (1, 1)) + self.last_linear = nn.Linear(2048, num_classes) + + def logits(self, input): + x = self.avg_pool(input) + x = x.view(x.size(0), -1) + x = self.last_linear(x) + return x + + def forward(self, input): + x = self.features(input) + x = self.logits(x) + return x + + +class ResNeXt101_64x4d(nn.Module): + + def __init__(self, num_classes=1000): + super(ResNeXt101_64x4d, self).__init__() + self.num_classes = num_classes + self.features = resnext101_64x4d_features + self.avg_pool = nn.AvgPool2d((7, 7), (1, 1)) + self.last_linear = nn.Linear(2048, num_classes) + + def logits(self, input): + x = self.avg_pool(input) + x = x.view(x.size(0), -1) + x = self.last_linear(x) + return x + + def forward(self, input): + x = self.features(input) + x = self.logits(x) + return x + + +def resnext101_32x4d(num_classes=1000, pretrained='imagenet'): + model = ResNeXt101_32x4d(num_classes=num_classes) + if pretrained is not None: + settings = pretrained_settings['resnext101_32x4d'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model + +def resnext101_64x4d(num_classes=1000, pretrained='imagenet'): + model = ResNeXt101_64x4d(num_classes=num_classes) + if pretrained is not None: + settings = pretrained_settings['resnext101_64x4d'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/senet.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/senet.py new file mode 100644 index 0000000000000000000000000000000000000000..ef097c148bd22f84668fdc88d28e1fa5cdadefe2 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/senet.py @@ -0,0 +1,453 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +""" +ResNet code gently borrowed from +https://github.com/pytorch/vision/blob/master/torchvision/models/resnet.py +""" +from __future__ import print_function, division, absolute_import +from collections import OrderedDict +import math + +import torch.nn as nn +from torch.utils import model_zoo + +__all__ = ['SENet', 'senet154', 'se_resnet50', 'se_resnet101', 'se_resnet152', + 'se_resnext50_32x4d', 'se_resnext101_32x4d'] + +pretrained_settings = { + 'senet154': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/senet154-c7b49a05.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [0.485, 0.456, 0.406], + 'std': [0.229, 0.224, 0.225], + 'num_classes': 1000 + } + }, + 'se_resnet50': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/se_resnet50-ce0d4300.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [0.485, 0.456, 0.406], + 'std': [0.229, 0.224, 0.225], + 'num_classes': 1000 + } + }, + 'se_resnet101': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/se_resnet101-7e38fcc6.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [0.485, 0.456, 0.406], + 'std': [0.229, 0.224, 0.225], + 'num_classes': 1000 + } + }, + 'se_resnet152': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/se_resnet152-d17c99b7.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [0.485, 0.456, 0.406], + 'std': [0.229, 0.224, 0.225], + 'num_classes': 1000 + } + }, + 'se_resnext50_32x4d': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/se_resnext50_32x4d-a260b3a4.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [0.485, 0.456, 0.406], + 'std': [0.229, 0.224, 0.225], + 'num_classes': 1000 + } + }, + 'se_resnext101_32x4d': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/se_resnext101_32x4d-3b2fe3d8.pth', + 'input_space': 'RGB', + 'input_size': [3, 224, 224], + 'input_range': [0, 1], + 'mean': [0.485, 0.456, 0.406], + 'std': [0.229, 0.224, 0.225], + 'num_classes': 1000 + } + }, +} + + +class SEModule(nn.Module): + + def __init__(self, channels, reduction): + super(SEModule, self).__init__() + self.avg_pool = nn.AdaptiveAvgPool2d(1) + self.fc1 = nn.Conv2d(channels, channels // reduction, kernel_size=1, + padding=0) + self.relu = nn.ReLU(inplace=True) + self.fc2 = nn.Conv2d(channels // reduction, channels, kernel_size=1, + padding=0) + self.sigmoid = nn.Sigmoid() + + def forward(self, x): + module_input = x + x = self.avg_pool(x) + x = self.fc1(x) + x = self.relu(x) + x = self.fc2(x) + x = self.sigmoid(x) + return module_input * x + + +class Bottleneck(nn.Module): + """ + Base class for bottlenecks that implements `forward()` method. + """ + def forward(self, x): + residual = x + + out = self.conv1(x) + out = self.bn1(out) + out = self.relu(out) + + out = self.conv2(out) + out = self.bn2(out) + out = self.relu(out) + + out = self.conv3(out) + out = self.bn3(out) + + if self.downsample is not None: + residual = self.downsample(x) + + out = self.se_module(out) + residual + out = self.relu(out) + + return out + + +class SEBottleneck(Bottleneck): + """ + Bottleneck for SENet154. + """ + expansion = 4 + + def __init__(self, inplanes, planes, groups, reduction, stride=1, + downsample=None): + super(SEBottleneck, self).__init__() + self.conv1 = nn.Conv2d(inplanes, planes * 2, kernel_size=1, bias=False) + self.bn1 = nn.BatchNorm2d(planes * 2) + self.conv2 = nn.Conv2d(planes * 2, planes * 4, kernel_size=3, + stride=stride, padding=1, groups=groups, + bias=False) + self.bn2 = nn.BatchNorm2d(planes * 4) + self.conv3 = nn.Conv2d(planes * 4, planes * 4, kernel_size=1, + bias=False) + self.bn3 = nn.BatchNorm2d(planes * 4) + self.relu = nn.ReLU(inplace=True) + self.se_module = SEModule(planes * 4, reduction=reduction) + self.downsample = downsample + self.stride = stride + + +class SEResNetBottleneck(Bottleneck): + """ + ResNet bottleneck with a Squeeze-and-Excitation module. It follows Caffe + implementation and uses `stride=stride` in `conv1` and not in `conv2` + (the latter is used in the torchvision implementation of ResNet). + """ + expansion = 4 + + def __init__(self, inplanes, planes, groups, reduction, stride=1, + downsample=None): + super(SEResNetBottleneck, self).__init__() + self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False, + stride=stride) + self.bn1 = nn.BatchNorm2d(planes) + self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, padding=1, + groups=groups, bias=False) + self.bn2 = nn.BatchNorm2d(planes) + self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=False) + self.bn3 = nn.BatchNorm2d(planes * 4) + self.relu = nn.ReLU(inplace=True) + self.se_module = SEModule(planes * 4, reduction=reduction) + self.downsample = downsample + self.stride = stride + + +class SEResNeXtBottleneck(Bottleneck): + """ + ResNeXt bottleneck type C with a Squeeze-and-Excitation module. + """ + expansion = 4 + + def __init__(self, inplanes, planes, groups, reduction, stride=1, + downsample=None, base_width=4): + super(SEResNeXtBottleneck, self).__init__() + width = math.floor(planes * (base_width / 64)) * groups + self.conv1 = nn.Conv2d(inplanes, width, kernel_size=1, bias=False, + stride=1) + self.bn1 = nn.BatchNorm2d(width) + self.conv2 = nn.Conv2d(width, width, kernel_size=3, stride=stride, + padding=1, groups=groups, bias=False) + self.bn2 = nn.BatchNorm2d(width) + self.conv3 = nn.Conv2d(width, planes * 4, kernel_size=1, bias=False) + self.bn3 = nn.BatchNorm2d(planes * 4) + self.relu = nn.ReLU(inplace=True) + self.se_module = SEModule(planes * 4, reduction=reduction) + self.downsample = downsample + self.stride = stride + + +class SENet(nn.Module): + + def __init__(self, block, layers, groups, reduction, dropout_p=0.2, + inplanes=128, input_3x3=True, downsample_kernel_size=3, + downsample_padding=1, num_classes=1000): + """ + Parameters + ---------- + block (nn.Module): Bottleneck class. + - For SENet154: SEBottleneck + - For SE-ResNet models: SEResNetBottleneck + - For SE-ResNeXt models: SEResNeXtBottleneck + layers (list of ints): Number of residual blocks for 4 layers of the + network (layer1...layer4). + groups (int): Number of groups for the 3x3 convolution in each + bottleneck block. + - For SENet154: 64 + - For SE-ResNet models: 1 + - For SE-ResNeXt models: 32 + reduction (int): Reduction ratio for Squeeze-and-Excitation modules. + - For all models: 16 + dropout_p (float or None): Drop probability for the Dropout layer. + If `None` the Dropout layer is not used. + - For SENet154: 0.2 + - For SE-ResNet models: None + - For SE-ResNeXt models: None + inplanes (int): Number of input channels for layer1. + - For SENet154: 128 + - For SE-ResNet models: 64 + - For SE-ResNeXt models: 64 + input_3x3 (bool): If `True`, use three 3x3 convolutions instead of + a single 7x7 convolution in layer0. + - For SENet154: True + - For SE-ResNet models: False + - For SE-ResNeXt models: False + downsample_kernel_size (int): Kernel size for downsampling convolutions + in layer2, layer3 and layer4. + - For SENet154: 3 + - For SE-ResNet models: 1 + - For SE-ResNeXt models: 1 + downsample_padding (int): Padding for downsampling convolutions in + layer2, layer3 and layer4. + - For SENet154: 1 + - For SE-ResNet models: 0 + - For SE-ResNeXt models: 0 + num_classes (int): Number of outputs in `last_linear` layer. + - For all models: 1000 + """ + super(SENet, self).__init__() + self.inplanes = inplanes + if input_3x3: + layer0_modules = [ + ('conv1', nn.Conv2d(3, 64, 3, stride=2, padding=1, + bias=False)), + ('bn1', nn.BatchNorm2d(64)), + ('relu1', nn.ReLU(inplace=True)), + ('conv2', nn.Conv2d(64, 64, 3, stride=1, padding=1, + bias=False)), + ('bn2', nn.BatchNorm2d(64)), + ('relu2', nn.ReLU(inplace=True)), + ('conv3', nn.Conv2d(64, inplanes, 3, stride=1, padding=1, + bias=False)), + ('bn3', nn.BatchNorm2d(inplanes)), + ('relu3', nn.ReLU(inplace=True)), + ] + else: + layer0_modules = [ + ('conv1', nn.Conv2d(3, inplanes, kernel_size=7, stride=2, + padding=3, bias=False)), + ('bn1', nn.BatchNorm2d(inplanes)), + ('relu1', nn.ReLU(inplace=True)), + ] + # To preserve compatibility with Caffe weights `ceil_mode=True` + # is used instead of `padding=1`. + layer0_modules.append(('pool', nn.MaxPool2d(3, stride=2, + ceil_mode=True))) + self.layer0 = nn.Sequential(OrderedDict(layer0_modules)) + self.layer1 = self._make_layer( + block, + planes=64, + blocks=layers[0], + groups=groups, + reduction=reduction, + downsample_kernel_size=1, + downsample_padding=0 + ) + self.layer2 = self._make_layer( + block, + planes=128, + blocks=layers[1], + stride=2, + groups=groups, + reduction=reduction, + downsample_kernel_size=downsample_kernel_size, + downsample_padding=downsample_padding + ) + self.layer3 = self._make_layer( + block, + planes=256, + blocks=layers[2], + stride=2, + groups=groups, + reduction=reduction, + downsample_kernel_size=downsample_kernel_size, + downsample_padding=downsample_padding + ) + self.layer4 = self._make_layer( + block, + planes=512, + blocks=layers[3], + stride=2, + groups=groups, + reduction=reduction, + downsample_kernel_size=downsample_kernel_size, + downsample_padding=downsample_padding + ) + self.avg_pool = nn.AvgPool2d(7, stride=1) + self.dropout = nn.Dropout(dropout_p) if dropout_p is not None else None + self.last_linear = nn.Linear(512 * block.expansion, num_classes) + + def _make_layer(self, block, planes, blocks, groups, reduction, stride=1, + downsample_kernel_size=1, downsample_padding=0): + downsample = None + if stride != 1 or self.inplanes != planes * block.expansion: + downsample = nn.Sequential( + nn.Conv2d(self.inplanes, planes * block.expansion, + kernel_size=downsample_kernel_size, stride=stride, + padding=downsample_padding, bias=False), + nn.BatchNorm2d(planes * block.expansion), + ) + + layers = [] + layers.append(block(self.inplanes, planes, groups, reduction, stride, + downsample)) + self.inplanes = planes * block.expansion + for i in range(1, blocks): + layers.append(block(self.inplanes, planes, groups, reduction)) + + return nn.Sequential(*layers) + + def features(self, x): + x = self.layer0(x) + x = self.layer1(x) + x = self.layer2(x) + x = self.layer3(x) + x = self.layer4(x) + return x + + def logits(self, x): + x = self.avg_pool(x) + if self.dropout is not None: + x = self.dropout(x) + x = x.view(x.size(0), -1) + x = self.last_linear(x) + return x + + def forward(self, x): + x = self.features(x) + x = self.logits(x) + return x + + +def initialize_pretrained_model(model, num_classes, settings): + assert num_classes == settings['num_classes'], \ + 'num_classes should be {}, but is {}'.format( + settings['num_classes'], num_classes) + model.load_state_dict(model_zoo.load_url(settings['url'])) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + + +def senet154(num_classes=1000, pretrained='imagenet'): + model = SENet(SEBottleneck, [3, 8, 36, 3], groups=64, reduction=16, + dropout_p=0.2, num_classes=num_classes) + if pretrained is not None: + settings = pretrained_settings['senet154'][pretrained] + initialize_pretrained_model(model, num_classes, settings) + return model + + +def se_resnet50(num_classes=1000, pretrained='imagenet'): + model = SENet(SEResNetBottleneck, [3, 4, 6, 3], groups=1, reduction=16, + dropout_p=None, inplanes=64, input_3x3=False, + downsample_kernel_size=1, downsample_padding=0, + num_classes=num_classes) + if pretrained is not None: + settings = pretrained_settings['se_resnet50'][pretrained] + initialize_pretrained_model(model, num_classes, settings) + return model + + +def se_resnet101(num_classes=1000, pretrained='imagenet'): + model = SENet(SEResNetBottleneck, [3, 4, 23, 3], groups=1, reduction=16, + dropout_p=None, inplanes=64, input_3x3=False, + downsample_kernel_size=1, downsample_padding=0, + num_classes=num_classes) + if pretrained is not None: + settings = pretrained_settings['se_resnet101'][pretrained] + initialize_pretrained_model(model, num_classes, settings) + return model + + +def se_resnet152(num_classes=1000, pretrained='imagenet'): + model = SENet(SEResNetBottleneck, [3, 8, 36, 3], groups=1, reduction=16, + dropout_p=None, inplanes=64, input_3x3=False, + downsample_kernel_size=1, downsample_padding=0, + num_classes=num_classes) + if pretrained is not None: + settings = pretrained_settings['se_resnet152'][pretrained] + initialize_pretrained_model(model, num_classes, settings) + return model + + +def se_resnext50_32x4d(num_classes=1000, pretrained='imagenet'): + model = SENet(SEResNeXtBottleneck, [3, 4, 6, 3], groups=32, reduction=16, + dropout_p=None, inplanes=64, input_3x3=False, + downsample_kernel_size=1, downsample_padding=0, + num_classes=num_classes) + if pretrained is not None: + settings = pretrained_settings['se_resnext50_32x4d'][pretrained] + initialize_pretrained_model(model, num_classes, settings) + return model + + +def se_resnext101_32x4d(num_classes=1000, pretrained='imagenet'): + model = SENet(SEResNeXtBottleneck, [3, 4, 23, 3], groups=32, reduction=16, + dropout_p=None, inplanes=64, input_3x3=False, + downsample_kernel_size=1, downsample_padding=0, + num_classes=num_classes) + if pretrained is not None: + settings = pretrained_settings['se_resnext101_32x4d'][pretrained] + initialize_pretrained_model(model, num_classes, settings) + return model diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/torchvision_models.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/torchvision_models.py new file mode 100644 index 0000000000000000000000000000000000000000..47ba6fe306adb857dd13b8050bab165cfcb37379 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/torchvision_models.py @@ -0,0 +1,584 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +# -*- coding: utf-8 -*- +from __future__ import print_function, division, absolute_import +import torchvision.models as models +import torch.utils.model_zoo as model_zoo +import torch.nn.functional as F +import types +import re + +################################################################# +# You can find the definitions of those models here: +# https://github.com/pytorch/vision/blob/master/torchvision/models +# +# To fit the API, we usually added/redefined some methods and +# renamed some attributs (see below for each models). +# +# However, you usually do not need to see the original model +# definition from torchvision. Just use `print(model)` to see +# the modules and see bellow the `model.features` and +# `model.classifier` definitions. +################################################################# + +__all__ = [ + 'alexnet', + 'densenet121', 'densenet169', 'densenet201', 'densenet161', + 'resnet18', 'resnet34', 'resnet50', 'resnet101', 'resnet152', + 'inceptionv3', + 'squeezenet1_0', 'squeezenet1_1', + 'vgg11', 'vgg11_bn', 'vgg13', 'vgg13_bn', 'vgg16', 'vgg16_bn', + 'vgg19_bn', 'vgg19' +] + +model_urls = { + 'alexnet': 'https://download.pytorch.org/models/alexnet-owt-4df8aa71.pth', + 'densenet121': 'http://data.lip6.fr/cadene/pretrainedmodels/densenet121-fbdb23505.pth', + 'densenet169': 'http://data.lip6.fr/cadene/pretrainedmodels/densenet169-f470b90a4.pth', + 'densenet201': 'http://data.lip6.fr/cadene/pretrainedmodels/densenet201-5750cbb1e.pth', + 'densenet161': 'http://data.lip6.fr/cadene/pretrainedmodels/densenet161-347e6b360.pth', + 'inceptionv3': 'https://download.pytorch.org/models/inception_v3_google-1a9a5a14.pth', + 'resnet18': 'https://download.pytorch.org/models/resnet18-5c106cde.pth', + 'resnet34': 'https://download.pytorch.org/models/resnet34-333f7ec4.pth', + 'resnet50': 'https://download.pytorch.org/models/resnet50-19c8e357.pth', + 'resnet101': 'https://download.pytorch.org/models/resnet101-5d3b4d8f.pth', + 'resnet152': 'https://download.pytorch.org/models/resnet152-b121ed2d.pth', + 'squeezenet1_0': 'https://download.pytorch.org/models/squeezenet1_0-a815701f.pth', + 'squeezenet1_1': 'https://download.pytorch.org/models/squeezenet1_1-f364aa15.pth', + 'vgg11': 'https://download.pytorch.org/models/vgg11-bbd30ac9.pth', + 'vgg13': 'https://download.pytorch.org/models/vgg13-c768596a.pth', + 'vgg16': 'https://download.pytorch.org/models/vgg16-397923af.pth', + 'vgg19': 'https://download.pytorch.org/models/vgg19-dcbb9e9d.pth', + 'vgg11_bn': 'https://download.pytorch.org/models/vgg11_bn-6002323d.pth', + 'vgg13_bn': 'https://download.pytorch.org/models/vgg13_bn-abd245e5.pth', + 'vgg16_bn': 'https://download.pytorch.org/models/vgg16_bn-6c64b313.pth', + 'vgg19_bn': 'https://download.pytorch.org/models/vgg19_bn-c79401a0.pth', + # 'vgg16_caffe': 'https://s3-us-west-2.amazonaws.com/jcjohns-models/vgg16-00b39a1b.pth', + # 'vgg19_caffe': 'https://s3-us-west-2.amazonaws.com/jcjohns-models/vgg19-d01eb7cb.pth' +} + +input_sizes = {} +means = {} +stds = {} + +for model_name in __all__: + input_sizes[model_name] = [3, 224, 224] + means[model_name] = [0.485, 0.456, 0.406] + stds[model_name] = [0.229, 0.224, 0.225] + +for model_name in ['inceptionv3']: + input_sizes[model_name] = [3, 299, 299] + means[model_name] = [0.5, 0.5, 0.5] + stds[model_name] = [0.5, 0.5, 0.5] + +pretrained_settings = {} + +for model_name in __all__: + pretrained_settings[model_name] = { + 'imagenet': { + 'url': model_urls[model_name], + 'input_space': 'RGB', + 'input_size': input_sizes[model_name], + 'input_range': [0, 1], + 'mean': means[model_name], + 'std': stds[model_name], + 'num_classes': 1000 + } + } + +# for model_name in ['vgg16', 'vgg19']: +# pretrained_settings[model_name]['imagenet_caffe'] = { +# 'url': model_urls[model_name + '_caffe'], +# 'input_space': 'BGR', +# 'input_size': input_sizes[model_name], +# 'input_range': [0, 255], +# 'mean': [103.939, 116.779, 123.68], +# 'std': [1., 1., 1.], +# 'num_classes': 1000 +# } + +def update_state_dict(state_dict): + # '.'s are no longer allowed in module names, but pervious _DenseLayer + # has keys 'norm.1', 'relu.1', 'conv.1', 'norm.2', 'relu.2', 'conv.2'. + # They are also in the checkpoints in model_urls. This pattern is used + # to find such keys. + pattern = re.compile( + r'^(.*denselayer\d+\.(?:norm|relu|conv))\.((?:[12])\.(?:weight|bias|running_mean|running_var))$') + for key in list(state_dict.keys()): + res = pattern.match(key) + if res: + new_key = res.group(1) + res.group(2) + state_dict[new_key] = state_dict[key] + del state_dict[key] + return state_dict + +def load_pretrained(model, num_classes, settings): + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + state_dict = model_zoo.load_url(settings['url']) + state_dict = update_state_dict(state_dict) + model.load_state_dict(state_dict) + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + return model + +################################################################# +# AlexNet + +def modify_alexnet(model): + # Modify attributs + model._features = model.features + del model.features + model.dropout0 = model.classifier[0] + model.linear0 = model.classifier[1] + model.relu0 = model.classifier[2] + model.dropout1 = model.classifier[3] + model.linear1 = model.classifier[4] + model.relu1 = model.classifier[5] + model.last_linear = model.classifier[6] + del model.classifier + + def features(self, input): + x = self._features(input) + x = x.view(x.size(0), 256 * 6 * 6) + x = self.dropout0(x) + x = self.linear0(x) + x = self.relu0(x) + x = self.dropout1(x) + x = self.linear1(x) + return x + + def logits(self, features): + x = self.relu1(features) + x = self.last_linear(x) + return x + + def forward(self, input): + x = self.features(input) + x = self.logits(x) + return x + + # Modify methods + model.features = types.MethodType(features, model) + model.logits = types.MethodType(logits, model) + model.forward = types.MethodType(forward, model) + return model + +def alexnet(num_classes=1000, pretrained='imagenet'): + r"""AlexNet model architecture from the + `"One weird trick..." `_ paper. + """ + # https://github.com/pytorch/vision/blob/master/torchvision/models/alexnet.py + model = models.alexnet(pretrained=False) + if pretrained is not None: + settings = pretrained_settings['alexnet'][pretrained] + model = load_pretrained(model, num_classes, settings) + model = modify_alexnet(model) + return model + +############################################################### +# DenseNets + +def modify_densenets(model): + # Modify attributs + model.last_linear = model.classifier + del model.classifier + + def logits(self, features): + x = F.relu(features, inplace=True) + x = F.avg_pool2d(x, kernel_size=7, stride=1) + x = x.view(x.size(0), -1) + x = self.last_linear(x) + return x + + def forward(self, input): + x = self.features(input) + x = self.logits(x) + return x + + # Modify methods + model.logits = types.MethodType(logits, model) + model.forward = types.MethodType(forward, model) + return model + +def densenet121(num_classes=1000, pretrained='imagenet'): + r"""Densenet-121 model from + `"Densely Connected Convolutional Networks" ` + """ + model = models.densenet121(pretrained=False) + if pretrained is not None: + settings = pretrained_settings['densenet121'][pretrained] + model = load_pretrained(model, num_classes, settings) + model = modify_densenets(model) + return model + +def densenet169(num_classes=1000, pretrained='imagenet'): + r"""Densenet-169 model from + `"Densely Connected Convolutional Networks" ` + """ + model = models.densenet169(pretrained=False) + if pretrained is not None: + settings = pretrained_settings['densenet169'][pretrained] + model = load_pretrained(model, num_classes, settings) + model = modify_densenets(model) + return model + +def densenet201(num_classes=1000, pretrained='imagenet'): + r"""Densenet-201 model from + `"Densely Connected Convolutional Networks" ` + """ + model = models.densenet201(pretrained=False) + if pretrained is not None: + settings = pretrained_settings['densenet201'][pretrained] + model = load_pretrained(model, num_classes, settings) + model = modify_densenets(model) + return model + +def densenet161(num_classes=1000, pretrained='imagenet'): + r"""Densenet-161 model from + `"Densely Connected Convolutional Networks" ` + """ + model = models.densenet161(pretrained=False) + if pretrained is not None: + settings = pretrained_settings['densenet161'][pretrained] + model = load_pretrained(model, num_classes, settings) + model = modify_densenets(model) + return model + +############################################################### +# InceptionV3 + +def inceptionv3(num_classes=1000, pretrained='imagenet'): + r"""Inception v3 model architecture from + `"Rethinking the Inception Architecture for Computer Vision" `_. + """ + model = models.inception_v3(pretrained=False) + if pretrained is not None: + settings = pretrained_settings['inceptionv3'][pretrained] + model = load_pretrained(model, num_classes, settings) + + # Modify attributs + model.last_linear = model.fc + del model.fc + + def features(self, input): + # 299 x 299 x 3 + x = self.Conv2d_1a_3x3(input) # 149 x 149 x 32 + x = self.Conv2d_2a_3x3(x) # 147 x 147 x 32 + x = self.Conv2d_2b_3x3(x) # 147 x 147 x 64 + x = F.max_pool2d(x, kernel_size=3, stride=2) # 73 x 73 x 64 + x = self.Conv2d_3b_1x1(x) # 73 x 73 x 80 + x = self.Conv2d_4a_3x3(x) # 71 x 71 x 192 + x = F.max_pool2d(x, kernel_size=3, stride=2) # 35 x 35 x 192 + x = self.Mixed_5b(x) # 35 x 35 x 256 + x = self.Mixed_5c(x) # 35 x 35 x 288 + x = self.Mixed_5d(x) # 35 x 35 x 288 + x = self.Mixed_6a(x) # 17 x 17 x 768 + x = self.Mixed_6b(x) # 17 x 17 x 768 + x = self.Mixed_6c(x) # 17 x 17 x 768 + x = self.Mixed_6d(x) # 17 x 17 x 768 + x = self.Mixed_6e(x) # 17 x 17 x 768 + if self.training and self.aux_logits: + self._out_aux = self.AuxLogits(x) # 17 x 17 x 768 + x = self.Mixed_7a(x) # 8 x 8 x 1280 + x = self.Mixed_7b(x) # 8 x 8 x 2048 + x = self.Mixed_7c(x) # 8 x 8 x 2048 + return x + + def logits(self, features): + x = F.avg_pool2d(features, kernel_size=8) # 1 x 1 x 2048 + x = F.dropout(x, training=self.training) # 1 x 1 x 2048 + x = x.view(x.size(0), -1) # 2048 + x = self.last_linear(x) # 1000 (num_classes) + if self.training and self.aux_logits: + aux = self._out_aux + self._out_aux = None + return x, aux + return x + + def forward(self, input): + x = self.features(input) + x = self.logits(x) + return x + + # Modify methods + model.features = types.MethodType(features, model) + model.logits = types.MethodType(logits, model) + model.forward = types.MethodType(forward, model) + return model + +############################################################### +# ResNets + +def modify_resnets(model): + # Modify attributs + model.last_linear = model.fc + model.fc = None + + def features(self, input): + x = self.conv1(input) + x = self.bn1(x) + x = self.relu(x) + x = self.maxpool(x) + + x = self.layer1(x) + x = self.layer2(x) + x = self.layer3(x) + x = self.layer4(x) + return x + + def logits(self, features): + x = self.avgpool(features) + x = x.view(x.size(0), -1) + x = self.last_linear(x) + return x + + def forward(self, input): + x = self.features(input) + x = self.logits(x) + return x + + # Modify methods + model.features = types.MethodType(features, model) + model.logits = types.MethodType(logits, model) + model.forward = types.MethodType(forward, model) + return model + +def resnet18(num_classes=1000, pretrained='imagenet'): + """Constructs a ResNet-18 model. + """ + model = models.resnet18(pretrained=False) + if pretrained is not None: + settings = pretrained_settings['resnet18'][pretrained] + model = load_pretrained(model, num_classes, settings) + model = modify_resnets(model) + return model + +def resnet34(num_classes=1000, pretrained='imagenet'): + """Constructs a ResNet-34 model. + """ + model = models.resnet34(pretrained=False) + if pretrained is not None: + settings = pretrained_settings['resnet34'][pretrained] + model = load_pretrained(model, num_classes, settings) + model = modify_resnets(model) + return model + +def resnet50(num_classes=1000, pretrained='imagenet'): + """Constructs a ResNet-50 model. + """ + model = models.resnet50(pretrained=False) + if pretrained is not None: + settings = pretrained_settings['resnet50'][pretrained] + model = load_pretrained(model, num_classes, settings) + model = modify_resnets(model) + return model + +def resnet101(num_classes=1000, pretrained='imagenet'): + """Constructs a ResNet-101 model. + """ + model = models.resnet101(pretrained=False) + if pretrained is not None: + settings = pretrained_settings['resnet101'][pretrained] + model = load_pretrained(model, num_classes, settings) + model = modify_resnets(model) + return model + +def resnet152(num_classes=1000, pretrained='imagenet'): + """Constructs a ResNet-152 model. + """ + model = models.resnet152(pretrained=False) + if pretrained is not None: + settings = pretrained_settings['resnet152'][pretrained] + model = load_pretrained(model, num_classes, settings) + model = modify_resnets(model) + return model + +############################################################### +# SqueezeNets + +def modify_squeezenets(model): + # /!\ Beware squeezenets do not have any last_linear module + + # Modify attributs + model.dropout = model.classifier[0] + model.last_conv = model.classifier[1] + model.relu = model.classifier[2] + model.avgpool = model.classifier[3] + del model.classifier + + def logits(self, features): + x = self.dropout(features) + x = self.last_conv(x) + x = self.relu(x) + x = self.avgpool(x) + return x + + def forward(self, input): + x = self.features(input) + x = self.logits(x) + return x + + # Modify methods + model.logits = types.MethodType(logits, model) + model.forward = types.MethodType(forward, model) + return model + +def squeezenet1_0(num_classes=1000, pretrained='imagenet'): + r"""SqueezeNet model architecture from the `"SqueezeNet: AlexNet-level + accuracy with 50x fewer parameters and <0.5MB model size" + `_ paper. + """ + model = models.squeezenet1_0(pretrained=False) + if pretrained is not None: + settings = pretrained_settings['squeezenet1_0'][pretrained] + model = load_pretrained(model, num_classes, settings) + model = modify_squeezenets(model) + return model + +def squeezenet1_1(num_classes=1000, pretrained='imagenet'): + r"""SqueezeNet 1.1 model from the `official SqueezeNet repo + `_. + SqueezeNet 1.1 has 2.4x less computation and slightly fewer parameters + than SqueezeNet 1.0, without sacrificing accuracy. + """ + model = models.squeezenet1_1(pretrained=False) + if pretrained is not None: + settings = pretrained_settings['squeezenet1_1'][pretrained] + model = load_pretrained(model, num_classes, settings) + model = modify_squeezenets(model) + return model + +############################################################### +# VGGs + +def modify_vggs(model): + # Modify attributs + model._features = model.features + del model.features + model.linear0 = model.classifier[0] + model.relu0 = model.classifier[1] + model.dropout0 = model.classifier[2] + model.linear1 = model.classifier[3] + model.relu1 = model.classifier[4] + model.dropout1 = model.classifier[5] + model.last_linear = model.classifier[6] + del model.classifier + + def features(self, input): + x = self._features(input) + x = x.view(x.size(0), -1) + x = self.linear0(x) + x = self.relu0(x) + x = self.dropout0(x) + x = self.linear1(x) + return x + + def logits(self, features): + x = self.relu1(features) + x = self.dropout1(x) + x = self.last_linear(x) + return x + + def forward(self, input): + x = self.features(input) + x = self.logits(x) + return x + + # Modify methods + model.features = types.MethodType(features, model) + model.logits = types.MethodType(logits, model) + model.forward = types.MethodType(forward, model) + return model + +def vgg11(num_classes=1000, pretrained='imagenet'): + """VGG 11-layer model (configuration "A") + """ + model = models.vgg11(pretrained=False) + if pretrained is not None: + settings = pretrained_settings['vgg11'][pretrained] + model = load_pretrained(model, num_classes, settings) + model = modify_vggs(model) + return model + +def vgg11_bn(num_classes=1000, pretrained='imagenet'): + """VGG 11-layer model (configuration "A") with batch normalization + """ + model = models.vgg11_bn(pretrained=False) + if pretrained is not None: + settings = pretrained_settings['vgg11_bn'][pretrained] + model = load_pretrained(model, num_classes, settings) + model = modify_vggs(model) + return model + +def vgg13(num_classes=1000, pretrained='imagenet'): + """VGG 13-layer model (configuration "B") + """ + model = models.vgg13(pretrained=False) + if pretrained is not None: + settings = pretrained_settings['vgg13'][pretrained] + model = load_pretrained(model, num_classes, settings) + model = modify_vggs(model) + return model + +def vgg13_bn(num_classes=1000, pretrained='imagenet'): + """VGG 13-layer model (configuration "B") with batch normalization + """ + model = models.vgg13_bn(pretrained=False) + if pretrained is not None: + settings = pretrained_settings['vgg13_bn'][pretrained] + model = load_pretrained(model, num_classes, settings) + model = modify_vggs(model) + return model + +def vgg16(num_classes=1000, pretrained='imagenet'): + """VGG 16-layer model (configuration "D") + """ + model = models.vgg16(pretrained=False) + if pretrained is not None: + settings = pretrained_settings['vgg16'][pretrained] + model = load_pretrained(model, num_classes, settings) + model = modify_vggs(model) + return model + +def vgg16_bn(num_classes=1000, pretrained='imagenet'): + """VGG 16-layer model (configuration "D") with batch normalization + """ + model = models.vgg16_bn(pretrained=False) + if pretrained is not None: + settings = pretrained_settings['vgg16_bn'][pretrained] + model = load_pretrained(model, num_classes, settings) + model = modify_vggs(model) + return model + +def vgg19(num_classes=1000, pretrained='imagenet'): + """VGG 19-layer model (configuration "E") + """ + model = models.vgg19(pretrained=False) + if pretrained is not None: + settings = pretrained_settings['vgg19'][pretrained] + model = load_pretrained(model, num_classes, settings) + model = modify_vggs(model) + return model + +def vgg19_bn(num_classes=1000, pretrained='imagenet'): + """VGG 19-layer model (configuration 'E') with batch normalization + """ + model = models.vgg19_bn(pretrained=False) + if pretrained is not None: + settings = pretrained_settings['vgg19_bn'][pretrained] + model = load_pretrained(model, num_classes, settings) + model = modify_vggs(model) + return model diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/utils.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..7086a5b06190e4c19a32c788ecef6522a92ce2f3 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/utils.py @@ -0,0 +1,50 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +from __future__ import print_function, division, absolute_import +from .fbresnet import pretrained_settings as fbresnet_settings +from .bninception import pretrained_settings as bninception_settings +from .resnext import pretrained_settings as resnext_settings +from .inceptionv4 import pretrained_settings as inceptionv4_settings +from .inceptionresnetv2 import pretrained_settings as inceptionresnetv2_settings +from .torchvision_models import pretrained_settings as torchvision_models_settings +from .nasnet_mobile import pretrained_settings as nasnet_mobile_settings +from .nasnet import pretrained_settings as nasnet_settings +from .dpn import pretrained_settings as dpn_settings +from .xception import pretrained_settings as xception_settings +from .senet import pretrained_settings as senet_settings +from .cafferesnet import pretrained_settings as cafferesnet_settings +from .pnasnet import pretrained_settings as pnasnet_settings +from .polynet import pretrained_settings as polynet_settings + +all_settings = [ + fbresnet_settings, + bninception_settings, + resnext_settings, + inceptionv4_settings, + inceptionresnetv2_settings, + torchvision_models_settings, + nasnet_mobile_settings, + nasnet_settings, + dpn_settings, + xception_settings, + senet_settings, + cafferesnet_settings, + pnasnet_settings, + polynet_settings +] + +model_names = [] +pretrained_settings = {} +for settings in all_settings: + for model_name, model_settings in settings.items(): + pretrained_settings[model_name] = model_settings + model_names.append(model_name) diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/vggm.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/vggm.py new file mode 100644 index 0000000000000000000000000000000000000000..8564da330c17a505ad58088c741d9e8af8b7e820 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/vggm.py @@ -0,0 +1,132 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +from __future__ import print_function, division, absolute_import +import torch +import torch.nn as nn +from torch.autograd import Variable +#from torch.legacy import nn as nnl +import torch.utils.model_zoo as model_zoo + +__all__ = ['vggm'] + +pretrained_settings = { + 'vggm': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/vggm-786f2434.pth', + 'input_space': 'BGR', + 'input_size': [3, 221, 221], + 'input_range': [0, 255], + 'mean': [123.68, 116.779, 103.939], + 'std': [1, 1, 1], + 'num_classes': 1000 + } + } +} + +class SpatialCrossMapLRN(nn.Module): + def __init__(self, local_size=1, alpha=1.0, beta=0.75, k=1, ACROSS_CHANNELS=True): + super(SpatialCrossMapLRN, self).__init__() + self.ACROSS_CHANNELS = ACROSS_CHANNELS + if ACROSS_CHANNELS: + self.average=nn.AvgPool3d(kernel_size=(local_size, 1, 1), + stride=1, + padding=(int((local_size-1.0)/2), 0, 0)) + else: + self.average=nn.AvgPool2d(kernel_size=local_size, + stride=1, + padding=int((local_size-1.0)/2)) + self.alpha = alpha + self.beta = beta + self.k = k + + def forward(self, x): + if self.ACROSS_CHANNELS: + div = x.pow(2).unsqueeze(1) + div = self.average(div).squeeze(1) + div = div.mul(self.alpha).add(self.k).pow(self.beta) + else: + div = x.pow(2) + div = self.average(div) + div = div.mul(self.alpha).add(self.k).pow(self.beta) + x = x.div(div) + return x + +class LambdaBase(nn.Sequential): + def __init__(self, fn, *args): + super(LambdaBase, self).__init__(*args) + self.lambda_func = fn + + def forward_prepare(self, input): + output = [] + for module in self._modules.values(): + output.append(module(input)) + return output if output else input + +class Lambda(LambdaBase): + def forward(self, input): + return self.lambda_func(self.forward_prepare(input)) + +class VGGM(nn.Module): + + def __init__(self, num_classes=1000): + super(VGGM, self).__init__() + self.num_classes = num_classes + self.features = nn.Sequential( + nn.Conv2d(3,96,(7, 7),(2, 2)), + nn.ReLU(), + SpatialCrossMapLRN(5, 0.0005, 0.75, 2), + nn.MaxPool2d((3, 3),(2, 2),(0, 0),ceil_mode=True), + nn.Conv2d(96,256,(5, 5),(2, 2),(1, 1)), + nn.ReLU(), + SpatialCrossMapLRN(5, 0.0005, 0.75, 2), + nn.MaxPool2d((3, 3),(2, 2),(0, 0),ceil_mode=True), + nn.Conv2d(256,512,(3, 3),(1, 1),(1, 1)), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1)), + nn.ReLU(), + nn.Conv2d(512,512,(3, 3),(1, 1),(1, 1)), + nn.ReLU(), + nn.MaxPool2d((3, 3),(2, 2),(0, 0),ceil_mode=True) + ) + self.classif = nn.Sequential( + nn.Linear(18432,4096), + nn.ReLU(), + nn.Dropout(0.5), + nn.Linear(4096,4096), + nn.ReLU(), + nn.Dropout(0.5), + nn.Linear(4096,num_classes) + ) + + def forward(self, x): + x = self.features(x) + x = x.view(x.size(0), -1) + x = self.classif(x) + return x + +def vggm(num_classes=1000, pretrained='imagenet'): + if pretrained: + settings = pretrained_settings['vggm'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + model = VGGM(num_classes=1000) + model.load_state_dict(model_zoo.load_url(settings['url'])) + + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + else: + model = VGGM(num_classes=num_classes) + return model \ No newline at end of file diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/wideresnet.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/wideresnet.py new file mode 100644 index 0000000000000000000000000000000000000000..4fc6b17a13f63308db717b54530101245913ea3d --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/wideresnet.py @@ -0,0 +1,97 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +from __future__ import print_function, division, absolute_import +import os +from os.path import expanduser +import hickle as hkl +import torch +import torch.nn.functional as F +from torch.autograd import Variable + +__all__ = ['wideresnet50'] + +model_urls = { + 'wideresnet152': 'https://s3.amazonaws.com/pytorch/h5models/wide-resnet-50-2-export.hkl' +} + +def define_model(params): + def conv2d(input, params, base, stride=1, pad=0): + return F.conv2d(input, params[base + '.weight'], + params[base + '.bias'], stride, pad) + + def group(input, params, base, stride, n): + o = input + for i in range(0,n): + b_base = ('%s.block%d.conv') % (base, i) + x = o + o = conv2d(x, params, b_base + '0') + o = F.relu(o) + o = conv2d(o, params, b_base + '1', stride=i==0 and stride or 1, pad=1) + o = F.relu(o) + o = conv2d(o, params, b_base + '2') + if i == 0: + o += conv2d(x, params, b_base + '_dim', stride=stride) + else: + o += x + o = F.relu(o) + return o + + # determine network size by parameters + blocks = [sum([re.match('group%d.block\d+.conv0.weight'%j, k) is not None + for k in params.keys()]) for j in range(4)] + + def f(input, params, pooling_classif=True): + o = F.conv2d(input, params['conv0.weight'], params['conv0.bias'], 2, 3) + o = F.relu(o) + o = F.max_pool2d(o, 3, 2, 1) + o_g0 = group(o, params, 'group0', 1, blocks[0]) + o_g1 = group(o_g0, params, 'group1', 2, blocks[1]) + o_g2 = group(o_g1, params, 'group2', 2, blocks[2]) + o_g3 = group(o_g2, params, 'group3', 2, blocks[3]) + if pooling_classif: + o = F.avg_pool2d(o_g3, 7, 1, 0) + o = o.view(o.size(0), -1) + o = F.linear(o, params['fc.weight'], params['fc.bias']) + return o + + return f + + +class WideResNet(nn.Module): + + def __init__(self, pooling): + super(WideResNet, self).__init__() + self.pooling = pooling + self.params = params + + def forward(self, x): + x = f(x, self.params, self.pooling) + return x + + +def wideresnet50(pooling): + dir_models = os.path.join(expanduser("~"), '.torch/wideresnet') + path_hkl = os.path.join(dir_models, 'wideresnet50.hkl') + if os.path.isfile(path_hkl): + params = hkl.load(path_hkl) + # convert numpy arrays to torch Variables + for k,v in sorted(params.items()): + print(k, v.shape) + params[k] = Variable(torch.from_numpy(v), requires_grad=True) + else: + os.system('mkdir -p ' + dir_models) + os.system('wget {} -O {}'.format(model_urls['wideresnet50'], path_hkl)) + f = define_model(params) + model = WideResNet(pooling) + return model + + diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/xception.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/xception.py new file mode 100644 index 0000000000000000000000000000000000000000..45284ee925230d1adff2ecb2cc39a2bef6b30e45 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/models/xception.py @@ -0,0 +1,246 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +""" +Ported to pytorch thanks to [tstandley](https://github.com/tstandley/Xception-PyTorch) + +@author: tstandley +Adapted by cadene + +Creates an Xception Model as defined in: + +Francois Chollet +Xception: Deep Learning with Depthwise Separable Convolutions +https://arxiv.org/pdf/1610.02357.pdf + +This weights ported from the Keras implementation. Achieves the following performance on the validation set: + +Loss:0.9173 Prec@1:78.892 Prec@5:94.292 + +REMEMBER to set your image size to 3x299x299 for both test and validation + +normalize = transforms.Normalize(mean=[0.5, 0.5, 0.5], + std=[0.5, 0.5, 0.5]) + +The resize parameter of the validation transform should be 333, and make sure to center crop at 299x299 +""" +from __future__ import print_function, division, absolute_import +import math +import torch +import torch.nn as nn +import torch.nn.functional as F +import torch.utils.model_zoo as model_zoo +from torch.nn import init + +__all__ = ['xception'] + +pretrained_settings = { + 'xception': { + 'imagenet': { + 'url': 'http://data.lip6.fr/cadene/pretrainedmodels/xception-43020ad28.pth', + 'input_space': 'RGB', + 'input_size': [3, 299, 299], + 'input_range': [0, 1], + 'mean': [0.5, 0.5, 0.5], + 'std': [0.5, 0.5, 0.5], + 'num_classes': 1000, + 'scale': 0.8975 # The resize parameter of the validation transform should be 333, and make sure to center crop at 299x299 + } + } +} + + +class SeparableConv2d(nn.Module): + def __init__(self,in_channels,out_channels,kernel_size=1,stride=1,padding=0,dilation=1,bias=False): + super(SeparableConv2d,self).__init__() + + self.conv1 = nn.Conv2d(in_channels,in_channels,kernel_size,stride,padding,dilation,groups=in_channels,bias=bias) + self.pointwise = nn.Conv2d(in_channels,out_channels,1,1,0,1,1,bias=bias) + + def forward(self,x): + x = self.conv1(x) + x = self.pointwise(x) + return x + + +class Block(nn.Module): + def __init__(self,in_filters,out_filters,reps,strides=1,start_with_relu=True,grow_first=True): + super(Block, self).__init__() + + if out_filters != in_filters or strides!=1: + self.skip = nn.Conv2d(in_filters,out_filters,1,stride=strides, bias=False) + self.skipbn = nn.BatchNorm2d(out_filters) + else: + self.skip=None + + rep=[] + + filters=in_filters + if grow_first: + rep.append(nn.ReLU(inplace=True)) + rep.append(SeparableConv2d(in_filters,out_filters,3,stride=1,padding=1,bias=False)) + rep.append(nn.BatchNorm2d(out_filters)) + filters = out_filters + + for i in range(reps-1): + rep.append(nn.ReLU(inplace=True)) + rep.append(SeparableConv2d(filters,filters,3,stride=1,padding=1,bias=False)) + rep.append(nn.BatchNorm2d(filters)) + + if not grow_first: + rep.append(nn.ReLU(inplace=True)) + rep.append(SeparableConv2d(in_filters,out_filters,3,stride=1,padding=1,bias=False)) + rep.append(nn.BatchNorm2d(out_filters)) + + if not start_with_relu: + rep = rep[1:] + else: + rep[0] = nn.ReLU(inplace=False) + + if strides != 1: + rep.append(nn.MaxPool2d(3,strides,1)) + self.rep = nn.Sequential(*rep) + + def forward(self,inp): + x = self.rep(inp) + + if self.skip is not None: + skip = self.skip(inp) + skip = self.skipbn(skip) + else: + skip = inp + + x+=skip + return x + + +class Xception(nn.Module): + """ + Xception optimized for the ImageNet dataset, as specified in + https://arxiv.org/pdf/1610.02357.pdf + """ + def __init__(self, num_classes=1000): + """ Constructor + Args: + num_classes: number of classes + """ + super(Xception, self).__init__() + self.num_classes = num_classes + + self.conv1 = nn.Conv2d(3, 32, 3,2, 0, bias=False) + self.bn1 = nn.BatchNorm2d(32) + self.relu1 = nn.ReLU(inplace=True) + + self.conv2 = nn.Conv2d(32,64,3,bias=False) + self.bn2 = nn.BatchNorm2d(64) + self.relu2 = nn.ReLU(inplace=True) + #do relu here + + self.block1=Block(64,128,2,2,start_with_relu=False,grow_first=True) + self.block2=Block(128,256,2,2,start_with_relu=True,grow_first=True) + self.block3=Block(256,728,2,2,start_with_relu=True,grow_first=True) + + self.block4=Block(728,728,3,1,start_with_relu=True,grow_first=True) + self.block5=Block(728,728,3,1,start_with_relu=True,grow_first=True) + self.block6=Block(728,728,3,1,start_with_relu=True,grow_first=True) + self.block7=Block(728,728,3,1,start_with_relu=True,grow_first=True) + + self.block8=Block(728,728,3,1,start_with_relu=True,grow_first=True) + self.block9=Block(728,728,3,1,start_with_relu=True,grow_first=True) + self.block10=Block(728,728,3,1,start_with_relu=True,grow_first=True) + self.block11=Block(728,728,3,1,start_with_relu=True,grow_first=True) + + self.block12=Block(728,1024,2,2,start_with_relu=True,grow_first=False) + + self.conv3 = SeparableConv2d(1024,1536,3,1,1) + self.bn3 = nn.BatchNorm2d(1536) + self.relu3 = nn.ReLU(inplace=True) + + #do relu here + self.conv4 = SeparableConv2d(1536,2048,3,1,1) + self.bn4 = nn.BatchNorm2d(2048) + + self.fc = nn.Linear(2048, num_classes) + + # #------- init weights -------- + # for m in self.modules(): + # if isinstance(m, nn.Conv2d): + # n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels + # m.weight.data.normal_(0, math.sqrt(2. / n)) + # elif isinstance(m, nn.BatchNorm2d): + # m.weight.data.fill_(1) + # m.bias.data.zero_() + # #----------------------------- + + def features(self, input): + x = self.conv1(input) + x = self.bn1(x) + x = self.relu1(x) + + x = self.conv2(x) + x = self.bn2(x) + x = self.relu2(x) + + x = self.block1(x) + x = self.block2(x) + x = self.block3(x) + x = self.block4(x) + x = self.block5(x) + x = self.block6(x) + x = self.block7(x) + x = self.block8(x) + x = self.block9(x) + x = self.block10(x) + x = self.block11(x) + x = self.block12(x) + + x = self.conv3(x) + x = self.bn3(x) + x = self.relu3(x) + + x = self.conv4(x) + x = self.bn4(x) + return x + + def logits(self, features): + x = nn.ReLU(inplace=True)(features) + + x = F.adaptive_avg_pool2d(x, (1, 1)) + x = x.view(x.size(0), -1) + x = self.last_linear(x) + return x + + def forward(self, input): + x = self.features(input) + x = self.logits(x) + return x + + +def xception(num_classes=1000, pretrained='imagenet'): + model = Xception(num_classes=num_classes) + if pretrained: + settings = pretrained_settings['xception'][pretrained] + assert num_classes == settings['num_classes'], \ + "num_classes should be {}, but is {}".format(settings['num_classes'], num_classes) + + model = Xception(num_classes=num_classes) + model.load_state_dict(model_zoo.load_url(settings['url'])) + + model.input_space = settings['input_space'] + model.input_size = settings['input_size'] + model.input_range = settings['input_range'] + model.mean = settings['mean'] + model.std = settings['std'] + + # TODO: ugly + model.last_linear = model.fc + del model.fc + return model diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/utils.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..70cc087dc14bb387a4749885ded0df56a2f2a240 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/utils.py @@ -0,0 +1,125 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +from __future__ import print_function, division, absolute_import +import math +import torch +import torch.nn as nn +import torchvision.transforms as transforms +from PIL import Image +from munch import munchify + +class ToSpaceBGR(object): + + def __init__(self, is_bgr): + self.is_bgr = is_bgr + + def __call__(self, tensor): + if self.is_bgr: + new_tensor = tensor.clone() + new_tensor[0] = tensor[2] + new_tensor[2] = tensor[0] + tensor = new_tensor + return tensor + + +class ToRange255(object): + + def __init__(self, is_255): + self.is_255 = is_255 + + def __call__(self, tensor): + if self.is_255: + tensor.mul_(255) + return tensor + + +class TransformImage(object): + + def __init__(self, opts, scale=0.875, random_crop=False, + random_hflip=False, random_vflip=False, + preserve_aspect_ratio=True): + if type(opts) == dict: + opts = munchify(opts) + self.input_size = opts.input_size + self.input_space = opts.input_space + self.input_range = opts.input_range + self.mean = opts.mean + self.std = opts.std + + # https://github.com/tensorflow/models/blob/master/research/inception/inception/image_processing.py#L294 + self.scale = scale + self.random_crop = random_crop + self.random_hflip = random_hflip + self.random_vflip = random_vflip + + tfs = [] + if preserve_aspect_ratio: + tfs.append(transforms.Resize(int(math.floor(max(self.input_size)/self.scale)))) + else: + height = int(self.input_size[1] / self.scale) + width = int(self.input_size[2] / self.scale) + tfs.append(transforms.Resize((height, width))) + + if random_crop: + tfs.append(transforms.RandomCrop(max(self.input_size))) + else: + tfs.append(transforms.CenterCrop(max(self.input_size))) + + if random_hflip: + tfs.append(transforms.RandomHorizontalFlip()) + + if random_vflip: + tfs.append(transforms.RandomVerticalFlip()) + + tfs.append(transforms.ToTensor()) + tfs.append(ToSpaceBGR(self.input_space=='BGR')) + tfs.append(ToRange255(max(self.input_range)==255)) + tfs.append(transforms.Normalize(mean=self.mean, std=self.std)) + + self.tf = transforms.Compose(tfs) + + def __call__(self, img): + tensor = self.tf(img) + return tensor + + +class LoadImage(object): + + def __init__(self, space='RGB'): + self.space = space + + def __call__(self, path_img): + with open(path_img, 'rb') as f: + with Image.open(f) as img: + img = img.convert(self.space) + return img + + +class LoadTransformImage(object): + + def __init__(self, model, scale=0.875): + self.load = LoadImage() + self.tf = TransformImage(model, scale=scale) + + def __call__(self, path_img): + img = self.load(path_img) + tensor = self.tf(img) + return tensor + + +class Identity(nn.Module): + + def __init__(self): + super(Identity, self).__init__() + + def forward(self, x): + return x \ No newline at end of file diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/version.py b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/version.py new file mode 100644 index 0000000000000000000000000000000000000000..6a4f2b23eaff580c4ee1e46f2ed3ba5b834eb7c9 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/pretrainedmodels/version.py @@ -0,0 +1,13 @@ +#Copyright (c) 2017, Remi Cadene +#All rights reserved. +#Copyright 2022 Huawei Technologies Co., Ltd + +#This source code is licensed under the license found in the +#LICENSE file in the root directory of this source tree. +#----------------------------------------------------- +#References: +#DPN68:https://https://github.com/Cadene/pretrained-models.pytorch#dualpathnetworks +#----------------------------------------------------- + +from __future__ import print_function, division, absolute_import +__version__ = '0.7.4' diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/test/env_npu.sh b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/test/env_npu.sh new file mode 100644 index 0000000000000000000000000000000000000000..93ec105c6e06b365fb805d3b30a6bf474d4df0a9 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/test/env_npu.sh @@ -0,0 +1,68 @@ +#!/bin/bash +CANN_INSTALL_PATH_CONF='/etc/Ascend/ascend_cann_install.info' + +if [ -f $CANN_INSTALL_PATH_CONF ]; then + CANN_INSTALL_PATH=$(cat $CANN_INSTALL_PATH_CONF | grep Install_Path | cut -d "=" -f 2) +else + CANN_INSTALL_PATH="/usr/local/Ascend" +fi + +if [ -d ${CANN_INSTALL_PATH}/ascend-toolkit/latest ]; then + source ${CANN_INSTALL_PATH}/ascend-toolkit/set_env.sh +else + source ${CANN_INSTALL_PATH}/nnae/set_env.sh +fi + +#设置device侧日志登记为error +msnpureport -g error -d 0 +msnpureport -g error -d 1 +msnpureport -g error -d 2 +msnpureport -g error -d 3 +msnpureport -g error -d 4 +msnpureport -g error -d 5 +msnpureport -g error -d 6 +msnpureport -g error -d 7 + +#将Host日志输出到串口,0-关闭/1-开启 +export ASCEND_SLOG_PRINT_TO_STDOUT=0 +#设置默认日志级别,0-debug/1-info/2-warning/3-error +export ASCEND_GLOBAL_LOG_LEVEL=3 +#设置Event日志开启标志,0-关闭/1-开启 +export ASCEND_GLOBAL_EVENT_ENABLE=0 +#设置是否开启taskque,0-关闭/1-开启 +export TASK_QUEUE_ENABLE=1 +#设置是否开启PTCopy,0-关闭/1-开启 +export PTCOPY_ENABLE=1 +#设置是否开启2个非连续combined标志,0-关闭/1-开启 +export COMBINED_ENABLE=1 +#设置是否开启3个非连续combined标志,0-关闭/1-开启 +export TRI_COMBINED_ENABLE=1 +#设置特殊场景是否需要重新编译,不需要修改 +export DYNAMIC_OP="ADD#MUL" +# HCCL白名单开关,1-关闭/0-开启 +export HCCL_WHITELIST_DISABLE=1 +# HCCL默认超时时间120s较少,修改为1800s对齐PyTorch默认设置 +export HCCL_CONNECT_TIMEOUT=1800 + +ulimit -SHn 512000 + +path_lib=$(python3.7 -c """ +import sys +import re +result='' +for index in range(len(sys.path)): + match_sit = re.search('-packages', sys.path[index]) + if match_sit is not None: + match_lib = re.search('lib', sys.path[index]) + + if match_lib is not None: + end=match_lib.span()[1] + result += sys.path[index][0:end] + ':' + + result+=sys.path[index] + '/torch/lib:' +print(result)""" +) + +echo ${path_lib} + +export LD_LIBRARY_PATH=/usr/local/python3.7.5/lib/:${path_lib}:$LD_LIBRARY_PATH diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/test/train_full_1p.sh b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/test/train_full_1p.sh new file mode 100644 index 0000000000000000000000000000000000000000..a922e31d2cdf45342e075c9d86493bf529a71716 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/test/train_full_1p.sh @@ -0,0 +1,128 @@ +#!/bin/bash + +################基础配置参数,需要模型审视修改################## +# 必选字段(必须在此处定义的参数): Network batch_size resume RANK_SIZE +# 网络名称,同目录名称 +Network="DPN-68_for_PyTorch" +# 训练batch_size +batch_size=256 +# 训练使用的npu卡数 +export RANK_SIZE=1 +# 加载数据集进程数 +workers=64 +# 数据集路径,保持为空,不需要修改 +data_path="" + +# 训练epoch +train_epochs=90 +# 指定训练所使用的npu device卡id +device_id=0 +# 学习率 +learning_rate=0.1 + +# 参数校验,data_path为必传参数,其他参数的增删由模型自身决定;此处新增参数需在上面有定义并赋值 +for para in $* +do + if [[ $para == --device_id* ]];then + device_id=`echo ${para#*=}` + elif [[ $para == --data_path* ]];then + data_path=`echo ${para#*=}` + fi +done + +# 校验是否传入data_path,不需要修改 +if [[ $data_path == "" ]];then + echo "[Error] para \"data_path\" must be confing" + exit 1 +fi + +###############指定训练脚本执行路径############### +# cd到与test文件夹同层级目录下执行脚本,提高兼容性;test_path_dir为包含test文件夹的路径 +cur_path=`pwd` +cur_path_last_dirname=${cur_path##*/} +if [ x"${cur_path_last_dirname}" == x"test" ];then + test_path_dir=${cur_path} + cd .. + cur_path=`pwd` +else + test_path_dir=${cur_path}/test +fi + + +#################创建日志输出目录,不需要修改################# +ASCEND_DEVICE_ID=0 +if [ -d ${test_path_dir}/output/${ASCEND_DEVICE_ID} ];then + rm -rf ${test_path_dir}/output/${ASCEND_DEVICE_ID} + mkdir -p ${test_path_dir}/output/$ASCEND_DEVICE_ID +else + mkdir -p ${test_path_dir}/output/$ASCEND_DEVICE_ID +fi + + +#################启动训练脚本################# +# 训练开始时间,不需要修改 +start_time=$(date +%s) +# source 环境变量 +# 非平台场景时source 环境变量 +check_etp_flag=`env | grep etp_running_flag` +etp_flag=`echo ${check_etp_flag#*=}` +if [ x"${etp_flag}" != x"true" ];then + source ${test_path_dir}/env_npu.sh +fi + +python3.7 ./examples/dpn68.py \ + --data_path ${data_path} \ + --gpu=1 \ + --epochs=1 \ + --batch-size=256 \ + --amp > ${test_path_dir}/output/${ASCEND_DEVICE_ID}/train_${ASCEND_DEVICE_ID}.log 2>&1 & + +wait + +##################获取训练数据################ +# 训练结束时间,不需要修改 +end_time=$(date +%s) +e2e_time=$(( $end_time - $start_time )) + +# 结果打印,不需要修改 +echo "------------------ Final result ------------------" +# 输出性能FPS,需要模型审视修改 +FPS=`grep -a 'batch_size' ${test_path_dir}/output/${ASCEND_DEVICE_ID}/train_${ASCEND_DEVICE_ID}.log|awk -F " " '{print $NF}'|awk 'END {print}'` +# 打印,不需要修改 +echo "Final Performance images/sec : $FPS" + +# 输出训练精度,需要模型审视修改 +train_accuracy=`grep -a 'AVG-ACC' ${test_path_dir}/output/${ASCEND_DEVICE_ID}/train_${ASCEND_DEVICE_ID}.log|awk -F " " '{print $8}'|awk 'END {print}'` +# 打印,不需要修改 +echo "Final Train Accuracy : ${train_accuracy}" +echo "E2E Training Duration sec : $e2e_time" + +# 性能看护结果汇总 +# 训练用例信息,不需要修改 +BatchSize=${batch_size} +DeviceType=`uname -m` +CaseName=${Network}_bs${BatchSize}_${RANK_SIZE}'p'_'acc' + +# 获取性能数据,不需要修改 +# 吞吐量 +ActualFPS=${FPS} +# 单迭代训练时长 +TrainingTime=`awk 'BEGIN{printf "%.2f\n", '${batch_size}'*1000/'${FPS}'}'` + +# 从train_$ASCEND_DEVICE_ID.log提取Loss到train_${CaseName}_loss.txt中,需要根据模型审视 +grep Epoch: ${test_path_dir}/output/$ASCEND_DEVICE_ID/train_$ASCEND_DEVICE_ID.log|grep -v Test|awk -F "Loss" '{print $NF}' | awk -F " " '{print $1}' >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/train_${CaseName}_loss.txt + +# 最后一个迭代loss值,不需要修改 +ActualLoss=`awk 'END {print}' ${test_path_dir}/output/$ASCEND_DEVICE_ID/train_${CaseName}_loss.txt` + +# 关键信息打印到${CaseName}.log中,不需要修改 +echo "Network = ${Network}" > ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "RankSize = ${RANK_SIZE}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "BatchSize = ${BatchSize}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "DeviceType = ${DeviceType}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "CaseName = ${CaseName}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "ActualFPS = ${ActualFPS}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "TrainingTime = ${TrainingTime}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "TrainAccuracy = ${train_accuracy}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "ActualLoss = ${ActualLoss}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "E2ETrainingTime = ${e2e_time}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log \ No newline at end of file diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/test/train_full_8p.sh b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/test/train_full_8p.sh new file mode 100644 index 0000000000000000000000000000000000000000..164e56a424ecbd145f739d7965457349c45e9816 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/test/train_full_8p.sh @@ -0,0 +1,129 @@ +#!/bin/bash + +################基础配置参数,需要模型审视修改################## +# 必选字段(必须在此处定义的参数): Network batch_size resume RANK_SIZE +# 网络名称,同目录名称 +Network="DPN-68_for_PyTorch" +# 训练batch_size +batch_size=2048 +# 训练使用的npu卡数 +export RANK_SIZE=8 +# 加载数据集进程数 +workers=64 +# 数据集路径,保持为空,不需要修改 +data_path="" + +# 训练epoch +train_epochs=90 +# 指定训练所使用的npu device卡id +# device_id=0 +# 学习率 +learning_rate=0.1 + +# 参数校验,data_path为必传参数,其他参数的增删由模型自身决定;此处新增参数需在上面有定义并赋值 +for para in $* +do + if [[ $para == --device_id* ]];then + device_id=`echo ${para#*=}` + elif [[ $para == --data_path* ]];then + data_path=`echo ${para#*=}` + fi +done + +# 校验是否传入data_path,不需要修改 +if [[ $data_path == "" ]];then + echo "[Error] para \"data_path\" must be confing" + exit 1 +fi + +###############指定训练脚本执行路径############### +# cd到与test文件夹同层级目录下执行脚本,提高兼容性;test_path_dir为包含test文件夹的路径 +cur_path=`pwd` +cur_path_last_dirname=${cur_path##*/} +if [ x"${cur_path_last_dirname}" == x"test" ];then + test_path_dir=${cur_path} + cd .. + cur_path=`pwd` +else + test_path_dir=${cur_path}/test +fi + + +#################创建日志输出目录,不需要修改################# +ASCEND_DEVICE_ID=0 +if [ -d ${test_path_dir}/output/${ASCEND_DEVICE_ID} ];then + rm -rf ${test_path_dir}/output/${ASCEND_DEVICE_ID} + mkdir -p ${test_path_dir}/output/$ASCEND_DEVICE_ID +else + mkdir -p ${test_path_dir}/output/$ASCEND_DEVICE_ID +fi + + +#################启动训练脚本################# +# 训练开始时间,不需要修改 +start_time=$(date +%s) +# source 环境变量 +# 非平台场景时source 环境变量 +check_etp_flag=`env | grep etp_running_flag` +etp_flag=`echo ${check_etp_flag#*=}` +if [ x"${etp_flag}" != x"true" ];then + source ${test_path_dir}/env_npu.sh +fi + +nohup python3.7 ./examples/dpn68.py \ + --data_path ${data_path} \ + --multiprocessing-distributed \ + --device='npu' \ + --epochs=90 \ + --amp \ + --batch-size=2048 > ${test_path_dir}/output/${ASCEND_DEVICE_ID}/train_${ASCEND_DEVICE_ID}.log 2>&1 & + +wait + +##################获取训练数据################ +# 训练结束时间,不需要修改 +end_time=$(date +%s) +e2e_time=$(( $end_time - $start_time )) + +# 结果打印,不需要修改 +echo "------------------ Final result ------------------" +# 输出性能FPS,需要模型审视修改 +FPS=`grep -a 'batch_size' ${test_path_dir}/output/${ASCEND_DEVICE_ID}/train_${ASCEND_DEVICE_ID}.log|awk -F " " '{print $NF}'|awk 'END {print}'` +# 打印,不需要修改 +echo "Final Performance images/sec : $FPS" + +# 输出训练精度,需要模型审视修改 +train_accuracy=`grep -a 'AVG-ACC' ${test_path_dir}/output/${ASCEND_DEVICE_ID}/train_${ASCEND_DEVICE_ID}.log|awk -F " " '{print $8}'|awk 'END {print}'` +# 打印,不需要修改 +echo "Final Train Accuracy : ${train_accuracy}" +echo "E2E Training Duration sec : $e2e_time" + +# 性能看护结果汇总 +# 训练用例信息,不需要修改 +BatchSize=${batch_size} +DeviceType=`uname -m` +CaseName=${Network}_bs${BatchSize}_${RANK_SIZE}'p'_'acc' + +# 获取性能数据,不需要修改 +# 吞吐量 +ActualFPS=${FPS} +# 单迭代训练时长 +TrainingTime=`awk 'BEGIN{printf "%.2f\n", '${batch_size}'*1000/'${FPS}'}'` + +# 从train_$ASCEND_DEVICE_ID.log提取Loss到train_${CaseName}_loss.txt中,需要根据模型审视 +grep Epoch: ${test_path_dir}/output/$ASCEND_DEVICE_ID/train_$ASCEND_DEVICE_ID.log|grep -v Test|awk -F "Loss" '{print $NF}' | awk -F " " '{print $1}' >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/train_${CaseName}_loss.txt + +# 最后一个迭代loss值,不需要修改 +ActualLoss=`awk 'END {print}' ${test_path_dir}/output/$ASCEND_DEVICE_ID/train_${CaseName}_loss.txt` + +# 关键信息打印到${CaseName}.log中,不需要修改 +echo "Network = ${Network}" > ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "RankSize = ${RANK_SIZE}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "BatchSize = ${BatchSize}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "DeviceType = ${DeviceType}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "CaseName = ${CaseName}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "ActualFPS = ${ActualFPS}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "TrainingTime = ${TrainingTime}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "TrainAccuracy = ${train_accuracy}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "ActualLoss = ${ActualLoss}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "E2ETrainingTime = ${e2e_time}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log \ No newline at end of file diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/test/train_performance_1p.sh b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/test/train_performance_1p.sh new file mode 100644 index 0000000000000000000000000000000000000000..3ae5dc8f8ad8a5714c56803cfda2e8ec17c2ad8d --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/test/train_performance_1p.sh @@ -0,0 +1,128 @@ +#!/bin/bash + +################基础配置参数,需要模型审视修改################## +# 必选字段(必须在此处定义的参数): Network batch_size resume RANK_SIZE +# 网络名称,同目录名称 +Network="DPN-68_for_PyTorch" +# 训练batch_size +batch_size=256 +# 训练使用的npu卡数 +export RANK_SIZE=1 +# 加载数据集进程数 +workers=64 +# 数据集路径,保持为空,不需要修改 +data_path="" + +# 训练epoch +train_epochs=1 +# 指定训练所使用的npu device卡id +device_id=0 +# 学习率 +learning_rate=0.1 + +# 参数校验,data_path为必传参数,其他参数的增删由模型自身决定;此处新增参数需在上面有定义并赋值 +for para in $* +do + if [[ $para == --device_id* ]];then + device_id=`echo ${para#*=}` + elif [[ $para == --data_path* ]];then + data_path=`echo ${para#*=}` + fi +done + +# 校验是否传入data_path,不需要修改 +if [[ $data_path == "" ]];then + echo "[Error] para \"data_path\" must be confing" + exit 1 +fi + +###############指定训练脚本执行路径############### +# cd到与test文件夹同层级目录下执行脚本,提高兼容性;test_path_dir为包含test文件夹的路径 +cur_path=`pwd` +cur_path_last_dirname=${cur_path##*/} +if [ x"${cur_path_last_dirname}" == x"test" ];then + test_path_dir=${cur_path} + cd .. + cur_path=`pwd` +else + test_path_dir=${cur_path}/test +fi + + +#################创建日志输出目录,不需要修改################# +ASCEND_DEVICE_ID=0 +if [ -d ${test_path_dir}/output/${ASCEND_DEVICE_ID} ];then + rm -rf ${test_path_dir}/output/${ASCEND_DEVICE_ID} + mkdir -p ${test_path_dir}/output/$ASCEND_DEVICE_ID +else + mkdir -p ${test_path_dir}/output/$ASCEND_DEVICE_ID +fi + + +#################启动训练脚本################# +# 训练开始时间,不需要修改 +start_time=$(date +%s) +# source 环境变量 +# 非平台场景时source 环境变量 +check_etp_flag=`env | grep etp_running_flag` +etp_flag=`echo ${check_etp_flag#*=}` +if [ x"${etp_flag}" != x"true" ];then + source ${test_path_dir}/env_npu.sh +fi + +python3 ./examples/dpn68.py \ + --data_path ${data_path} \ + --gpu=0 \ + --epochs=1 \ + --batch-size=256 \ + --amp > ${test_path_dir}/output/${ASCEND_DEVICE_ID}/train_${ASCEND_DEVICE_ID}.log 2>&1 & + +wait + +##################获取训练数据################ +# 训练结束时间,不需要修改 +end_time=$(date +%s) +e2e_time=$(( $end_time - $start_time )) + +# 结果打印,不需要修改 +echo "------------------ Final result ------------------" +# 输出性能FPS,需要模型审视修改 +FPS=`grep -a 'batch_size' ${test_path_dir}/output/${ASCEND_DEVICE_ID}/train_${ASCEND_DEVICE_ID}.log|awk -F " " '{print $NF}'|awk 'END {print}'` +# 打印,不需要修改 +echo "Final Performance images/sec : $FPS" + +# 输出训练精度,需要模型审视修改 +train_accuracy=`grep -a 'AVG-ACC' ${test_path_dir}/output/${ASCEND_DEVICE_ID}/train_${ASCEND_DEVICE_ID}.log|awk -F " " '{print $8}'|awk 'END {print}'` +# 打印,不需要修改 +echo "Final Train Accuracy : ${train_accuracy}" +echo "E2E Training Duration sec : $e2e_time" + +# 性能看护结果汇总 +# 训练用例信息,不需要修改 +BatchSize=${batch_size} +DeviceType=`uname -m` +CaseName=${Network}_bs${BatchSize}_${RANK_SIZE}'p'_'perf' + +# 获取性能数据,不需要修改 +# 吞吐量 +ActualFPS=${FPS} +# 单迭代训练时长 +TrainingTime=`awk 'BEGIN{printf "%.2f\n", '${batch_size}'*1000/'${FPS}'}'` + +# 从train_$ASCEND_DEVICE_ID.log提取Loss到train_${CaseName}_loss.txt中,需要根据模型审视 +grep Epoch: ${test_path_dir}/output/$ASCEND_DEVICE_ID/train_$ASCEND_DEVICE_ID.log|grep -v Test|awk -F "Loss" '{print $NF}' | awk -F " " '{print $1}' >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/train_${CaseName}_loss.txt + +# 最后一个迭代loss值,不需要修改 +ActualLoss=`awk 'END {print}' ${test_path_dir}/output/$ASCEND_DEVICE_ID/train_${CaseName}_loss.txt` + +# 关键信息打印到${CaseName}.log中,不需要修改 +echo "Network = ${Network}" > ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "RankSize = ${RANK_SIZE}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "BatchSize = ${BatchSize}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "DeviceType = ${DeviceType}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "CaseName = ${CaseName}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "ActualFPS = ${ActualFPS}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "TrainingTime = ${TrainingTime}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "TrainAccuracy = ${train_accuracy}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "ActualLoss = ${ActualLoss}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "E2ETrainingTime = ${e2e_time}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log diff --git a/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/test/train_performance_8p.sh b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/test/train_performance_8p.sh new file mode 100644 index 0000000000000000000000000000000000000000..a3f219a363fefeac85db43d0c94cf66c488439e4 --- /dev/null +++ b/PyTorch/contrib/cv/classification/DPN-68_for_PyTorch/test/train_performance_8p.sh @@ -0,0 +1,127 @@ +#!/bin/bash + +################基础配置参数,需要模型审视修改################## +# 必选字段(必须在此处定义的参数): Network batch_size resume RANK_SIZE +# 网络名称,同目录名称 +Network="DPN-68_for_PyTorch" +# 训练batch_size +batch_size=2048 +# 训练使用的npu卡数 +export RANK_SIZE=8 +# 加载数据集进程数 +workers=64 +# 数据集路径,保持为空,不需要修改 +data_path="" + +# 训练epoch +train_epochs=1 +# 学习率 +learning_rate=0.1 + +# 参数校验,data_path为必传参数,其他参数的增删由模型自身决定;此处新增参数需在上面有定义并赋值 +for para in $* +do + if [[ $para == --device_id* ]];then + device_id=`echo ${para#*=}` + elif [[ $para == --data_path* ]];then + data_path=`echo ${para#*=}` + fi +done + +# 校验是否传入data_path,不需要修改 +if [[ $data_path == "" ]];then + echo "[Error] para \"data_path\" must be confing" + exit 1 +fi + +###############指定训练脚本执行路径############### +# cd到与test文件夹同层级目录下执行脚本,提高兼容性;test_path_dir为包含test文件夹的路径 +cur_path=`pwd` +cur_path_last_dirname=${cur_path##*/} +if [ x"${cur_path_last_dirname}" == x"test" ];then + test_path_dir=${cur_path} + cd .. + cur_path=`pwd` +else + test_path_dir=${cur_path}/test +fi + + +#################创建日志输出目录,不需要修改################# +ASCEND_DEVICE_ID=0 +if [ -d ${test_path_dir}/output/${ASCEND_DEVICE_ID} ];then + rm -rf ${test_path_dir}/output/${ASCEND_DEVICE_ID} + mkdir -p ${test_path_dir}/output/$ASCEND_DEVICE_ID +else + mkdir -p ${test_path_dir}/output/$ASCEND_DEVICE_ID +fi + + +#################启动训练脚本################# +# 训练开始时间,不需要修改 +start_time=$(date +%s) +# source 环境变量 +# 非平台场景时source 环境变量 +check_etp_flag=`env | grep etp_running_flag` +etp_flag=`echo ${check_etp_flag#*=}` +if [ x"${etp_flag}" != x"true" ];then + source ${test_path_dir}/env_npu.sh +fi + +nohup python3.7 ./examples/dpn68.py \ + --data_path ${data_path} \ + --multiprocessing-distributed \ + --device='npu' \ + --epochs=1 \ + --amp \ + --batch-size=2048 > ${test_path_dir}/output/${ASCEND_DEVICE_ID}/train_${ASCEND_DEVICE_ID}.log 2>&1 & + +wait + +##################获取训练数据################ +# 训练结束时间,不需要修改 +end_time=$(date +%s) +e2e_time=$(( $end_time - $start_time )) + +# 结果打印,不需要修改 +echo "------------------ Final result ------------------" +# 输出性能FPS,需要模型审视修改 +FPS=`grep -a 'batch_size' ${test_path_dir}/output/${ASCEND_DEVICE_ID}/train_${ASCEND_DEVICE_ID}.log|awk -F " " '{print $NF}'|awk 'END {print}'` +# 打印,不需要修改 +echo "Final Performance images/sec : $FPS" + +# 输出训练精度,需要模型审视修改 +train_accuracy=`grep -a 'AVG-ACC' ${test_path_dir}/output/${ASCEND_DEVICE_ID}/train_${ASCEND_DEVICE_ID}.log|awk -F " " '{print $8}'|awk 'END {print}'` +# 打印,不需要修改 +echo "Final Train Accuracy : ${train_accuracy}" +echo "E2E Training Duration sec : $e2e_time" + +# 性能看护结果汇总 +# 训练用例信息,不需要修改 +BatchSize=${batch_size} +DeviceType=`uname -m` +CaseName=${Network}_bs${BatchSize}_${RANK_SIZE}'p'_'perf' + +# 获取性能数据,不需要修改 +# 吞吐量 +ActualFPS=${FPS} +# 单迭代训练时长 +TrainingTime=`awk 'BEGIN{printf "%.2f\n", '${batch_size}'*1000/'${FPS}'}'` + +# 从train_$ASCEND_DEVICE_ID.log提取Loss到train_${CaseName}_loss.txt中,需要根据模型审视 +grep Epoch: ${test_path_dir}/output/$ASCEND_DEVICE_ID/train_$ASCEND_DEVICE_ID.log|grep -v Test|awk -F "Loss" '{print $NF}' | awk -F " " '{print $1}' >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/train_${CaseName}_loss.txt + +# 最后一个迭代loss值,不需要修改 +ActualLoss=`awk 'END {print}' ${test_path_dir}/output/$ASCEND_DEVICE_ID/train_${CaseName}_loss.txt` + +# 关键信息打印到${CaseName}.log中,不需要修改 +echo "Network = ${Network}" > ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "RankSize = ${RANK_SIZE}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "BatchSize = ${BatchSize}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "DeviceType = ${DeviceType}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "CaseName = ${CaseName}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "ActualFPS = ${ActualFPS}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "TrainingTime = ${TrainingTime}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "TrainAccuracy = ${train_accuracy}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "ActualLoss = ${ActualLoss}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log +echo "E2ETrainingTime = ${e2e_time}" >> ${test_path_dir}/output/$ASCEND_DEVICE_ID/${CaseName}.log \ No newline at end of file