aayanb09 commited on
Commit
505efb2
·
verified ·
1 Parent(s): a4c3c03

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +30 -15
app.py CHANGED
@@ -12,12 +12,12 @@ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
12
  print(f"Using device: {device}")
13
 
14
  # -----------------------------
15
- # Model definition (same as training)
16
  # -----------------------------
17
  class FoodIngredientClassifier(nn.Module):
18
  def __init__(self, num_classes):
19
  super().__init__()
20
- self.backbone = models.resnet50(pretrained=False)
21
  num_features = self.backbone.fc.in_features
22
  self.backbone.fc = nn.Sequential(
23
  nn.Dropout(0.5),
@@ -31,7 +31,7 @@ class FoodIngredientClassifier(nn.Module):
31
  return self.backbone(x)
32
 
33
  # -----------------------------
34
- # Load checkpoint
35
  # -----------------------------
36
  checkpoint = torch.load(
37
  "best_model.pth",
@@ -39,7 +39,6 @@ checkpoint = torch.load(
39
  weights_only=False
40
  )
41
 
42
-
43
  mlb = checkpoint["mlb"]
44
  class_names = mlb.classes_
45
  num_classes = len(class_names)
@@ -70,11 +69,11 @@ def clean_name(name):
70
  return name.replace("_", " ").title()
71
 
72
  # -----------------------------
73
- # Prediction function
74
  # -----------------------------
75
- def predict(image, threshold=0.00005):
76
  if image is None:
77
- return {}
78
 
79
  if not isinstance(image, Image.Image):
80
  image = Image.fromarray(image)
@@ -86,10 +85,20 @@ def predict(image, threshold=0.00005):
86
  logits = model(input_tensor)
87
  probs = torch.sigmoid(logits).cpu().numpy()[0]
88
 
89
- results = {}
90
- for idx, prob in enumerate(probs):
91
- if prob >= threshold:
92
- results[clean_name(class_names[idx])] = float(prob)
 
 
 
 
 
 
 
 
 
 
93
 
94
  # Sort by confidence
95
  results = dict(sorted(results.items(), key=lambda x: x[1], reverse=True))
@@ -103,17 +112,23 @@ iface = gr.Interface(
103
  fn=predict,
104
  inputs=[
105
  gr.Image(type="pil", label="Upload Food Image"),
106
- gr.Slider(0.1, 0.9, value=0.5, step=0.05, label="Confidence Threshold")
 
 
 
 
 
 
107
  ],
108
  outputs=gr.JSON(label="Detected Ingredients"),
109
  title="Food Ingredient Detection (Multi-Label)",
110
  description=(
111
- "Upload a food image to detect **multiple ingredients at once**. "
112
- "This model is trained with multi-label classification using ResNet-50."
113
  ),
114
  theme=gr.themes.Soft(),
115
  allow_flagging="never"
116
  )
117
 
118
  if __name__ == "__main__":
119
- iface.launch()
 
12
  print(f"Using device: {device}")
13
 
14
  # -----------------------------
15
+ # Model definition (MATCHES TRAINING)
16
  # -----------------------------
17
  class FoodIngredientClassifier(nn.Module):
18
  def __init__(self, num_classes):
19
  super().__init__()
20
+ self.backbone = models.resnet50(weights=None)
21
  num_features = self.backbone.fc.in_features
22
  self.backbone.fc = nn.Sequential(
23
  nn.Dropout(0.5),
 
31
  return self.backbone(x)
32
 
33
  # -----------------------------
34
+ # Load checkpoint (PyTorch 2.6+ safe)
35
  # -----------------------------
36
  checkpoint = torch.load(
37
  "best_model.pth",
 
39
  weights_only=False
40
  )
41
 
 
42
  mlb = checkpoint["mlb"]
43
  class_names = mlb.classes_
44
  num_classes = len(class_names)
 
69
  return name.replace("_", " ").title()
70
 
71
  # -----------------------------
72
+ # Prediction function (BULLETPROOF)
73
  # -----------------------------
74
+ def predict(image, threshold):
75
  if image is None:
76
+ return {"error": "No image provided"}
77
 
78
  if not isinstance(image, Image.Image):
79
  image = Image.fromarray(image)
 
85
  logits = model(input_tensor)
86
  probs = torch.sigmoid(logits).cpu().numpy()[0]
87
 
88
+ # Threshold-based predictions
89
+ results = {
90
+ clean_name(class_names[i]): float(probs[i])
91
+ for i in range(len(probs))
92
+ if probs[i] >= threshold
93
+ }
94
+
95
+ # 🔒 Fallback: always return top 5
96
+ if not results:
97
+ top_idx = np.argsort(probs)[-5:][::-1]
98
+ results = {
99
+ clean_name(class_names[i]): float(probs[i])
100
+ for i in top_idx
101
+ }
102
 
103
  # Sort by confidence
104
  results = dict(sorted(results.items(), key=lambda x: x[1], reverse=True))
 
112
  fn=predict,
113
  inputs=[
114
  gr.Image(type="pil", label="Upload Food Image"),
115
+ gr.Slider(
116
+ minimum=0.00001,
117
+ maximum=0.5,
118
+ value=0.05,
119
+ step=0.01,
120
+ label="Confidence Threshold"
121
+ )
122
  ],
123
  outputs=gr.JSON(label="Detected Ingredients"),
124
  title="Food Ingredient Detection (Multi-Label)",
125
  description=(
126
+ "Upload a food image to detect **multiple ingredients at once**.\n\n"
127
+ "This is a **multi-label ResNet-50 model** using sigmoid outputs."
128
  ),
129
  theme=gr.themes.Soft(),
130
  allow_flagging="never"
131
  )
132
 
133
  if __name__ == "__main__":
134
+ iface.launch(enable_queue=True)