Shilpaj commited on
Commit
ebbea61
·
1 Parent(s): 73329bc

Debug: Issue with prediction

Browse files
Files changed (2) hide show
  1. app.py +45 -32
  2. inference.py +65 -54
app.py CHANGED
@@ -17,23 +17,34 @@ def load_model(model_path: str):
17
  """
18
  Load the model.
19
  """
20
- # Check if CUDA is available and set device
21
  device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
22
  print(f"Using device: {device}")
23
 
24
- # Load the pre-trained ResNet50 model
25
- model = models.resnet50(weights=None)
26
  model = model.to(device)
27
 
28
- # Load custom weights from a .pth file
29
  state_dict = torch.load(model_path, map_location=device)
30
-
31
- # Filter out unexpected keys
 
 
 
 
 
 
 
32
  filtered_state_dict = {k: v for k, v in state_dict['model_state_dict'].items() if k in model.state_dict()}
33
-
34
- # Load the filtered state dictionary into the model
35
  model.load_state_dict(filtered_state_dict, strict=False)
36
  model.eval()
 
 
 
 
 
37
  return model
38
 
39
 
@@ -41,8 +52,8 @@ def load_classes():
41
  """
42
  Load the classes.
43
  """
44
- # Get ImageNet class names from ResNet50 weights
45
- weights = models.ResNet50_Weights.IMAGENET1K_V2
46
  classes = weights.meta["categories"]
47
  return classes
48
 
@@ -53,7 +64,7 @@ def inference_wrapper(image, alpha, top_k, target_layer):
53
  """
54
  try:
55
  if image is None:
56
- return {"No image provided": 1.0}, None
57
 
58
  results = inference(
59
  image,
@@ -65,19 +76,21 @@ def inference_wrapper(image, alpha, top_k, target_layer):
65
  )
66
 
67
  if results is None:
68
- return {"Processing failed": 1.0}, None
69
 
70
  return results
71
 
72
- except Exception as e:
73
  error_msg = str(e)
74
  print(f"Error in inference: {error_msg}")
75
 
76
- # Handle GPU quota error specifically
77
- if "GPU quota" in error_msg:
78
- return {"GPU quota exceeded - Please try again later": 1.0}, None
79
 
80
- # Handle other errors
 
 
81
  return {"Error: " + error_msg: 1.0}, None
82
 
83
 
@@ -166,12 +179,12 @@ def main():
166
 
167
  # Examples section for Gradio 5.x
168
  examples = [
169
- [
170
- "assets/examples/dog.jpg",
171
- 0.5, # alpha slider
172
- 3, # top_k slider
173
- 4 # target_layer slider
174
- ],
175
  [
176
  "assets/examples/cat.jpg",
177
  0.5,
@@ -190,12 +203,12 @@ def main():
190
  3,
191
  4
192
  ],
193
- [
194
- "assets/examples/shark-plane.jpg",
195
- 0.5,
196
- 3,
197
- 4
198
- ],
199
  [
200
  "assets/examples/car.jpg",
201
  0.5,
@@ -241,14 +254,14 @@ def main():
241
  gradcam_output
242
  ],
243
  fn=inference_wrapper,
244
- cache_examples=True,
245
  label="Click on any example to run GradCAM"
246
  )
247
 
248
  # Queue configuration
249
- demo.queue(max_size=1)
250
 
251
- # Launch configuration
252
  demo.launch(
253
  server_name="0.0.0.0",
254
  server_port=7860,
 
17
  """
18
  Load the model.
19
  """
 
20
  device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
21
  print(f"Using device: {device}")
22
 
23
+ # Load the model with default weights first
24
+ model = models.resnet50(weights=models.ResNet50_Weights.IMAGENET1K_V1)
25
  model = model.to(device)
26
 
27
+ # Load custom weights
28
  state_dict = torch.load(model_path, map_location=device)
29
+
30
+ # Debug: Print state dict info
31
+ print("\nState dict keys:", list(state_dict['model_state_dict'].keys())[:5])
32
+ print("Model state dict keys:", list(model.state_dict().keys())[:5])
33
+
34
+ # Check if the final layer weights match
35
+ fc_weight_shape = state_dict['model_state_dict']['fc.weight'].shape
36
+ print(f"\nFC layer weight shape: {fc_weight_shape}")
37
+
38
  filtered_state_dict = {k: v for k, v in state_dict['model_state_dict'].items() if k in model.state_dict()}
39
+ print(f"Filtered state dict size: {len(filtered_state_dict)} / {len(state_dict['model_state_dict'])}")
40
+
41
  model.load_state_dict(filtered_state_dict, strict=False)
42
  model.eval()
43
+
44
+ # Verify model
45
+ print("\nModel architecture:")
46
+ print(model)
47
+
48
  return model
49
 
50
 
 
52
  """
53
  Load the classes.
54
  """
55
+ # Load classes from the same weights version as the model was trained with
56
+ weights = models.ResNet50_Weights.IMAGENET1K_V1 # Try V1 instead of V2
57
  classes = weights.meta["categories"]
58
  return classes
59
 
 
64
  """
65
  try:
66
  if image is None:
67
+ return {"Error": 1.0}, None
68
 
69
  results = inference(
70
  image,
 
76
  )
77
 
78
  if results is None:
79
+ return {"Error": 1.0}, None
80
 
81
  return results
82
 
83
+ except RuntimeError as e:
84
  error_msg = str(e)
85
  print(f"Error in inference: {error_msg}")
86
 
87
+ if "out of memory" in error_msg.lower():
88
+ return {"GPU Memory Error - Please try again": 1.0}, None
89
+ return {"Runtime Error: " + error_msg: 1.0}, None
90
 
91
+ except Exception as e:
92
+ error_msg = str(e)
93
+ print(f"Error in inference: {error_msg}")
94
  return {"Error: " + error_msg: 1.0}, None
95
 
96
 
 
179
 
180
  # Examples section for Gradio 5.x
181
  examples = [
182
+ # [
183
+ # "assets/examples/dog.jpg",
184
+ # 0.5, # alpha slider
185
+ # 3, # top_k slider
186
+ # 4 # target_layer slider
187
+ # ],
188
  [
189
  "assets/examples/cat.jpg",
190
  0.5,
 
203
  3,
204
  4
205
  ],
206
+ # [
207
+ # "assets/examples/shark-plane.jpg",
208
+ # 0.5,
209
+ # 3,
210
+ # 4
211
+ # ],
212
  [
213
  "assets/examples/car.jpg",
214
  0.5,
 
254
  gradcam_output
255
  ],
256
  fn=inference_wrapper,
257
+ cache_examples=False, # Disable caching to prevent memory issues
258
  label="Click on any example to run GradCAM"
259
  )
260
 
261
  # Queue configuration
262
+ demo.queue(max_size=1) # Only allow one job at a time
263
 
264
+ # Launch with minimal memory usage
265
  demo.launch(
266
  server_name="0.0.0.0",
267
  server_port=7860,
inference.py CHANGED
@@ -23,76 +23,87 @@ def inference(image, alpha, top_k, target_layer, model=None, classes=None):
23
  Run inference with GradCAM visualization
24
  """
25
  try:
 
 
 
 
26
  device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
27
 
28
  # Ensure model is on correct device and in eval mode
29
  model = model.to(device)
30
  model.eval()
31
 
32
- # Save a copy of input img
33
- org_img = image.copy()
 
 
34
 
35
- # Convert img to tensor and normalize it
36
- _transform = transforms.Compose([
37
- transforms.ToTensor(),
38
- transforms.Normalize(
39
- mean=[0.485, 0.456, 0.406],
40
- std=[0.229, 0.224, 0.225]
41
- )
42
- ])
43
 
44
- # Preprocess the input image and move to device
45
- input_tensor = _transform(image).to(device)
46
- input_tensor = input_tensor.unsqueeze(0)
47
- input_tensor.requires_grad = True
48
-
49
- # Get Model Predictions
50
- outputs = model(input_tensor)
51
- probabilities = torch.softmax(outputs, dim=1)[0]
52
- confidences = {classes[i]: float(probabilities[i]) for i in range(1000)}
53
 
54
- # Select the top classes based on user input
55
- sorted_confidences = sorted(confidences.items(), key=lambda val: val[1], reverse=True)
56
- show_confidences = OrderedDict(sorted_confidences[:top_k])
57
 
58
- # Map layer numbers to meaningful parts of the ResNet architecture
59
- _layers = {
60
- 1: model.conv1,
61
- 2: model.layer1[-1],
62
- 3: model.layer2[-1],
63
- 4: model.layer3[-1],
64
- 5: model.layer4[-1],
65
- 6: model.layer4[-1]
66
- }
67
 
68
- # Ensure valid layer selection
69
- target_layer = min(max(target_layer, 1), 6)
70
- target_layers = [_layers[target_layer]]
71
 
72
- # Get the class activations from the selected layer
73
- cam = GradCAM(model=model, target_layers=target_layers)
74
 
75
- # Get the most probable class index
76
- top_class = max(confidences.items(), key=lambda x: x[1])[0]
77
- class_idx = classes.index(top_class)
78
-
79
- # Generate GradCAM for the top predicted class
80
- grayscale_cam = cam(
81
- input_tensor=input_tensor,
82
- targets=[ClassifierOutputTarget(class_idx)],
83
- aug_smooth=False, # Disable augmentation for memory efficiency
84
- eigen_smooth=False # Disable eigen smoothing for memory efficiency
85
- )
86
- grayscale_cam = grayscale_cam[0, :]
87
 
88
- # Overlay input image with Class activations
89
- visualization = show_cam_on_image(org_img/255., grayscale_cam, use_rgb=True, image_weight=alpha)
90
-
91
- # Clear CUDA cache
 
 
 
 
 
 
92
  if torch.cuda.is_available():
93
  torch.cuda.empty_cache()
94
-
95
- return show_confidences, visualization
96
 
97
  except Exception as e:
98
  if torch.cuda.is_available():
 
23
  Run inference with GradCAM visualization
24
  """
25
  try:
26
+ # Clear CUDA cache before starting
27
+ if torch.cuda.is_available():
28
+ torch.cuda.empty_cache()
29
+
30
  device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
31
 
32
  # Ensure model is on correct device and in eval mode
33
  model = model.to(device)
34
  model.eval()
35
 
36
+ # Process with reduced precision to save memory
37
+ with torch.cuda.amp.autocast():
38
+ # Save a copy of input img
39
+ org_img = image.copy()
40
 
41
+ # Convert img to tensor and normalize it
42
+ _transform = transforms.Compose([
43
+ transforms.ToTensor(),
44
+ transforms.Normalize(
45
+ mean=[0.485, 0.456, 0.406],
46
+ std=[0.229, 0.224, 0.225]
47
+ )
48
+ ])
49
 
50
+ # Preprocess the input image and move to device
51
+ input_tensor = _transform(image).to(device)
52
+ input_tensor = input_tensor.unsqueeze(0)
53
+ input_tensor.requires_grad = True
54
+
55
+ # Get Model Predictions
56
+ outputs = model(input_tensor)
57
+ probabilities = torch.softmax(outputs, dim=1)[0]
58
+ confidences = {classes[i]: float(probabilities[i]) for i in range(1000)}
59
 
60
+ # Select the top classes based on user input
61
+ sorted_confidences = sorted(confidences.items(), key=lambda val: val[1], reverse=True)
62
+ show_confidences = OrderedDict(sorted_confidences[:top_k])
63
 
64
+ # Map layer numbers to meaningful parts of the ResNet architecture
65
+ _layers = {
66
+ 1: model.conv1,
67
+ 2: model.layer1[-1],
68
+ 3: model.layer2[-1],
69
+ 4: model.layer3[-1],
70
+ 5: model.layer4[-1],
71
+ 6: model.layer4[-1]
72
+ }
73
 
74
+ # Ensure valid layer selection
75
+ target_layer = min(max(target_layer, 1), 6)
76
+ target_layers = [_layers[target_layer]]
77
 
78
+ # Get the class activations from the selected layer
79
+ cam = GradCAM(model=model, target_layers=target_layers)
80
 
81
+ # Get the most probable class index
82
+ top_class = max(confidences.items(), key=lambda x: x[1])[0]
83
+ class_idx = classes.index(top_class)
84
+
85
+ # Generate GradCAM for the top predicted class
86
+ grayscale_cam = cam(
87
+ input_tensor=input_tensor,
88
+ targets=[ClassifierOutputTarget(class_idx)],
89
+ aug_smooth=False, # Disable augmentation for memory efficiency
90
+ eigen_smooth=False # Disable eigen smoothing for memory efficiency
91
+ )
92
+ grayscale_cam = grayscale_cam[0, :]
93
 
94
+ # Overlay input image with Class activations
95
+ visualization = show_cam_on_image(org_img/255., grayscale_cam, use_rgb=True, image_weight=alpha)
96
+
97
+ # Clear CUDA cache after processing
98
+ if torch.cuda.is_available():
99
+ torch.cuda.empty_cache()
100
+
101
+ return show_confidences, visualization
102
+
103
+ except torch.cuda.OutOfMemoryError:
104
  if torch.cuda.is_available():
105
  torch.cuda.empty_cache()
106
+ raise RuntimeError("GPU out of memory - Please try again with a smaller image")
 
107
 
108
  except Exception as e:
109
  if torch.cuda.is_available():