mirror of
https://github.com/aladdinpersson/Machine-Learning-Collection.git
synced 2026-04-10 12:33:44 +00:00
Initial commit
This commit is contained in:
67
ML/Pytorch/CNN_architectures/lenet5_pytorch.py
Normal file
67
ML/Pytorch/CNN_architectures/lenet5_pytorch.py
Normal file
@@ -0,0 +1,67 @@
|
||||
"""
|
||||
An implementation of LeNet CNN architecture.
|
||||
|
||||
Video explanation: https://youtu.be/fcOW-Zyb5Bo
|
||||
Got any questions leave a comment on youtube :)
|
||||
|
||||
Programmed by Aladdin Persson <aladdin.persson at hotmail dot com>
|
||||
* 2020-04-05 Initial coding
|
||||
|
||||
"""
|
||||
|
||||
import torch
|
||||
import torch.nn as nn # All neural network modules, nn.Linear, nn.Conv2d, BatchNorm, Loss functions
|
||||
|
||||
|
||||
class LeNet(nn.Module):
|
||||
def __init__(self):
|
||||
super(LeNet, self).__init__()
|
||||
self.relu = nn.ReLU()
|
||||
self.pool = nn.AvgPool2d(kernel_size=(2, 2), stride=(2, 2))
|
||||
self.conv1 = nn.Conv2d(
|
||||
in_channels=1,
|
||||
out_channels=6,
|
||||
kernel_size=(5, 5),
|
||||
stride=(1, 1),
|
||||
padding=(0, 0),
|
||||
)
|
||||
self.conv2 = nn.Conv2d(
|
||||
in_channels=6,
|
||||
out_channels=16,
|
||||
kernel_size=(5, 5),
|
||||
stride=(1, 1),
|
||||
padding=(0, 0),
|
||||
)
|
||||
self.conv3 = nn.Conv2d(
|
||||
in_channels=16,
|
||||
out_channels=120,
|
||||
kernel_size=(5, 5),
|
||||
stride=(1, 1),
|
||||
padding=(0, 0),
|
||||
)
|
||||
self.linear1 = nn.Linear(120, 84)
|
||||
self.linear2 = nn.Linear(84, 10)
|
||||
|
||||
def forward(self, x):
|
||||
x = self.relu(self.conv1(x))
|
||||
x = self.pool(x)
|
||||
x = self.relu(self.conv2(x))
|
||||
x = self.pool(x)
|
||||
x = self.relu(
|
||||
self.conv3(x)
|
||||
) # num_examples x 120 x 1 x 1 --> num_examples x 120
|
||||
x = x.reshape(x.shape[0], -1)
|
||||
x = self.relu(self.linear1(x))
|
||||
x = self.linear2(x)
|
||||
return x
|
||||
|
||||
|
||||
def test_lenet():
|
||||
x = torch.randn(64, 1, 32, 32)
|
||||
model = LeNet()
|
||||
return model(x)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
out = test_lenet()
|
||||
print(out.shape)
|
||||
166
ML/Pytorch/CNN_architectures/pytorch_inceptionet.py
Normal file
166
ML/Pytorch/CNN_architectures/pytorch_inceptionet.py
Normal file
@@ -0,0 +1,166 @@
|
||||
"""
|
||||
An implementation of GoogLeNet / InceptionNet from scratch.
|
||||
|
||||
Video explanation: https://youtu.be/uQc4Fs7yx5I
|
||||
Got any questions leave a comment on youtube :)
|
||||
|
||||
Programmed by Aladdin Persson <aladdin.persson at hotmail dot com>
|
||||
* 2020-04-07 Initial coding
|
||||
|
||||
"""
|
||||
|
||||
# Imports
|
||||
import torch
|
||||
import torch.nn as nn # All neural network modules, nn.Linear, nn.Conv2d, BatchNorm, Loss functions
|
||||
|
||||
|
||||
class GoogLeNet(nn.Module):
|
||||
def __init__(self, aux_logits=True, num_classes=1000):
|
||||
super(GoogLeNet, self).__init__()
|
||||
assert aux_logits == True or aux_logits == False
|
||||
self.aux_logits = aux_logits
|
||||
|
||||
# Write in_channels, etc, all explicit in self.conv1, rest will write to
|
||||
# make everything as compact as possible, kernel_size=3 instead of (3,3)
|
||||
self.conv1 = conv_block(
|
||||
in_channels=3,
|
||||
out_channels=64,
|
||||
kernel_size=(7, 7),
|
||||
stride=(2, 2),
|
||||
padding=(3, 3),
|
||||
)
|
||||
|
||||
self.maxpool1 = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
|
||||
self.conv2 = conv_block(64, 192, kernel_size=3, stride=1, padding=1)
|
||||
self.maxpool2 = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
|
||||
|
||||
# In this order: in_channels, out_1x1, red_3x3, out_3x3, red_5x5, out_5x5, out_1x1pool
|
||||
self.inception3a = Inception_block(192, 64, 96, 128, 16, 32, 32)
|
||||
self.inception3b = Inception_block(256, 128, 128, 192, 32, 96, 64)
|
||||
self.maxpool3 = nn.MaxPool2d(kernel_size=(3, 3), stride=2, padding=1)
|
||||
|
||||
self.inception4a = Inception_block(480, 192, 96, 208, 16, 48, 64)
|
||||
self.inception4b = Inception_block(512, 160, 112, 224, 24, 64, 64)
|
||||
self.inception4c = Inception_block(512, 128, 128, 256, 24, 64, 64)
|
||||
self.inception4d = Inception_block(512, 112, 144, 288, 32, 64, 64)
|
||||
self.inception4e = Inception_block(528, 256, 160, 320, 32, 128, 128)
|
||||
self.maxpool4 = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
|
||||
|
||||
self.inception5a = Inception_block(832, 256, 160, 320, 32, 128, 128)
|
||||
self.inception5b = Inception_block(832, 384, 192, 384, 48, 128, 128)
|
||||
|
||||
self.avgpool = nn.AvgPool2d(kernel_size=7, stride=1)
|
||||
self.dropout = nn.Dropout(p=0.4)
|
||||
self.fc1 = nn.Linear(1024, 1000)
|
||||
|
||||
if self.aux_logits:
|
||||
self.aux1 = InceptionAux(512, num_classes)
|
||||
self.aux2 = InceptionAux(528, num_classes)
|
||||
else:
|
||||
self.aux1 = self.aux2 = None
|
||||
|
||||
def forward(self, x):
|
||||
x = self.conv1(x)
|
||||
x = self.maxpool1(x)
|
||||
x = self.conv2(x)
|
||||
# x = self.conv3(x)
|
||||
x = self.maxpool2(x)
|
||||
|
||||
x = self.inception3a(x)
|
||||
x = self.inception3b(x)
|
||||
x = self.maxpool3(x)
|
||||
|
||||
x = self.inception4a(x)
|
||||
|
||||
# Auxiliary Softmax classifier 1
|
||||
if self.aux_logits and self.training:
|
||||
aux1 = self.aux1(x)
|
||||
|
||||
x = self.inception4b(x)
|
||||
x = self.inception4c(x)
|
||||
x = self.inception4d(x)
|
||||
|
||||
# Auxiliary Softmax classifier 2
|
||||
if self.aux_logits and self.training:
|
||||
aux2 = self.aux2(x)
|
||||
|
||||
x = self.inception4e(x)
|
||||
x = self.maxpool4(x)
|
||||
x = self.inception5a(x)
|
||||
x = self.inception5b(x)
|
||||
x = self.avgpool(x)
|
||||
x = x.reshape(x.shape[0], -1)
|
||||
x = self.dropout(x)
|
||||
x = self.fc1(x)
|
||||
|
||||
if self.aux_logits and self.training:
|
||||
return aux1, aux2, x
|
||||
else:
|
||||
return x
|
||||
|
||||
|
||||
class Inception_block(nn.Module):
|
||||
def __init__(
|
||||
self, in_channels, out_1x1, red_3x3, out_3x3, red_5x5, out_5x5, out_1x1pool
|
||||
):
|
||||
super(Inception_block, self).__init__()
|
||||
self.branch1 = conv_block(in_channels, out_1x1, kernel_size=(1, 1))
|
||||
|
||||
self.branch2 = nn.Sequential(
|
||||
conv_block(in_channels, red_3x3, kernel_size=(1, 1)),
|
||||
conv_block(red_3x3, out_3x3, kernel_size=(3, 3), padding=(1, 1)),
|
||||
)
|
||||
|
||||
self.branch3 = nn.Sequential(
|
||||
conv_block(in_channels, red_5x5, kernel_size=(1, 1)),
|
||||
conv_block(red_5x5, out_5x5, kernel_size=(5, 5), padding=(2, 2)),
|
||||
)
|
||||
|
||||
self.branch4 = nn.Sequential(
|
||||
nn.MaxPool2d(kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
|
||||
conv_block(in_channels, out_1x1pool, kernel_size=(1, 1)),
|
||||
)
|
||||
|
||||
def forward(self, x):
|
||||
return torch.cat(
|
||||
[self.branch1(x), self.branch2(x), self.branch3(x), self.branch4(x)], 1
|
||||
)
|
||||
|
||||
|
||||
class InceptionAux(nn.Module):
|
||||
def __init__(self, in_channels, num_classes):
|
||||
super(InceptionAux, self).__init__()
|
||||
self.relu = nn.ReLU()
|
||||
self.dropout = nn.Dropout(p=0.7)
|
||||
self.pool = nn.AvgPool2d(kernel_size=5, stride=3)
|
||||
self.conv = conv_block(in_channels, 128, kernel_size=1)
|
||||
self.fc1 = nn.Linear(2048, 1024)
|
||||
self.fc2 = nn.Linear(1024, num_classes)
|
||||
|
||||
def forward(self, x):
|
||||
x = self.pool(x)
|
||||
x = self.conv(x)
|
||||
x = x.reshape(x.shape[0], -1)
|
||||
x = self.relu(self.fc1(x))
|
||||
x = self.dropout(x)
|
||||
x = self.fc2(x)
|
||||
|
||||
return x
|
||||
|
||||
|
||||
class conv_block(nn.Module):
|
||||
def __init__(self, in_channels, out_channels, **kwargs):
|
||||
super(conv_block, self).__init__()
|
||||
self.relu = nn.ReLU()
|
||||
self.conv = nn.Conv2d(in_channels, out_channels, **kwargs)
|
||||
self.batchnorm = nn.BatchNorm2d(out_channels)
|
||||
|
||||
def forward(self, x):
|
||||
return self.relu(self.batchnorm(self.conv(x)))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# N = 3 (Mini batch size)
|
||||
x = torch.randn(3, 3, 224, 224)
|
||||
model = GoogLeNet(aux_logits=True, num_classes=1000)
|
||||
print(model(x)[2].shape)
|
||||
163
ML/Pytorch/CNN_architectures/pytorch_resnet.py
Normal file
163
ML/Pytorch/CNN_architectures/pytorch_resnet.py
Normal file
@@ -0,0 +1,163 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
From scratch implementation of the famous ResNet models.
|
||||
The intuition for ResNet is simple and clear, but to code
|
||||
it didn't feel super clear at first, even when reading Pytorch own
|
||||
implementation.
|
||||
|
||||
Video explanation:
|
||||
Got any questions leave a comment on youtube :)
|
||||
|
||||
Programmed by Aladdin Persson <aladdin.persson at hotmail dot com>
|
||||
* 2020-04-12 Initial coding
|
||||
"""
|
||||
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
|
||||
|
||||
class block(nn.Module):
|
||||
def __init__(
|
||||
self, in_channels, intermediate_channels, identity_downsample=None, stride=1
|
||||
):
|
||||
super(block, self).__init__()
|
||||
self.expansion = 4
|
||||
self.conv1 = nn.Conv2d(
|
||||
in_channels, intermediate_channels, kernel_size=1, stride=1, padding=0
|
||||
)
|
||||
self.bn1 = nn.BatchNorm2d(intermediate_channels)
|
||||
self.conv2 = nn.Conv2d(
|
||||
intermediate_channels,
|
||||
intermediate_channels,
|
||||
kernel_size=3,
|
||||
stride=stride,
|
||||
padding=1,
|
||||
)
|
||||
self.bn2 = nn.BatchNorm2d(intermediate_channels)
|
||||
self.conv3 = nn.Conv2d(
|
||||
intermediate_channels,
|
||||
intermediate_channels * self.expansion,
|
||||
kernel_size=1,
|
||||
stride=1,
|
||||
padding=0,
|
||||
)
|
||||
self.bn3 = nn.BatchNorm2d(intermediate_channels * self.expansion)
|
||||
self.relu = nn.ReLU()
|
||||
self.identity_downsample = identity_downsample
|
||||
self.stride = stride
|
||||
|
||||
def forward(self, x):
|
||||
identity = x.clone()
|
||||
|
||||
x = self.conv1(x)
|
||||
x = self.bn1(x)
|
||||
x = self.relu(x)
|
||||
x = self.conv2(x)
|
||||
x = self.bn2(x)
|
||||
x = self.relu(x)
|
||||
x = self.conv3(x)
|
||||
x = self.bn3(x)
|
||||
|
||||
if self.identity_downsample is not None:
|
||||
identity = self.identity_downsample(identity)
|
||||
|
||||
x += identity
|
||||
x = self.relu(x)
|
||||
return x
|
||||
|
||||
|
||||
class ResNet(nn.Module):
|
||||
def __init__(self, block, layers, image_channels, num_classes):
|
||||
super(ResNet, self).__init__()
|
||||
self.in_channels = 64
|
||||
self.conv1 = nn.Conv2d(image_channels, 64, kernel_size=7, stride=2, padding=3)
|
||||
self.bn1 = nn.BatchNorm2d(64)
|
||||
self.relu = nn.ReLU()
|
||||
self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
|
||||
|
||||
# Essentially the entire ResNet architecture are in these 4 lines below
|
||||
self.layer1 = self._make_layer(
|
||||
block, layers[0], intermediate_channels=64, stride=1
|
||||
)
|
||||
self.layer2 = self._make_layer(
|
||||
block, layers[1], intermediate_channels=128, stride=2
|
||||
)
|
||||
self.layer3 = self._make_layer(
|
||||
block, layers[2], intermediate_channels=256, stride=2
|
||||
)
|
||||
self.layer4 = self._make_layer(
|
||||
block, layers[3], intermediate_channels=512, stride=2
|
||||
)
|
||||
|
||||
self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
|
||||
self.fc = nn.Linear(512 * 4, num_classes)
|
||||
|
||||
def forward(self, x):
|
||||
x = self.conv1(x)
|
||||
x = self.bn1(x)
|
||||
x = self.relu(x)
|
||||
x = self.maxpool(x)
|
||||
x = self.layer1(x)
|
||||
x = self.layer2(x)
|
||||
x = self.layer3(x)
|
||||
x = self.layer4(x)
|
||||
|
||||
x = self.avgpool(x)
|
||||
x = x.reshape(x.shape[0], -1)
|
||||
x = self.fc(x)
|
||||
|
||||
return x
|
||||
|
||||
def _make_layer(self, block, num_residual_blocks, intermediate_channels, stride):
|
||||
identity_downsample = None
|
||||
layers = []
|
||||
|
||||
# Either if we half the input space for ex, 56x56 -> 28x28 (stride=2), or channels changes
|
||||
# we need to adapt the Identity (skip connection) so it will be able to be added
|
||||
# to the layer that's ahead
|
||||
if stride != 1 or self.in_channels != intermediate_channels * 4:
|
||||
identity_downsample = nn.Sequential(
|
||||
nn.Conv2d(
|
||||
self.in_channels,
|
||||
intermediate_channels * 4,
|
||||
kernel_size=1,
|
||||
stride=stride,
|
||||
),
|
||||
nn.BatchNorm2d(intermediate_channels * 4),
|
||||
)
|
||||
|
||||
layers.append(
|
||||
block(self.in_channels, intermediate_channels, identity_downsample, stride)
|
||||
)
|
||||
|
||||
# The expansion size is always 4 for ResNet 50,101,152
|
||||
self.in_channels = intermediate_channels * 4
|
||||
|
||||
# For example for first resnet layer: 256 will be mapped to 64 as intermediate layer,
|
||||
# then finally back to 256. Hence no identity downsample is needed, since stride = 1,
|
||||
# and also same amount of channels.
|
||||
for i in range(num_residual_blocks - 1):
|
||||
layers.append(block(self.in_channels, intermediate_channels))
|
||||
|
||||
return nn.Sequential(*layers)
|
||||
|
||||
|
||||
def ResNet50(img_channel=3, num_classes=1000):
|
||||
return ResNet(block, [3, 4, 6, 3], img_channel, num_classes)
|
||||
|
||||
|
||||
def ResNet101(img_channel=3, num_classes=1000):
|
||||
return ResNet(block, [3, 4, 23, 3], img_channel, num_classes)
|
||||
|
||||
|
||||
def ResNet152(img_channel=3, num_classes=1000):
|
||||
return ResNet(block, [3, 8, 36, 3], img_channel, num_classes)
|
||||
|
||||
|
||||
def test():
|
||||
net = ResNet101(img_channel=3, num_classes=1000)
|
||||
y = net(torch.randn(4, 3, 224, 224)).to("cuda")
|
||||
print(y.size())
|
||||
|
||||
|
||||
test()
|
||||
119
ML/Pytorch/CNN_architectures/pytorch_vgg_implementation.py
Normal file
119
ML/Pytorch/CNN_architectures/pytorch_vgg_implementation.py
Normal file
@@ -0,0 +1,119 @@
|
||||
"""
|
||||
A from scratch implementation of the VGG architecture.
|
||||
|
||||
Video explanation: https://youtu.be/ACmuBbuXn20
|
||||
Got any questions leave a comment on youtube :)
|
||||
|
||||
Programmed by Aladdin Persson <aladdin.persson at hotmail dot com>
|
||||
* 2020-04-05 Initial coding
|
||||
|
||||
"""
|
||||
|
||||
# Imports
|
||||
import torch
|
||||
import torch.nn as nn # All neural network modules, nn.Linear, nn.Conv2d, BatchNorm, Loss functions
|
||||
|
||||
VGG_types = {
|
||||
"VGG11": [64, "M", 128, "M", 256, 256, "M", 512, 512, "M", 512, 512, "M"],
|
||||
"VGG13": [64, 64, "M", 128, 128, "M", 256, 256, "M", 512, 512, "M", 512, 512, "M"],
|
||||
"VGG16": [
|
||||
64,
|
||||
64,
|
||||
"M",
|
||||
128,
|
||||
128,
|
||||
"M",
|
||||
256,
|
||||
256,
|
||||
256,
|
||||
"M",
|
||||
512,
|
||||
512,
|
||||
512,
|
||||
"M",
|
||||
512,
|
||||
512,
|
||||
512,
|
||||
"M",
|
||||
],
|
||||
"VGG19": [
|
||||
64,
|
||||
64,
|
||||
"M",
|
||||
128,
|
||||
128,
|
||||
"M",
|
||||
256,
|
||||
256,
|
||||
256,
|
||||
256,
|
||||
"M",
|
||||
512,
|
||||
512,
|
||||
512,
|
||||
512,
|
||||
"M",
|
||||
512,
|
||||
512,
|
||||
512,
|
||||
512,
|
||||
"M",
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
class VGG_net(nn.Module):
|
||||
def __init__(self, in_channels=3, num_classes=1000):
|
||||
super(VGG_net, self).__init__()
|
||||
self.in_channels = in_channels
|
||||
self.conv_layers = self.create_conv_layers(VGG_types["VGG16"])
|
||||
|
||||
self.fcs = nn.Sequential(
|
||||
nn.Linear(512 * 7 * 7, 4096),
|
||||
nn.ReLU(),
|
||||
nn.Dropout(p=0.5),
|
||||
nn.Linear(4096, 4096),
|
||||
nn.ReLU(),
|
||||
nn.Dropout(p=0.5),
|
||||
nn.Linear(4096, num_classes),
|
||||
)
|
||||
|
||||
def forward(self, x):
|
||||
x = self.conv_layers(x)
|
||||
x = x.reshape(x.shape[0], -1)
|
||||
x = self.fcs(x)
|
||||
return x
|
||||
|
||||
def create_conv_layers(self, architecture):
|
||||
layers = []
|
||||
in_channels = self.in_channels
|
||||
|
||||
for x in architecture:
|
||||
if type(x) == int:
|
||||
out_channels = x
|
||||
|
||||
layers += [
|
||||
nn.Conv2d(
|
||||
in_channels=in_channels,
|
||||
out_channels=out_channels,
|
||||
kernel_size=(3, 3),
|
||||
stride=(1, 1),
|
||||
padding=(1, 1),
|
||||
),
|
||||
nn.BatchNorm2d(x),
|
||||
nn.ReLU(),
|
||||
]
|
||||
in_channels = x
|
||||
elif x == "M":
|
||||
layers += [nn.MaxPool2d(kernel_size=(2, 2), stride=(2, 2))]
|
||||
|
||||
return nn.Sequential(*layers)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
device = "cuda" if torch.cuda.is_available() else "cpu"
|
||||
model = VGG_net(in_channels=3, num_classes=1000).to(device)
|
||||
print(model)
|
||||
## N = 3 (Mini batch size)
|
||||
# x = torch.randn(3, 3, 224, 224).to(device)
|
||||
# print(model(x).shape)
|
||||
Reference in New Issue
Block a user