Ayush0110 commited on
Commit
5960711
·
verified ·
1 Parent(s): c07737e

Upload 13 files

Browse files
.gitattributes CHANGED
@@ -33,3 +33,9 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ data/cifar-10-batches-py/data_batch_1 filter=lfs diff=lfs merge=lfs -text
37
+ data/cifar-10-batches-py/data_batch_2 filter=lfs diff=lfs merge=lfs -text
38
+ data/cifar-10-batches-py/data_batch_3 filter=lfs diff=lfs merge=lfs -text
39
+ data/cifar-10-batches-py/data_batch_4 filter=lfs diff=lfs merge=lfs -text
40
+ data/cifar-10-batches-py/data_batch_5 filter=lfs diff=lfs merge=lfs -text
41
+ data/cifar-10-batches-py/test_batch filter=lfs diff=lfs merge=lfs -text
app.py ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import torch
3
+ import torch.nn as nn
4
+ import torchvision.transforms as transforms
5
+ from PIL import Image
6
+ import torch.nn.functional as F
7
+ import matplotlib.pyplot as plt
8
+ import numpy as np
9
+ import os
10
+
11
+ # ----------------- CLASS LABELS -----------------
12
+ CLASSES = [
13
+ "airplane", "automobile", "bird", "cat", "deer",
14
+ "dog", "frog", "horse", "ship", "truck"
15
+ ]
16
+
17
+ # ----------------- CNN MODEL (same as training) -----------------
18
+ class CNN(nn.Module):
19
+ def __init__(self):
20
+ super().__init__()
21
+ self.conv_layer = nn.Sequential(
22
+ nn.Conv2d(3, 32, kernel_size=3, padding=1),
23
+ nn.ReLU(),
24
+ nn.MaxPool2d(2, 2),
25
+
26
+ nn.Conv2d(32, 64, kernel_size=3, padding=1),
27
+ nn.ReLU(),
28
+ nn.MaxPool2d(2, 2)
29
+ )
30
+
31
+ self.fc_layer = nn.Sequential(
32
+ nn.Linear(64 * 8 * 8, 256),
33
+ nn.ReLU(),
34
+ nn.Linear(256, 10)
35
+ )
36
+
37
+ def forward(self, x):
38
+ x = self.conv_layer(x)
39
+ x = x.view(x.size(0), -1)
40
+ x = self.fc_layer(x)
41
+ return x
42
+
43
+ # ----------------- LOAD TRAINED MODEL -----------------
44
+ model = CNN()
45
+ import os
46
+ MODEL_PATH = os.path.join(os.getcwd(), "model.pth")
47
+ model.load_state_dict(torch.load(MODEL_PATH, map_location=torch.device('cpu')))
48
+
49
+ model.eval()
50
+
51
+ # ----------------- IMAGE TRANSFORMS -----------------
52
+ transform = transforms.Compose([
53
+ transforms.Resize((32, 32)),
54
+ transforms.ToTensor(),
55
+ transforms.Normalize((0.5,), (0.5,))
56
+ ])
57
+ # ----------------- GRAD CAM UTILS -----------------
58
+
59
+ # ----------------- CORRECT GRAD-CAM IMPLEMENTATION -----------------
60
+
61
+ # Store activations + gradients
62
+ activations = None
63
+ gradients = None
64
+
65
+ # Save forward activations
66
+ def save_activation(module, input, output):
67
+ global activations
68
+ activations = output
69
+
70
+ # Save backward gradients
71
+ def save_gradient(module, grad_input, grad_output):
72
+ global gradients
73
+ gradients = grad_output[0]
74
+
75
+
76
+ def generate_gradcam(model, image_tensor):
77
+ global activations, gradients
78
+
79
+ # Last conv layer
80
+ last_conv_layer = model.conv_layer[3] # Conv2d(32 → 64)
81
+
82
+ # Hook for forward activations
83
+ forward_handle = last_conv_layer.register_forward_hook(save_activation)
84
+
85
+ # Hook for backward gradients
86
+ backward_handle = last_conv_layer.register_backward_hook(save_gradient)
87
+
88
+ # Forward pass
89
+ output = model(image_tensor)
90
+ pred_class = output.argmax(dim=1)
91
+
92
+ # Backward pass
93
+ model.zero_grad()
94
+ output[0, pred_class].backward()
95
+
96
+ # Remove hooks
97
+ forward_handle.remove()
98
+ backward_handle.remove()
99
+
100
+ # Process gradients + activations
101
+ pooled_grads = torch.mean(gradients, dim=[0, 2, 3])
102
+ activation_maps = activations[0]
103
+
104
+ # Weight channels
105
+ for i in range(len(pooled_grads)):
106
+ activation_maps[i, :, :] *= pooled_grads[i]
107
+
108
+ heatmap = torch.mean(activation_maps, dim=0).detach().cpu().numpy()
109
+
110
+ # Normalize
111
+ heatmap = np.maximum(heatmap, 0)
112
+ heatmap = heatmap / np.max(heatmap)
113
+
114
+ return heatmap
115
+
116
+ def overlay_heatmap(img, heatmap):
117
+ heatmap = np.uint8(255 * heatmap)
118
+ heatmap = Image.fromarray(heatmap).resize(img.size, Image.BILINEAR)
119
+ heatmap = np.array(heatmap)
120
+
121
+ # Colorize heatmap
122
+ heatmap_color = plt.cm.jet(heatmap)[:, :, :3] * 255
123
+ heatmap_color = heatmap_color.astype(np.uint8)
124
+
125
+ # Overlay with original
126
+ img_np = np.array(img)
127
+ superimposed = (0.6 * heatmap_color + 0.4 * img_np).astype(np.uint8)
128
+
129
+ return Image.fromarray(superimposed)
130
+
131
+ # ----------------- STREAMLIT UI -----------------
132
+ st.title("🖼️ CIFAR-10 Image Classifier (CNN)")
133
+
134
+ uploaded_image = st.file_uploader("Upload an image", type=["jpg", "jpeg", "png"])
135
+
136
+ if uploaded_image:
137
+ image = Image.open(uploaded_image).convert("RGB")
138
+ st.image(image, caption="Uploaded Image", width=250)
139
+
140
+ img_tensor = transform(image).unsqueeze(0)
141
+
142
+ with torch.no_grad():
143
+ outputs = model(img_tensor)
144
+
145
+ # Apply softmax to get probabilities
146
+ probs = F.softmax(outputs, dim=1)[0]
147
+
148
+ # Get top-3 predictions
149
+ top3_prob, top3_idx = torch.topk(probs, 3)
150
+
151
+ st.write("### 🔍 Top Predictions:")
152
+ for i in range(3):
153
+ st.write(f"**{CLASSES[top3_idx[i]]}: {top3_prob[i].item()*100:.2f}%**")
154
+
155
+ # ----------------- BAR CHART -----------------
156
+ st.write("### 📊 Probability Distribution")
157
+
158
+ fig, ax = plt.subplots()
159
+ ax.bar(CLASSES, probs.tolist())
160
+ plt.xticks(rotation=45)
161
+ st.pyplot(fig)
162
+ # ----------------- GENERATE GRAD-CAM -----------------
163
+ heatmap = generate_gradcam(model, img_tensor)
164
+ cam_image = overlay_heatmap(image, heatmap)
165
+
166
+ st.write("### 🔥 Grad-CAM Heatmap")
167
+ st.image(cam_image, caption="Where the model is looking", use_column_width=True)
168
+
169
+
data/cifar-10-batches-py/batches.meta ADDED
Binary file (158 Bytes). View file
 
data/cifar-10-batches-py/data_batch_1 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:54636561a3ce25bd3e19253c6b0d8538147b0ae398331ac4a2d86c6d987368cd
3
+ size 31035704
data/cifar-10-batches-py/data_batch_2 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:766b2cef9fbc745cf056b3152224f7cf77163b330ea9a15f9392beb8b89bc5a8
3
+ size 31035320
data/cifar-10-batches-py/data_batch_3 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0f00d98ebfb30b3ec0ad19f9756dc2630b89003e10525f5e148445e82aa6a1f9
3
+ size 31035999
data/cifar-10-batches-py/data_batch_4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3f7bb240661948b8f4d53e36ec720d8306f5668bd0071dcb4e6c947f78e9682b
3
+ size 31035696
data/cifar-10-batches-py/data_batch_5 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d91802434d8376bbaeeadf58a737e3a1b12ac839077e931237e0dcd43adcb154
3
+ size 31035623
data/cifar-10-batches-py/readme.html ADDED
@@ -0,0 +1 @@
 
 
1
+ <meta HTTP-EQUIV="REFRESH" content="0; url=http://www.cs.toronto.edu/~kriz/cifar.html">
data/cifar-10-batches-py/test_batch ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f53d8d457504f7cff4ea9e021afcf0e0ad8e24a91f3fc42091b8adef61157831
3
+ size 31035526
data/cifar-10-python.tar.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6d958be074577803d12ecdefd02955f39262c83c16fe9348329d7fe0b5c001ce
3
+ size 170498071
model.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:20372faa89ed838d94fddbb2c548b87504e87c8f663542656585bb11b1367736
3
+ size 4286056
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ streamlit
2
+ torch
3
+ torchvision
4
+ pillow
5
+ matplotlib
6
+ numpy
train.py ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ import torch.optim as optim
4
+ import torchvision
5
+ import torchvision.transforms as transforms
6
+
7
+
8
+ # ----------------- TRANSFORMS -----------------
9
+ transform = transforms.Compose([
10
+ transforms.ToTensor(),
11
+ transforms.Normalize((0.5,), (0.5,))
12
+ ])
13
+
14
+
15
+ # ----------------- LOAD DATASET -----------------
16
+ train_set = torchvision.datasets.CIFAR10(
17
+ root="./data", train=True, download=True, transform=transform
18
+ )
19
+
20
+ test_set = torchvision.datasets.CIFAR10(
21
+ root="./data", train=False, download=True, transform=transform
22
+ )
23
+
24
+ train_loader = torch.utils.data.DataLoader(train_set, batch_size=64, shuffle=True)
25
+ test_loader = torch.utils.data.DataLoader(test_set, batch_size=64, shuffle=False)
26
+
27
+
28
+ # ----------------- BUILD CNN MODEL -----------------
29
+ class CNN(nn.Module):
30
+ def __init__(self):
31
+ super().__init__()
32
+ self.conv_layer = nn.Sequential(
33
+ nn.Conv2d(3, 32, kernel_size=3, padding=1),
34
+ nn.ReLU(),
35
+ nn.MaxPool2d(2, 2),
36
+
37
+ nn.Conv2d(32, 64, kernel_size=3, padding=1),
38
+ nn.ReLU(),
39
+ nn.MaxPool2d(2, 2)
40
+ )
41
+
42
+ self.fc_layer = nn.Sequential(
43
+ nn.Linear(64 * 8 * 8, 256),
44
+ nn.ReLU(),
45
+ nn.Linear(256, 10)
46
+ )
47
+
48
+ def forward(self, x):
49
+ x = self.conv_layer(x)
50
+ x = x.view(x.size(0), -1)
51
+ x = self.fc_layer(x)
52
+ return x
53
+
54
+
55
+ model = CNN()
56
+
57
+ criterion = nn.CrossEntropyLoss()
58
+ optimizer = optim.Adam(model.parameters(), lr=0.001)
59
+
60
+
61
+ # ----------------- TRAIN LOOP -----------------
62
+ for epoch in range(5):
63
+ running_loss = 0.0
64
+ for images, labels in train_loader:
65
+ optimizer.zero_grad()
66
+
67
+ outputs = model(images)
68
+ loss = criterion(outputs, labels)
69
+ loss.backward()
70
+ optimizer.step()
71
+
72
+ running_loss += loss.item()
73
+
74
+ print(f"Epoch {epoch+1}, Loss: {running_loss/len(train_loader)}")
75
+
76
+
77
+ # ----------------- SAVE MODEL -----------------
78
+ torch.save(model.state_dict(), "model.pth")
79
+ print("Model saved as model.pth")