Skip to content

Commit b6985ec

Browse files
updated and checked CNN architectures still works with latest pytorch
1 parent 28a6abe commit b6985ec

File tree

5 files changed

+100
-77
lines changed

5 files changed

+100
-77
lines changed

ML/Pytorch/CNN_architectures/lenet5_pytorch.py

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
"""
22
An implementation of LeNet CNN architecture.
33
4-
Video explanation: https://youtu.be/fcOW-Zyb5Bo
5-
Got any questions leave a comment on youtube :)
6-
74
Programmed by Aladdin Persson <aladdin.persson at hotmail dot com>
85
* 2020-04-05 Initial coding
9-
6+
* 2022-12-20 Update comments, code revision, checked still works with latest PyTorch version
107
"""
118

129
import torch
@@ -17,27 +14,27 @@ class LeNet(nn.Module):
1714
def __init__(self):
1815
super(LeNet, self).__init__()
1916
self.relu = nn.ReLU()
20-
self.pool = nn.AvgPool2d(kernel_size=(2, 2), stride=(2, 2))
17+
self.pool = nn.AvgPool2d(kernel_size=2, stride=2)
2118
self.conv1 = nn.Conv2d(
2219
in_channels=1,
2320
out_channels=6,
24-
kernel_size=(5, 5),
25-
stride=(1, 1),
26-
padding=(0, 0),
21+
kernel_size=5,
22+
stride=1,
23+
padding=0,
2724
)
2825
self.conv2 = nn.Conv2d(
2926
in_channels=6,
3027
out_channels=16,
31-
kernel_size=(5, 5),
32-
stride=(1, 1),
33-
padding=(0, 0),
28+
kernel_size=5,
29+
stride=1,
30+
padding=0,
3431
)
3532
self.conv3 = nn.Conv2d(
3633
in_channels=16,
3734
out_channels=120,
38-
kernel_size=(5, 5),
39-
stride=(1, 1),
40-
padding=(0, 0),
35+
kernel_size=5,
36+
stride=1,
37+
padding=0,
4138
)
4239
self.linear1 = nn.Linear(120, 84)
4340
self.linear2 = nn.Linear(84, 10)
@@ -64,4 +61,4 @@ def test_lenet():
6461

6562
if __name__ == "__main__":
6663
out = test_lenet()
67-
print(out.shape)
64+
print(out.shape)

ML/Pytorch/CNN_architectures/pytorch_efficientnet.py

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
"""
2+
An implementation of EfficientNet CNN architecture.
3+
4+
Programmed by Aladdin Persson <aladdin.persson at hotmail dot com>
5+
* 2021-02-05 Initial coding
6+
* 2022-12-20 Update comments, code revision, checked still works with latest PyTorch version
7+
"""
8+
9+
110
import torch
211
import torch.nn as nn
312
from math import ceil
@@ -25,9 +34,10 @@
2534
"b7": (6, 600, 0.5),
2635
}
2736

37+
2838
class CNNBlock(nn.Module):
2939
def __init__(
30-
self, in_channels, out_channels, kernel_size, stride, padding, groups=1
40+
self, in_channels, out_channels, kernel_size, stride, padding, groups=1
3141
):
3242
super(CNNBlock, self).__init__()
3343
self.cnn = nn.Conv2d(
@@ -40,16 +50,17 @@ def __init__(
4050
bias=False,
4151
)
4252
self.bn = nn.BatchNorm2d(out_channels)
43-
self.silu = nn.SiLU() # SiLU <-> Swish
53+
self.silu = nn.SiLU() # SiLU <-> Swish
4454

4555
def forward(self, x):
4656
return self.silu(self.bn(self.cnn(x)))
4757

58+
4859
class SqueezeExcitation(nn.Module):
4960
def __init__(self, in_channels, reduced_dim):
5061
super(SqueezeExcitation, self).__init__()
5162
self.se = nn.Sequential(
52-
nn.AdaptiveAvgPool2d(1), # C x H x W -> C x 1 x 1
63+
nn.AdaptiveAvgPool2d(1), # C x H x W -> C x 1 x 1
5364
nn.Conv2d(in_channels, reduced_dim, 1),
5465
nn.SiLU(),
5566
nn.Conv2d(reduced_dim, in_channels, 1),
@@ -59,17 +70,18 @@ def __init__(self, in_channels, reduced_dim):
5970
def forward(self, x):
6071
return x * self.se(x)
6172

73+
6274
class InvertedResidualBlock(nn.Module):
6375
def __init__(
64-
self,
65-
in_channels,
66-
out_channels,
67-
kernel_size,
68-
stride,
69-
padding,
70-
expand_ratio,
71-
reduction=4, # squeeze excitation
72-
survival_prob=0.8, # for stochastic depth
76+
self,
77+
in_channels,
78+
out_channels,
79+
kernel_size,
80+
stride,
81+
padding,
82+
expand_ratio,
83+
reduction=4, # squeeze excitation
84+
survival_prob=0.8, # for stochastic depth
7385
):
7486
super(InvertedResidualBlock, self).__init__()
7587
self.survival_prob = 0.8
@@ -80,12 +92,21 @@ def __init__(
8092

8193
if self.expand:
8294
self.expand_conv = CNNBlock(
83-
in_channels, hidden_dim, kernel_size=3, stride=1, padding=1,
95+
in_channels,
96+
hidden_dim,
97+
kernel_size=3,
98+
stride=1,
99+
padding=1,
84100
)
85101

86102
self.conv = nn.Sequential(
87103
CNNBlock(
88-
hidden_dim, hidden_dim, kernel_size, stride, padding, groups=hidden_dim,
104+
hidden_dim,
105+
hidden_dim,
106+
kernel_size,
107+
stride,
108+
padding,
109+
groups=hidden_dim,
89110
),
90111
SqueezeExcitation(hidden_dim, reduced_dim),
91112
nn.Conv2d(hidden_dim, out_channels, 1, bias=False),
@@ -96,7 +117,9 @@ def stochastic_depth(self, x):
96117
if not self.training:
97118
return x
98119

99-
binary_tensor = torch.rand(x.shape[0], 1, 1, 1, device=x.device) < self.survival_prob
120+
binary_tensor = (
121+
torch.rand(x.shape[0], 1, 1, 1, device=x.device) < self.survival_prob
122+
)
100123
return torch.div(x, self.survival_prob) * binary_tensor
101124

102125
def forward(self, inputs):
@@ -122,8 +145,8 @@ def __init__(self, version, num_classes):
122145

123146
def calculate_factors(self, version, alpha=1.2, beta=1.1):
124147
phi, res, drop_rate = phi_values[version]
125-
depth_factor = alpha ** phi
126-
width_factor = beta ** phi
148+
depth_factor = alpha**phi
149+
width_factor = beta**phi
127150
return width_factor, depth_factor, drop_rate
128151

129152
def create_features(self, width_factor, depth_factor, last_channels):
@@ -132,7 +155,7 @@ def create_features(self, width_factor, depth_factor, last_channels):
132155
in_channels = channels
133156

134157
for expand_ratio, channels, repeats, stride, kernel_size in base_model:
135-
out_channels = 4*ceil(int(channels*width_factor) / 4)
158+
out_channels = 4 * ceil(int(channels * width_factor) / 4)
136159
layers_repeats = ceil(repeats * depth_factor)
137160

138161
for layer in range(layers_repeats):
@@ -141,9 +164,9 @@ def create_features(self, width_factor, depth_factor, last_channels):
141164
in_channels,
142165
out_channels,
143166
expand_ratio=expand_ratio,
144-
stride = stride if layer == 0 else 1,
167+
stride=stride if layer == 0 else 1,
145168
kernel_size=kernel_size,
146-
padding=kernel_size//2, # if k=1:pad=0, k=3:pad=1, k=5:pad=2
169+
padding=kernel_size // 2, # if k=1:pad=0, k=3:pad=1, k=5:pad=2
147170
)
148171
)
149172
in_channels = out_channels
@@ -170,6 +193,8 @@ def test():
170193
num_classes=num_classes,
171194
).to(device)
172195

173-
print(model(x).shape) # (num_examples, num_classes)
196+
print(model(x).shape) # (num_examples, num_classes)
197+
174198

175-
test()
199+
if __name__ == "__main__":
200+
test()

ML/Pytorch/CNN_architectures/pytorch_inceptionet.py

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
"""
22
An implementation of GoogLeNet / InceptionNet from scratch.
33
4-
Video explanation: https://youtu.be/uQc4Fs7yx5I
5-
Got any questions leave a comment on youtube :)
6-
74
Programmed by Aladdin Persson <aladdin.persson at hotmail dot com>
85
* 2020-04-07 Initial coding
9-
6+
* 2022-12-20 Update comments, code revision, checked still works with latest PyTorch version
107
"""
118

12-
# Imports
139
import torch
1410
from torch import nn
1511

@@ -25,9 +21,9 @@ def __init__(self, aux_logits=True, num_classes=1000):
2521
self.conv1 = conv_block(
2622
in_channels=3,
2723
out_channels=64,
28-
kernel_size=(7, 7),
29-
stride=(2, 2),
30-
padding=(3, 3),
24+
kernel_size=7,
25+
stride=2,
26+
padding=3,
3127
)
3228

3329
self.maxpool1 = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
@@ -37,7 +33,7 @@ def __init__(self, aux_logits=True, num_classes=1000):
3733
# In this order: in_channels, out_1x1, red_3x3, out_3x3, red_5x5, out_5x5, out_1x1pool
3834
self.inception3a = Inception_block(192, 64, 96, 128, 16, 32, 32)
3935
self.inception3b = Inception_block(256, 128, 128, 192, 32, 96, 64)
40-
self.maxpool3 = nn.MaxPool2d(kernel_size=(3, 3), stride=2, padding=1)
36+
self.maxpool3 = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
4137

4238
self.inception4a = Inception_block(480, 192, 96, 208, 16, 48, 64)
4339
self.inception4b = Inception_block(512, 160, 112, 224, 24, 64, 64)
@@ -63,7 +59,6 @@ def forward(self, x):
6359
x = self.conv1(x)
6460
x = self.maxpool1(x)
6561
x = self.conv2(x)
66-
# x = self.conv3(x)
6762
x = self.maxpool2(x)
6863

6964
x = self.inception3a(x)
@@ -104,21 +99,21 @@ def __init__(
10499
self, in_channels, out_1x1, red_3x3, out_3x3, red_5x5, out_5x5, out_1x1pool
105100
):
106101
super(Inception_block, self).__init__()
107-
self.branch1 = conv_block(in_channels, out_1x1, kernel_size=(1, 1))
102+
self.branch1 = conv_block(in_channels, out_1x1, kernel_size=1)
108103

109104
self.branch2 = nn.Sequential(
110-
conv_block(in_channels, red_3x3, kernel_size=(1, 1)),
111-
conv_block(red_3x3, out_3x3, kernel_size=(3, 3), padding=(1, 1)),
105+
conv_block(in_channels, red_3x3, kernel_size=1),
106+
conv_block(red_3x3, out_3x3, kernel_size=(3, 3), padding=1),
112107
)
113108

114109
self.branch3 = nn.Sequential(
115-
conv_block(in_channels, red_5x5, kernel_size=(1, 1)),
116-
conv_block(red_5x5, out_5x5, kernel_size=(5, 5), padding=(2, 2)),
110+
conv_block(in_channels, red_5x5, kernel_size=1),
111+
conv_block(red_5x5, out_5x5, kernel_size=5, padding=2),
117112
)
118113

119114
self.branch4 = nn.Sequential(
120-
nn.MaxPool2d(kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
121-
conv_block(in_channels, out_1x1pool, kernel_size=(1, 1)),
115+
nn.MaxPool2d(kernel_size=3, stride=1, padding=1),
116+
conv_block(in_channels, out_1x1pool, kernel_size=1),
122117
)
123118

124119
def forward(self, x):
@@ -144,7 +139,6 @@ def forward(self, x):
144139
x = self.relu(self.fc1(x))
145140
x = self.dropout(x)
146141
x = self.fc2(x)
147-
148142
return x
149143

150144

@@ -160,7 +154,8 @@ def forward(self, x):
160154

161155

162156
if __name__ == "__main__":
163-
# N = 3 (Mini batch size)
164-
x = torch.randn(3, 3, 224, 224)
157+
BATCH_SIZE = 5
158+
x = torch.randn(BATCH_SIZE, 3, 224, 224)
165159
model = GoogLeNet(aux_logits=True, num_classes=1000)
166160
print(model(x)[2].shape)
161+
assert model(x)[2].shape == torch.Size([BATCH_SIZE, 1000])

ML/Pytorch/CNN_architectures/pytorch_resnet.py

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@
55
it didn't feel super clear at first, even when reading Pytorch own
66
implementation.
77
8-
Video explanation:
9-
Got any questions leave a comment on youtube :)
10-
118
Programmed by Aladdin Persson <aladdin.persson at hotmail dot com>
129
* 2020-04-12 Initial coding
10+
* 2022-12-20 Update comments, code revision, checked still works with latest PyTorch version
1311
"""
1412

1513
import torch
@@ -20,10 +18,15 @@ class block(nn.Module):
2018
def __init__(
2119
self, in_channels, intermediate_channels, identity_downsample=None, stride=1
2220
):
23-
super(block, self).__init__()
21+
super().__init__()
2422
self.expansion = 4
2523
self.conv1 = nn.Conv2d(
26-
in_channels, intermediate_channels, kernel_size=1, stride=1, padding=0, bias=False
24+
in_channels,
25+
intermediate_channels,
26+
kernel_size=1,
27+
stride=1,
28+
padding=0,
29+
bias=False,
2730
)
2831
self.bn1 = nn.BatchNorm2d(intermediate_channels)
2932
self.conv2 = nn.Conv2d(
@@ -32,7 +35,7 @@ def __init__(
3235
kernel_size=3,
3336
stride=stride,
3437
padding=1,
35-
bias=False
38+
bias=False,
3639
)
3740
self.bn2 = nn.BatchNorm2d(intermediate_channels)
3841
self.conv3 = nn.Conv2d(
@@ -41,7 +44,7 @@ def __init__(
4144
kernel_size=1,
4245
stride=1,
4346
padding=0,
44-
bias=False
47+
bias=False,
4548
)
4649
self.bn3 = nn.BatchNorm2d(intermediate_channels * self.expansion)
4750
self.relu = nn.ReLU()
@@ -72,7 +75,9 @@ class ResNet(nn.Module):
7275
def __init__(self, block, layers, image_channels, num_classes):
7376
super(ResNet, self).__init__()
7477
self.in_channels = 64
75-
self.conv1 = nn.Conv2d(image_channels, 64, kernel_size=7, stride=2, padding=3, bias=False)
78+
self.conv1 = nn.Conv2d(
79+
image_channels, 64, kernel_size=7, stride=2, padding=3, bias=False
80+
)
7681
self.bn1 = nn.BatchNorm2d(64)
7782
self.relu = nn.ReLU()
7883
self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
@@ -124,7 +129,7 @@ def _make_layer(self, block, num_residual_blocks, intermediate_channels, stride)
124129
intermediate_channels * 4,
125130
kernel_size=1,
126131
stride=stride,
127-
bias=False
132+
bias=False,
128133
),
129134
nn.BatchNorm2d(intermediate_channels * 4),
130135
)
@@ -158,9 +163,13 @@ def ResNet152(img_channel=3, num_classes=1000):
158163

159164

160165
def test():
161-
net = ResNet101(img_channel=3, num_classes=1000)
162-
y = net(torch.randn(4, 3, 224, 224)).to("cuda")
166+
BATCH_SIZE = 4
167+
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
168+
net = ResNet101(img_channel=3, num_classes=1000).to(device)
169+
y = net(torch.randn(BATCH_SIZE, 3, 224, 224)).to(device)
170+
assert y.size() == torch.Size([BATCH_SIZE, 1000])
163171
print(y.size())
164172

165173

166-
test()
174+
if __name__ == "__main__":
175+
test()

0 commit comments

Comments
 (0)