Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add files via upload #11

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added ImageReport.docx
Binary file not shown.
Binary file added Project_Presentation.pptx
Binary file not shown.
136 changes: 50 additions & 86 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,86 +1,50 @@
![logo_ironhack_blue 7](https://user-images.githubusercontent.com/23629340/40541063-a07a0a8a-601a-11e8-91b5-2f13e4e6b441.png)

# Project I | Deep Learning: Image Classification with CNN

## Task Description

Students will build a Convolutional Neural Network (CNN) model to classify images from a given dataset into predefined categories/classes.

## Datasets (pick one!)

1. The dataset for this task is the CIFAR-10 dataset, which consists of 60,000 32x32 color images in 10 classes, with 6,000 images per class. You can download the dataset from [here](https://www.cs.toronto.edu/~kriz/cifar.html).
2. The second dataset contains about 28,000 medium quality animal images belonging to 10 categories: dog, cat, horse, spyder, butterfly, chicken, sheep, cow, squirrel, elephant. The link is [here](https://www.kaggle.com/datasets/alessiocorrado99/animals10/data).

## Assessment Components

1. **Data Preprocessing**
- Data loading and preprocessing (e.g., normalization, resizing, augmentation).
- Create visualizations of some images, and labels.

2. **Model Architecture**
- Design a CNN architecture suitable for image classification.
- Include convolutional layers, pooling layers, and fully connected layers.

3. **Model Training**
- Train the CNN model using appropriate optimization techniques (e.g., stochastic gradient descent, Adam).
- Utilize techniques such as early stopping to prevent overfitting.

4. **Model Evaluation**
- Evaluate the trained model on a separate validation set.
- Compute and report metrics such as accuracy, precision, recall, and F1-score.
- Visualize the confusion matrix to understand model performance across different classes.

5. **Transfer Learning**
- Evaluate the accuracy of your model on a pre-trained models like ImagNet, VGG16, Inception... (pick one an justify your choice)
- You may find this [link](https://www.tensorflow.org/tutorials/images/transfer_learning_with_hub) helpful.
- [This](https://pytorch.org/tutorials/beginner/transfer_learning_tutorial.html) is the Pytorch version.
- Perform transfer learning with your chosen pre-trained models i.e., you will probably try a few and choose the best one.

5. **Code Quality**
- Well-structured and commented code.
- Proper documentation of functions and processes.
- Efficient use of libraries and resources.

6. **Report**
- Write a concise report detailing the approach taken, including:
- Description of the chosen CNN architecture.
- Explanation of preprocessing steps.
- Details of the training process (e.g., learning rate, batch size, number of epochs).
- Results and analysis of models performance.
- What is your best model. Why?
- Insights gained from the experimentation process.
- Include visualizations and diagrams where necessary.

7. **Model deployment**
- Pick the best model
- Build an app using Flask - Can you host somewhere other than your laptop? **+5 Bonus points if you use [Tensorflow Serving](https://www.tensorflow.org/tfx/guide/serving)**
- User should be able to upload one or multiples images get predictions including probabilities for each prediction


## Evaluation Criteria

- Accuracy of the trained models on the validation set. **30 points**
- Clarity and completeness of the report. **20 points**
- Quality of code implementation. **5 points**
- Proper handling of data preprocessing and models training. **30 points**
- Demonstration of understanding key concepts of deep learning. **5 points**
- Model deployment. **10 points**

<span style="color:red; weight: bold">**Passing Score is 70 points**</span>.

## Submission Details

- Deadline for submission: end of the week or as communicated by your teaching team.
- Submit the following:
1. Python code files (`*.py`, `ipynb`) containing the model implementation and training process.
2. A data folder with 5-10 images to test the deployed model/app if hosted somewhere else other than your laptop (strongly recommended! Not a must have)
2. A PDF report documenting the approach, results, and analysis.
3. Any additional files necessary for reproducing the results (e.g., requirements.txt, README.md).
4. PPT presentation

## Additional Notes

- Students are encourage to experiment with different architectures, hyper-parameters, and optimization techniques.
- Provide guidance and resources for troubleshooting common issues during model training and evaluation.
- Students will discuss their approaches and findings in class during assessment evaluation sessions.

# Image Classifier

This is a simple image classification application using Flask for the backend and a Tailwind CSS-based UI. It allows users to upload an image and get predictions from a pre-trained TensorFlow model.

---

## Features
- Upload images via a user-friendly web interface.
- Classify images using a pre-trained TensorFlow model.
- Display prediction probabilities for each class.

---

## Requirements
- Python 3.8, 3.9, or 3.10
- Pip (Python package installer)

---

## Installation and Setup Instructions

1. **Install Python Dependencies**
Run the following command to install all required Python libraries:
- pip install flask tensorflow pillow

---

2. **Download the Pre-trained Model**
Ensure your TensorFlow model file (`Final.keras`) is located at the following path:
- model\Final.keras

---

3. **Open the Application**
Open your browser and navigate to:
- http://localhost:5000

---

## Usage

1. Select an image file by clicking the "Choose File" button in the UI.
2. Click "Upload and Classify" to send the image to the server.
3. View the predicted class and probabilities for all classes in the UI.

---

### Error: TensorFlow Compatibility
Ensure you are using Python 3.8, 3.9, or 3.10. TensorFlow may not work with other Python versions.

26 changes: 26 additions & 0 deletions client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# import requests

# # Ruta de la imagen a enviar
# image_path = "C:/Users/matel/Desktop/a1.png"

# # URL del servidor Flask
# url = "http://localhost:5000/predict"

# try:
# # Abrir la imagen y enviar la solicitud
# with open(image_path, "rb") as file:
# files = {"file": file}
# response = requests.post(url, files=files)

# # Verificar el estado de la respuesta
# if response.status_code == 200:
# result = response.json()
# print("Predicted Class:", result["predicted_class"])
# print("Probabilities:")
# for class_name, prob in result["probabilities"].items():
# print(f" {class_name}: {prob:.4f}")
# else:
# print(f"Error: {response.status_code}")
# print(response.json())
# except Exception as e:
# print(f"Error while sending the request: {str(e)}")
91 changes: 91 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image Classifier</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-100 flex items-center justify-center min-h-screen">
<div class="bg-white shadow-md rounded-lg p-8 max-w-md w-full">
<h1 class="text-2xl font-bold text-gray-800 text-center mb-6">Image Classifier</h1>
<form id="uploadForm" class="flex flex-col items-center">
<label class="block">
<span class="sr-only">Choose file</span>
<input
type="file"
id="fileInput"
accept="image/*"
required
class="block w-full text-sm text-gray-900 hidden"
>
<button
type="button"
onclick="document.getElementById('fileInput').click()"
class="bg-gray-200 text-gray-700 font-semibold py-2 px-4 rounded-lg hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
>
Choose File
</button>
</label>
<span id="fileName" class="mt-2 text-sm text-gray-600">No file selected</span>
<button
type="submit"
class="mt-4 bg-blue-600 text-white font-semibold py-2 px-4 rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
>
Upload and Classify
</button>
</form>
<div id="result" class="mt-6 text-center text-gray-700"></div>
</div>

<script>
document.getElementById("fileInput").addEventListener("change", function(event) {
const fileName = event.target.files[0]?.name || "No file selected";
document.getElementById("fileName").textContent = fileName;
});

document.getElementById("uploadForm").addEventListener("submit", async function(event) {
event.preventDefault();

const fileInput = document.getElementById("fileInput");
const resultDiv = document.getElementById("result");

if (!fileInput.files.length) {
resultDiv.textContent = "Please select an image file.";
return;
}

const formData = new FormData();
formData.append("file", fileInput.files[0]);

try {
resultDiv.innerHTML = "<p class='text-gray-600'>Uploading and classifying...</p>";

const response = await fetch("http://localhost:5000/predict", {
method: "POST",
body: formData
});

if (!response.ok) {
throw new Error(`Server error: ${response.statusText}`);
}

const data = await response.json();
const { predicted_class, probabilities } = data;

let resultHTML = `<p class='text-xl font-bold text-green-600'>Predicted Class: ${predicted_class}</p>`;
resultHTML += "<p class='text-lg font-semibold mt-4'>Probabilities:</p><ul class='mt-2 text-left'>";

for (const [className, prob] of Object.entries(probabilities)) {
resultHTML += `<li class='mt-1'><span class='font-medium text-gray-800'>${className}:</span> ${(prob * 100).toFixed(2)}%</li>`;
}
resultHTML += "</ul>";

resultDiv.innerHTML = resultHTML;
} catch (error) {
resultDiv.innerHTML = `<p class='text-red-600'>Error: ${error.message}</p>`;
}
});
</script>
</body>
</html>
Binary file added model/Final.keras
Binary file not shown.
42 changes: 42 additions & 0 deletions server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from flask import Flask, request, jsonify, send_from_directory
from flask_cors import CORS
import tensorflow as tf
import numpy as np
from PIL import Image

app = Flask(__name__, static_folder='.', static_url_path='')
CORS(app) # Habilitar CORS para todas las rutas

# Cargar el modelo
model = tf.keras.models.load_model(r"model\Final.keras")
class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']

def preprocess_image(image):
if image.mode != "RGB":
image = image.convert("RGB")
image = image.resize((32, 32))
image = np.array(image) / 255.0
return np.expand_dims(image, axis=0)

@app.route('/')
def index():
return send_from_directory('.', 'index.html')

@app.route('/predict', methods=['POST'])
def predict():
if 'file' not in request.files:
return jsonify({'error': 'No file uploaded'}), 400

file = request.files['file']
try:
image = Image.open(file.stream)
processed_image = preprocess_image(image)
predictions = model.predict(processed_image)
predicted_class = class_names[np.argmax(predictions[0])]
probabilities = {class_names[i]: float(predictions[0][i]) for i in range(10)}
return jsonify({'predicted_class': predicted_class, 'probabilities': probabilities})
except Exception as e:
return jsonify({'error': str(e)}), 500

if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)