In https://pytorch.org/docs/stable/torchvision/models.html ,
When comparing the models in the tables by error rate \ IoU, I think it can be beneficial to also add the number of learned parameters.
It will assist in choosing the right model given the performance\runtime trade-off.
1 Like
I second this. Would be very handy
2 Likes
I wrote a snippet for it.
import torchvision.models as models
from types import FunctionType
def calculate_num_of_learned_params(model):
cnt = 0
for param in model.parameters():
if param.requires_grad:
cnt += param.numel()
return cnt
for model_name in dir(models):
if model_name[0].islower():
attr = getattr(models, model_name)
if isinstance(attr, FunctionType):
print(model_name, '\t\t\t', calculate_num_of_learned_params(attr()))
Results:
alexnet 61100840
densenet121 7978856
densenet161 28681000
densenet169 14149480
densenet201 20013928
googlenet 13004888
inception_v3 27161264
mobilenet_v2 3504872
resnet101 44549160
resnet152 60192808
resnet18 11689512
resnet34 21797672
resnet50 25557032
resnext101_32x8d 88791336
resnext50_32x4d 25028904
shufflenet_v2_x0_5 1366792
shufflenet_v2_x1_0 2278604
shufflenet_v2_x1_5 3503624
shufflenet_v2_x2_0 7393996
squeezenet1_0 1248424
squeezenet1_1 1235496
vgg11 132863336
vgg11_bn 132868840
vgg13 133047848
vgg13_bn 133053736
vgg16 138357544
vgg16_bn 138365992
vgg19 143667240
vgg19_bn 143678248
1 Like
Great Was hard to count the zeros so I made a human readable tweak
import torchvision.models as models
from types import FunctionType
def calculate_num_of_learned_params(model):
cnt = 0
for param in model.parameters():
if param.requires_grad:
cnt += param.numel()
return cnt
def human_readable(n_params):
if n_params >= 1e6:
return '{:.2f} million'.format(n_params/1e6)
if n_params >= 1e3:
return '{:.2f} thousands'.format(n_params/1e3)
else:
return n_params
for model_name in dir(models):
if model_name[0].islower():
attr = getattr(models, model_name)
if isinstance(attr, FunctionType):
n_params = calculate_num_of_learned_params(attr())
print(model_name, '\t\t\t', human_readable(n_params))
Edit: torchvision 0.3.0
alexnet 61.10 million
densenet121 7.98 million
densenet161 28.68 million
densenet169 14.15 million
densenet201 20.01 million
googlenet 13.00 million
inception_v3 27.16 million
mobilenet_v2 3.50 million
resnet101 44.55 million
resnet152 60.19 million
resnet18 11.69 million
resnet34 21.80 million
resnet50 25.56 million
resnext101_32x8d 88.79 million
resnext50_32x4d 25.03 million
shufflenet_v2_x0_5 1.37 million
shufflenet_v2_x1_0 2.28 million
shufflenet_v2_x1_5 3.50 million
shufflenet_v2_x2_0 7.39 million
squeezenet1_0 1.25 million
squeezenet1_1 1.24 million
vgg11 132.86 million
vgg11_bn 132.87 million
vgg13 133.05 million
vgg13_bn 133.05 million
vgg16 138.36 million
vgg16_bn 138.37 million
vgg19 143.67 million
vgg19_bn 143.68 million
Great! I noticed you have some missing models, probably due to an old torchvision version.
Anyway I shortened one of the functions:
def calculate_num_of_learned_params(model):
return sum([param.numel() for param in model.parameters() if param.requires_grad])
1 Like
As this was not integrated yet, here are results as of torchvision 0.12:
Torchvision 0.12.0.dev20211108+cpu
squeezenet1_1 1.24 million
squeezenet1_0 1.25 million
shufflenet_v2_x0_5 1.37 million
mnasnet0_5 2.22 million
shufflenet_v2_x1_0 2.28 million
mobilenet_v3_small 2.54 million
mnasnet0_75 3.17 million
shufflenet_v2_x1_5 3.50 million
mobilenet_v2 3.50 million
regnet_y_400mf 4.34 million
mnasnet1_0 4.38 million
efficientnet_b0 5.29 million
mobilenet_v3_large 5.48 million
regnet_x_400mf 5.50 million
mnasnet1_3 6.28 million
regnet_y_800mf 6.43 million
regnet_x_800mf 7.26 million
shufflenet_v2_x2_0 7.39 million
efficientnet_b1 7.79 million
densenet121 7.98 million
efficientnet_b2 9.11 million
regnet_x_1_6gf 9.19 million
regnet_y_1_6gf 11.20 million
resnet18 11.69 million
efficientnet_b3 12.23 million
googlenet 13.00 million
densenet169 14.15 million
regnet_x_3_2gf 15.30 million
efficientnet_b4 19.34 million
regnet_y_3_2gf 19.44 million
densenet201 20.01 million
resnet34 21.80 million
resnext50_32x4d 25.03 million
resnet50 25.56 million
inception_v3 27.16 million
densenet161 28.68 million
efficientnet_b5 30.39 million
regnet_y_8gf 39.38 million
regnet_x_8gf 39.57 million
efficientnet_b6 43.04 million
resnet101 44.55 million
regnet_x_16gf 54.28 million
resnet152 60.19 million
alexnet 61.10 million
efficientnet_b7 66.35 million
wide_resnet50_2 68.88 million
regnet_y_16gf 83.59 million
resnext101_32x8d 88.79 million
regnet_x_32gf 107.81 million
wide_resnet101_2 126.89 million
vgg11 132.86 million
vgg11_bn 132.87 million
vgg13 133.05 million
vgg13_bn 133.05 million
vgg16 138.36 million
vgg16_bn 138.37 million
vgg19 143.67 million
vgg19_bn 143.68 million
regnet_y_32gf 145.05 million
Updated code:
import torchvision
import torchvision.models as models
from types import FunctionType
def calculate_num_of_learned_params(model):
return sum(param.numel() for param in model.parameters() if param.requires_grad)
def human_readable(n_params):
if n_params >= 1e6:
return f'{n_params/1e6 :.2f} million'
if n_params >= 1e3:
return f'{n_params/1e3:.2f} thousands'
else:
return n_params
model_sizes = {}
for model_name in dir(models):
if model_name[0].islower():
attr = getattr(models, model_name)
if isinstance(attr, FunctionType):
n_params = calculate_num_of_learned_params(attr())
model_sizes[model_name] = n_params
print(f"Torchvision {torchvision.__version__}")
model_sizes = sorted(model_sizes.items(), key=lambda x: x[1])
for model_name, model_size in model_sizes:
print(model_name.ljust(20), '\t', human_readable(model_size))
2 Likes