Umer78786 commited on
Commit
df039cf
Β·
verified Β·
1 Parent(s): 60f715f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +27 -28
app.py CHANGED
@@ -3,7 +3,6 @@ import tensorflow as tf
3
  import numpy as np
4
  import json
5
  from tensorflow.keras.preprocessing.image import img_to_array
6
- from tensorflow.keras.applications.vgg16 import preprocess_input
7
  from PIL import Image
8
  import re
9
 
@@ -14,7 +13,6 @@ def clean_class_name(raw_name):
14
  and 'pear_1' to 'Pear'.
15
  """
16
  # Remove the trailing underscore and number (e.g., '_1', '_2')
17
- # Using regex to remove '_' followed by digits at the end
18
  cleaned = re.sub(r'_\d+$', '', raw_name)
19
  # Replace underscores with spaces
20
  cleaned = cleaned.replace('_', ' ')
@@ -25,7 +23,7 @@ def clean_class_name(raw_name):
25
  # ---------- Load the Model (.keras format) ----------
26
  model_path = 'fruits_classifier.keras'
27
  model = tf.keras.models.load_model(model_path)
28
- print("Model loaded successfully!")
29
 
30
  # ---------- Load Class Names ----------
31
  with open('class_indices.json', 'r') as f:
@@ -33,46 +31,46 @@ with open('class_indices.json', 'r') as f:
33
 
34
  # Convert dictionary to a list for easy index-based access
35
  class_names_list = [class_names_dict[str(i)] for i in range(len(class_names_dict))]
 
36
 
37
- # ---------- Create a list of cleaned class names for display ----------
38
- # Format: ["Apple Red", "Apple Braeburn", "Cucumber", ...]
39
- cleaned_class_names = [clean_class_name(name) for name in class_names_list]
40
- print(f"Total classes loaded: {len(cleaned_class_names)}")
41
-
42
- # ---------- Prediction Function ----------
43
  def predict_image(image):
44
  """
45
- Takes an input image, preprocesses it for VGG16, runs inference,
46
- and returns the predicted class name and confidence.
 
 
47
  """
48
- # Resize image to match the model's input shape (64x64)
49
  img = image.resize((64, 64))
50
- # Convert PIL image to numpy array
 
51
  img_array = img_to_array(img)
52
- # Add batch dimension (1, 64, 64, 3)
 
 
 
 
 
53
  img_array = np.expand_dims(img_array, axis=0)
54
- # Apply VGG16-specific preprocessing (scaling and mean subtraction)
55
- img_array = preprocess_input(img_array)
56
 
57
- # Run inference
58
- predictions = model.predict(img_array)
59
  predicted_index = np.argmax(predictions, axis=-1)[0]
60
  confidence = np.max(predictions, axis=-1)[0]
61
 
62
- # Get the raw class name
63
  raw_class_name = class_names_list[predicted_index]
64
- # Clean the class name for display
65
  predicted_class = clean_class_name(raw_class_name)
66
  confidence_percentage = float(confidence) * 100
67
 
68
  return predicted_class, f"{confidence_percentage:.2f}%"
69
 
70
- # ---------- Create a formatted list of categories for display ----------
71
- # Format: "Apple, Apple Braeburn, Apple Crimson Snow, ..."
72
- categories_list = sorted(cleaned_class_names) # Sort alphabetically
73
- categories_text = ", ".join(categories_list) # Join with commas
74
 
75
- # Create the description with categories
76
  description_text = f"""
77
  ### 🍎 Upload an image of a fruit.
78
 
@@ -82,10 +80,11 @@ description_text = f"""
82
 
83
  ---
84
 
85
- *Model: VGG16-based Transfer Learning trained on Fruits-360 dataset.*
 
86
  """
87
 
88
- # ---------- Gradio Interface Setup ----------
89
  interface = gr.Interface(
90
  fn=predict_image,
91
  inputs=gr.Image(type="pil", label="Upload Fruit Image"),
@@ -97,6 +96,6 @@ interface = gr.Interface(
97
  description=description_text,
98
  )
99
 
100
- # ---------- Launch the App ----------
101
  if __name__ == "__main__":
102
  interface.launch()
 
3
  import numpy as np
4
  import json
5
  from tensorflow.keras.preprocessing.image import img_to_array
 
6
  from PIL import Image
7
  import re
8
 
 
13
  and 'pear_1' to 'Pear'.
14
  """
15
  # Remove the trailing underscore and number (e.g., '_1', '_2')
 
16
  cleaned = re.sub(r'_\d+$', '', raw_name)
17
  # Replace underscores with spaces
18
  cleaned = cleaned.replace('_', ' ')
 
23
  # ---------- Load the Model (.keras format) ----------
24
  model_path = 'fruits_classifier.keras'
25
  model = tf.keras.models.load_model(model_path)
26
+ print("βœ… Model loaded successfully!")
27
 
28
  # ---------- Load Class Names ----------
29
  with open('class_indices.json', 'r') as f:
 
31
 
32
  # Convert dictionary to a list for easy index-based access
33
  class_names_list = [class_names_dict[str(i)] for i in range(len(class_names_dict))]
34
+ print(f"βœ… Total classes loaded: {len(class_names_list)}")
35
 
36
+ # ---------- Prediction Function (Matches Training Preprocessing) ----------
 
 
 
 
 
37
  def predict_image(image):
38
  """
39
+ Preprocessing exactly matches training:
40
+ - Resize to (64, 64)
41
+ - Rescale by 1.0/255.0 (same as ImageDataGenerator rescale)
42
+ - NO preprocess_input (VGG16 mean subtraction) because training didn't use it
43
  """
44
+ # Step 1: Resize image to (64, 64) - matches target_size in training
45
  img = image.resize((64, 64))
46
+
47
+ # Step 2: Convert PIL image to numpy array
48
  img_array = img_to_array(img)
49
+
50
+ # Step 3: Rescale pixel values to [0, 1]
51
+ # This matches: rescale=1.0/255.0 in ImageDataGenerator
52
+ img_array = img_array / 255.0
53
+
54
+ # Step 4: Add batch dimension (1, 64, 64, 3)
55
  img_array = np.expand_dims(img_array, axis=0)
 
 
56
 
57
+ # Step 5: Run inference (same as model.predict in notebook)
58
+ predictions = model.predict(img_array, verbose=0)
59
  predicted_index = np.argmax(predictions, axis=-1)[0]
60
  confidence = np.max(predictions, axis=-1)[0]
61
 
62
+ # Step 6: Get the raw class name and clean it for display
63
  raw_class_name = class_names_list[predicted_index]
 
64
  predicted_class = clean_class_name(raw_class_name)
65
  confidence_percentage = float(confidence) * 100
66
 
67
  return predicted_class, f"{confidence_percentage:.2f}%"
68
 
69
+ # ---------- Create Categories List for Display ----------
70
+ cleaned_class_names = [clean_class_name(name) for name in class_names_list]
71
+ categories_list = sorted(cleaned_class_names)
72
+ categories_text = ", ".join(categories_list)
73
 
 
74
  description_text = f"""
75
  ### 🍎 Upload an image of a fruit.
76
 
 
80
 
81
  ---
82
 
83
+ *Model: VGG16-based Transfer Learning*
84
+ *Input size: 64x64 | Preprocessing: Rescale to [0, 1]*
85
  """
86
 
87
+ # ---------- Gradio Interface ----------
88
  interface = gr.Interface(
89
  fn=predict_image,
90
  inputs=gr.Image(type="pil", label="Upload Fruit Image"),
 
96
  description=description_text,
97
  )
98
 
99
+ # ---------- Launch ----------
100
  if __name__ == "__main__":
101
  interface.launch()