Spaces:
Sleeping
Sleeping
File size: 3,235 Bytes
8d1f2ed | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | # ================================
# 0. PATCH pour huggingface_hub (contourne l'absence de HfFolder)
# ================================
import huggingface_hub
if not hasattr(huggingface_hub, 'HfFolder'):
class HfFolder:
_token = None
@staticmethod
def get_token():
return HfFolder._token
@staticmethod
def save_token(token):
HfFolder._token = token
huggingface_hub.HfFolder = HfFolder
# ================================
# 1. PATCH pour contourner le bug de Gradio 4.44.0
# (TypeError: argument of type 'bool' is not iterable)
# ================================
import gradio_client.utils
original_get_type = gradio_client.utils.get_type
def patched_get_type(schema):
if isinstance(schema, bool):
return "boolean"
return original_get_type(schema)
gradio_client.utils.get_type = patched_get_type
# ================================
# 2. IMPORTS STANDARDS
# ================================
import gradio as gr
import tensorflow as tf
import numpy as np
from PIL import Image
# Forcer la précision float32 (évite les warnings de mixed precision sur CPU)
tf.keras.mixed_precision.set_global_policy('float32')
# ================================
# 3. CHARGEMENT DU MODÈLE (binaire)
# ================================
MODEL_PATH = "final_model.keras"
# Charger le modèle sans compiler pour éviter l'avertissement sur l'optimiseur
model = tf.keras.models.load_model(MODEL_PATH, compile=False)
# Recompiler avec une configuration simple (nécessaire pour faire des prédictions)
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
# ================================
# 4. CONSTANTES
# ================================
IMG_SIZE = 380 # Taille d'entrée du modèle (EfficientNetB4)
# ================================
# 5. FONCTION DE PRÉDICTION
# ================================
def preprocess_image(img):
"""
Redimensionne et normalise l'image pour le modèle.
L'entraînement a utilisé : cv2.resize + /255.0
"""
img = img.resize((IMG_SIZE, IMG_SIZE))
img_array = np.array(img, dtype=np.float32) / 255.0
img_array = np.expand_dims(img_array, axis=0)
return img_array
def predict(img):
"""
Retourne un dictionnaire {classe: probabilité} pour les deux classes.
La sortie du modèle est la probabilité d'être une mauvaise herbe (weed).
"""
processed = preprocess_image(img)
prob_weed = float(model.predict(processed, verbose=0)[0][0])
prob_crop = 1 - prob_weed
return {
"crop": prob_crop,
"weed": prob_weed
}
# ================================
# 6. INTERFACE GRADIO
# ================================
iface = gr.Interface(
fn=predict,
inputs=gr.Image(type="pil", label="Chargez une image de champ (culture ou mauvaise herbe)"),
outputs=gr.Label(num_top_classes=2, label="Prédiction"),
title="Classification Culture / Mauvaise Herbe",
description="Ce modèle (EfficientNetB4) distingue les cultures des mauvaises herbes. \
Il a été entraîné sur un dataset avec bounding boxes, pour une tâche de classification binaire."
)
if __name__ == "__main__":
iface.launch(share=True) |