Downloads · 30 days
3
3% of all-time downloads
FYP-PROJECT/UNET-5-Classes
UNET-5-Classes is a machine learning model from FYP-PROJECT. Use it for the machine learning task on the model card, and read the license before you ship it in a product. It is set up for keras.
import os import numpy as np import tensorflow as tf import keras from tensorflow.keras import layers Used only to satisfy model loading structure import matplotlib.pyplot as plt import matplotlib.colors as mcolors im…
Downloads · 30 days
3
3% of all-time downloads
All-time downloads
89
Public
Repo size
373 MB
Likes
0
Public
Click a slice to open those files.
.keras373 MB · 100%
From the Hugging Face model README
import os import numpy as np import tensorflow as tf import keras from tensorflow.keras import layers # Used only to satisfy model loading structure import matplotlib.pyplot as plt import matplotlib.colors as mcolors import rasterio # REQUIRED for reading TIF files from huggingface_hub import hf_hub_download # NEW IMPORT for reliable download
CONFIG = { "HEIGHT": 512, "WIDTH": 512, "N_CLASSES": 5, # Class labels are 1-5 "N_CHANNELS": 10 # 10 Sentinel-2 bands }
HF_REPO_ID = "FYP-PROJECT/UNET-5-Classes"
HF_MODEL_FILE = "best_multiclass_model.keras"
TIF_FILE_PATH = "/content/drive/MyDrive/new-data-2025/test/images/9.tif"
CLASS_MAPPING = { 1: "Water", 2: "Built-up", 3: "Forest", 4: "Soil", 5: "Crop" }
COLOR_MAP = { 1: [0, 0, 255], 2: [255, 0, 0], 3: [0, 100, 0], 4: [139, 69, 19], 5: [255, 255, 0] }
def sparse_mean_iou(y_true, y_pred): """Mean IoU across all classes (Re-defining the custom metric for model loading).""" # y_true and y_pred are (B, H, W, 5) y_pred_labels = tf.argmax(y_pred, axis=-1) y_true_labels = tf.argmax(y_true, axis=-1)
ious = []
for i in range(CONFIG["N_CLASSES"]):
y_true_class = tf.cast(y_true_labels == i, tf.float32)
y_pred_class = tf.cast(y_pred_labels == i, tf.float32)
intersection = tf.reduce_sum(y_true_class * y_pred_class)
union = tf.reduce_sum(y_true_class) + tf.reduce_sum(y_pred_class) - intersection
iou = intersection / (union + 1e-7)
ious.append(iou)
return tf.reduce_mean(ious)
def mask_to_rgb(mask_1_indexed): """Convert 1-indexed class mask (1-5) to an RGB image.""" h, w = mask_1_indexed.shape rgb = np.zeros((h, w, 3), dtype=np.uint8)
for class_id, color in COLOR_MAP.items():
rgb[mask_1_indexed == class_id] = color
return rgb
def load_and_preprocess_patch(image_data, normalization_factor=10000.0): """ 1. Normalizes the input patch (H, W, C) to 0-1 range. 2. Adds the batch dimension (1, H, W, C). """ if image_data.ndim != 3 or image_data.shape[-1] != CONFIG["N_CHANNELS"]: print(f"Error: Input shape must be (512, 512, 10), but got {image_data.shape}") return None, None
# 1. Normalize the data (Crucial step to match training: reflectance / 10000)
normalized_data = np.clip(image_data.astype(np.float32) / normalization_factor, 0.0, 1.0)
# 2. Add batch dimension: (H, W, C) -> (1, H, W, C)
input_tensor = np.expand_dims(normalized_data, axis=0)
return input_tensor, normalized_data
def visualize_prediction(input_image, pred_labels_1_indexed): """Displays the input RGB composite and the final segmented mask."""
# Show RGB composite (bands 3,2,1 for natural color - indices 2, 1, 0)
# The input image here is the normalized data (0-1 range)
rgb_display = input_image[..., [2, 1, 0]]
# Convert prediction to RGB
pred_rgb = mask_to_rgb(pred_labels_1_indexed)
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.title("Input Image (Normalized RGB Composite)")
plt.imshow(rgb_display)
plt.axis('off')
plt.subplot(1, 2, 2)
plt.title("Predicted Segmentation")
plt.imshow(pred_rgb)
plt.axis('off')
plt.tight_layout()
plt.show()
if name == "main":
# --- MODEL LOADING ---
model = None
custom_objects = {"sparse_mean_iou": sparse_mean_iou}
try:
print(f"Downloading model file '{HF_MODEL_FILE}' from Hub: {HF_REPO_ID}...")
# 1. Download the file locally first
# CRITICAL CHECK: The 404 error means the file or repo is not found.
# Ensure the filename and REPO_ID are EXACTLY correct in HF_MODEL_FILE and HF_REPO_ID.
# Ensure your token (if required for private repo) has 'read' access.
local_model_path = hf_hub_download(
repo_id=HF_REPO_ID,
filename=HF_MODEL_FILE,
repo_type="model"
)
print(f"Model downloaded to temporary path: {local_model_path}")
# 2. Load the model from the local path
model = keras.saving.load_model(
local_model_path,
custom_objects=custom_objects
)
print("Model loaded successfully.")
except Exception as e:
print(f"\nFATAL ERROR: Model Loading Failed: {e}")
print("-" * 50)
print(f"DEBUG STEP 1: VERIFY REPOSITORY AND FILENAME.")
print(f"The download attempt failed for file '{HF_MODEL_FILE}'.")
print(f"ACTION: Go to https://huggingface.co/{HF_REPO_ID}/tree/main in your browser and check the exact case-sensitive filename.")
print("-" * 50)
print("DEBUG STEP 2: CHECK READ ACCESS.")
print("If the repository is private or belongs to an organization, ensure your token has 'read' permissions (you may need to run `from huggingface_hub import notebook_login; notebook_login()` and paste your token).")
print("-" * 50)
# Exit the script immediately if loading failed, preventing the NameError later
exit()
# --- LOAD INPUT DATA from TIF file ---
try:
with rasterio.open(TIF_FILE_PATH) as src:
if src.height != CONFIG["HEIGHT"] or src.width != CONFIG["WIDTH"] or src.count != CONFIG["N_CHANNELS"]:
print(f"Error: Input TIF shape ({src.height}, {src.width}, {src.count}) does not match expected model input.")
exit()
# Read all 10 bands. Shape: (10, 512, 512)
real_input_patch = src.read()
# Transpose to (512, 512, 10) to match model input shape
real_input_patch = np.transpose(real_input_patch, (1, 2, 0))
print(f"\nSuccessfully loaded TIF patch with shape: {real_input_patch.shape}")
except rasterio.RasterioIOError:
print(f"Error: Could not open TIF file at {TIF_FILE_PATH}. Check file path and Google Drive mounting.")
exit()
except Exception as e:
print(f"An unexpected error occurred during TIF loading: {e}")
exit()
# --- PREPROCESS ---
input_tensor, normalized_input_for_display = load_and_preprocess_patch(real_input_patch)
if input_tensor is None:
exit()
# --- PREDICT ---
print("Generating prediction...")
# 'model' is guaranteed to be defined here because we exit() on failure above.
prediction_output = model.predict(input_tensor, verbose=0)
# --- POST-PROCESS & VISUALIZE ---
prediction_mask_ohe = prediction_output[0]
pred_labels_0_indexed = np.argmax(prediction_mask_ohe, axis=-1)
pred_labels_1_indexed = pred_labels_0_indexed + 1
print("Prediction complete. Displaying results...")
visualize_prediction(normalized_input_for_display, pred_labels_1_indexed)