Update app.py

#12
by Muthuraja18 - opened
Files changed (1) hide show
  1. app.py +73 -70
app.py CHANGED
@@ -1,7 +1,7 @@
1
  import streamlit as st
2
  import tensorflow as tf
3
  from tensorflow.keras.preprocessing.image import ImageDataGenerator
4
- from tensorflow.keras.models import Sequential
5
  from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout
6
  import numpy as np
7
  from PIL import Image, UnidentifiedImageError
@@ -12,6 +12,7 @@ import os
12
  # -----------------------------
13
  DATASET_DIR = "dataset-resized"
14
  MODEL_PATH = "waste_classifier.h5"
 
15
  IMG_SIZE = (128, 128)
16
  BATCH_SIZE = 16
17
  EPOCHS = 5
@@ -25,7 +26,7 @@ st.set_page_config(
25
  )
26
 
27
  # -----------------------------
28
- # REMOVE CORRUPTED IMAGES
29
  # -----------------------------
30
  def clean_dataset(dataset_path):
31
  valid_extensions = (".jpg", ".jpeg", ".png")
@@ -46,7 +47,7 @@ def clean_dataset(dataset_path):
46
  try:
47
  with Image.open(file_path) as img:
48
  img.verify()
49
- except (UnidentifiedImageError, OSError):
50
  try:
51
  os.remove(file_path)
52
  removed += 1
@@ -105,7 +106,7 @@ def train_model():
105
  Dense(256, activation='relu'),
106
  Dropout(0.5),
107
 
108
- Dense(train_data.num_classes, activation='softmax')
109
  ])
110
 
111
  model.compile(
@@ -114,28 +115,50 @@ def train_model():
114
  metrics=['accuracy']
115
  )
116
 
117
- with st.spinner("Training AI model... Please wait."):
118
  model.fit(
119
  train_data,
120
  validation_data=val_data,
121
  epochs=EPOCHS
122
  )
123
 
 
124
  model.save(MODEL_PATH)
 
125
 
126
  return model, classes
127
 
128
  # -----------------------------
129
- # LOAD OR TRAIN MODEL
130
  # -----------------------------
131
- if not os.path.exists(MODEL_PATH):
132
- st.warning("Training model for first-time use. Please wait...")
133
- model, classes = train_model()
134
- else:
135
- model = tf.keras.models.load_model(MODEL_PATH)
136
 
137
- # Ensure exact dataset folder order
138
- classes = ['cardboard', 'glass', 'metal', 'paper', 'plastic', 'trash']
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
 
140
  # -----------------------------
141
  # STREAMLIT UI
@@ -145,15 +168,11 @@ st.write("Upload an image to classify waste and support sustainable recycling.")
145
 
146
  uploaded_file = st.file_uploader(
147
  "Upload Waste Image",
148
- type=["jpg", "jpeg", "png"],
149
- accept_multiple_files=False
150
  )
151
 
152
  if uploaded_file is not None:
153
  try:
154
- # -----------------------------
155
- # LOAD IMAGE
156
- # -----------------------------
157
  image = Image.open(uploaded_file).convert("RGB")
158
 
159
  st.image(
@@ -163,7 +182,7 @@ if uploaded_file is not None:
163
  )
164
 
165
  # -----------------------------
166
- # PREPROCESS IMAGE
167
  # -----------------------------
168
  img = image.resize(IMG_SIZE)
169
  img_array = np.array(img) / 255.0
@@ -173,71 +192,55 @@ if uploaded_file is not None:
173
  # PREDICT
174
  # -----------------------------
175
  with st.spinner("Analyzing waste type..."):
176
- prediction = model.predict(
177
- img_array,
178
- verbose=0
179
- )
180
 
181
  probabilities = prediction.flatten()
182
 
 
 
 
 
183
  # -----------------------------
184
- # VALIDATE OUTPUT
185
  # -----------------------------
186
- if len(probabilities) != len(classes):
187
- st.error(
188
- f"Model output mismatch: Expected {len(classes)} classes but got {len(probabilities)}."
189
- )
190
-
191
- else:
192
- predicted_index = np.argmax(probabilities)
193
- predicted_class = classes[predicted_index]
194
- confidence = probabilities[predicted_index] * 100
195
-
196
- # -----------------------------
197
- # DISPLAY SCORES
198
- # -----------------------------
199
- st.subheader("📊 Prediction Scores")
200
-
201
- for i, class_name in enumerate(classes):
202
- st.write(
203
- f"{class_name.upper()}: {probabilities[i] * 100:.2f}%"
204
- )
205
-
206
- # -----------------------------
207
- # MAIN RESULT
208
- # -----------------------------
209
- st.success(
210
- f"Predicted Type: {predicted_class.upper()}"
211
- )
212
 
213
- st.info(
214
- f"Confidence: {confidence:.2f}%"
 
215
  )
216
 
217
- # -----------------------------
218
- # SUSTAINABILITY TIPS
219
- # -----------------------------
220
- tips = {
221
- 'plastic': 'Recycle plastic properly to reduce pollution.',
222
- 'paper': 'Reuse or recycle paper to save trees.',
223
- 'metal': 'Metal can be recycled efficiently.',
224
- 'glass': 'Glass is reusable and recyclable.',
225
- 'trash': 'Dispose responsibly to reduce environmental damage.',
226
- 'cardboard': 'Recycle cardboard to reduce waste.'
227
- }
228
 
229
- st.subheader("🌱 Sustainability Suggestion")
 
 
230
 
231
- st.write(
232
- tips.get(
233
- predicted_class,
234
- "Dispose responsibly."
235
- )
 
 
 
 
 
 
 
 
 
 
 
 
236
  )
 
237
 
238
  except UnidentifiedImageError:
239
  st.error(
240
- "Invalid image file. Please upload a valid JPG, JPEG, or PNG image."
241
  )
242
 
243
  except Exception as e:
 
1
  import streamlit as st
2
  import tensorflow as tf
3
  from tensorflow.keras.preprocessing.image import ImageDataGenerator
4
+ from tensorflow.keras.models import Sequential, load_model
5
  from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout
6
  import numpy as np
7
  from PIL import Image, UnidentifiedImageError
 
12
  # -----------------------------
13
  DATASET_DIR = "dataset-resized"
14
  MODEL_PATH = "waste_classifier.h5"
15
+ CLASS_FILE = "classes.npy"
16
  IMG_SIZE = (128, 128)
17
  BATCH_SIZE = 16
18
  EPOCHS = 5
 
26
  )
27
 
28
  # -----------------------------
29
+ # CLEAN DATASET
30
  # -----------------------------
31
  def clean_dataset(dataset_path):
32
  valid_extensions = (".jpg", ".jpeg", ".png")
 
47
  try:
48
  with Image.open(file_path) as img:
49
  img.verify()
50
+ except:
51
  try:
52
  os.remove(file_path)
53
  removed += 1
 
106
  Dense(256, activation='relu'),
107
  Dropout(0.5),
108
 
109
+ Dense(len(classes), activation='softmax')
110
  ])
111
 
112
  model.compile(
 
115
  metrics=['accuracy']
116
  )
117
 
118
+ with st.spinner("Training AI model... Please wait..."):
119
  model.fit(
120
  train_data,
121
  validation_data=val_data,
122
  epochs=EPOCHS
123
  )
124
 
125
+ # Save model + classes
126
  model.save(MODEL_PATH)
127
+ np.save(CLASS_FILE, classes)
128
 
129
  return model, classes
130
 
131
  # -----------------------------
132
+ # LOAD MODEL
133
  # -----------------------------
134
+ def load_or_train_model():
135
+ if not os.path.exists(MODEL_PATH) or not os.path.exists(CLASS_FILE):
136
+ st.warning("Training model for first-time use. Please wait...")
137
+ return train_model()
 
138
 
139
+ try:
140
+ model = load_model(MODEL_PATH)
141
+ classes = np.load(CLASS_FILE, allow_pickle=True).tolist()
142
+
143
+ # Verify output layer
144
+ output_classes = model.output_shape[-1]
145
+
146
+ if output_classes != len(classes):
147
+ st.warning("Old incorrect model detected. Retraining...")
148
+ os.remove(MODEL_PATH)
149
+ os.remove(CLASS_FILE)
150
+ return train_model()
151
+
152
+ return model, classes
153
+
154
+ except:
155
+ st.warning("Model corrupted. Retraining...")
156
+ return train_model()
157
+
158
+ # -----------------------------
159
+ # LOAD MODEL
160
+ # -----------------------------
161
+ model, classes = load_or_train_model()
162
 
163
  # -----------------------------
164
  # STREAMLIT UI
 
168
 
169
  uploaded_file = st.file_uploader(
170
  "Upload Waste Image",
171
+ type=["jpg", "jpeg", "png"]
 
172
  )
173
 
174
  if uploaded_file is not None:
175
  try:
 
 
 
176
  image = Image.open(uploaded_file).convert("RGB")
177
 
178
  st.image(
 
182
  )
183
 
184
  # -----------------------------
185
+ # PREPROCESS
186
  # -----------------------------
187
  img = image.resize(IMG_SIZE)
188
  img_array = np.array(img) / 255.0
 
192
  # PREDICT
193
  # -----------------------------
194
  with st.spinner("Analyzing waste type..."):
195
+ prediction = model.predict(img_array, verbose=0)
 
 
 
196
 
197
  probabilities = prediction.flatten()
198
 
199
+ predicted_index = np.argmax(probabilities)
200
+ predicted_class = classes[predicted_index]
201
+ confidence = probabilities[predicted_index] * 100
202
+
203
  # -----------------------------
204
+ # RESULTS
205
  # -----------------------------
206
+ st.subheader("📊 Prediction Scores")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207
 
208
+ for i, class_name in enumerate(classes):
209
+ st.write(
210
+ f"{class_name.upper()}: {probabilities[i]*100:.2f}%"
211
  )
212
 
213
+ st.success(
214
+ f"Predicted Type: {predicted_class.upper()}"
215
+ )
 
 
 
 
 
 
 
 
216
 
217
+ st.info(
218
+ f"Confidence: {confidence:.2f}%"
219
+ )
220
 
221
+ # -----------------------------
222
+ # SUSTAINABILITY TIPS
223
+ # -----------------------------
224
+ tips = {
225
+ 'plastic': 'Recycle plastic properly to reduce pollution.',
226
+ 'paper': 'Reuse or recycle paper to save trees.',
227
+ 'metal': 'Metal can be recycled efficiently.',
228
+ 'glass': 'Glass is reusable and recyclable.',
229
+ 'trash': 'Dispose responsibly to reduce environmental damage.',
230
+ 'cardboard': 'Recycle cardboard to reduce waste.'
231
+ }
232
+
233
+ st.subheader("🌱 Sustainability Suggestion")
234
+ st.write(
235
+ tips.get(
236
+ predicted_class,
237
+ "Dispose responsibly."
238
  )
239
+ )
240
 
241
  except UnidentifiedImageError:
242
  st.error(
243
+ "Invalid image file. Please upload a valid image."
244
  )
245
 
246
  except Exception as e: