Browse Source

Initial commit.

pull/187/head
Gitea 5 months ago
commit
8a15c6cae1
100 changed files with 4428 additions and 0 deletions
  1. +53
    -0
      CV_benchmark/config/logger.conf
  2. +25
    -0
      CV_benchmark/config/mainconfig.py
  3. +35
    -0
      CV_benchmark/config/re_ID.yaml
  4. +3
    -0
      CV_benchmark/data_utils/__init__.py
  5. +33
    -0
      CV_benchmark/data_utils/label_smooth.py
  6. +157
    -0
      CV_benchmark/data_utils/model_train.py
  7. +170
    -0
      CV_benchmark/data_utils/triplet.py
  8. +56
    -0
      Case_CIFAR10/README.md
  9. +21
    -0
      Case_CIFAR10/case1/LICENSE
  10. BIN
      Case_CIFAR10/case1/__pycache__/utils.cpython-37.pyc
  11. BIN
      Case_CIFAR10/case1/img/train.png
  12. +154
    -0
      Case_CIFAR10/case1/main.py
  13. +18
    -0
      Case_CIFAR10/case1/models/__init__.py
  14. BIN
      Case_CIFAR10/case1/models/__pycache__/__init__.cpython-37.pyc
  15. BIN
      Case_CIFAR10/case1/models/__pycache__/densenet.cpython-37.pyc
  16. BIN
      Case_CIFAR10/case1/models/__pycache__/dla.cpython-37.pyc
  17. BIN
      Case_CIFAR10/case1/models/__pycache__/dla_simple.cpython-37.pyc
  18. BIN
      Case_CIFAR10/case1/models/__pycache__/dpn.cpython-37.pyc
  19. BIN
      Case_CIFAR10/case1/models/__pycache__/efficientnet.cpython-37.pyc
  20. BIN
      Case_CIFAR10/case1/models/__pycache__/googlenet.cpython-37.pyc
  21. BIN
      Case_CIFAR10/case1/models/__pycache__/lenet.cpython-37.pyc
  22. BIN
      Case_CIFAR10/case1/models/__pycache__/mobilenet.cpython-37.pyc
  23. BIN
      Case_CIFAR10/case1/models/__pycache__/mobilenetv2.cpython-37.pyc
  24. BIN
      Case_CIFAR10/case1/models/__pycache__/pnasnet.cpython-37.pyc
  25. BIN
      Case_CIFAR10/case1/models/__pycache__/preact_resnet.cpython-37.pyc
  26. BIN
      Case_CIFAR10/case1/models/__pycache__/regnet.cpython-37.pyc
  27. BIN
      Case_CIFAR10/case1/models/__pycache__/resnet.cpython-37.pyc
  28. BIN
      Case_CIFAR10/case1/models/__pycache__/resnext.cpython-37.pyc
  29. BIN
      Case_CIFAR10/case1/models/__pycache__/senet.cpython-37.pyc
  30. BIN
      Case_CIFAR10/case1/models/__pycache__/shufflenet.cpython-37.pyc
  31. BIN
      Case_CIFAR10/case1/models/__pycache__/shufflenetv2.cpython-37.pyc
  32. BIN
      Case_CIFAR10/case1/models/__pycache__/vgg.cpython-37.pyc
  33. +107
    -0
      Case_CIFAR10/case1/models/densenet.py
  34. +135
    -0
      Case_CIFAR10/case1/models/dla.py
  35. +128
    -0
      Case_CIFAR10/case1/models/dla_simple.py
  36. +98
    -0
      Case_CIFAR10/case1/models/dpn.py
  37. +175
    -0
      Case_CIFAR10/case1/models/efficientnet.py
  38. +107
    -0
      Case_CIFAR10/case1/models/googlenet.py
  39. +23
    -0
      Case_CIFAR10/case1/models/lenet.py
  40. +61
    -0
      Case_CIFAR10/case1/models/mobilenet.py
  41. +86
    -0
      Case_CIFAR10/case1/models/mobilenetv2.py
  42. +125
    -0
      Case_CIFAR10/case1/models/pnasnet.py
  43. +118
    -0
      Case_CIFAR10/case1/models/preact_resnet.py
  44. +155
    -0
      Case_CIFAR10/case1/models/regnet.py
  45. +132
    -0
      Case_CIFAR10/case1/models/resnet.py
  46. +95
    -0
      Case_CIFAR10/case1/models/resnext.py
  47. +121
    -0
      Case_CIFAR10/case1/models/senet.py
  48. +109
    -0
      Case_CIFAR10/case1/models/shufflenet.py
  49. +162
    -0
      Case_CIFAR10/case1/models/shufflenetv2.py
  50. +47
    -0
      Case_CIFAR10/case1/models/vgg.py
  51. +124
    -0
      Case_CIFAR10/case1/utils.py
  52. BIN
      Case_CIFAR10/case2/__pycache__/mox_parser.cpython-37.pyc
  53. +39
    -0
      Case_CIFAR10/case2/inference.py
  54. +122
    -0
      Case_CIFAR10/case2/main.py
  55. +28
    -0
      Case_CIFAR10/case2/mox_parser.py
  56. +311
    -0
      Case_CIFAR10/case2/resnet.py
  57. +30
    -0
      Case_CIFAR10/case2/train.py
  58. BIN
      Case_CIFAR10/cifar.zip
  59. BIN
      Case_CIFAR10/教程/img/L14-1-1.png
  60. BIN
      Case_CIFAR10/教程/img/L14-1.gif
  61. BIN
      Case_CIFAR10/教程/img/L14-10.gif
  62. BIN
      Case_CIFAR10/教程/img/L14-10.png
  63. BIN
      Case_CIFAR10/教程/img/L14-11.png
  64. BIN
      Case_CIFAR10/教程/img/L14-12.png
  65. BIN
      Case_CIFAR10/教程/img/L14-13.png
  66. BIN
      Case_CIFAR10/教程/img/L14-14.png
  67. BIN
      Case_CIFAR10/教程/img/L14-15.png
  68. BIN
      Case_CIFAR10/教程/img/L14-16.png
  69. BIN
      Case_CIFAR10/教程/img/L14-17.png
  70. BIN
      Case_CIFAR10/教程/img/L14-18.png
  71. BIN
      Case_CIFAR10/教程/img/L14-19.png
  72. BIN
      Case_CIFAR10/教程/img/L14-2.gif
  73. BIN
      Case_CIFAR10/教程/img/L14-20.png
  74. BIN
      Case_CIFAR10/教程/img/L14-21-1.png
  75. BIN
      Case_CIFAR10/教程/img/L14-21-2.png
  76. BIN
      Case_CIFAR10/教程/img/L14-21-3.png
  77. BIN
      Case_CIFAR10/教程/img/L14-21-4.png
  78. BIN
      Case_CIFAR10/教程/img/L14-21.png
  79. BIN
      Case_CIFAR10/教程/img/L14-22.png
  80. BIN
      Case_CIFAR10/教程/img/L14-3.gif
  81. BIN
      Case_CIFAR10/教程/img/L14-3.png
  82. BIN
      Case_CIFAR10/教程/img/L14-4.gif
  83. BIN
      Case_CIFAR10/教程/img/L14-4.png
  84. BIN
      Case_CIFAR10/教程/img/L14-5.png
  85. BIN
      Case_CIFAR10/教程/img/L14-6.png
  86. BIN
      Case_CIFAR10/教程/img/L14-7-1.png
  87. BIN
      Case_CIFAR10/教程/img/L14-7.png
  88. BIN
      Case_CIFAR10/教程/img/L14-8.png
  89. BIN
      Case_CIFAR10/教程/img/L14-9.png
  90. +292
    -0
      Case_CIFAR10/教程/教程.md
  91. +60
    -0
      English_Version/Lesson 1-Create a repository.md
  92. +31
    -0
      English_Version/Lesson 2-Download and Install Git.md
  93. +49
    -0
      English_Version/Lesson 3-Code (created over HTTPS) .md
  94. +94
    -0
      English_Version/Lesson 4-Code (created over SSH) .md
  95. +52
    -0
      English_Version/Lesson 5-Code (clone repository) .md
  96. +165
    -0
      English_Version/Lesson 6-Code (submit and update documents) .md
  97. +104
    -0
      English_Version/Lesson 7-Dataset.md
  98. +164
    -0
      English_Version/Lesson 8-CPU and GPU debug task.md
  99. +54
    -0
      English_Version/README.md
  100. BIN
      English_Version/img/0.png

+ 53
- 0
CV_benchmark/config/logger.conf View File

@@ -0,0 +1,53 @@
[loggers]
keys=root,TRAIN,TEST,EVAL

[handlers]
keys=consoleHandler,fileHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=INFO
handlers=consoleHandler,fileHandler

[logger_TRAIN]
level=INFO
handlers=consoleHandler,fileHandler
qualname=TRAIN
propagate=0

[logger_VAL]
level=INFO
handlers=consoleHandler,fileHandler
qualname=VAL
propagate=0

[logger_TEST]
level=INFO
handlers=consoleHandler,fileHandler
qualname=TEST
propagate=0

[logger_EVAL]
level=INFO
handlers=consoleHandler,fileHandler
qualname=simpleExample
propagate=0

[handler_consoleHandler]
class=StreamHandler
level=INFO
formatter=simpleFormatter
args=(sys.stdout,)

[handler_fileHandler]
class = FileHandler
level=INFO
formatter=simpleFormatter
args=('/output/log/log.txt','a')


[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=%Y-%m-%d %H:%M:%S

+ 25
- 0
CV_benchmark/config/mainconfig.py View File

@@ -0,0 +1,25 @@
# file location

# ROOT_DIR="/home/xujiahong/VeRi_try/openI"
ROOT_DIR=""

# output dir
CODE_ROOT_DIR = ROOT_DIR + "/code"
# CODE_ROOT_DIR = '/home/xujiahong/openI_benchmark/BoT_person_reID'

# config dir
CONFIG_PATH = CODE_ROOT_DIR + "/config/re_ID.yaml"

# output dir
OUTPUT_RESULT_DIR= "/output/result/"
EVAL_RESULT_PATH = "/output/log/eval_result.json"
FULL_INFO_PATH = "/output/log/full_info.json"
LOGGER_PATH = "/output/log/log.txt" #与logger.conf 中的值保持一致

# upload API
UPLOAD_EVAL_RESULT_API = "http://192.168.202.90:6134/api/benchmark-result/"
DEBUG_MODE = True
REID_TYPE = {1: "vehicle reid", 2:"image-based person reid", 3:"person search", 4:"video-based person reid"}
ALG_TYPE = "Re-ID"
USER_INFO_PATH = "/benchmark/taskInfo"


+ 35
- 0
CV_benchmark/config/re_ID.yaml View File

@@ -0,0 +1,35 @@
# scene: type of re-ID
# four types in total:
# 1. vehicle reid
# 2. image_based person reid
# 3. person search
# 4. video-based person reid
scene: 2
attr_name:
attr_value:

input:
dataset:
# data_dir: /root/small_market1501
# data_dir: /dataset/small_market1501
data_dir: /dataset/benchmark_vehicle_reID
# data_dir: /dataset/1_Market1501

config:
adam: True
batchsize: 128
droprate: 0.2
erasing_p: 0
h: 256
w: 256
inputsize: 256
lr: 0.00035
name: Res50
nclass: 2304 #class number of benchmark_person_reID
num_epochs: 1
pool: avg
stride: 1
warm_epoch: 0

test:
flip_test: True

+ 3
- 0
CV_benchmark/data_utils/__init__.py View File

@@ -0,0 +1,3 @@
from .label_smooth import *
from .model_train import *
from .triplet import *

+ 33
- 0
CV_benchmark/data_utils/label_smooth.py View File

@@ -0,0 +1,33 @@
from __future__ import print_function, absolute_import

import torch
from torch import nn


class LSR_loss(nn.Module):

def __init__(self, e=0.1):
super().__init__()
self.log_softmax = nn.LogSoftmax(dim=1)
self.e = e

def _one_hot(self, labels, classes, value=1):
one_hot = torch.zeros(labels.size(0), classes)
# labels and value_added size must match
labels = labels.view(labels.size(0), -1)
value_added = torch.Tensor(labels.size(0), 1).fill_(value)
value_added = value_added.to(labels.device)
one_hot = one_hot.to(labels.device)
one_hot.scatter_add_(1, labels, value_added)
return one_hot

def _smooth_label(self, target, length, smooth_factor):
one_hot = self._one_hot(target, length, value=1 - smooth_factor)
one_hot += smooth_factor / length
return one_hot.to(target.device)

def forward(self, x, target):
smoothed_target = self._smooth_label(target, x.size(1), self.e)
x = self.log_softmax(x)
loss = torch.sum(- x * smoothed_target, dim=1)
return torch.mean(loss)

+ 157
- 0
CV_benchmark/data_utils/model_train.py View File

@@ -0,0 +1,157 @@
import argparse
import torch
import torch.nn as nn
from torch.nn import init
from torchvision import models
from torch.autograd import Variable
#from efficientnet_pytorch import EfficientNet
#import pretrainedmodels
from torch.nn import functional as F

######################################################################
def weights_init_kaiming(m):
classname = m.__class__.__name__
# print(classname)
if classname.find('Conv') != -1:
init.kaiming_normal_(m.weight.data, a=0, mode='fan_in') # For old pytorch, you may use kaiming_normal.
elif classname.find('Linear') != -1:
init.kaiming_normal_(m.weight.data, a=0, mode='fan_out')
init.constant_(m.bias.data, 0.0)
elif classname.find('BatchNorm1d') != -1:
init.normal_(m.weight.data, 1.0, 0.02)
init.constant_(m.bias.data, 0.0)

def weights_init_classifier(m):
classname = m.__class__.__name__
if classname.find('Linear') != -1:
init.normal_(m.weight.data, std=0.001)
init.constant_(m.bias.data, 0.0)

def fix_relu(m):
classname = m.__class__.__name__
if classname.find('ReLU') != -1:
m.inplace=True
# Defines the new fc layer and classification layer
# |--Linear--|--bn--|--relu--|--Linear--|
class ClassBlock(nn.Module):
'''
xjh_notes:
-----------------------
Defines the linear layers after the adp avg pooling layer in the backbone
-----------------------
Parameters:
linear - if add a fc layer of size [input_dim, num_bottleneck]
bnorm - if add a bn layer
relu - if add a leakyReLU layer
droprate - if droprate > 0, using dropout in add_block

'''
def __init__(self, input_dim, class_num, droprate, relu=True, bnorm=True, num_bottleneck=2048, linear=True, return_f = False):
super(ClassBlock, self).__init__()
self.return_f = return_f
add_block = []
if linear:
add_block += [nn.Linear(input_dim, num_bottleneck)]
else:
num_bottleneck = input_dim
if bnorm:
add_block += [nn.BatchNorm1d(num_bottleneck)]
if relu:
add_block += [nn.LeakyReLU(0.1)]
if droprate>0:
add_block += [nn.Dropout(p=droprate)]
add_block = nn.Sequential(*add_block)
add_block.apply(weights_init_kaiming)

classifier = []
classifier += [nn.Linear(num_bottleneck, class_num)]
classifier = nn.Sequential(*classifier)
classifier.apply(weights_init_classifier)

self.add_block = add_block
self.classifier = classifier
def forward(self, x):
f = x
x = self.add_block(x)
x = self.classifier(x)
if self.return_f:
return x,f
else:
return x

# Define the ResNet50-based Model
class ft_net(nn.Module):

def __init__(self, class_num, droprate=0.5, stride=2, init_model=None, pool='avg', return_f=True):
self.return_f=return_f
super(ft_net, self).__init__()
model_ft = models.resnet50(pretrained=True)
# avg pooling to global pooling
if stride == 1:
model_ft.layer4[0].downsample[0].stride = (1,1)
model_ft.layer4[0].conv2.stride = (1,1)

self.pool = pool
if pool =='avg+max':
model_ft.avgpool2 = nn.AdaptiveAvgPool2d((1,1))
model_ft.maxpool2 = nn.AdaptiveMaxPool2d((1,1))
self.model = model_ft
self.classifier= ClassBlock(2048, class_num, droprate, return_f=self.return_f, linear=False)
elif pool=='avg':
model_ft.avgpool = nn.AdaptiveAvgPool2d((1,1))
self.model = model_ft
self.classifier= ClassBlock(2048, class_num, droprate, return_f=self.return_f, linear=False)

if init_model!=None:
self.flag = True
self.model = init_model.model
self.pool = init_model.pool
self.classifier.add_block = init_model.classifier.add_block
# avg pooling to global pooling

def forward(self, x):
x = self.model.conv1(x)
x = self.model.bn1(x)
x = self.model.relu(x)
x = self.model.maxpool(x)
x = self.model.layer1(x)
x = self.model.layer2(x)
x = self.model.layer3(x)
x = self.model.layer4(x)
if self.pool == 'avg+max':
x1 = self.model.avgpool2(x)
x2 = self.model.maxpool2(x)
x = torch.cat((x1,x2), dim = 1)
x = x.view(x.size(0), x.size(1))
elif self.pool == 'avg':
x = self.model.avgpool(x)
x = x.view(x.size(0), x.size(1))
output = self.classifier(x) #if return_f: return (fc, feature) else return fc
return output


'''
# debug model structure
# Run this code with:
python model.py
'''
if __name__ == '__main__':
# Here I left a simple forward function.
# Test the model, before you train it.

'''
net = CPB(751)
#net = ft_net_SE(751)
print(net)
input = Variable(torch.FloatTensor(4, 3, 320, 320))
output = net(input)
print('net output size:')
#print(output.shape)
'''

xjh_net = ft_net(333)
print(xjh_net)
input = Variable(torch.FloatTensor(2,3,384,384))
output = xjh_net(input)
print(output.shape)

+ 170
- 0
CV_benchmark/data_utils/triplet.py View File

@@ -0,0 +1,170 @@
from __future__ import absolute_import

import torch
from torch import nn


def normalize(x, axis=-1):
"""Normalizing to unit length along the specified dimension.
Args:
x: pytorch Variable
Returns:
x: pytorch Variable, same shape as input
"""
x = 1. * x / (torch.norm(x, 2, axis, keepdim=True).expand_as(x) + 1e-12)
return x


def euclidean_dist(x, y):
"""
Args:
x: pytorch Variable, with shape [m, d]
y: pytorch Variable, with shape [n, d]
Returns:
dist: pytorch Variable, with shape [m, n]
"""
m, n = x.size(0), y.size(0)
xx = torch.pow(x, 2).sum(1, keepdim=True).expand(m, n)
yy = torch.pow(y, 2).sum(1, keepdim=True).expand(n, m).t()
dist = xx + yy
# dist.addmm_(1, -2, x, y.t())
dist.addmm_( x, y.t(), beta = 1, alpha = -2)
dist = dist.clamp(min=1e-12).sqrt() # for numerical stability
return dist


def hard_example_mining(dist_mat, labels, return_inds=False):
"""For each anchor, find the hardest positive and negative sample.
Args:
dist_mat: pytorch Variable, pair wise distance between samples, shape [N, N]
labels: pytorch LongTensor, with shape [N]
return_inds: whether to return the indices. Save time if `False`(?)
Returns:
dist_ap: pytorch Variable, distance(anchor, positive); shape [N]
dist_an: pytorch Variable, distance(anchor, negative); shape [N]
p_inds: pytorch LongTensor, with shape [N];
indices of selected hard positive samples; 0 <= p_inds[i] <= N - 1
n_inds: pytorch LongTensor, with shape [N];
indices of selected hard negative samples; 0 <= n_inds[i] <= N - 1
NOTE: Only consider the case in which all labels have same num of samples,
thus we can cope with all anchors in parallel.
"""

assert len(dist_mat.size()) == 2
assert dist_mat.size(0) == dist_mat.size(1)
N = dist_mat.size(0)

# shape [N, N]
is_pos = labels.expand(N, N).eq(labels.expand(N, N).t())
is_neg = labels.expand(N, N).ne(labels.expand(N, N).t())

'''
# `dist_ap` means distance(anchor, positive)
# both `dist_ap` and `relative_p_inds` with shape [N, 1]

dist_ap, relative_p_inds = torch.max(dist_mat[is_pos].contiguous().view(N, -1), 1, keepdim=True)
# `dist_an` means distance(anchor, negative)
# both `dist_an` and `relative_n_inds` with shape [N, 1]
dist_an, relative_n_inds = torch.min(dist_mat[is_neg].contiguous().view(N, -1), 1, keepdim=True)
# shape [N]
dist_ap = dist_ap.squeeze(1)
dist_an = dist_an.squeeze(1)
'''

dist_ap, relative_p_inds = torch.max(dist_mat.masked_fill(is_neg, 0), 1, keepdim=True)
dist_an, relative_n_inds = torch.min(dist_mat.masked_fill(is_pos, float("inf")), 1, keepdim=True)

# dist_ap1, dist_an1 = [], []
# for i in range(N):
# dist_ap1.append(dist_mat[i][is_pos[i]].max().unsqueeze(0))
# dist_an1.append(dist_mat[i][is_pos[i] == 0].min().unsqueeze(0))

# dist_ap1, dist_an1 = torch.tensor(dist_ap1), torch.tensor(dist_an1)

if return_inds:
# shape [N, N]
ind = (labels.new().resize_as_(labels).copy_(torch.arange(0, N).long()).unsqueeze(0).expand(N, N))
# shape [N, 1]
p_inds = torch.gather(ind[is_pos].contiguous().view(N, -1), 1, relative_p_inds.data)
n_inds = torch.gather(ind[is_neg].contiguous().view(N, -1), 1, relative_n_inds.data)
# shape [N]
p_inds = p_inds.squeeze(1)
n_inds = n_inds.squeeze(1)
return dist_ap, dist_an, p_inds, n_inds

return dist_ap, dist_an


class TripletLoss(nn.Module):
def __init__(self, margin=None):
super(TripletLoss, self).__init__()
self.margin = margin
if self.margin is not None:
self.ranking_loss = nn.MarginRankingLoss(margin=margin)
else:
self.ranking_loss = nn.SoftMarginLoss()

def forward(self, global_feat, labels, normalize_feature=False):
if normalize_feature:
global_feat = normalize(global_feat, axis=-1)
# shape [N, N]
dist_mat = euclidean_dist(global_feat, global_feat)
dist_ap, dist_an = hard_example_mining(dist_mat, labels)
y = dist_an.new().resize_as_(dist_an).fill_(1)
if self.margin is not None:
loss = self.ranking_loss(dist_an, dist_ap, y)
else:
loss = self.ranking_loss(dist_an - dist_ap, y)
prec = (dist_an.data > dist_ap.data).sum().float() / y.size(0)
return loss, prec, dist_ap, dist_an


class Center_loss(nn.Module):
"""Center loss.
Reference:
Wen et al. A Discriminative Feature Learning Approach for Deep Face Recognition. ECCV 2016.
Args:
num_classes (int): number of classes.
feat_dim (int): feature dimension.
"""

def __init__(self, num_classes=751, feat_dim=2048, use_gpu=True):
super(Center_loss, self).__init__()
self.num_classes = num_classes
self.feat_dim = feat_dim
self.use_gpu = use_gpu

if self.use_gpu:
self.centers = nn.Parameter(torch.randn(self.num_classes, self.feat_dim).cuda())
else:
self.centers = nn.Parameter(torch.randn(self.num_classes, self.feat_dim))

def forward(self, x, labels):
"""
Args:
x: feature matrix with shape (batch_size, feat_dim).
labels: ground truth labels with shape (num_classes).
"""
assert x.size(0) == labels.size(0), "features.size(0) is not equal to labels.size(0)"

batch_size = x.size(0)
distmat = torch.pow(x, 2).sum(dim=1, keepdim=True).expand(batch_size, self.num_classes) + \
torch.pow(self.centers, 2).sum(dim=1, keepdim=True).expand(self.num_classes, batch_size).t()
distmat.addmm_(1, -2, x, self.centers.t())

classes = torch.arange(self.num_classes).long()
if self.use_gpu: classes = classes.cuda()
labels = labels.unsqueeze(1).expand(batch_size, self.num_classes)
mask = labels.eq(classes.expand(batch_size, self.num_classes))

dist = distmat * mask.float()
loss = dist.clamp(min=1e-12, max=1e+12).sum() / batch_size
#dist = []
#for i in range(batch_size):
# value = distmat[i][mask[i]]
# value = value.clamp(min=1e-12, max=1e+12) # for numerical stability
# dist.append(value)
#dist = torch.cat(dist)
#loss = dist.mean()
return loss


+ 56
- 0
Case_CIFAR10/README.md View File

@@ -0,0 +1,56 @@
# CIFAR-10图像识别项目实战

本实战项目是一个CIFAR-10的图像分类任务,基于CIFAR10的数据集和【PyTorch】,通过在云脑环境调试和训练模型,最终评估模型的准确率。

## 文件资料说明

- 《Case1》文件夹,是基于云脑1算力资源(CPU/GPU)进行任务调试与训练的代码文件

- 《Case2》文件夹,是基于云脑2算力资源(Ascend NPU)进行任务调试与训练的代码文件

- 《教程》文件夹,是本次项目实战的详细教程

- CIFAR.zip,是本次项目使用的数据集

## 前置条件
- Python 3.6+
- PyTorch 1.0+

## 云脑1(CPU/GPU)模型调试与训练
```
ls

#(相应代码放在/code下,相应数据集放在/dataset下)
cd /code/case1

python main.py
```
<div align="center">
<img src= ./case1/img/train.png width=100%>
</div>
<br>

## 云脑2(Ascend NPU)模型调试
```
#克隆代码,在代码页的HTTPS点击复制链接,在此处!git clone后面粘贴链接
!git clone

#解压数据集
!unzip cifar.zip

#运行代码
!python OpenI_test/case2/train.py --dataset_path ./cifar-10-batches-bin/
```

## 云脑2(Ascend NPU)模型训练

在新建训练任务中,输入指定文件为“case2/train.py”,数据集指定为cifar.zip,点击提交即可


## 部分模型准确率训练结果:

| Model | Acc. |
| ----------------- | ----------- |
| [VGG16](https://arxiv.org/abs/1409.1556) | 92.64% |
| [DLA](https://arxiv.org/pdf/1707.06484.pdf) | 95.47% |


+ 21
- 0
Case_CIFAR10/case1/LICENSE View File

@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2017 liukuang

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

BIN
Case_CIFAR10/case1/__pycache__/utils.cpython-37.pyc View File


BIN
Case_CIFAR10/case1/img/train.png View File

Before After
Width: 1894  |  Height: 601  |  Size: 95 kB

+ 154
- 0
Case_CIFAR10/case1/main.py View File

@@ -0,0 +1,154 @@
'''Train CIFAR10 with PyTorch.'''
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import torch.backends.cudnn as cudnn

import torchvision
import torchvision.transforms as transforms

import os
import argparse

from models import *
from utils import progress_bar


parser = argparse.ArgumentParser(description='PyTorch CIFAR10 Training')
parser.add_argument('--lr', default=0.1, type=float, help='learning rate')
parser.add_argument('--resume', '-r', action='store_true',
help='resume from checkpoint')
args = parser.parse_args()

device = 'cuda' if torch.cuda.is_available() else 'cpu'
best_acc = 0 # best test accuracy
start_epoch = 0 # start from epoch 0 or last checkpoint epoch

# Data
print('==> Preparing data..')
transform_train = transforms.Compose([
transforms.RandomCrop(32, padding=4),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
])

transform_test = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
])

trainset = torchvision.datasets.CIFAR10(
root='/dataset/', train=True, download=False, transform=transform_train)
trainloader = torch.utils.data.DataLoader(
trainset, batch_size=128, shuffle=True, num_workers=2)

testset = torchvision.datasets.CIFAR10(
root='/dataset/', train=False, download=False, transform=transform_test)
testloader = torch.utils.data.DataLoader(
testset, batch_size=100, shuffle=False, num_workers=2)

classes = ('plane', 'car', 'bird', 'cat', 'deer',
'dog', 'frog', 'horse', 'ship', 'truck')

# Model
print('==> Building model..')
# net = VGG('VGG19')
# net = ResNet18()
# net = PreActResNet18()
# net = GoogLeNet()
# net = DenseNet121()
# net = ResNeXt29_2x64d()
# net = MobileNet()
# net = MobileNetV2()
# net = DPN92()
# net = ShuffleNetG2()
# net = SENet18()
# net = ShuffleNetV2(1)
# net = EfficientNetB0()
# net = RegNetX_200MF()
net = SimpleDLA()
net = net.to(device)
if device == 'cuda':
net = torch.nn.DataParallel(net)
cudnn.benchmark = True

if args.resume:
# Load checkpoint.
print('==> Resuming from checkpoint..')
assert os.path.isdir('checkpoint'), 'Error: no checkpoint directory found!'
checkpoint = torch.load('./checkpoint/ckpt.pth')
net.load_state_dict(checkpoint['net'])
best_acc = checkpoint['acc']
start_epoch = checkpoint['epoch']

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=args.lr,
momentum=0.9, weight_decay=5e-4)
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=200)


# Training
def train(epoch):
print('\nEpoch: %d' % epoch)
net.train()
train_loss = 0
correct = 0
total = 0
for batch_idx, (inputs, targets) in enumerate(trainloader):
inputs, targets = inputs.to(device), targets.to(device)
optimizer.zero_grad()
outputs = net(inputs)
loss = criterion(outputs, targets)
loss.backward()
optimizer.step()

train_loss += loss.item()
_, predicted = outputs.max(1)
total += targets.size(0)
correct += predicted.eq(targets).sum().item()

progress_bar(batch_idx, len(trainloader), 'Loss: %.3f | Acc: %.3f%% (%d/%d)'
% (train_loss/(batch_idx+1), 100.*correct/total, correct, total))


def test(epoch):
global best_acc
net.eval()
test_loss = 0
correct = 0
total = 0
with torch.no_grad():
for batch_idx, (inputs, targets) in enumerate(testloader):
inputs, targets = inputs.to(device), targets.to(device)
outputs = net(inputs)
loss = criterion(outputs, targets)

test_loss += loss.item()
_, predicted = outputs.max(1)
total += targets.size(0)
correct += predicted.eq(targets).sum().item()

progress_bar(batch_idx, len(testloader), 'Loss: %.3f | Acc: %.3f%% (%d/%d)'
% (test_loss/(batch_idx+1), 100.*correct/total, correct, total))

# Save checkpoint.
acc = 100.*correct/total
if acc > best_acc:
print('Saving..')
state = {
'net': net.state_dict(),
'acc': acc,
'epoch': epoch,
}
if not os.path.isdir('checkpoint'):
os.mkdir('checkpoint')
torch.save(state, './checkpoint/ckpt.pth')
best_acc = acc


for epoch in range(start_epoch, start_epoch+200):
train(epoch)
test(epoch)
scheduler.step()

+ 18
- 0
Case_CIFAR10/case1/models/__init__.py View File

@@ -0,0 +1,18 @@
from .vgg import *
from .dpn import *
from .lenet import *
from .senet import *
from .pnasnet import *
from .densenet import *
from .googlenet import *
from .shufflenet import *
from .shufflenetv2 import *
from .resnet import *
from .resnext import *
from .preact_resnet import *
from .mobilenet import *
from .mobilenetv2 import *
from .efficientnet import *
from .regnet import *
from .dla_simple import *
from .dla import *

BIN
Case_CIFAR10/case1/models/__pycache__/__init__.cpython-37.pyc View File


BIN
Case_CIFAR10/case1/models/__pycache__/densenet.cpython-37.pyc View File


BIN
Case_CIFAR10/case1/models/__pycache__/dla.cpython-37.pyc View File


BIN
Case_CIFAR10/case1/models/__pycache__/dla_simple.cpython-37.pyc View File


BIN
Case_CIFAR10/case1/models/__pycache__/dpn.cpython-37.pyc View File


BIN
Case_CIFAR10/case1/models/__pycache__/efficientnet.cpython-37.pyc View File


BIN
Case_CIFAR10/case1/models/__pycache__/googlenet.cpython-37.pyc View File


BIN
Case_CIFAR10/case1/models/__pycache__/lenet.cpython-37.pyc View File


BIN
Case_CIFAR10/case1/models/__pycache__/mobilenet.cpython-37.pyc View File


BIN
Case_CIFAR10/case1/models/__pycache__/mobilenetv2.cpython-37.pyc View File


BIN
Case_CIFAR10/case1/models/__pycache__/pnasnet.cpython-37.pyc View File


BIN
Case_CIFAR10/case1/models/__pycache__/preact_resnet.cpython-37.pyc View File


BIN
Case_CIFAR10/case1/models/__pycache__/regnet.cpython-37.pyc View File


BIN
Case_CIFAR10/case1/models/__pycache__/resnet.cpython-37.pyc View File


BIN
Case_CIFAR10/case1/models/__pycache__/resnext.cpython-37.pyc View File


BIN
Case_CIFAR10/case1/models/__pycache__/senet.cpython-37.pyc View File


BIN
Case_CIFAR10/case1/models/__pycache__/shufflenet.cpython-37.pyc View File


BIN
Case_CIFAR10/case1/models/__pycache__/shufflenetv2.cpython-37.pyc View File


BIN
Case_CIFAR10/case1/models/__pycache__/vgg.cpython-37.pyc View File


+ 107
- 0
Case_CIFAR10/case1/models/densenet.py View File

@@ -0,0 +1,107 @@
'''DenseNet in PyTorch.'''
import math

import torch
import torch.nn as nn
import torch.nn.functional as F


class Bottleneck(nn.Module):
def __init__(self, in_planes, growth_rate):
super(Bottleneck, self).__init__()
self.bn1 = nn.BatchNorm2d(in_planes)
self.conv1 = nn.Conv2d(in_planes, 4*growth_rate, kernel_size=1, bias=False)
self.bn2 = nn.BatchNorm2d(4*growth_rate)
self.conv2 = nn.Conv2d(4*growth_rate, growth_rate, kernel_size=3, padding=1, bias=False)

def forward(self, x):
out = self.conv1(F.relu(self.bn1(x)))
out = self.conv2(F.relu(self.bn2(out)))
out = torch.cat([out,x], 1)
return out


class Transition(nn.Module):
def __init__(self, in_planes, out_planes):
super(Transition, self).__init__()
self.bn = nn.BatchNorm2d(in_planes)
self.conv = nn.Conv2d(in_planes, out_planes, kernel_size=1, bias=False)

def forward(self, x):
out = self.conv(F.relu(self.bn(x)))
out = F.avg_pool2d(out, 2)
return out


class DenseNet(nn.Module):
def __init__(self, block, nblocks, growth_rate=12, reduction=0.5, num_classes=10):
super(DenseNet, self).__init__()
self.growth_rate = growth_rate

num_planes = 2*growth_rate
self.conv1 = nn.Conv2d(3, num_planes, kernel_size=3, padding=1, bias=False)

self.dense1 = self._make_dense_layers(block, num_planes, nblocks[0])
num_planes += nblocks[0]*growth_rate
out_planes = int(math.floor(num_planes*reduction))
self.trans1 = Transition(num_planes, out_planes)
num_planes = out_planes

self.dense2 = self._make_dense_layers(block, num_planes, nblocks[1])
num_planes += nblocks[1]*growth_rate
out_planes = int(math.floor(num_planes*reduction))
self.trans2 = Transition(num_planes, out_planes)
num_planes = out_planes

self.dense3 = self._make_dense_layers(block, num_planes, nblocks[2])
num_planes += nblocks[2]*growth_rate
out_planes = int(math.floor(num_planes*reduction))
self.trans3 = Transition(num_planes, out_planes)
num_planes = out_planes

self.dense4 = self._make_dense_layers(block, num_planes, nblocks[3])
num_planes += nblocks[3]*growth_rate

self.bn = nn.BatchNorm2d(num_planes)
self.linear = nn.Linear(num_planes, num_classes)

def _make_dense_layers(self, block, in_planes, nblock):
layers = []
for i in range(nblock):
layers.append(block(in_planes, self.growth_rate))
in_planes += self.growth_rate
return nn.Sequential(*layers)

def forward(self, x):
out = self.conv1(x)
out = self.trans1(self.dense1(out))
out = self.trans2(self.dense2(out))
out = self.trans3(self.dense3(out))
out = self.dense4(out)
out = F.avg_pool2d(F.relu(self.bn(out)), 4)
out = out.view(out.size(0), -1)
out = self.linear(out)
return out

def DenseNet121():
return DenseNet(Bottleneck, [6,12,24,16], growth_rate=32)

def DenseNet169():
return DenseNet(Bottleneck, [6,12,32,32], growth_rate=32)

def DenseNet201():
return DenseNet(Bottleneck, [6,12,48,32], growth_rate=32)

def DenseNet161():
return DenseNet(Bottleneck, [6,12,36,24], growth_rate=48)

def densenet_cifar():
return DenseNet(Bottleneck, [6,12,24,16], growth_rate=12)

def test():
net = densenet_cifar()
x = torch.randn(1,3,32,32)
y = net(x)
print(y)

# test()

+ 135
- 0
Case_CIFAR10/case1/models/dla.py View File

@@ -0,0 +1,135 @@
'''DLA in PyTorch.

Reference:
Deep Layer Aggregation. https://arxiv.org/abs/1707.06484
'''
import torch
import torch.nn as nn
import torch.nn.functional as F


class BasicBlock(nn.Module):
expansion = 1

def __init__(self, in_planes, planes, stride=1):
super(BasicBlock, self).__init__()
self.conv1 = nn.Conv2d(
in_planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(planes)
self.conv2 = nn.Conv2d(planes, planes, kernel_size=3,
stride=1, padding=1, bias=False)
self.bn2 = nn.BatchNorm2d(planes)

self.shortcut = nn.Sequential()
if stride != 1 or in_planes != self.expansion*planes:
self.shortcut = nn.Sequential(
nn.Conv2d(in_planes, self.expansion*planes,
kernel_size=1, stride=stride, bias=False),
nn.BatchNorm2d(self.expansion*planes)
)

def forward(self, x):
out = F.relu(self.bn1(self.conv1(x)))
out = self.bn2(self.conv2(out))
out += self.shortcut(x)
out = F.relu(out)
return out


class Root(nn.Module):
def __init__(self, in_channels, out_channels, kernel_size=1):
super(Root, self).__init__()
self.conv = nn.Conv2d(
in_channels, out_channels, kernel_size,
stride=1, padding=(kernel_size - 1) // 2, bias=False)
self.bn = nn.BatchNorm2d(out_channels)

def forward(self, xs):
x = torch.cat(xs, 1)
out = F.relu(self.bn(self.conv(x)))
return out


class Tree(nn.Module):
def __init__(self, block, in_channels, out_channels, level=1, stride=1):
super(Tree, self).__init__()
self.level = level
if level == 1:
self.root = Root(2*out_channels, out_channels)
self.left_node = block(in_channels, out_channels, stride=stride)
self.right_node = block(out_channels, out_channels, stride=1)
else:
self.root = Root((level+2)*out_channels, out_channels)
for i in reversed(range(1, level)):
subtree = Tree(block, in_channels, out_channels,
level=i, stride=stride)
self.__setattr__('level_%d' % i, subtree)
self.prev_root = block(in_channels, out_channels, stride=stride)
self.left_node = block(out_channels, out_channels, stride=1)
self.right_node = block(out_channels, out_channels, stride=1)

def forward(self, x):
xs = [self.prev_root(x)] if self.level > 1 else []
for i in reversed(range(1, self.level)):
level_i = self.__getattr__('level_%d' % i)
x = level_i(x)
xs.append(x)
x = self.left_node(x)
xs.append(x)
x = self.right_node(x)
xs.append(x)
out = self.root(xs)
return out


class DLA(nn.Module):
def __init__(self, block=BasicBlock, num_classes=10):
super(DLA, self).__init__()
self.base = nn.Sequential(
nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1, bias=False),
nn.BatchNorm2d(16),
nn.ReLU(True)
)

self.layer1 = nn.Sequential(
nn.Conv2d(16, 16, kernel_size=3, stride=1, padding=1, bias=False),
nn.BatchNorm2d(16),
nn.ReLU(True)
)

self.layer2 = nn.Sequential(
nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1, bias=False),
nn.BatchNorm2d(32),
nn.ReLU(True)
)

self.layer3 = Tree(block, 32, 64, level=1, stride=1)
self.layer4 = Tree(block, 64, 128, level=2, stride=2)
self.layer5 = Tree(block, 128, 256, level=2, stride=2)
self.layer6 = Tree(block, 256, 512, level=1, stride=2)
self.linear = nn.Linear(512, num_classes)

def forward(self, x):
out = self.base(x)
out = self.layer1(out)
out = self.layer2(out)
out = self.layer3(out)
out = self.layer4(out)
out = self.layer5(out)
out = self.layer6(out)
out = F.avg_pool2d(out, 4)
out = out.view(out.size(0), -1)
out = self.linear(out)
return out


def test():
net = DLA()
print(net)
x = torch.randn(1, 3, 32, 32)
y = net(x)
print(y.size())


if __name__ == '__main__':
test()

+ 128
- 0
Case_CIFAR10/case1/models/dla_simple.py View File

@@ -0,0 +1,128 @@
'''Simplified version of DLA in PyTorch.

Note this implementation is not identical to the original paper version.
But it seems works fine.

See dla.py for the original paper version.

Reference:
Deep Layer Aggregation. https://arxiv.org/abs/1707.06484
'''
import torch
import torch.nn as nn
import torch.nn.functional as F


class BasicBlock(nn.Module):
expansion = 1

def __init__(self, in_planes, planes, stride=1):
super(BasicBlock, self).__init__()
self.conv1 = nn.Conv2d(
in_planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(planes)
self.conv2 = nn.Conv2d(planes, planes, kernel_size=3,
stride=1, padding=1, bias=False)
self.bn2 = nn.BatchNorm2d(planes)

self.shortcut = nn.Sequential()
if stride != 1 or in_planes != self.expansion*planes:
self.shortcut = nn.Sequential(
nn.Conv2d(in_planes, self.expansion*planes,
kernel_size=1, stride=stride, bias=False),
nn.BatchNorm2d(self.expansion*planes)
)

def forward(self, x):
out = F.relu(self.bn1(self.conv1(x)))
out = self.bn2(self.conv2(out))
out += self.shortcut(x)
out = F.relu(out)
return out


class Root(nn.Module):
def __init__(self, in_channels, out_channels, kernel_size=1):
super(Root, self).__init__()
self.conv = nn.Conv2d(
in_channels, out_channels, kernel_size,
stride=1, padding=(kernel_size - 1) // 2, bias=False)
self.bn = nn.BatchNorm2d(out_channels)

def forward(self, xs):
x = torch.cat(xs, 1)
out = F.relu(self.bn(self.conv(x)))
return out


class Tree(nn.Module):
def __init__(self, block, in_channels, out_channels, level=1, stride=1):
super(Tree, self).__init__()
self.root = Root(2*out_channels, out_channels)
if level == 1:
self.left_tree = block(in_channels, out_channels, stride=stride)
self.right_tree = block(out_channels, out_channels, stride=1)
else:
self.left_tree = Tree(block, in_channels,
out_channels, level=level-1, stride=stride)
self.right_tree = Tree(block, out_channels,
out_channels, level=level-1, stride=1)

def forward(self, x):
out1 = self.left_tree(x)
out2 = self.right_tree(out1)
out = self.root([out1, out2])
return out


class SimpleDLA(nn.Module):
def __init__(self, block=BasicBlock, num_classes=10):
super(SimpleDLA, self).__init__()
self.base = nn.Sequential(
nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1, bias=False),
nn.BatchNorm2d(16),
nn.ReLU(True)
)

self.layer1 = nn.Sequential(
nn.Conv2d(16, 16, kernel_size=3, stride=1, padding=1, bias=False),
nn.BatchNorm2d(16),
nn.ReLU(True)
)

self.layer2 = nn.Sequential(
nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1, bias=False),
nn.BatchNorm2d(32),
nn.ReLU(True)
)

self.layer3 = Tree(block, 32, 64, level=1, stride=1)
self.layer4 = Tree(block, 64, 128, level=2, stride=2)
self.layer5 = Tree(block, 128, 256, level=2, stride=2)
self.layer6 = Tree(block, 256, 512, level=1, stride=2)
self.linear = nn.Linear(512, num_classes)

def forward(self, x):
out = self.base(x)
out = self.layer1(out)
out = self.layer2(out)
out = self.layer3(out)
out = self.layer4(out)
out = self.layer5(out)
out = self.layer6(out)
out = F.avg_pool2d(out, 4)
out = out.view(out.size(0), -1)
out = self.linear(out)
return out


def test():
net = SimpleDLA()
print(net)
x = torch.randn(1, 3, 32, 32)
y = net(x)
print(y.size())


if __name__ == '__main__':
test()

+ 98
- 0
Case_CIFAR10/case1/models/dpn.py View File

@@ -0,0 +1,98 @@
'''Dual Path Networks in PyTorch.'''
import torch
import torch.nn as nn
import torch.nn.functional as F


class Bottleneck(nn.Module):
def __init__(self, last_planes, in_planes, out_planes, dense_depth, stride, first_layer):
super(Bottleneck, self).__init__()
self.out_planes = out_planes
self.dense_depth = dense_depth

self.conv1 = nn.Conv2d(last_planes, in_planes, kernel_size=1, bias=False)
self.bn1 = nn.BatchNorm2d(in_planes)
self.conv2 = nn.Conv2d(in_planes, in_planes, kernel_size=3, stride=stride, padding=1, groups=32, bias=False)
self.bn2 = nn.BatchNorm2d(in_planes)
self.conv3 = nn.Conv2d(in_planes, out_planes+dense_depth, kernel_size=1, bias=False)
self.bn3 = nn.BatchNorm2d(out_planes+dense_depth)

self.shortcut = nn.Sequential()
if first_layer:
self.shortcut = nn.Sequential(
nn.Conv2d(last_planes, out_planes+dense_depth, kernel_size=1, stride=stride, bias=False),
nn.BatchNorm2d(out_planes+dense_depth)
)

def forward(self, x):
out = F.relu(self.bn1(self.conv1(x)))
out = F.relu(self.bn2(self.conv2(out)))
out = self.bn3(self.conv3(out))
x = self.shortcut(x)
d = self.out_planes
out = torch.cat([x[:,:d,:,:]+out[:,:d,:,:], x[:,d:,:,:], out[:,d:,:,:]], 1)
out = F.relu(out)
return out


class DPN(nn.Module):
def __init__(self, cfg):
super(DPN, self).__init__()
in_planes, out_planes = cfg['in_planes'], cfg['out_planes']
num_blocks, dense_depth = cfg['num_blocks'], cfg['dense_depth']

self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(64)
self.last_planes = 64
self.layer1 = self._make_layer(in_planes[0], out_planes[0], num_blocks[0], dense_depth[0], stride=1)
self.layer2 = self._make_layer(in_planes[1], out_planes[1], num_blocks[1], dense_depth[1], stride=2)
self.layer3 = self._make_layer(in_planes[2], out_planes[2], num_blocks[2], dense_depth[2], stride=2)
self.layer4 = self._make_layer(in_planes[3], out_planes[3], num_blocks[3], dense_depth[3], stride=2)
self.linear = nn.Linear(out_planes[3]+(num_blocks[3]+1)*dense_depth[3], 10)

def _make_layer(self, in_planes, out_planes, num_blocks, dense_depth, stride):
strides = [stride] + [1]*(num_blocks-1)
layers = []
for i,stride in enumerate(strides):
layers.append(Bottleneck(self.last_planes, in_planes, out_planes, dense_depth, stride, i==0))
self.last_planes = out_planes + (i+2) * dense_depth
return nn.Sequential(*layers)

def forward(self, x):
out = F.relu(self.bn1(self.conv1(x)))
out = self.layer1(out)
out = self.layer2(out)
out = self.layer3(out)
out = self.layer4(out)
out = F.avg_pool2d(out, 4)
out = out.view(out.size(0), -1)
out = self.linear(out)
return out


def DPN26():
cfg = {
'in_planes': (96,192,384,768),
'out_planes': (256,512,1024,2048),
'num_blocks': (2,2,2,2),
'dense_depth': (16,32,24,128)
}
return DPN(cfg)

def DPN92():
cfg = {
'in_planes': (96,192,384,768),
'out_planes': (256,512,1024,2048),
'num_blocks': (3,4,20,3),
'dense_depth': (16,32,24,128)
}
return DPN(cfg)


def test():
net = DPN92()
x = torch.randn(1,3,32,32)
y = net(x)
print(y)

# test()

+ 175
- 0
Case_CIFAR10/case1/models/efficientnet.py View File

@@ -0,0 +1,175 @@
'''EfficientNet in PyTorch.

Paper: "EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks".

Reference: https://github.com/keras-team/keras-applications/blob/master/keras_applications/efficientnet.py
'''
import torch
import torch.nn as nn
import torch.nn.functional as F


def swish(x):
return x * x.sigmoid()


def drop_connect(x, drop_ratio):
keep_ratio = 1.0 - drop_ratio
mask = torch.empty([x.shape[0], 1, 1, 1], dtype=x.dtype, device=x.device)
mask.bernoulli_(keep_ratio)
x.div_(keep_ratio)
x.mul_(mask)
return x


class SE(nn.Module):
'''Squeeze-and-Excitation block with Swish.'''

def __init__(self, in_channels, se_channels):
super(SE, self).__init__()
self.se1 = nn.Conv2d(in_channels, se_channels,
kernel_size=1, bias=True)
self.se2 = nn.Conv2d(se_channels, in_channels,
kernel_size=1, bias=True)

def forward(self, x):
out = F.adaptive_avg_pool2d(x, (1, 1))
out = swish(self.se1(out))
out = self.se2(out).sigmoid()
out = x * out
return out


class Block(nn.Module):
'''expansion + depthwise + pointwise + squeeze-excitation'''

def __init__(self,
in_channels,
out_channels,
kernel_size,
stride,
expand_ratio=1,
se_ratio=0.,
drop_rate=0.):
super(Block, self).__init__()
self.stride = stride
self.drop_rate = drop_rate
self.expand_ratio = expand_ratio

# Expansion
channels = expand_ratio * in_channels
self.conv1 = nn.Conv2d(in_channels,
channels,
kernel_size=1,
stride=1,
padding=0,
bias=False)
self.bn1 = nn.BatchNorm2d(channels)

# Depthwise conv
self.conv2 = nn.Conv2d(channels,
channels,
kernel_size=kernel_size,
stride=stride,
padding=(1 if kernel_size == 3 else 2),
groups=channels,
bias=False)
self.bn2 = nn.BatchNorm2d(channels)

# SE layers
se_channels = int(in_channels * se_ratio)
self.se = SE(channels, se_channels)

# Output
self.conv3 = nn.Conv2d(channels,
out_channels,
kernel_size=1,
stride=1,
padding=0,
bias=False)
self.bn3 = nn.BatchNorm2d(out_channels)

# Skip connection if in and out shapes are the same (MV-V2 style)
self.has_skip = (stride == 1) and (in_channels == out_channels)

def forward(self, x):
out = x if self.expand_ratio == 1 else swish(self.bn1(self.conv1(x)))
out = swish(self.bn2(self.conv2(out)))
out = self.se(out)
out = self.bn3(self.conv3(out))
if self.has_skip:
if self.training and self.drop_rate > 0:
out = drop_connect(out, self.drop_rate)
out = out + x
return out


class EfficientNet(nn.Module):
def __init__(self, cfg, num_classes=10):
super(EfficientNet, self).__init__()
self.cfg = cfg
self.conv1 = nn.Conv2d(3,
32,
kernel_size=3,
stride=1,
padding=1,
bias=False)
self.bn1 = nn.BatchNorm2d(32)
self.layers = self._make_layers(in_channels=32)
self.linear = nn.Linear(cfg['out_channels'][-1], num_classes)

def _make_layers(self, in_channels):
layers = []
cfg = [self.cfg[k] for k in ['expansion', 'out_channels', 'num_blocks', 'kernel_size',
'stride']]
b = 0
blocks = sum(self.cfg['num_blocks'])
for expansion, out_channels, num_blocks, kernel_size, stride in zip(*cfg):
strides = [stride] + [1] * (num_blocks - 1)
for stride in strides:
drop_rate = self.cfg['drop_connect_rate'] * b / blocks
layers.append(
Block(in_channels,
out_channels,
kernel_size,
stride,
expansion,
se_ratio=0.25,
drop_rate=drop_rate))
in_channels = out_channels
return nn.Sequential(*layers)

def forward(self, x):
out = swish(self.bn1(self.conv1(x)))
out = self.layers(out)
out = F.adaptive_avg_pool2d(out, 1)
out = out.view(out.size(0), -1)
dropout_rate = self.cfg['dropout_rate']
if self.training and dropout_rate > 0:
out = F.dropout(out, p=dropout_rate)
out = self.linear(out)
return out


def EfficientNetB0():
cfg = {
'num_blocks': [1, 2, 2, 3, 3, 4, 1],
'expansion': [1, 6, 6, 6, 6, 6, 6],
'out_channels': [16, 24, 40, 80, 112, 192, 320],
'kernel_size': [3, 3, 5, 3, 5, 5, 3],
'stride': [1, 2, 2, 2, 1, 2, 1],
'dropout_rate': 0.2,
'drop_connect_rate': 0.2,
}
return EfficientNet(cfg)


def test():
net = EfficientNetB0()
x = torch.randn(2, 3, 32, 32)
y = net(x)
print(y.shape)


if __name__ == '__main__':
test()

+ 107
- 0
Case_CIFAR10/case1/models/googlenet.py View File

@@ -0,0 +1,107 @@
'''GoogLeNet with PyTorch.'''
import torch
import torch.nn as nn
import torch.nn.functional as F


class Inception(nn.Module):
def __init__(self, in_planes, n1x1, n3x3red, n3x3, n5x5red, n5x5, pool_planes):
super(Inception, self).__init__()
# 1x1 conv branch
self.b1 = nn.Sequential(
nn.Conv2d(in_planes, n1x1, kernel_size=1),
nn.BatchNorm2d(n1x1),
nn.ReLU(True),
)

# 1x1 conv -> 3x3 conv branch
self.b2 = nn.Sequential(
nn.Conv2d(in_planes, n3x3red, kernel_size=1),
nn.BatchNorm2d(n3x3red),
nn.ReLU(True),
nn.Conv2d(n3x3red, n3x3, kernel_size=3, padding=1),
nn.BatchNorm2d(n3x3),
nn.ReLU(True),
)

# 1x1 conv -> 5x5 conv branch
self.b3 = nn.Sequential(
nn.Conv2d(in_planes, n5x5red, kernel_size=1),
nn.BatchNorm2d(n5x5red),
nn.ReLU(True),
nn.Conv2d(n5x5red, n5x5, kernel_size=3, padding=1),
nn.BatchNorm2d(n5x5),
nn.ReLU(True),
nn.Conv2d(n5x5, n5x5, kernel_size=3, padding=1),
nn.BatchNorm2d(n5x5),
nn.ReLU(True),
)

# 3x3 pool -> 1x1 conv branch
self.b4 = nn.Sequential(
nn.MaxPool2d(3, stride=1, padding=1),
nn.Conv2d(in_planes, pool_planes, kernel_size=1),
nn.BatchNorm2d(pool_planes),
nn.ReLU(True),
)

def forward(self, x):
y1 = self.b1(x)
y2 = self.b2(x)
y3 = self.b3(x)
y4 = self.b4(x)
return torch.cat([y1,y2,y3,y4], 1)


class GoogLeNet(nn.Module):
def __init__(self):
super(GoogLeNet, self).__init__()
self.pre_layers = nn.Sequential(
nn.Conv2d(3, 192, kernel_size=3, padding=1),
nn.BatchNorm2d(192),
nn.ReLU(True),
)

self.a3 = Inception(192, 64, 96, 128, 16, 32, 32)
self.b3 = Inception(256, 128, 128, 192, 32, 96, 64)

self.maxpool = nn.MaxPool2d(3, stride=2, padding=1)

self.a4 = Inception(480, 192, 96, 208, 16, 48, 64)
self.b4 = Inception(512, 160, 112, 224, 24, 64, 64)
self.c4 = Inception(512, 128, 128, 256, 24, 64, 64)
self.d4 = Inception(512, 112, 144, 288, 32, 64, 64)
self.e4 = Inception(528, 256, 160, 320, 32, 128, 128)

self.a5 = Inception(832, 256, 160, 320, 32, 128, 128)
self.b5 = Inception(832, 384, 192, 384, 48, 128, 128)

self.avgpool = nn.AvgPool2d(8, stride=1)
self.linear = nn.Linear(1024, 10)

def forward(self, x):
out = self.pre_layers(x)
out = self.a3(out)
out = self.b3(out)
out = self.maxpool(out)
out = self.a4(out)
out = self.b4(out)
out = self.c4(out)
out = self.d4(out)
out = self.e4(out)
out = self.maxpool(out)
out = self.a5(out)
out = self.b5(out)
out = self.avgpool(out)
out = out.view(out.size(0), -1)
out = self.linear(out)
return out


def test():
net = GoogLeNet()
x = torch.randn(1,3,32,32)
y = net(x)
print(y.size())

# test()

+ 23
- 0
Case_CIFAR10/case1/models/lenet.py View File

@@ -0,0 +1,23 @@
'''LeNet in PyTorch.'''
import torch.nn as nn
import torch.nn.functional as F

class LeNet(nn.Module):
def __init__(self):
super(LeNet, self).__init__()
self.conv1 = nn.Conv2d(3, 6, 5)
self.conv2 = nn.Conv2d(6, 16, 5)
self.fc1 = nn.Linear(16*5*5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)

def forward(self, x):
out = F.relu(self.conv1(x))
out = F.max_pool2d(out, 2)
out = F.relu(self.conv2(out))
out = F.max_pool2d(out, 2)
out = out.view(out.size(0), -1)
out = F.relu(self.fc1(out))
out = F.relu(self.fc2(out))
out = self.fc3(out)
return out

+ 61
- 0
Case_CIFAR10/case1/models/mobilenet.py View File

@@ -0,0 +1,61 @@
'''MobileNet in PyTorch.

See the paper "MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications"
for more details.
'''
import torch
import torch.nn as nn
import torch.nn.functional as F


class Block(nn.Module):
'''Depthwise conv + Pointwise conv'''
def __init__(self, in_planes, out_planes, stride=1):
super(Block, self).__init__()
self.conv1 = nn.Conv2d(in_planes, in_planes, kernel_size=3, stride=stride, padding=1, groups=in_planes, bias=False)
self.bn1 = nn.BatchNorm2d(in_planes)
self.conv2 = nn.Conv2d(in_planes, out_planes, kernel_size=1, stride=1, padding=0, bias=False)
self.bn2 = nn.BatchNorm2d(out_planes)

def forward(self, x):
out = F.relu(self.bn1(self.conv1(x)))
out = F.relu(self.bn2(self.conv2(out)))
return out


class MobileNet(nn.Module):
# (128,2) means conv planes=128, conv stride=2, by default conv stride=1
cfg = [64, (128,2), 128, (256,2), 256, (512,2), 512, 512, 512, 512, 512, (1024,2), 1024]

def __init__(self, num_classes=10):
super(MobileNet, self).__init__()
self.conv1 = nn.Conv2d(3, 32, kernel_size=3, stride=1, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(32)
self.layers = self._make_layers(in_planes=32)
self.linear = nn.Linear(1024, num_classes)

def _make_layers(self, in_planes):
layers = []
for x in self.cfg:
out_planes = x if isinstance(x, int) else x[0]
stride = 1 if isinstance(x, int) else x[1]
layers.append(Block(in_planes, out_planes, stride))
in_planes = out_planes
return nn.Sequential(*layers)

def forward(self, x):
out = F.relu(self.bn1(self.conv1(x)))
out = self.layers(out)
out = F.avg_pool2d(out, 2)
out = out.view(out.size(0), -1)
out = self.linear(out)
return out


def test():
net = MobileNet()
x = torch.randn(1,3,32,32)
y = net(x)
print(y.size())

# test()

+ 86
- 0
Case_CIFAR10/case1/models/mobilenetv2.py View File

@@ -0,0 +1,86 @@
'''MobileNetV2 in PyTorch.

See the paper "Inverted Residuals and Linear Bottlenecks:
Mobile Networks for Classification, Detection and Segmentation" for more details.
'''
import torch
import torch.nn as nn
import torch.nn.functional as F


class Block(nn.Module):
'''expand + depthwise + pointwise'''
def __init__(self, in_planes, out_planes, expansion, stride):
super(Block, self).__init__()
self.stride = stride

planes = expansion * in_planes
self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=1, stride=1, padding=0, bias=False)
self.bn1 = nn.BatchNorm2d(planes)
self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride, padding=1, groups=planes, bias=False)
self.bn2 = nn.BatchNorm2d(planes)
self.conv3 = nn.Conv2d(planes, out_planes, kernel_size=1, stride=1, padding=0, bias=False)
self.bn3 = nn.BatchNorm2d(out_planes)

self.shortcut = nn.Sequential()
if stride == 1 and in_planes != out_planes:
self.shortcut = nn.Sequential(
nn.Conv2d(in_planes, out_planes, kernel_size=1, stride=1, padding=0, bias=False),
nn.BatchNorm2d(out_planes),
)

def forward(self, x):
out = F.relu(self.bn1(self.conv1(x)))
out = F.relu(self.bn2(self.conv2(out)))
out = self.bn3(self.conv3(out))
out = out + self.shortcut(x) if self.stride==1 else out
return out


class MobileNetV2(nn.Module):
# (expansion, out_planes, num_blocks, stride)
cfg = [(1, 16, 1, 1),
(6, 24, 2, 1), # NOTE: change stride 2 -> 1 for CIFAR10
(6, 32, 3, 2),
(6, 64, 4, 2),
(6, 96, 3, 1),
(6, 160, 3, 2),
(6, 320, 1, 1)]

def __init__(self, num_classes=10):
super(MobileNetV2, self).__init__()
# NOTE: change conv1 stride 2 -> 1 for CIFAR10
self.conv1 = nn.Conv2d(3, 32, kernel_size=3, stride=1, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(32)
self.layers = self._make_layers(in_planes=32)
self.conv2 = nn.Conv2d(320, 1280, kernel_size=1, stride=1, padding=0, bias=False)
self.bn2 = nn.BatchNorm2d(1280)
self.linear = nn.Linear(1280, num_classes)

def _make_layers(self, in_planes):
layers = []
for expansion, out_planes, num_blocks, stride in self.cfg:
strides = [stride] + [1]*(num_blocks-1)
for stride in strides:
layers.append(Block(in_planes, out_planes, expansion, stride))
in_planes = out_planes
return nn.Sequential(*layers)

def forward(self, x):
out = F.relu(self.bn1(self.conv1(x)))
out = self.layers(out)
out = F.relu(self.bn2(self.conv2(out)))
# NOTE: change pooling kernel_size 7 -> 4 for CIFAR10
out = F.avg_pool2d(out, 4)
out = out.view(out.size(0), -1)
out = self.linear(out)
return out


def test():
net = MobileNetV2()
x = torch.randn(2,3,32,32)
y = net(x)
print(y.size())

# test()

+ 125
- 0
Case_CIFAR10/case1/models/pnasnet.py View File

@@ -0,0 +1,125 @@
'''PNASNet in PyTorch.

Paper: Progressive Neural Architecture Search
'''
import torch
import torch.nn as nn
import torch.nn.functional as F


class SepConv(nn.Module):
'''Separable Convolution.'''
def __init__(self, in_planes, out_planes, kernel_size, stride):
super(SepConv, self).__init__()
self.conv1 = nn.Conv2d(in_planes, out_planes,
kernel_size, stride,
padding=(kernel_size-1)//2,
bias=False, groups=in_planes)
self.bn1 = nn.BatchNorm2d(out_planes)

def forward(self, x):
return self.bn1(self.conv1(x))


class CellA(nn.Module):
def __init__(self, in_planes, out_planes, stride=1):
super(CellA, self).__init__()
self.stride = stride
self.sep_conv1 = SepConv(in_planes, out_planes, kernel_size=7, stride=stride)
if stride==2:
self.conv1 = nn.Conv2d(in_planes, out_planes, kernel_size=1, stride=1, padding=0, bias=False)
self.bn1 = nn.BatchNorm2d(out_planes)

def forward(self, x):
y1 = self.sep_conv1(x)
y2 = F.max_pool2d(x, kernel_size=3, stride=self.stride, padding=1)
if self.stride==2:
y2 = self.bn1(self.conv1(y2))
return F.relu(y1+y2)

class CellB(nn.Module):
def __init__(self, in_planes, out_planes, stride=1):
super(CellB, self).__init__()
self.stride = stride
# Left branch
self.sep_conv1 = SepConv(in_planes, out_planes, kernel_size=7, stride=stride)
self.sep_conv2 = SepConv(in_planes, out_planes, kernel_size=3, stride=stride)
# Right branch
self.sep_conv3 = SepConv(in_planes, out_planes, kernel_size=5, stride=stride)
if stride==2:
self.conv1 = nn.Conv2d(in_planes, out_planes, kernel_size=1, stride=1, padding=0, bias=False)
self.bn1 = nn.BatchNorm2d(out_planes)
# Reduce channels
self.conv2 = nn.Conv2d(2*out_planes, out_planes, kernel_size=1, stride=1, padding=0, bias=False)
self.bn2 = nn.BatchNorm2d(out_planes)

def forward(self, x):
# Left branch
y1 = self.sep_conv1(x)
y2 = self.sep_conv2(x)
# Right branch
y3 = F.max_pool2d(x, kernel_size=3, stride=self.stride, padding=1)
if self.stride==2:
y3 = self.bn1(self.conv1(y3))
y4 = self.sep_conv3(x)
# Concat & reduce channels
b1 = F.relu(y1+y2)
b2 = F.relu(y3+y4)
y = torch.cat([b1,b2], 1)
return F.relu(self.bn2(self.conv2(y)))

class PNASNet(nn.Module):
def __init__(self, cell_type, num_cells, num_planes):
super(PNASNet, self).__init__()
self.in_planes = num_planes
self.cell_type = cell_type

self.conv1 = nn.Conv2d(3, num_planes, kernel_size=3, stride=1, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(num_planes)

self.layer1 = self._make_layer(num_planes, num_cells=6)
self.layer2 = self._downsample(num_planes*2)
self.layer3 = self._make_layer(num_planes*2, num_cells=6)
self.layer4 = self._downsample(num_planes*4)
self.layer5 = self._make_layer(num_planes*4, num_cells=6)

self.linear = nn.Linear(num_planes*4, 10)

def _make_layer(self, planes, num_cells):
layers = []
for _ in range(num_cells):
layers.append(self.cell_type(self.in_planes, planes, stride=1))
self.in_planes = planes
return nn.Sequential(*layers)

def _downsample(self, planes):
layer = self.cell_type(self.in_planes, planes, stride=2)
self.in_planes = planes
return layer

def forward(self, x):
out = F.relu(self.bn1(self.conv1(x)))
out = self.layer1(out)
out = self.layer2(out)
out = self.layer3(out)
out = self.layer4(out)
out = self.layer5(out)
out = F.avg_pool2d(out, 8)
out = self.linear(out.view(out.size(0), -1))
return out


def PNASNetA():
return PNASNet(CellA, num_cells=6, num_planes=44)

def PNASNetB():
return PNASNet(CellB, num_cells=6, num_planes=32)


def test():
net = PNASNetB()
x = torch.randn(1,3,32,32)
y = net(x)
print(y)

# test()

+ 118
- 0
Case_CIFAR10/case1/models/preact_resnet.py View File

@@ -0,0 +1,118 @@
'''Pre-activation ResNet in PyTorch.

Reference:
[1] Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun
Identity Mappings in Deep Residual Networks. arXiv:1603.05027
'''
import torch
import torch.nn as nn
import torch.nn.functional as F


class PreActBlock(nn.Module):
'''Pre-activation version of the BasicBlock.'''
expansion = 1

def __init__(self, in_planes, planes, stride=1):
super(PreActBlock, self).__init__()
self.bn1 = nn.BatchNorm2d(in_planes)
self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)
self.bn2 = nn.BatchNorm2d(planes)
self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=1, padding=1, bias=False)

if stride != 1 or in_planes != self.expansion*planes:
self.shortcut = nn.Sequential(
nn.Conv2d(in_planes, self.expansion*planes, kernel_size=1, stride=stride, bias=False)
)

def forward(self, x):
out = F.relu(self.bn1(x))
shortcut = self.shortcut(out) if hasattr(self, 'shortcut') else x
out = self.conv1(out)
out = self.conv2(F.relu(self.bn2(out)))
out += shortcut
return out


class PreActBottleneck(nn.Module):
'''Pre-activation version of the original Bottleneck module.'''
expansion = 4

def __init__(self, in_planes, planes, stride=1):
super(PreActBottleneck, self).__init__()
self.bn1 = nn.BatchNorm2d(in_planes)
self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=1, bias=False)
self.bn2 = nn.BatchNorm2d(planes)
self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)
self.bn3 = nn.BatchNorm2d(planes)
self.conv3 = nn.Conv2d(planes, self.expansion*planes, kernel_size=1, bias=False)

if stride != 1 or in_planes != self.expansion*planes:
self.shortcut = nn.Sequential(
nn.Conv2d(in_planes, self.expansion*planes, kernel_size=1, stride=stride, bias=False)
)

def forward(self, x):
out = F.relu(self.bn1(x))
shortcut = self.shortcut(out) if hasattr(self, 'shortcut') else x
out = self.conv1(out)
out = self.conv2(F.relu(self.bn2(out)))
out = self.conv3(F.relu(self.bn3(out)))
out += shortcut
return out


class PreActResNet(nn.Module):
def __init__(self, block, num_blocks, num_classes=10):
super(PreActResNet, self).__init__()
self.in_planes = 64

self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1, bias=False)
self.layer1 = self._make_layer(block, 64, num_blocks[0], stride=1)
self.layer2 = self._make_layer(block, 128, num_blocks[1], stride=2)
self.layer3 = self._make_layer(block, 256, num_blocks[2], stride=2)
self.layer4 = self._make_layer(block, 512, num_blocks[3], stride=2)
self.linear = nn.Linear(512*block.expansion, num_classes)

def _make_layer(self, block, planes, num_blocks, stride):
strides = [stride] + [1]*(num_blocks-1)
layers = []
for stride in strides:
layers.append(block(self.in_planes, planes, stride))
self.in_planes = planes * block.expansion
return nn.Sequential(*layers)

def forward(self, x):
out = self.conv1(x)
out = self.layer1(out)
out = self.layer2(out)
out = self.layer3(out)
out = self.layer4(out)
out = F.avg_pool2d(out, 4)
out = out.view(out.size(0), -1)
out = self.linear(out)
return out


def PreActResNet18():
return PreActResNet(PreActBlock, [2,2,2,2])

def PreActResNet34():
return PreActResNet(PreActBlock, [3,4,6,3])

def PreActResNet50():
return PreActResNet(PreActBottleneck, [3,4,6,3])

def PreActResNet101():
return PreActResNet(PreActBottleneck, [3,4,23,3])

def PreActResNet152():
return PreActResNet(PreActBottleneck, [3,8,36,3])


def test():
net = PreActResNet18()
y = net((torch.randn(1,3,32,32)))
print(y.size())

# test()

+ 155
- 0
Case_CIFAR10/case1/models/regnet.py View File

@@ -0,0 +1,155 @@
'''RegNet in PyTorch.

Paper: "Designing Network Design Spaces".

Reference: https://github.com/keras-team/keras-applications/blob/master/keras_applications/efficientnet.py
'''
import torch
import torch.nn as nn
import torch.nn.functional as F


class SE(nn.Module):
'''Squeeze-and-Excitation block.'''

def __init__(self, in_planes, se_planes):
super(SE, self).__init__()
self.se1 = nn.Conv2d(in_planes, se_planes, kernel_size=1, bias=True)
self.se2 = nn.Conv2d(se_planes, in_planes, kernel_size=1, bias=True)

def forward(self, x):
out = F.adaptive_avg_pool2d(x, (1, 1))
out = F.relu(self.se1(out))
out = self.se2(out).sigmoid()
out = x * out
return out


class Block(nn.Module):
def __init__(self, w_in, w_out, stride, group_width, bottleneck_ratio, se_ratio):
super(Block, self).__init__()
# 1x1
w_b = int(round(w_out * bottleneck_ratio))
self.conv1 = nn.Conv2d(w_in, w_b, kernel_size=1, bias=False)
self.bn1 = nn.BatchNorm2d(w_b)
# 3x3
num_groups = w_b // group_width
self.conv2 = nn.Conv2d(w_b, w_b, kernel_size=3,
stride=stride, padding=1, groups=num_groups, bias=False)
self.bn2 = nn.BatchNorm2d(w_b)
# se
self.with_se = se_ratio > 0
if self.with_se:
w_se = int(round(w_in * se_ratio))
self.se = SE(w_b, w_se)
# 1x1
self.conv3 = nn.Conv2d(w_b, w_out, kernel_size=1, bias=False)
self.bn3 = nn.BatchNorm2d(w_out)

self.shortcut = nn.Sequential()
if stride != 1 or w_in != w_out:
self.shortcut = nn.Sequential(
nn.Conv2d(w_in, w_out,
kernel_size=1, stride=stride, bias=False),
nn.BatchNorm2d(w_out)
)

def forward(self, x):
out = F.relu(self.bn1(self.conv1(x)))
out = F.relu(self.bn2(self.conv2(out)))
if self.with_se:
out = self.se(out)
out = self.bn3(self.conv3(out))
out += self.shortcut(x)
out = F.relu(out)
return o