arpit-gour02 commited on
Commit
5045b6c
·
1 Parent(s): 493925a

more examples

Browse files
.DS_Store CHANGED
Binary files a/.DS_Store and b/.DS_Store differ
 
examples/.DS_Store CHANGED
Binary files a/examples/.DS_Store and b/examples/.DS_Store differ
 
examples/20251226_205217.jpg ADDED

Git LFS Details

  • SHA256: 058d994c0c2816f9cd94e924787f9e691fe169ab32ee0d03b4aa78242561d4cf
  • Pointer size: 132 Bytes
  • Size of remote file: 2.54 MB
examples/{resume2.png → 29961.png} RENAMED
File without changes
examples/IMG20251226152516.jpg ADDED

Git LFS Details

  • SHA256: 16156ee169bf21f6e1627926ad3955aa9735aca310904e862a037cb50804423e
  • Pointer size: 132 Bytes
  • Size of remote file: 3.71 MB
examples/IMG20251226154706.jpg ADDED

Git LFS Details

  • SHA256: 1448dfd431edc3d8c2574b1a988b59c93c92600a8eb439b7cdff6325c9b46631
  • Pointer size: 133 Bytes
  • Size of remote file: 12.4 MB
examples/IMG20251226154713.jpg ADDED

Git LFS Details

  • SHA256: 791576a4a7686e35ea9f50f91de89378c682b47d43c9988b81839e37924ace12
  • Pointer size: 133 Bytes
  • Size of remote file: 12.8 MB
examples/IMG20251226154719.jpg ADDED

Git LFS Details

  • SHA256: fac59914dea550060d6b641bf167b132493b063b482744175e04d800ed3e8ac3
  • Pointer size: 133 Bytes
  • Size of remote file: 10.4 MB
examples/IMG20251226154735.jpg ADDED

Git LFS Details

  • SHA256: c9ff26bfe593fc08730256492a0b1016eda4779a1cc2c1af9a368381e29c075c
  • Pointer size: 133 Bytes
  • Size of remote file: 11.8 MB
examples/article-1.png ADDED

Git LFS Details

  • SHA256: cbf220eb2e239e0c52cb7f50999cfed0a5ba1e60bbd284f4f6c512d17facd412
  • Pointer size: 131 Bytes
  • Size of remote file: 256 kB
explainability.py ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ from torchvision import transforms
4
+ from PIL import Image
5
+ import numpy as np
6
+ import cv2
7
+ import os
8
+
9
+ # 1. RE-DEFINE THE MODEL
10
+ # ---------------------------------------------------------
11
+ class BottleneckBlock(nn.Module):
12
+ expansion = 4
13
+ def __init__(self, in_channels, mid_channels, stride=1):
14
+ super(BottleneckBlock, self).__init__()
15
+ out_channels = mid_channels * self.expansion
16
+ self.conv1 = nn.Conv2d(in_channels, mid_channels, kernel_size=1, bias=False)
17
+ self.bn1 = nn.BatchNorm2d(mid_channels)
18
+ self.conv2 = nn.Conv2d(mid_channels, mid_channels, kernel_size=3, stride=stride, padding=1, bias=False)
19
+ self.bn2 = nn.BatchNorm2d(mid_channels)
20
+ self.conv3 = nn.Conv2d(mid_channels, out_channels, kernel_size=1, bias=False)
21
+ self.bn3 = nn.BatchNorm2d(out_channels)
22
+ self.relu = nn.ReLU(inplace=True)
23
+ self.shortcut = nn.Sequential()
24
+ if stride != 1 or in_channels != out_channels:
25
+ self.shortcut = nn.Sequential(
26
+ nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride, bias=False),
27
+ nn.BatchNorm2d(out_channels)
28
+ )
29
+
30
+ def forward(self, x):
31
+ identity = x
32
+ out = self.conv1(x)
33
+ out = self.bn1(out)
34
+ out = self.relu(out)
35
+ out = self.conv2(out)
36
+ out = self.bn2(out)
37
+ out = self.relu(out)
38
+ out = self.conv3(out)
39
+ out = self.bn3(out)
40
+ identity = self.shortcut(identity)
41
+ out += identity
42
+ out = self.relu(out)
43
+ return out
44
+
45
+ class ResNet50(nn.Module):
46
+ def __init__(self, num_classes=16, channels_img=3):
47
+ super(ResNet50, self).__init__()
48
+ self.in_channels = 64
49
+ self.conv1 = nn.Conv2d(channels_img, 64, kernel_size=7, stride=2, padding=3, bias=False)
50
+ self.bn1 = nn.BatchNorm2d(64)
51
+ self.relu = nn.ReLU(inplace=True)
52
+ self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
53
+ self.layer1 = self._make_layer(mid_channels=64, num_blocks=3, stride=1)
54
+ self.layer2 = self._make_layer(mid_channels=128, num_blocks=4, stride=2)
55
+ self.layer3 = self._make_layer(mid_channels=256, num_blocks=6, stride=2)
56
+ self.layer4 = self._make_layer(mid_channels=512, num_blocks=3, stride=2)
57
+ self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
58
+ self.fc = nn.Linear(512 * 4, num_classes)
59
+
60
+ def _make_layer(self, mid_channels, num_blocks, stride):
61
+ layers = []
62
+ layers.append(BottleneckBlock(self.in_channels, mid_channels, stride))
63
+ self.in_channels = mid_channels * 4
64
+ for _ in range(num_blocks - 1):
65
+ layers.append(BottleneckBlock(self.in_channels, mid_channels, stride=1))
66
+ return nn.Sequential(*layers)
67
+
68
+ def forward(self, x):
69
+ x = self.conv1(x)
70
+ x = self.bn1(x)
71
+ x = self.relu(x)
72
+ x = self.maxpool(x)
73
+ x = self.layer1(x)
74
+ x = self.layer2(x)
75
+ x = self.layer3(x)
76
+ x = self.layer4(x)
77
+ x = self.avgpool(x)
78
+ x = torch.flatten(x, 1)
79
+ x = self.fc(x)
80
+ return x
81
+
82
+ # 2. GRAD-CAM LOGIC
83
+ # ---------------------------------------------------------
84
+ class GradCAM:
85
+ def __init__(self, model, target_layer):
86
+ self.model = model
87
+ self.target_layer = target_layer
88
+ self.gradients = None
89
+ self.activations = None
90
+
91
+ target_layer.register_forward_hook(self.save_activation)
92
+ target_layer.register_full_backward_hook(self.save_gradient)
93
+
94
+ def save_activation(self, module, input, output):
95
+ self.activations = output
96
+
97
+ def save_gradient(self, module, grad_input, grad_output):
98
+ self.gradients = grad_output[0]
99
+
100
+ def __call__(self, x, class_idx=None):
101
+ output = self.model(x)
102
+ if class_idx is None:
103
+ class_idx = torch.argmax(output, dim=1)
104
+
105
+ self.model.zero_grad()
106
+ score = output[0, class_idx]
107
+ score.backward()
108
+
109
+ gradients = self.gradients.data.numpy()[0]
110
+ activations = self.activations.data.numpy()[0]
111
+ weights = np.mean(gradients, axis=(1, 2))
112
+
113
+ cam = np.zeros(activations.shape[1:], dtype=np.float32)
114
+ for i, w in enumerate(weights):
115
+ cam += w * activations[i]
116
+
117
+ cam = np.maximum(cam, 0)
118
+ cam = cv2.resize(cam, (224, 224))
119
+ cam = cam - np.min(cam)
120
+ if np.max(cam) != 0:
121
+ cam = cam / np.max(cam)
122
+ return cam, int(class_idx)
123
+
124
+ # 3. RUN IT
125
+ # ---------------------------------------------------------
126
+ model = ResNet50(num_classes=16)
127
+
128
+ # FIXED: Ensure we point to the file in the root directory
129
+ checkpoint_path = "resnet50_epoch_4.pth"
130
+
131
+ if not os.path.exists(checkpoint_path):
132
+ print(f"CRITICAL ERROR: '{checkpoint_path}' not found in {os.getcwd()}")
133
+ exit()
134
+
135
+ try:
136
+ print(f"Loading model from: {checkpoint_path}")
137
+
138
+ # --- THE FIX IS HERE: weights_only=False ---
139
+ checkpoint = torch.load(checkpoint_path, map_location='cpu', weights_only=False)
140
+
141
+ if isinstance(checkpoint, dict) and 'state_dict' in checkpoint:
142
+ model.load_state_dict(checkpoint['state_dict'])
143
+ else:
144
+ model.load_state_dict(checkpoint)
145
+ print("Model loaded successfully.")
146
+ except Exception as e:
147
+ print(f"Error loading weights: {e}")
148
+ exit()
149
+
150
+ model.eval()
151
+
152
+ # Hook into the last convolutional layer
153
+ target_layer = model.layer4[2].conv3
154
+ grad_cam = GradCAM(model, target_layer)
155
+
156
+ # --- IMAGE LOADING ---
157
+ image_path = "examples/email.png"
158
+
159
+ if not os.path.exists(image_path):
160
+ print(f"Error: Image '{image_path}' not found. Please check the path.")
161
+ exit()
162
+
163
+ original_image = Image.open(image_path).convert('RGB')
164
+ preprocess = transforms.Compose([
165
+ transforms.Resize((224, 224)),
166
+ transforms.ToTensor(),
167
+ transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
168
+ ])
169
+ input_tensor = preprocess(original_image).unsqueeze(0)
170
+
171
+ # Generate
172
+ heatmap, class_id = grad_cam(input_tensor)
173
+
174
+ class_names = [
175
+ 'advertisement', 'budget', 'email', 'file folder', 'form', 'handwritten',
176
+ 'invoice', 'letter', 'memo', 'news article', 'presentation', 'questionnaire',
177
+ 'resume', 'scientific publication', 'scientific report', 'specification'
178
+ ]
179
+ predicted_label = class_names[class_id]
180
+
181
+ # Save
182
+ heatmap = np.uint8(255 * heatmap)
183
+ heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
184
+ original_cv = cv2.cvtColor(np.array(original_image.resize((224, 224))), cv2.COLOR_RGB2BGR)
185
+ superimposed = cv2.addWeighted(original_cv, 0.6, heatmap, 0.4, 0)
186
+
187
+ output_filename = "gradcam_result.jpg"
188
+ cv2.imwrite(output_filename, superimposed)
189
+ print(f"SUCCESS! Visualization saved to {output_filename}")
190
+ print(f"Model Predicted: {predicted_label}")