Skip to content

Commit dcbbc01

Browse files
authored
Merge pull request #38 from DataTalksClub/articles/1tPeJGo-oMlMN9cLdn1goC-M5StxtlyRsO0nTcpk9VVI
Article draft: How to Build a Waste Classifier: A Case Study from ML Zoomcamp
2 parents 0c621ba + 4d14025 commit dcbbc01

File tree

11 files changed

+241
-0
lines changed

11 files changed

+241
-0
lines changed
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
---
2+
authors:
3+
- valeriiakuka, serenahaidar
4+
description: Learn what you can build after ML Zoomcamp based on the final end-to-end
5+
ML engineering project from one of the graduates.
6+
image: images/posts/2025-08-05-how-to-build-waste-classifier-case-study-from-ml-zoomcamp/cover.jpg
7+
layout: post
8+
subtitle: Learn what you can build after ML Zoomcamp based on the final end-to-end
9+
ML engineering project from one of the graduates.
10+
tags:
11+
- courses
12+
- machine-learning
13+
- final-project
14+
title: 'How to Build a Waste Classifier: A Case Study from ML Zoomcamp'
15+
---
16+
17+
<figure>
18+
<img src="/images/posts/2025-08-05-how-to-build-waste-classifier-case-study-from-ml-zoomcamp/image9.png" />
19+
<figcaption>GitHub of Serena’s final project from ML Zoomcamp</figcaption>
20+
</figure>
21+
22+
How does ML Zoomcamp translate into real ML engineering? At DataTalks.Club, [ML Zoomcamp](https://datatalks.club/blog/machine-learning-zoomcamp.html){:target="_blank"} is a free, four-month online course on core machine learning and taking models to production. A key requirement is an end-to-end capstone/final project that turns course concepts into a working system.
23+
24+
In this case study, Serena Haidar walks through her final project: training an Xception-based image classifier on ~15k waste images, achieving 93.3% test accuracy, and serving predictions via a Flask API in Docker.
25+
26+
If you’re evaluating the program, this is how a graduate takes the course material from notebook to a small production app, and what you can build after the course and how to approach it step by step.
27+
28+
## Interview with Serena about Her Project Idea
29+
30+
### Q: How did you select the problem for your final project?
31+
32+
The idea behind [my project](https://github.com/Serena-github-c/Deep-Learning--Waste-Classification/tree/main){:target="_blank"} was to accurately classify waste, ensuring that different types of waste are sent to the appropriate locations.
33+
34+
For example, plastics, metals, and glass should go to recycling centers. When they end up in regular trash bins, they can remain for decades, contaminating soil and harming wildlife. Organic waste like food scraps, on the other hand, should be composted. If it ends up in landfills instead, it breaks down without oxygen and releases methane, a greenhouse gas many times more potent than carbon dioxide.
35+
36+
These two sorting mistakes can speed up environmental damage and worsen climate change.
37+
38+
### Q: How did you technically approach it?
39+
40+
The initial task was to differentiate between biodegradable and non-biodegradable waste, then classify it further into 8 subcategories: e-waste, food waste, leaf waste, metal waste, paper waste, plastic bags, plastic bottles, and wood waste.
41+
42+
For classification into subcategories, I chose to use deep learning, specifically a Convolutional Neural Network (CNN) based on the Xception pre-trained model. To consider the project successful, the benchmarks included: an accuracy score of over 90% and a small model size suitable for lightweight deployment.
43+
44+
### Q: Who could potentially use a similar approach to waste classification in real-life settings?
45+
46+
This project helps companies begin automating sustainable waste management. It’s the very first link in a chain of actions that lead to improved recycling.
47+
48+
Here’s how the process works:
49+
50+
- An embedded camera (for example, an ESP32‑CAM) monitors each piece of waste as it arrives.
51+
- The device runs a simple image classification model to determine whether the item is plastic, metal, glass, organic, etc.
52+
- It sends that label to the sorting equipment downstream.
53+
54+
55+
56+
Correct labels lead to fewer mistakes, less manual checking, and quicker routing of materials to recycling or composting.
57+
58+
## Technical Overview
59+
60+
In this section, Serena will guide you through the key components of her project.
61+
62+
### Data Selection
63+
64+
<figure>
65+
<img src="/images/posts/2025-08-05-how-to-build-waste-classifier-case-study-from-ml-zoomcamp/image3.png" />
66+
<figcaption>Waste Segregation Image Dataset on Kaggle. Source: <a href="https://www.kaggle.com/datasets/aashidutt3/waste-segregation-image-dataset/data">https://www.kaggle.com/datasets/aashidutt3/waste-segregation-image-dataset/data</a></figcaption>
67+
</figure>
68+
69+
I used a public [dataset](https://www.kaggle.com/datasets/aashidutt3/waste-segregation-image-dataset/data){:target="_blank"} from Kaggle, comprising 15,200 images, split into 3 subsets: train, test, and validation.
70+
71+
Each subset contains images for 8 classes:
72+
73+
- Train: 13,999 images
74+
- Validation: 1,201 images
75+
- Test: 1,201 images
76+
77+
78+
79+
Images were resized to 150x150 initially to reduce training time and later to 299x299 for final training.
80+
81+
### Model Selection
82+
83+
Instead of training a model from scratch, I used a pre-trained Keras model from the official website. After comparing models based on performance and size, I chose the [Xception model](https://keras.io/api/applications/xception/){:target="_blank"}. It’s a CNN architecture trained on over a million ImageNet [images](https://www.image-net.org/){:target="_blank"} with 1000 output classes.
84+
85+
<figure>
86+
<img src="/images/posts/2025-08-05-how-to-build-waste-classifier-case-study-from-ml-zoomcamp/image7.png" />
87+
<figcaption>A snapshot of the ImageNet data. Screenshot from the original paper: "ImageNet: A large-scale hierarchical image database</figcaption>
88+
</figure>
89+
90+
#### Xception Model Architecture
91+
92+
The Xception model consists of a series of convolutional layers arranged into a deep CNN architecture. It starts with two standard convolution layers, followed by 36 depthwise separable convolution layers organized into 14 modules.
93+
94+
<figure>
95+
<img src="/images/posts/2025-08-05-how-to-build-waste-classifier-case-study-from-ml-zoomcamp/image2.jpg" />
96+
<figcaption>The diagram above shows the Xception model architecture, displaying the three stages: entry, middle, and exit, and the layers with the number of neurons in each of them. Source: <a href="https://viso.ai/deep-learning/xception-model/">https://viso.ai/deep-learning/xception-model/</a></figcaption>
97+
</figure>
98+
99+
Each module contains a stack of operations like depthwise convolutions (which filter each input channel separately) and pointwise convolutions (which combine the outputs), allowing the model to be both efficient and powerful.
100+
101+
<figure>
102+
<img src="/images/posts/2025-08-05-how-to-build-waste-classifier-case-study-from-ml-zoomcamp/image1.jpg" />
103+
<figcaption>This diagram depicts the difference between the pointwise and depthwise convolution used in the Xception model. Source: <a href="https://viso.ai/deep-learning/xception-model/">https://viso.ai/deep-learning/xception-model/</a></figcaption>
104+
</figure>
105+
106+
These layers are designed to extract increasingly abstract features from input images, starting with basic edges and colors in early layers and progressing to complex textures and shapes in deeper layers. The architecture concludes with a Global Average Pooling layer and a fully connected Dense layer of 1000 neurons with a softmax activation, used to classify images into 1000 categories from the ImageNet dataset.
107+
108+
You can visualize the block diagram of the Xception model by running this code:
109+
110+
> model = Xception(weights='imagenet', input_shape=(299, 299, 3))
111+
>
112+
> visualkeras.layered_view(model, legend=True)
113+
>
114+
> <figure>
115+
<img src="/images/posts/2025-08-05-how-to-build-waste-classifier-case-study-from-ml-zoomcamp/image10.png" />
116+
<figcaption>This diagram illustrates that the model comprises an input layer, a functional layer, GlobalAveragePooling2D layers, and a dense layer.</figcaption>
117+
</figure>
118+
119+
#### My Modifications of the Original Model
120+
121+
For the waste classification task, I removed the top layer and added a new custom head to predict 8 waste classes. The “top layer” in a pre-trained model is the final Dense (fully connected) layer that maps extracted features into the original classes. In the case of Xception, the top layer maps to the original 1000 classes from the ImageNet dataset.
122+
123+
Since my dataset only contains 8 categories of waste, I replaced this layer with a custom classification head to output probabilities for only these 8 classes. This technique is known as **"transfer learning**," where we retain the convolutional layers of the Xception model, remove the top (dense) layer, and add a new one to learn our specific classes and make predictions.
124+
125+
Transfer learning helps reduce training time and improves performance by leveraging features learned from a large dataset, such as ImageNet.
126+
127+
Specifically, I used:
128+
129+
- A dense layer for the 8 subcategories.
130+
- Another dense layer for biodegradability.
131+
132+
133+
134+
After adding a new top layer, we can visualize the model summary using model.summary().
135+
136+
<figure>
137+
<img src="/images/posts/2025-08-05-how-to-build-waste-classifier-case-study-from-ml-zoomcamp/image4.png" />
138+
<figcaption>A summary of the resulting model</figcaption>
139+
</figure>
140+
141+
### Hyperparameter Tuning
142+
143+
The first model didn’t perform well enough. The validation accuracy was oscillating between 0.83 and 0.88. Hyperparameter tuning was necessary.
144+
145+
I determined the optimal learning rate by training the model on four different learning rates: \[0.0001, 0.001, 0.01, 0.1\]. After plotting, I chose **lr=0.001** as the best value, as it achieved the highest validation accuracy.
146+
147+
Then, I added Dropout for regularization, a technique that randomly deactivates a small number of neurons during training, changing which neurons are active between each epoch. It helps prevent overfitting and encourages the network to learn more robust features.
148+
149+
Finally, I used softmax activation with 8 units as the output layer of my model. This setup allows the model to output a probability for each of the 8 waste subcategories. Softmax is ideal for the output layer of a multi-class classification network because it assigns a probability score to each class that sums up to 1.
150+
151+
### Training Strategy and Optimization
152+
153+
In addition to tuning the learning rate and adding dropout, I implemented a few more strategies to improve performance and stability during training:
154+
155+
- **Checkpointing:** It’s a technique that saves the best-performing model from a list of training models based on a specific parameter. In my project, I used **ModelCheckpoint** callback from **keras.callbacks** to automatically save only the best version of the model (the one with the highest validation accuracy). This ensured that training didn’t overwrite a good model with a worse one in later epochs.
156+
- **Inner Dense Layer Tuning**: I experimented with different values for the **inner_size** (number of units) parameter in the Dense layer before the output. After testing 3 values: \[10, 100, 500\], I found that 100 worked best. This layer acts as the bridge between the extracted features and the final classification layer.
157+
158+
159+
160+
### Data augmentation
161+
162+
To enrich the dataset, instead of taking pictures of new images, we can apply a technique called **data augmentation**.
163+
164+
This adds images to the dataset from the existing images, by applying augmentations to the images, such as:
165+
166+
- flip (horizontally or vertically)
167+
- rotate (by an angle, clockwise or counter-clockwise)
168+
- shift (by height or width)
169+
- shear (extend from one corner)
170+
- zoom (in/out, horizontally/vertically)
171+
- brightness or contrast shifts
172+
173+
174+
175+
This technique helps with overfitting by increasing data diversity.
176+
177+
After data augmentation, I trained a larger model with 299x299 images, which is closer to the production environment where users will upload photos and receive classification results for their waste.
178+
179+
### Final results
180+
181+
After tuning many hyperparameters and training the model on larger images, I tested it on the test data subset to evaluate its performance. Since the best model is saved using callbacks, we restart the kernel, load the best saved model, and then test it.
182+
183+
**model = keras.models.load_model('xception_299_04_0.934.keras')**
184+
185+
**model.evaluate(test_ds)**
186+
187+
The final accuracy is 93.3%, which is above our threshold.
188+
189+
<figure>
190+
<img src="/images/posts/2025-08-05-how-to-build-waste-classifier-case-study-from-ml-zoomcamp/image6.png" />
191+
<figcaption>Screenshot showing the model accuracy</figcaption>
192+
</figure>
193+
194+
Then, we can test it on a random image of a metal can that it hasn't seen before from the val dataset, and get the final prediction, which features the predicted category, biodegradability, and confidence scores.
195+
196+
<figure>
197+
<img src="/images/posts/2025-08-05-how-to-build-waste-classifier-case-study-from-ml-zoomcamp/image5.png" />
198+
<figcaption>A ' make_prediction' function that utilizes the final model and outputs predicted category, biodegradability, and confidence scores.</figcaption>
199+
</figure>
200+
201+
### Serving and Deployment
202+
203+
To deploy my model and create a user-friendly interface that allows users to upload an image and receive a prediction, I took the following steps.
204+
205+
#### Step 1: Built a Flask API for inference
206+
207+
I created a Flask web server that receives image uploads, passes them to the model, and returns the prediction. This allows the model to serve predictions through HTTP requests.
208+
209+
#### Step 2: Dockerized the app for consistent deployment
210+
211+
To ensure the app runs identically across different environments, I created a Docker container containing the Flask app, the trained model, and all necessary dependencies.
212+
213+
##### **Docker usage:**
214+
215+
> docker build -t waste-segregation-app .
216+
217+
This command builds the Docker image from the **Dockerfile** and names it **waste-segregation-app**
218+
219+
> docker run -p 9696:9696 waste-segregation-app
220+
221+
This runs the container and maps port **9696** on your machine to the container’s port **9696**, making the API accessible
222+
223+
#### Step 3: Inference
224+
225+
As a result, a user can call the model and retrieve results using either a command line or a web interface.
226+
227+
##### Option 1: Using the command line
228+
229+
curl -X POST -F "file=@your_image.jpg" http://localhost:9696/predict
230+
231+
This sends a POST request with an image to the /predict endpoint, and the model returns the predicted waste category
232+
233+
##### Option 2: Using the web interface
234+
235+
I created a simple HTML web interface where a user can upload an image, click a button, and receive a classification result. This interface is connected to the same backend. At localhost:9696
236+
237+
> <figure>
238+
<img src="/images/posts/2025-08-05-how-to-build-waste-classifier-case-study-from-ml-zoomcamp/image8.png" />
239+
<figcaption><blockquote></blockquote></figcaption>
240+
</figure>
241+
> Screenshot of the web interface and the result after uploading an image from the Internet.
26.8 KB
Loading
33.1 KB
Loading
119 KB
Loading
442 KB
Loading
39.4 KB
Loading
54.6 KB
Loading
53.5 KB
Loading
2.31 MB
Loading
372 KB
Loading

0 commit comments

Comments
 (0)