Skip to content

Commit

Permalink
Update some model presets (ResNet, XDenseNet)
Browse files Browse the repository at this point in the history
  • Loading branch information
osmr committed Apr 13, 2019
1 parent 60820fa commit 7788fd3
Show file tree
Hide file tree
Showing 13 changed files with 545 additions and 137 deletions.
6 changes: 5 additions & 1 deletion chainer_/chainercv2/model_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,14 @@
'resnet10': resnet10,
'resnet12': resnet12,
'resnet14': resnet14,
'resnetbc14b': resnetbc14b,
'resnet16': resnet16,
'resnet18_wd4': resnet18_wd4,
'resnet18_wd2': resnet18_wd2,
'resnet18_w3d4': resnet18_w3d4,

'resnet18': resnet18,
'resnet26': resnet26,
'resnetbc26b': resnetbc26b,
'resnet34': resnet34,
'resnet50': resnet50,
'resnet50b': resnet50b,
Expand Down Expand Up @@ -471,8 +473,10 @@

'xdensenet40_2_k24_bc_cifar10': xdensenet40_2_k24_bc_cifar10,
'xdensenet40_2_k24_bc_cifar100': xdensenet40_2_k24_bc_cifar100,
'xdensenet40_2_k24_bc_svhn': xdensenet40_2_k24_bc_svhn,
'xdensenet40_2_k36_bc_cifar10': xdensenet40_2_k36_bc_cifar10,
'xdensenet40_2_k36_bc_cifar100': xdensenet40_2_k36_bc_cifar100,
'xdensenet40_2_k36_bc_svhn': xdensenet40_2_k36_bc_svhn,

'wrn16_10_cifar10': wrn16_10_cifar10,
'wrn16_10_cifar100': wrn16_10_cifar100,
Expand Down
94 changes: 79 additions & 15 deletions chainer_/chainercv2/models/resnet.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
Original paper: 'Deep Residual Learning for Image Recognition,' https://arxiv.org/abs/1512.03385.
"""

__all__ = ['ResNet', 'resnet10', 'resnet12', 'resnet14', 'resnet16', 'resnet18_wd4', 'resnet18_wd2', 'resnet18_w3d4',
'resnet18', 'resnet34', 'resnet50', 'resnet50b', 'resnet101', 'resnet101b', 'resnet152', 'resnet152b',
'resnet200', 'resnet200b', 'ResBlock', 'ResBottleneck', 'ResUnit', 'ResInitBlock']
__all__ = ['ResNet', 'resnet10', 'resnet12', 'resnet14', 'resnetbc14b', 'resnet16', 'resnet18_wd4', 'resnet18_wd2',
'resnet18_w3d4', 'resnet18', 'resnet26', 'resnetbc26b', 'resnet34', 'resnet50', 'resnet50b', 'resnet101',
'resnet101b', 'resnet152', 'resnet152b', 'resnet200', 'resnet200b', 'ResBlock', 'ResBottleneck', 'ResUnit',
'ResInitBlock']

import os
import chainer.functions as F
Expand Down Expand Up @@ -280,6 +281,7 @@ def __call__(self, x):


def get_resnet(blocks,
bottleneck=None,
conv1_stride=True,
width_scale=1.0,
model_name=None,
Expand All @@ -293,6 +295,8 @@ def get_resnet(blocks,
----------
blocks : int
Number of blocks.
bottleneck : bool, default None
Whether to use a bottleneck or simple block in units.
conv1_stride : bool, default True
Whether to use stride in the first or the second convolution layer in units.
width_scale : float, default 1.0
Expand All @@ -304,17 +308,25 @@ def get_resnet(blocks,
root : str, default '~/.chainer/models'
Location for keeping the model parameters.
"""
if bottleneck is None:
bottleneck = (blocks >= 50)

if blocks == 10:
layers = [1, 1, 1, 1]
elif blocks == 12:
layers = [2, 1, 1, 1]
elif blocks == 14:
elif blocks == 14 and not bottleneck:
layers = [2, 2, 1, 1]
elif (blocks == 14) and bottleneck:
layers = [1, 1, 1, 1]
elif blocks == 16:
layers = [2, 2, 2, 1]
elif blocks == 18:
layers = [2, 2, 2, 2]
elif (blocks == 26) and not bottleneck:
layers = [3, 3, 3, 3]
elif (blocks == 26) and bottleneck:
layers = [2, 2, 2, 2]
elif blocks == 34:
layers = [3, 4, 6, 3]
elif blocks == 50:
Expand All @@ -328,19 +340,21 @@ def get_resnet(blocks,
else:
raise ValueError("Unsupported ResNet with number of blocks: {}".format(blocks))

if bottleneck:
assert (sum(layers) * 3 + 2 == blocks)
else:
assert (sum(layers) * 2 + 2 == blocks)

init_block_channels = 64
channels_per_layers = [64, 128, 256, 512]

if blocks < 50:
channels_per_layers = [64, 128, 256, 512]
bottleneck = False
else:
channels_per_layers = [256, 512, 1024, 2048]
bottleneck = True
if bottleneck:
bottleneck_factor = 4
channels_per_layers = [ci * bottleneck_factor for ci in channels_per_layers]

channels = [[ci] * li for (ci, li) in zip(channels_per_layers, layers)]

if width_scale != 1.0:
# channels = [[int(cij * width_scale) for cij in ci] for ci in channels]
channels = [[int(cij * width_scale) if (i != len(channels) - 1) or (j != len(ci) - 1) else cij
for j, cij in enumerate(ci)] for i, ci in enumerate(channels)]
init_block_channels = int(init_block_channels * width_scale)
Expand Down Expand Up @@ -410,6 +424,21 @@ def resnet14(**kwargs):
return get_resnet(blocks=14, model_name="resnet14", **kwargs)


def resnetbc14b(**kwargs):
"""
ResNet-BC-14b model from 'Deep Residual Learning for Image Recognition,' https://arxiv.org/abs/1512.03385.
It's an experimental model (bottleneck compressed).
Parameters:
----------
pretrained : bool, default False
Whether to load the pretrained weights for model.
root : str, default '~/.chainer/models'
Location for keeping the model parameters.
"""
return get_resnet(blocks=14, bottleneck=True, conv1_stride=False, model_name="resnetbc14b", **kwargs)


def resnet16(**kwargs):
"""
ResNet-16 model from 'Deep Residual Learning for Image Recognition,' https://arxiv.org/abs/1512.03385.
Expand Down Expand Up @@ -484,6 +513,36 @@ def resnet18(**kwargs):
return get_resnet(blocks=18, model_name="resnet18", **kwargs)


def resnet26(**kwargs):
"""
ResNet-26 model from 'Deep Residual Learning for Image Recognition,' https://arxiv.org/abs/1512.03385.
It's an experimental model.
Parameters:
----------
pretrained : bool, default False
Whether to load the pretrained weights for model.
root : str, default '~/.chainer/models'
Location for keeping the model parameters.
"""
return get_resnet(blocks=26, bottleneck=False, model_name="resnet26", **kwargs)


def resnetbc26b(**kwargs):
"""
ResNet-BC-26b model from 'Deep Residual Learning for Image Recognition,' https://arxiv.org/abs/1512.03385.
It's an experimental model (bottleneck compressed).
Parameters:
----------
pretrained : bool, default False
Whether to load the pretrained weights for model.
root : str, default '~/.chainer/models'
Location for keeping the model parameters.
"""
return get_resnet(blocks=26, bottleneck=True, conv1_stride=False, model_name="resnetbc26b", **kwargs)


def resnet34(**kwargs):
"""
ResNet-34 model from 'Deep Residual Learning for Image Recognition,' https://arxiv.org/abs/1512.03385.
Expand Down Expand Up @@ -627,12 +686,14 @@ def _test():
resnet10,
resnet12,
resnet14,
resnetbc14b,
resnet16,
resnet18_wd4,
resnet18_wd2,
resnet18_w3d4,

resnet18,
resnet26,
resnetbc26b,
resnet34,
resnet50,
resnet50b,
Expand All @@ -652,11 +713,14 @@ def _test():
assert (model != resnet10 or weight_count == 5418792)
assert (model != resnet12 or weight_count == 5492776)
assert (model != resnet14 or weight_count == 5788200)
assert (model != resnetbc14b or weight_count == 10064936)
assert (model != resnet16 or weight_count == 6968872)
assert (model != resnet18_wd4 or weight_count == 3937400) # 831096
assert (model != resnet18_wd2 or weight_count == 5804296) # 3055880
assert (model != resnet18_w3d4 or weight_count == 8476056) # 6675352
assert (model != resnet18_wd4 or weight_count == 3937400)
assert (model != resnet18_wd2 or weight_count == 5804296)
assert (model != resnet18_w3d4 or weight_count == 8476056)
assert (model != resnet18 or weight_count == 11689512)
assert (model != resnet26 or weight_count == 17960232)
assert (model != resnetbc26b or weight_count == 15995176)
assert (model != resnet34 or weight_count == 21797672)
assert (model != resnet50 or weight_count == 25557032)
assert (model != resnet50b or weight_count == 25557032)
Expand Down
45 changes: 43 additions & 2 deletions chainer_/chainercv2/models/xdensenet_cifar.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
"""
X-DenseNet for CIFAR, implemented in Chainer.
X-DenseNet for CIFAR/SVHN, implemented in Chainer.
Original paper: 'Deep Expander Networks: Efficient Deep Networks from Graph Theory,'
https://arxiv.org/abs/1711.08757.
"""

__all__ = ['CIFARXDenseNet', 'xdensenet40_2_k24_bc_cifar10', 'xdensenet40_2_k24_bc_cifar100',
'xdensenet40_2_k36_bc_cifar10', 'xdensenet40_2_k36_bc_cifar100']
'xdensenet40_2_k24_bc_svhn', 'xdensenet40_2_k36_bc_cifar10', 'xdensenet40_2_k36_bc_cifar100',
'xdensenet40_2_k36_bc_svhn']

import os
import chainer.functions as F
Expand Down Expand Up @@ -251,6 +252,24 @@ def xdensenet40_2_k24_bc_cifar100(classes=100, **kwargs):
model_name="xdensenet40_2_k24_bc_cifar100", **kwargs)


def xdensenet40_2_k24_bc_svhn(classes=10, **kwargs):
"""
X-DenseNet-BC-40-2 (k=24) model for SVHN from 'Deep Expander Networks: Efficient Deep Networks from Graph
Theory,' https://arxiv.org/abs/1711.08757.
Parameters:
----------
classes : int, default 10
Number of classification classes.
pretrained : bool, default False
Whether to load the pretrained weights for model.
root : str, default '~/.chainer/models'
Location for keeping the model parameters.
"""
return get_xdensenet_cifar(classes=classes, blocks=40, growth_rate=24, bottleneck=True,
model_name="xdensenet40_2_k24_bc_svhn", **kwargs)


def xdensenet40_2_k36_bc_cifar10(classes=10, **kwargs):
"""
X-DenseNet-BC-40-2 (k=36) model for CIFAR-10 from 'Deep Expander Networks: Efficient Deep Networks from Graph
Expand Down Expand Up @@ -287,6 +306,24 @@ def xdensenet40_2_k36_bc_cifar100(classes=100, **kwargs):
model_name="xdensenet40_2_k36_bc_cifar100", **kwargs)


def xdensenet40_2_k36_bc_svhn(classes=10, **kwargs):
"""
X-DenseNet-BC-40-2 (k=36) model for SVHN from 'Deep Expander Networks: Efficient Deep Networks from Graph
Theory,' https://arxiv.org/abs/1711.08757.
Parameters:
----------
classes : int, default 10
Number of classification classes.
pretrained : bool, default False
Whether to load the pretrained weights for model.
root : str, default '~/.chainer/models'
Location for keeping the model parameters.
"""
return get_xdensenet_cifar(classes=classes, blocks=40, growth_rate=36, bottleneck=True,
model_name="xdensenet40_2_k36_bc_svhn", **kwargs)


def _test():
import numpy as np
import chainer
Expand All @@ -298,8 +335,10 @@ def _test():
models = [
(xdensenet40_2_k24_bc_cifar10, 10),
(xdensenet40_2_k24_bc_cifar100, 100),
(xdensenet40_2_k24_bc_svhn, 10),
(xdensenet40_2_k36_bc_cifar10, 10),
(xdensenet40_2_k36_bc_cifar100, 100),
(xdensenet40_2_k36_bc_svhn, 10),
]

for model, classes in models:
Expand All @@ -309,8 +348,10 @@ def _test():
print("m={}, {}".format(model.__name__, weight_count))
assert (model != xdensenet40_2_k24_bc_cifar10 or weight_count == 690346)
assert (model != xdensenet40_2_k24_bc_cifar100 or weight_count == 714196)
assert (model != xdensenet40_2_k24_bc_svhn or weight_count == 690346)
assert (model != xdensenet40_2_k36_bc_cifar10 or weight_count == 1542682)
assert (model != xdensenet40_2_k36_bc_cifar100 or weight_count == 1578412)
assert (model != xdensenet40_2_k36_bc_svhn or weight_count == 1542682)

x = np.zeros((1, 3, 32, 32), np.float32)
y = net(x)
Expand Down
10 changes: 5 additions & 5 deletions gluon/gluoncv2/model_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,14 @@
'resnet10': resnet10,
'resnet12': resnet12,
'resnet14': resnet14,
'resnetbc14b': resnetbc14b,
'resnet16': resnet16,
'resnet18_wd4': resnet18_wd4,
'resnet18_wd2': resnet18_wd2,
'resnet18_w3d4': resnet18_w3d4,

'resnet18': resnet18,
'resnet26': resnet26,
'resnetbc26b': resnetbc26b,
'resnet34': resnet34,
'resnet50': resnet50,
'resnet50b': resnet50b,
Expand All @@ -125,10 +127,6 @@
'resnet200': resnet200,
'resnet200b': resnet200b,

'resnetbn14b': resnetbn14b,
'resnet26': resnet26,
'resnetbn26b': resnetbn26b,

'preresnet10': preresnet10,
'preresnet12': preresnet12,
'preresnet14': preresnet14,
Expand Down Expand Up @@ -509,8 +507,10 @@

'xdensenet40_2_k24_bc_cifar10': xdensenet40_2_k24_bc_cifar10,
'xdensenet40_2_k24_bc_cifar100': xdensenet40_2_k24_bc_cifar100,
'xdensenet40_2_k24_bc_svhn': xdensenet40_2_k24_bc_svhn,
'xdensenet40_2_k36_bc_cifar10': xdensenet40_2_k36_bc_cifar10,
'xdensenet40_2_k36_bc_cifar100': xdensenet40_2_k36_bc_cifar100,
'xdensenet40_2_k36_bc_svhn': xdensenet40_2_k36_bc_svhn,

'wrn16_10_cifar10': wrn16_10_cifar10,
'wrn16_10_cifar100': wrn16_10_cifar100,
Expand Down
Loading

0 comments on commit 7788fd3

Please sign in to comment.