Vasudevakrishna commited on
Commit
d250771
·
1 Parent(s): 1b7ed18

S13 added.

Browse files
README.md CHANGED
@@ -10,4 +10,10 @@ pinned: false
10
  license: mit
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
10
  license: mit
11
  ---
12
 
13
+ **Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
14
+
15
+ *Objective*: Get hands on woth hugging face and pytorch lightning, gradio.
16
+
17
+ Here we have trained CIFAR10 dataset with custom resnet.
18
+ We can visualize the results of classification using GradCAM and play around with them.
19
+ We can upload our own images and get the top classification results.
app.py ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch, torchvision
2
+ from torchvision import transforms
3
+ import numpy as np
4
+ import gradio as gr
5
+ from PIL import Image
6
+ from pytorch_grad_cam import GradCAM
7
+ from pytorch_grad_cam.utils.image import show_cam_on_image
8
+ from torch.utils.data import DataLoader
9
+ import itertools
10
+ import matplotlib.pyplot as plt
11
+ import utils as utils
12
+ from model import Net
13
+
14
+
15
+ model = Net()
16
+ model.load_state_dict(torch.load("model.pth", map_location=torch.device('cpu')), strict=False)
17
+ model.eval()
18
+
19
+ classes = ('plane', 'car', 'bird', 'cat', 'deer',
20
+ 'dog', 'frog', 'horse', 'ship', 'truck')
21
+
22
+ cifar_valid = utils.Cifar10SearchDataset('.', train=False, download=True, transform=utils.augmentation_custom_resnet())
23
+
24
+ inv_normalize = transforms.Normalize(
25
+ mean=[-0.50/0.23, -0.50/0.23, -0.50/0.23],
26
+ std=[1/0.23, 1/0.23, 1/0.23]
27
+ )
28
+
29
+ def inference(wants_gradcam, n_gradcam, target_layer_number, transparency, wants_misclassified, n_misclassified, input_img = None, n_top_classes=10):
30
+
31
+ if wants_gradcam:
32
+
33
+ outputs_inference_gc = []
34
+ cifar_valid_loader = DataLoader(cifar_valid, batch_size=1, shuffle = True)
35
+ count_gradcam = 1
36
+
37
+ for data, target in cifar_valid_loader:
38
+
39
+ data, target = data.to('cpu'), target.to('cpu')
40
+ if target_layer_number == '-2':
41
+ target_layers = [model.convblock31[0]]
42
+ elif target_layer_number == '-1':
43
+ target_layers = [model.convblock21[0]]
44
+
45
+ cam = GradCAM(model=model, target_layers=target_layers, use_cuda=False)
46
+ grayscale_cam = cam(input_tensor=data, targets=None)
47
+ grayscale_cam = grayscale_cam[0, :]
48
+
49
+ org_img = inv_normalize(data).squeeze(0).numpy()
50
+ org_img = np.transpose(org_img, (1, 2, 0))
51
+ visualization = np.array(show_cam_on_image(org_img, grayscale_cam, use_rgb=True, image_weight=transparency))
52
+ outputs_inference_gc.append(visualization)
53
+
54
+ count_gradcam += 1
55
+ if count_gradcam > n_gradcam:
56
+ break
57
+ else:
58
+ outputs_inference_gc = None
59
+
60
+ if wants_misclassified:
61
+ outputs_inference_mis = []
62
+
63
+ cifar_valid_loader = DataLoader(cifar_valid, batch_size=1, shuffle = True)
64
+ count_mis = 1
65
+
66
+ for data, target in cifar_valid_loader:
67
+
68
+ data, target = data.to('cpu'), target.to('cpu')
69
+
70
+ outputs = model(data)
71
+ softmax = torch.nn.Softmax(dim=0)
72
+ o = softmax(outputs.flatten())
73
+ confidences = {classes[i]: float(o[i]) for i in range(10)}
74
+ _, prediction = torch.max(outputs, 1)
75
+
76
+ if target.numpy()[0] != prediction.numpy()[0]:
77
+
78
+ count_mis += 1
79
+
80
+ org_img = inv_normalize(data).squeeze(0).numpy()
81
+ org_img = np.transpose(org_img, (1, 2, 0))
82
+
83
+ fig = plt.figure()
84
+ fig.add_subplot(111)
85
+
86
+ plt.imshow(org_img)
87
+ plt.title(f'Target: {classes[target.numpy()[0]]}\nPred: {classes[prediction.numpy()[0]]}')
88
+ plt.axis('off')
89
+
90
+ fig.canvas.draw()
91
+
92
+ fig_img = np.frombuffer(fig.canvas.tostring_rgb(), dtype=np.uint8)
93
+ fig_img = fig_img.reshape(fig.canvas.get_width_height()[::-1] + (3,))
94
+
95
+ plt.close(fig)
96
+
97
+ outputs_inference_mis.append(fig_img)
98
+
99
+ if count_mis > n_misclassified:
100
+ break
101
+
102
+ else:
103
+ outputs_inference_mis = None
104
+
105
+ if input_img is not None:
106
+ transform=utils.augmentation_custom_resnet('Valid')
107
+ org_img = input_img
108
+ input_img = transform(image=input_img)
109
+ input_img = input_img['image'].unsqueeze(0)
110
+ outputs = model(input_img)
111
+ softmax = torch.nn.Softmax(dim=0)
112
+ o = softmax(outputs.flatten())
113
+ confidences = {classes[i]: float(o[i]) for i in range(10)}
114
+ _, prediction = torch.max(outputs, 1)
115
+
116
+ confidences = {k: v for k, v in sorted(confidences.items(), key=lambda item: item[1], reverse=True)}
117
+ confidences = dict(itertools.islice(confidences.items(), n_top_classes))
118
+ else:
119
+ confidences = None
120
+
121
+
122
+ return outputs_inference_gc, outputs_inference_mis, confidences
123
+
124
+
125
+ title = "CIFAR10 trained on Custom ResNet Model with GradCAM"
126
+ description = "A Gradio interface to infer on Custom ResNet model, and to get GradCAM results"
127
+ examples = [[None, None, None, None, None, None, 'examples/gr_'+str(i)+'.jpg', None] for i in range(10)]
128
+
129
+ demo = gr.Interface(inference,
130
+ inputs = [gr.Checkbox(False, label='Do you want to see GradCAM outputs?'),
131
+ gr.Slider(0, 10, value = 0, step=1, label="How many?"),
132
+ gr.inputs.Dropdown([-2, -1], label="Which target layer?"),
133
+ gr.Slider(0, 1, value = 0, label="Opacity of GradCAM"),
134
+ gr.Checkbox(False, label='Do you want to see misclassified images?'),
135
+ gr.Slider(0, 10, value = 0, step=1, label="How many?"),
136
+ gr.Image(shape=(32, 32), label="Input image"),
137
+ gr.Slider(0, 10, value = 0, step=1, label="How many top classes you want to see?")
138
+ ],
139
+ outputs = [
140
+ gr.Gallery(label="GradCAM Outputs", show_label=True, elem_id="gallery").style(columns=[2], rows=[2], object_fit="contain", height="auto"),
141
+ gr.Gallery(label="Misclassified Images", show_label=True, elem_id="gallery").style(columns=[2], rows=[2], object_fit="contain", height="auto"),
142
+ gr.Label(num_top_classes=10, label = "Top classes")
143
+ ],
144
+ title = title,
145
+ description = description,
146
+ examples = examples
147
+ )
148
+ demo.launch()
examples/gr_0.jpg ADDED
examples/gr_1.jpg ADDED
examples/gr_2.jpg ADDED
examples/gr_3.jpg ADDED
examples/gr_4.jpg ADDED
examples/gr_5.jpg ADDED
examples/gr_6.jpg ADDED
examples/gr_7.jpg ADDED
examples/gr_8.jpg ADDED
examples/gr_9.jpg ADDED
model.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4d62f0ddc5b26c9683a7f0100912df3b927865b24421fa9307664d53b75a3fa8
3
+ size 26324147
model.py ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ import torch.nn.functional as F
4
+
5
+
6
+ class ResidualBlock(nn.Module):
7
+ def __init__(self, in_channels, out_channels):
8
+ super(ResidualBlock, self).__init__()
9
+ self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=1, padding=1, bias=False)
10
+ self.bn1 = nn.BatchNorm2d(out_channels)
11
+ self.relu = nn.ReLU()
12
+ self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1, bias=False)
13
+ self.bn2 = nn.BatchNorm2d(out_channels)
14
+
15
+
16
+ def forward(self, x):
17
+ out = self.conv1(x)
18
+ out = self.bn1(out)
19
+ out = self.relu(out)
20
+
21
+ out = self.conv2(out)
22
+ out = self.bn2(out)
23
+ out = self.relu(out)
24
+
25
+ return out
26
+
27
+ dropout_value = 0.01
28
+ class Net(nn.Module):
29
+ def __init__(self):
30
+ super(Net, self).__init__()
31
+ # Prep Layer
32
+ self.convblock01 = nn.Sequential(
33
+ nn.Conv2d(in_channels=3, out_channels=64, kernel_size=(3, 3), padding=1, bias=False),
34
+ nn.ReLU(),
35
+ nn.BatchNorm2d(64),
36
+ nn.Dropout(dropout_value))
37
+
38
+
39
+ # Layer 1
40
+ self.convblock11 = nn.Sequential(
41
+ nn.Conv2d(in_channels=64, out_channels=128, kernel_size=(3, 3), padding=1, bias=False),
42
+ nn.MaxPool2d((2,2)),
43
+ nn.BatchNorm2d(128),
44
+ nn.ReLU(),
45
+ nn.Dropout(dropout_value)
46
+ )
47
+
48
+ self.residual11 = ResidualBlock(in_channels = 128, out_channels = 128)
49
+
50
+
51
+ # Layer 2
52
+ self.convblock21 = nn.Sequential(
53
+ nn.Conv2d(in_channels=128, out_channels=256, kernel_size=(3, 3), padding=1, bias=False),
54
+ nn.MaxPool2d((2,2)),
55
+ nn.BatchNorm2d(256),
56
+ nn.ReLU(),
57
+ nn.Dropout(dropout_value)
58
+ )
59
+
60
+
61
+ # Layer 3
62
+ self.convblock31 = nn.Sequential(
63
+ nn.Conv2d(in_channels=256, out_channels=512, kernel_size=(3, 3), padding=1, bias=False),
64
+ nn.MaxPool2d((2,2)),
65
+ nn.BatchNorm2d(512),
66
+ nn.ReLU(),
67
+ nn.Dropout(dropout_value)
68
+ )
69
+
70
+ self.residual31 = ResidualBlock(in_channels = 512, out_channels = 512)
71
+
72
+ self.pool = nn.MaxPool2d((4,4))
73
+
74
+ ## Fully Connected Layer
75
+ self.fc = nn.Linear(512, 10)
76
+
77
+ def forward(self, x):
78
+ x1 = self.convblock01(x)
79
+ x2 = self.convblock11(x1)
80
+ x3 = x2 + self.residual11(x2)
81
+ x4 = self.convblock21(x3)
82
+ x5 = self.convblock31(x4)
83
+ x6 = x5 + self.residual31(x5)
84
+ x = self.pool(x6)
85
+ x = x.view(-1, 512)
86
+ x = self.fc(x)
87
+ return x
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ torch
2
+ torchvision
3
+ torch-lr-finder
4
+ grad-cam
5
+ pillow
6
+ numpy
7
+ albumentations
utils.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # utils file
2
+
3
+ import matplotlib.pyplot as plt
4
+ import torch
5
+ from torchvision import transforms
6
+ import torchvision
7
+ import numpy as np
8
+ import albumentations as A
9
+ from albumentations.pytorch.transforms import ToTensorV2
10
+
11
+ class Cifar10SearchDataset(torchvision.datasets.CIFAR10):
12
+
13
+ def __init__(self, root="./data", train=True, download=True, transform=None):
14
+ super().__init__(root=root, train=train, download=download, transform=transform)
15
+
16
+ def __getitem__(self, index):
17
+ image, label = self.data[index], self.targets[index]
18
+
19
+ if self.transform is not None:
20
+ transformed = self.transform(image=image)
21
+ image = transformed["image"]
22
+
23
+ return image, label
24
+
25
+ def augmentation_custom_resnet(mean=(0.4914, 0.4822, 0.4465), std=(0.2470, 0.2435, 0.2616), pad=4):
26
+
27
+ transform = A.Compose([A.Normalize(mean=mean, std=std),
28
+ ToTensorV2()])
29
+
30
+ return transform