Coderx7/SimpleNet_Pytorch

SimpleNetV1 Implementation in Pytorch

Python

54

85 commits

updated Feb 7, 2024

See the code

README

بسم الله الرحمن الرحیم
پیاده سازی پایتورچ سیمپل نت

SimpleNet in Pytorch

SimpleNetV1 architecture implementation in Pytorch

Lets Keep it simple, Using simple architectures to outperform deeper and more complex architectures (2016).

GitHub Logo

This is the pytorch implementation of our architecture SimpleNetV1(2016) .
Pytorch is different from caffe in several sections, and this made it a bit harder to have the architecture properly ported especially since I'm a complete newbie in Pytorch. However, thanks to this great work, I could easily focus on the model and port the architecture and hopefully achieve my reported results in Caffe and also exceed them as well!

The pytorch implementation is also very effieicent and the whole model takes only 1239MB with the batch size of 64! (compare this to other architectures such as ResNet,WRN, DenseNet which a 800K model takes more than 6G of vram!)

Update History:

-- 2023 May 13:
  -- Add support for torch hub.
-- 2023 Apr 14:
  -- update benchmark results.
-- 2023 Apr 13:
  -- new weights for the removed paddings for 1x1 conv layers.
  -- some minor fixes
-- 2023 Feb 12: 
  -- re-structured the repository, moving the old implementation into new directory named 'Cifar` and imagenet into its respective directory
  -- updated the old implementation to work with latest version of pytorch.
  -- updated the imagenet scripts/models compatible with timm and a separate version for pure pytorch uscases
  -- updated pretrained models with the latest results 
-- 2022: Adding initial ImageNet models   
-- 2018: Initial Pytorch implementation (for CIFAR10/100/MNIST/SVHN datasets)    
-- 2016: Initial model release for caffe

The original Caffe implementation can be found here : Original Caffe implementation - 2016

ImageNet Result:

Model#ParamsImageNetImageNet-Real-Labels
simplenetv1_9m_m2(36.3 MB)9.5m74.23 / 91.74881.22 / 94.756
simplenetv1_5m_m2(22 MB)5.7m72.03 / 90.32479.328/ 93.714
simplenetv1_small_m2_075(12.6 MB)3m68.506/ 88.1576.283/ 92.02
simplenetv1_small_m2_05(5.78 MB)1.5m61.67 / 83.48869.31 / 88.195

SimpleNet performs very decently, it outperforms VGGNet, variants of ResNet and MobileNets(1-3)
and its pretty fast as well! and its all using plain old CNN!.

Here's an example of benchmark run on small variants of simplenet and some other known architectures such as mobilenets.
Small variants of simplenet consistently achieve high performance/accuracy:

modelsamples_per_secparam_counttop1top5
simplenetv1_small_m1_053100.261.5161.12282.988
mobilenetv3_small_0503082.851.5957.8980.194
lcnet_0502713.021.8863.184.382
simplenetv1_small_m2_052536.161.5161.6783.488
mobilenetv3_small_0751793.422.0465.24285.438
tf_mobilenetv3_small_0751689.532.0465.71486.134
simplenetv1_small_m1_0751626.873.2967.78487.718
tf_mobilenetv3_small_minimal_1001316.912.0462.90884.234
simplenetv1_small_m2_0751313.63.2968.50688.15
mobilenetv3_small_1001261.092.5467.65687.634
tf_mobilenetv3_small_1001213.032.5467.92487.664
mnasnet_small1089.332.0366.20686.508
mobilenetv2_050857.661.9765.94286.082
dla46_c537.081.364.86686.294
dla46x_c323.031.0765.9786.98
dla60x_c301.711.3267.89288.426

and this is a sample for larger models: simplenet variants outperform many newer architecures.

modelsamples_per_secparam_counttop1top5
simplenetv1_small_m1_0752893.913.2967.78487.718
simplenetv1_small_m2_0752478.413.2968.50688.15
vit_tiny_r_s16_p8_2242337.236.3471.79290.822
simplenetv1_5m_m12105.065.7571.54889.94
simplenetv1_5m_m21754.255.7572.0390.324
resnet181750.3811.6969.74489.082
regnetx_0061620.256.273.8691.672
mobilenetv3_large_1001491.865.4875.76692.544
tf_mobilenetv3_large_minimal_1001476.293.9272.2590.63
tf_mobilenetv3_large_0751474.773.9973.43691.344
ghostnet_1001390.195.1873.97491.46
tinynet_b1345.823.7374.97692.184
tf_mobilenetv3_large_1001325.065.4875.51892.604
mnasnet_1001183.694.3874.65892.112
mobilenetv2_1001101.583.572.9791.02
simplenetv1_9m_m11048.919.5173.79291.486
resnet341030.421.875.11492.284
deit_tiny_patch16_224990.855.7272.17291.114
efficientnet_lite0977.764.6575.47692.512
simplenetv1_9m_m2900.459.5174.2391.748
tf_efficientnet_lite0876.664.6574.83292.174
dla34834.3515.7474.6292.072
mobilenetv2_110d824.44.5275.03892.184
resnet26771.11675.392.578
repvgg_b0751.0115.8275.1692.418
crossvit_9_240606.28.5573.9691.968
vgg11576.32132.8669.02888.626
vit_base_patch32_224_sam561.9988.2273.69491.01
vgg11_bn504.29132.8770.3689.802
densenet121435.37.9875.58492.652
vgg13363.69133.0569.92689.246
vgg13_bn315.85133.0571.59490.376
vgg16302.84138.3671.5990.382
vgg16_bn265.99138.3773.3591.504
vgg19259.82143.6772.36690.87
vgg19_bn229.77143.6874.21491.848

Benchmark was done using a GTX1080 on Pytorch 1.11 with fp32, nchw, batchsize of 256, input size = 224x224x3.
For all benchmark results look here

-- The models pretrained weights (pytorch, onnx, jit) can be found in Release section

CIFAR10/100 Results achieved using this implementation :

DatasetAccuracy
CIFAR1095.51
CIFAR10078.37

CIFAR10/100 top results (2016):

Method#ParamsCIFAR10CIFAR100
VGGNet(16L) /Enhanced138m91.4 / 92.45-
ResNet-110L / 1202L *1.7/10.2m93.57 / 92.0774.84/72.18
SD-110L / 1202L1.7/10.2m94.77 / 95.0975.42 / -
WRN-(16/8)/(28/10)11/36m95.19 / 95.8377.11/79.5
Highway NetworkN/A92.4067.76
FitNet1M91.6164.96
FMP* (1 tests)12M95.5073.61
Max-out(k=2)6M90.6265.46
Network in Network1M91.1964.32
DSN1M92.0365.43
Max-out NIN-93.2571.14
LSUVN/A94.16N/A
SimpleNet5.48M95.5178.37

Models and logs

-- refer to each dataset directory in the repository for further information on how to access models.

How to use

You can either download the simplenet.py model and use it directly in your projects or you can use torch hub.

Using torch hub you can do something like this:

import torch
# use the latest master
model = torch.hub.load("coderx7/simplenet_pytorch", "simplenetv1_5m_m1", pretrained=True)
# or any of these variants at the moment
# model = torch.hub.load("coderx7/simplenet_pytorch:v1.0.0", "simplenetv1_5m_m2", pretrained=True)
# model = torch.hub.load("coderx7/simplenet_pytorch:v1.0.0", "simplenetv1_9m_m1", pretrained=True)
# model = torch.hub.load("coderx7/simplenet_pytorch:v1.0.0", "simplenetv1_9m_m2", pretrained=True)
# model = torch.hub.load("coderx7/simplenet_pytorch:v1.0.0", "simplenetv1_small_m1_05", pretrained=True)
# model = torch.hub.load("coderx7/simplenet_pytorch:v1.0.0", "simplenetv1_small_m2_05", pretrained=True)
# model = torch.hub.load("coderx7/simplenet_pytorch:v1.0.0", "simplenetv1_small_m1_075", pretrained=True)
# model = torch.hub.load("coderx7/simplenet_pytorch:v1.0.0", "simplenetv1_small_m2_075", pretrained=True)
model.eval()

# Download an example image from the pytorch website
import urllib
url, filename = ("https://github.com/pytorch/hub/raw/master/images/dog.jpg", "dog.jpg")
try: urllib.URLopener().retrieve(url, filename)
except: urllib.request.urlretrieve(url, filename)

# sample execution (requires torchvision)
from PIL import Image
from torchvision import transforms
input_image = Image.open(filename)
preprocess = transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
input_tensor = preprocess(input_image)
input_batch = input_tensor.unsqueeze(0) # create a mini-batch as expected by the model

# move the input and model to GPU for speed if available
if torch.cuda.is_available():
    input_batch = input_batch.to('cuda')
    model.to('cuda')

with torch.no_grad():
    output = model(input_batch)
# Tensor of shape 1000, with confidence scores over Imagenet's 1000 classes
print(output[0])
# The output has unnormalized scores. To get probabilities, you can run a softmax on it.
probabilities = torch.nn.functional.softmax(output[0], dim=0)
print(probabilities)

# Download ImageNet labels
!wget https://raw.githubusercontent.com/pytorch/hub/master/imagenet_classes.txt

# Read the categories
with open("imagenet_classes.txt", "r") as f:
    categories = [s.strip() for s in f.readlines()]
# Show top categories per image
top5_prob, top5_catid = torch.topk(probabilities, 5)
for i in range(top5_prob.size(0)):
    print(categories[top5_catid[i]], top5_prob[i].item())

or you can run the demo online from huggingface simplenetspace: https://huggingface.co/spaces/coderx7/simplenet

Citation

If you find SimpleNet useful in your research, please consider citing:

@article{hasanpour2016lets,
  title={Lets keep it simple, Using simple architectures to outperform deeper and more complex architectures},
  author={Hasanpour, Seyyed Hossein and Rouhani, Mohammad and Fayyaz, Mohsen and Sabokrou, Mohammad},
  journal={arXiv preprint arXiv:1608.06037},
  year={2016}
}
convolutional-neural-networks
imagenet
imagenet-classification
simplenet

Coderx7/SimpleNet_Pytorch

SimpleNetV1 Implementation in Pytorch

Python

54

85 commits

updated Feb 7, 2024

See the code

README

بسم الله الرحمن الرحیم
پیاده سازی پایتورچ سیمپل نت

SimpleNet in Pytorch

SimpleNetV1 architecture implementation in Pytorch

Lets Keep it simple, Using simple architectures to outperform deeper and more complex architectures (2016).

GitHub Logo

This is the pytorch implementation of our architecture SimpleNetV1(2016) .
Pytorch is different from caffe in several sections, and this made it a bit harder to have the architecture properly ported especially since I'm a complete newbie in Pytorch. However, thanks to this great work, I could easily focus on the model and port the architecture and hopefully achieve my reported results in Caffe and also exceed them as well!

The pytorch implementation is also very effieicent and the whole model takes only 1239MB with the batch size of 64! (compare this to other architectures such as ResNet,WRN, DenseNet which a 800K model takes more than 6G of vram!)

Update History:

-- 2023 May 13:
  -- Add support for torch hub.
-- 2023 Apr 14:
  -- update benchmark results.
-- 2023 Apr 13:
  -- new weights for the removed paddings for 1x1 conv layers.
  -- some minor fixes
-- 2023 Feb 12: 
  -- re-structured the repository, moving the old implementation into new directory named 'Cifar` and imagenet into its respective directory
  -- updated the old implementation to work with latest version of pytorch.
  -- updated the imagenet scripts/models compatible with timm and a separate version for pure pytorch uscases
  -- updated pretrained models with the latest results 
-- 2022: Adding initial ImageNet models   
-- 2018: Initial Pytorch implementation (for CIFAR10/100/MNIST/SVHN datasets)    
-- 2016: Initial model release for caffe

The original Caffe implementation can be found here : Original Caffe implementation - 2016

ImageNet Result:

Model#ParamsImageNetImageNet-Real-Labels
simplenetv1_9m_m2(36.3 MB)9.5m74.23 / 91.74881.22 / 94.756
simplenetv1_5m_m2(22 MB)5.7m72.03 / 90.32479.328/ 93.714
simplenetv1_small_m2_075(12.6 MB)3m68.506/ 88.1576.283/ 92.02
simplenetv1_small_m2_05(5.78 MB)1.5m61.67 / 83.48869.31 / 88.195

SimpleNet performs very decently, it outperforms VGGNet, variants of ResNet and MobileNets(1-3)
and its pretty fast as well! and its all using plain old CNN!.

Here's an example of benchmark run on small variants of simplenet and some other known architectures such as mobilenets.
Small variants of simplenet consistently achieve high performance/accuracy:

modelsamples_per_secparam_counttop1top5
simplenetv1_small_m1_053100.261.5161.12282.988
mobilenetv3_small_0503082.851.5957.8980.194
lcnet_0502713.021.8863.184.382
simplenetv1_small_m2_052536.161.5161.6783.488
mobilenetv3_small_0751793.422.0465.24285.438
tf_mobilenetv3_small_0751689.532.0465.71486.134
simplenetv1_small_m1_0751626.873.2967.78487.718
tf_mobilenetv3_small_minimal_1001316.912.0462.90884.234
simplenetv1_small_m2_0751313.63.2968.50688.15
mobilenetv3_small_1001261.092.5467.65687.634
tf_mobilenetv3_small_1001213.032.5467.92487.664
mnasnet_small1089.332.0366.20686.508
mobilenetv2_050857.661.9765.94286.082
dla46_c537.081.364.86686.294
dla46x_c323.031.0765.9786.98
dla60x_c301.711.3267.89288.426

and this is a sample for larger models: simplenet variants outperform many newer architecures.

modelsamples_per_secparam_counttop1top5
simplenetv1_small_m1_0752893.913.2967.78487.718
simplenetv1_small_m2_0752478.413.2968.50688.15
vit_tiny_r_s16_p8_2242337.236.3471.79290.822
simplenetv1_5m_m12105.065.7571.54889.94
simplenetv1_5m_m21754.255.7572.0390.324
resnet181750.3811.6969.74489.082
regnetx_0061620.256.273.8691.672
mobilenetv3_large_1001491.865.4875.76692.544
tf_mobilenetv3_large_minimal_1001476.293.9272.2590.63
tf_mobilenetv3_large_0751474.773.9973.43691.344
ghostnet_1001390.195.1873.97491.46
tinynet_b1345.823.7374.97692.184
tf_mobilenetv3_large_1001325.065.4875.51892.604
mnasnet_1001183.694.3874.65892.112
mobilenetv2_1001101.583.572.9791.02
simplenetv1_9m_m11048.919.5173.79291.486
resnet341030.421.875.11492.284
deit_tiny_patch16_224990.855.7272.17291.114
efficientnet_lite0977.764.6575.47692.512
simplenetv1_9m_m2900.459.5174.2391.748
tf_efficientnet_lite0876.664.6574.83292.174
dla34834.3515.7474.6292.072
mobilenetv2_110d824.44.5275.03892.184
resnet26771.11675.392.578
repvgg_b0751.0115.8275.1692.418
crossvit_9_240606.28.5573.9691.968
vgg11576.32132.8669.02888.626
vit_base_patch32_224_sam561.9988.2273.69491.01
vgg11_bn504.29132.8770.3689.802
densenet121435.37.9875.58492.652
vgg13363.69133.0569.92689.246
vgg13_bn315.85133.0571.59490.376
vgg16302.84138.3671.5990.382
vgg16_bn265.99138.3773.3591.504
vgg19259.82143.6772.36690.87
vgg19_bn229.77143.6874.21491.848

Benchmark was done using a GTX1080 on Pytorch 1.11 with fp32, nchw, batchsize of 256, input size = 224x224x3.
For all benchmark results look here

-- The models pretrained weights (pytorch, onnx, jit) can be found in Release section

CIFAR10/100 Results achieved using this implementation :

DatasetAccuracy
CIFAR1095.51
CIFAR10078.37

CIFAR10/100 top results (2016):

Method#ParamsCIFAR10CIFAR100
VGGNet(16L) /Enhanced138m91.4 / 92.45-
ResNet-110L / 1202L *1.7/10.2m93.57 / 92.0774.84/72.18
SD-110L / 1202L1.7/10.2m94.77 / 95.0975.42 / -
WRN-(16/8)/(28/10)11/36m95.19 / 95.8377.11/79.5
Highway NetworkN/A92.4067.76
FitNet1M91.6164.96
FMP* (1 tests)12M95.5073.61
Max-out(k=2)6M90.6265.46
Network in Network1M91.1964.32
DSN1M92.0365.43
Max-out NIN-93.2571.14
LSUVN/A94.16N/A
SimpleNet5.48M95.5178.37

Models and logs

-- refer to each dataset directory in the repository for further information on how to access models.

How to use

You can either download the simplenet.py model and use it directly in your projects or you can use torch hub.

Using torch hub you can do something like this:

import torch
# use the latest master
model = torch.hub.load("coderx7/simplenet_pytorch", "simplenetv1_5m_m1", pretrained=True)
# or any of these variants at the moment
# model = torch.hub.load("coderx7/simplenet_pytorch:v1.0.0", "simplenetv1_5m_m2", pretrained=True)
# model = torch.hub.load("coderx7/simplenet_pytorch:v1.0.0", "simplenetv1_9m_m1", pretrained=True)
# model = torch.hub.load("coderx7/simplenet_pytorch:v1.0.0", "simplenetv1_9m_m2", pretrained=True)
# model = torch.hub.load("coderx7/simplenet_pytorch:v1.0.0", "simplenetv1_small_m1_05", pretrained=True)
# model = torch.hub.load("coderx7/simplenet_pytorch:v1.0.0", "simplenetv1_small_m2_05", pretrained=True)
# model = torch.hub.load("coderx7/simplenet_pytorch:v1.0.0", "simplenetv1_small_m1_075", pretrained=True)
# model = torch.hub.load("coderx7/simplenet_pytorch:v1.0.0", "simplenetv1_small_m2_075", pretrained=True)
model.eval()

# Download an example image from the pytorch website
import urllib
url, filename = ("https://github.com/pytorch/hub/raw/master/images/dog.jpg", "dog.jpg")
try: urllib.URLopener().retrieve(url, filename)
except: urllib.request.urlretrieve(url, filename)

# sample execution (requires torchvision)
from PIL import Image
from torchvision import transforms
input_image = Image.open(filename)
preprocess = transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
input_tensor = preprocess(input_image)
input_batch = input_tensor.unsqueeze(0) # create a mini-batch as expected by the model

# move the input and model to GPU for speed if available
if torch.cuda.is_available():
    input_batch = input_batch.to('cuda')
    model.to('cuda')

with torch.no_grad():
    output = model(input_batch)
# Tensor of shape 1000, with confidence scores over Imagenet's 1000 classes
print(output[0])
# The output has unnormalized scores. To get probabilities, you can run a softmax on it.
probabilities = torch.nn.functional.softmax(output[0], dim=0)
print(probabilities)

# Download ImageNet labels
!wget https://raw.githubusercontent.com/pytorch/hub/master/imagenet_classes.txt

# Read the categories
with open("imagenet_classes.txt", "r") as f:
    categories = [s.strip() for s in f.readlines()]
# Show top categories per image
top5_prob, top5_catid = torch.topk(probabilities, 5)
for i in range(top5_prob.size(0)):
    print(categories[top5_catid[i]], top5_prob[i].item())

or you can run the demo online from huggingface simplenetspace: https://huggingface.co/spaces/coderx7/simplenet

Citation

If you find SimpleNet useful in your research, please consider citing:

@article{hasanpour2016lets,
  title={Lets keep it simple, Using simple architectures to outperform deeper and more complex architectures},
  author={Hasanpour, Seyyed Hossein and Rouhani, Mohammad and Fayyaz, Mohsen and Sabokrou, Mohammad},
  journal={arXiv preprint arXiv:1608.06037},
  year={2016}
}
convolutional-neural-networks
imagenet
imagenet-classification
simplenet