| import gradio as gr |
| import numpy as np |
| import torch |
| import torch.nn.functional as F |
| from torchvision import transforms |
| from torchvision.models import mobilenet_v2 |
| import tensorflow as tf |
| from tensorflow.keras.applications.efficientnet import preprocess_input |
| import matplotlib.pyplot as plt |
| import io |
| from PIL import Image |
| |
| |
| class_names = ['bidayuh', 'iban', 'kadazandusun', 'orang ulu'] |
|
|
| |
| efficientnet_model = tf.keras.models.load_model('models/efficientnet.keras') |
|
|
| |
| custom_cnn_model = tf.keras.models.load_model('models/custom_cnn_model.keras') |
|
|
| |
| torch_model = mobilenet_v2(weights=False) |
| torch_model.classifier[1] = torch.nn.Linear(torch_model.last_channel, len(class_names)) |
| torch_model.load_state_dict(torch.load('models/final_best_mobilenetv2_model.pth', map_location='cpu')) |
| torch_model.eval() |
|
|
| |
| torch_transform = transforms.Compose([ |
| transforms.Resize((224, 224)), |
| transforms.ToTensor(), |
| transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) |
| ]) |
|
|
| |
| def fig_to_pil(fig): |
| buf = io.BytesIO() |
| fig.savefig(buf, format='png', bbox_inches='tight') |
| plt.close(fig) |
| buf.seek(0) |
| return Image.open(buf) |
|
|
| |
| def preprocess_tf_image(img): |
| img_resized = img.resize((224, 224)).convert('RGB') |
| img_array = preprocess_input(np.array(img_resized)) |
| return np.expand_dims(img_array, axis=0) |
|
|
| |
| def create_prediction_chart(class_names, confidences): |
| fig, ax = plt.subplots(figsize=(6, 3)) |
| bars = ax.barh(class_names, confidences, color='skyblue') |
| ax.set_xlim([0, 1]) |
| ax.set_xlabel("Confidence") |
| ax.set_title("Class Probabilities") |
|
|
| |
| for bar, confidence in zip(bars, confidences): |
| width = bar.get_width() |
| ax.text(width + 0.01, bar.get_y() + bar.get_height()/2, f"{confidence*100:.2f}%", |
| va='center', fontsize=9, fontweight='bold') |
|
|
| plt.tight_layout() |
| return fig_to_pil(fig) |
|
|
| |
| def predict_with_efficientnet(img): |
| img_array = preprocess_tf_image(img) |
| pred = efficientnet_model.predict(img_array, verbose=0)[0] |
| top_idx = int(np.argmax(pred)) |
| caption = f"{class_names[top_idx]} ({pred[top_idx]*100:.2f}%)" |
| chart = create_prediction_chart(class_names, pred.tolist()) |
| return (img, caption), chart |
|
|
| |
| def predict_with_custom_cnn(img): |
| img_array = preprocess_tf_image(img) |
| pred = custom_cnn_model.predict(img_array, verbose=0)[0] |
| top_idx = int(np.argmax(pred)) |
| caption = f"{class_names[top_idx]} ({pred[top_idx] * 100:.2f}%)" |
| chart = create_prediction_chart(class_names, pred.tolist()) |
| return (img, caption), chart |
|
|
| |
| def predict_with_torch(img): |
| input_tensor = torch_transform(img).unsqueeze(0) |
| with torch.no_grad(): |
| output = torch_model(input_tensor) |
| probs_tensor = F.softmax(output[0], dim=0) |
| probs_list = probs_tensor.tolist() |
| top_idx = int(torch.argmax(probs_tensor)) |
| caption = f"{class_names[top_idx]} ({probs_list[top_idx] * 100:.2f}%)" |
| chart = create_prediction_chart(class_names, probs_list) |
| return (img, caption), chart |
|
|
| |
| def predict_multiple_images(image_list, model_choice): |
| images = [] |
| charts = [] |
| for img in image_list: |
| try: |
| img = Image.open(img).convert('RGB') |
| if model_choice == "EfficientNet (TensorFlow)": |
| image_out, chart_out = predict_with_efficientnet(img) |
| elif model_choice == "Custom CNN (TensorFlow)": |
| image_out, chart_out = predict_with_custom_cnn(img) |
| elif model_choice == "MobileNet (PyTorch)": |
| image_out, chart_out = predict_with_torch(img) |
| else: |
| continue |
| images.append(image_out) |
| charts.append(chart_out) |
| except Exception as e: |
| print(f"Error processing image: {e}") |
| return images, charts |
|
|
| |
| demo = gr.Interface( |
| fn=predict_multiple_images, |
| inputs=[ |
| gr.Files(file_types=['image']), |
| gr.Radio(["EfficientNet (TensorFlow)","Custom CNN (TensorFlow)", "MobileNet (PyTorch)"], label="Choose Model", value="EfficientNet (TensorFlow)") |
| ], |
| outputs=[ |
| gr.Gallery(label="Predictions with Labels"), |
| gr.Gallery(label="Prediction Charts") |
| ], |
| title="Multi-Image Classifier (TF + PyTorch)", |
| description="Upload multiple images and choose a model to see predictions with confidence bar charts." |
| ) |
|
|
| demo.launch(debug=True) |
|
|