nssharmaofficial commited on
Commit
3bdf51a
·
1 Parent(s): 702d527

Add source code and saved weights

Browse files
source/model.py ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch.nn as nn
2
+ import torch.nn.functional as F
3
+ from dataset import get_paths, get_data_loader, Dataset
4
+ from setup import Setup
5
+
6
+
7
+ class CNN(nn.Module):
8
+ """
9
+ Convolutional Neural Network (CNN) for classifying 'normal' and 'red' eye images.
10
+
11
+ The network consists of four convolutional layers followed by two fully connected layers.
12
+ Each convolutional layer is followed by batch normalization and a LeakyReLU activation function.
13
+ A dropout layer is added before the final fully connected layer to prevent overfitting.
14
+
15
+ Attributes:
16
+ conv1 (nn.Sequential): First convolutional layer block.
17
+ conv2 (nn.Sequential): Second convolutional layer block.
18
+ conv3 (nn.Sequential): Third convolutional layer block.
19
+ conv4 (nn.Sequential): Fourth convolutional layer block.
20
+ fc1 (nn.Linear): First fully connected layer.
21
+ fc2 (nn.Linear): Second fully connected layer (output layer).
22
+ dropout (nn.Dropout): Dropout layer with a probability of 0.5.
23
+ """
24
+ def __init__(self):
25
+ super(CNN, self).__init__()
26
+ self.conv1 = nn.Sequential(
27
+ nn.Conv2d(3, 8, 4, stride=2, padding=1),
28
+ nn.BatchNorm2d(8),
29
+ nn.LeakyReLU(0.2, inplace=True)
30
+ )
31
+ self.conv2 = nn.Sequential(
32
+ nn.Conv2d(8, 16, 4, stride=2, padding=1),
33
+ nn.BatchNorm2d(16),
34
+ nn.LeakyReLU(0.2, inplace=True)
35
+ )
36
+ self.conv3 = nn.Sequential(
37
+ nn.Conv2d(16, 32, 4, stride=2, padding=1),
38
+ nn.BatchNorm2d(32),
39
+ nn.LeakyReLU(0.2, inplace=True)
40
+ )
41
+ self.conv4 = nn.Sequential(
42
+ nn.Conv2d(32, 64, 4, stride=2, padding=1),
43
+ nn.BatchNorm2d(64),
44
+ nn.LeakyReLU(0.2, inplace=True)
45
+ )
46
+ self.fc1 = nn.Linear(64 * 2 * 2, 32)
47
+ self.fc2 = nn.Linear(32, 2)
48
+ self.dropout = nn.Dropout(0.5)
49
+
50
+ def forward(self, x):
51
+ """
52
+ Defines the forward pass of the CNN.
53
+
54
+ Args:
55
+ x (torch.Tensor): Input tensor of shape (batch_size, 3, 32, 32).
56
+
57
+ Returns:
58
+ torch.Tensor: Output tensor of shape (batch_size, 2).
59
+ """
60
+ # print('\nOriginal: ', x.size())
61
+ x = self.conv1(x)
62
+ # print('Conv1: ', x.size())
63
+ x = self.conv2(x)
64
+ # print('Conv2: ', x.size())
65
+ x = self.conv3(x)
66
+ # print('Conv3: ', x.size())
67
+ x = self.conv4(x)
68
+ # print('Conv4: ', x.size())
69
+
70
+ x = x.view(x.size(0), -1)
71
+
72
+ x = F.leaky_relu(self.fc1(x))
73
+ x = self.dropout(x)
74
+ x = self.fc2(x)
75
+ # print('Out: ', x.size())
76
+ return F.log_softmax(x, dim=1)
77
+
78
+ if __name__ == '__main__':
79
+ """
80
+ Main script to initialize the setup, load datasets, create DataLoader,
81
+ instantiate the CNN model, and display the number of trainable parameters
82
+ and the output size for a batch of images.
83
+ """
84
+
85
+ setup = Setup()
86
+
87
+ normal_train_paths, red_train_paths, normal_test_paths, red_test_paths = get_paths()
88
+
89
+ train_dataset = Dataset(red_train_paths, normal_train_paths)
90
+ train_loader = get_data_loader(train_dataset, batch_size=setup.BATCH)
91
+
92
+ imgs, labels = next(iter(train_loader))
93
+
94
+ cnn = CNN()
95
+ print(f'Number of trainable parameters in CNN: {sum(p.numel() for p in cnn.parameters() if p.requires_grad)}')
96
+ output = cnn.forward(imgs)
97
+
98
+ # Print info
99
+ print('\nBatch size: ', setup.BATCH)
100
+ print('Images size: ', imgs.size()) # (batch, 3, 32, 32)
101
+ print('CNN output size: ', output.size()) # (batch, 2)
source/predict_sample.py ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from torchvision import transforms
2
+ import torch
3
+ import torch.utils.data
4
+ from PIL import Image
5
+ from source.model import CNN
6
+
7
+
8
+ def classify_eye(image: torch.Tensor,
9
+ model: CNN) -> str:
10
+ """
11
+ Generate caption of a single image of size (3, 224, 224).
12
+ Generating of caption starts with <sos>, and each next predicted word ID
13
+ is appended for the next LSTM input until the sentence reaches MAX_LENGTH or <eos>.
14
+
15
+ Returns:
16
+ list[str]: caption for given image
17
+ """
18
+
19
+ # image: (3, 32, 32)
20
+ image = image.unsqueeze(0)
21
+ # image: (1, 3, 32, 32)
22
+
23
+ output = model.forward(image)
24
+ _, prediction = torch.max(output, dim=1)
25
+
26
+ if prediction == 0:
27
+ output = 'Normal'
28
+ elif prediction == 1:
29
+ output = 'Red'
30
+
31
+ return output
32
+
33
+ def main_classification(image):
34
+
35
+ image = Image.fromarray(image.astype('uint8'), 'RGB')
36
+
37
+ transform = transforms.Compose([
38
+ transforms.Resize((32, 32)),
39
+ transforms.ToTensor(),
40
+ transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
41
+ ])
42
+ image = transform(image)
43
+ image = image.to(torch.device("cpu"))
44
+
45
+ cnn = CNN().to(torch.device("cpu"))
46
+ cnn.eval()
47
+
48
+ cnn.load_state_dict(torch.load(f='weights/CNN-B8-LR-0.01-E30.pt', map_location=torch.device("cpu")))
49
+
50
+ prediction_outcome = classify_eye(image, cnn)
51
+
52
+ return prediction_outcome
source/weights/CNN-B8-LR-0.01-E30.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f9fb3f4e01f9420578b5e55c4975a5a5b3574e1b54d15d448ca9120a244eba9f
3
+ size 219842