Spaces:
Sleeping
Sleeping
File size: 6,092 Bytes
d0ed1b8 224e3c9 | 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 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | import gradio as gr
import pandas as pd
import numpy as np
from xgboost import XGBRegressor
import joblib
import os
import logging
# -----------------------------
# 1️⃣ File paths
# -----------------------------
MODEL_PATH = "xgb_model_corn_final.json"
SCALER_PATH = "minmax_scaler.pkl"
EXCEL_PATH = "microalgae_pot_experiment_corrected_doses.xlsx"
# Check files exist
for path in [MODEL_PATH, SCALER_PATH, EXCEL_PATH]:
if not os.path.exists(path):
raise FileNotFoundError(f"File not found: {path}")
# -----------------------------
# 2️⃣ Load model, scaler, and data
# -----------------------------
xgb_model = XGBRegressor()
xgb_model.load_model(MODEL_PATH)
scaler = joblib.load(SCALER_PATH)
df = pd.read_excel(EXCEL_PATH)
# Only one strain exists
strain_names = df['Microalgae_Strain'].unique().tolist()
single_strain_value = 0 # training used LabelEncoder -> 0
# -----------------------------
# 3️⃣ Prediction function
# -----------------------------
def predict_dose(crop, microalgae_strain, soil_n, soil_p, soil_k, soil_ec, soil_moisture,
chlorophyll, shoot_length, root_length, yield_g, relative_yield,
actual_dose):
logs = [] # Capture all debug info
# 1️⃣ Validate inputs
required = [soil_n, soil_p, soil_k, soil_ec, soil_moisture,
chlorophyll, shoot_length, root_length, yield_g, relative_yield]
if any(v is None for v in required):
logs.append("[DEBUG] Missing numeric inputs!")
return "⚠️ Please fill all numeric input fields.", None, None, "\n".join(logs)
logs.append("[DEBUG] All inputs received.")
# 2️⃣ Encode strain
strain_encoded = single_strain_value
logs.append(f"[DEBUG] Using Microalgae_Strain encoded value: {strain_encoded}")
# 3️⃣ Create DataFrame
feature_cols = ['Soil_N_ppm','Soil_P_ppm','Soil_K_ppm','Soil_EC_dS_m',
'Soil_Moisture_%','Chlorophyll_SPAD','Shoot_Length_cm',
'Root_Length_cm','Yield_g_per_pot','Relative_Yield_%','Microalgae_Strain']
X_input_df = pd.DataFrame([[soil_n, soil_p, soil_k, soil_ec, soil_moisture,
chlorophyll, shoot_length, root_length, yield_g,
relative_yield, strain_encoded]],
columns=feature_cols).astype(float)
logs.append(f"[DEBUG] Input DataFrame:\n{X_input_df}")
# 4️⃣ Scale
X_input_scaled = scaler.transform(X_input_df)
logs.append(f"[DEBUG] Scaled Input:\n{X_input_scaled}")
# 5️⃣ Predict
predicted_dose = xgb_model.predict(X_input_scaled)[0]
logs.append(f"[DEBUG] Predicted dose (raw): {predicted_dose}")
# 6️⃣ Compute error
if actual_dose is not None:
abs_error = abs(predicted_dose - actual_dose)
logs.append(f"[DEBUG] Actual dose: {actual_dose}")
logs.append(f"[DEBUG] Absolute Error: {abs_error}")
return (f"🌱 **Predicted Dose:** {predicted_dose:.2f} g/pot",
f"📏 **Actual Dose:** {actual_dose:.2f} g/pot",
f"❌ **Absolute Error:** {abs_error:.2f} g/pot",
"\n".join(logs))
else:
logs.append("[DEBUG] Actual dose not provided.")
return (f"🌱 **Predicted Dose:** {predicted_dose:.2f} g/pot",
"📏 Actual Dose: Not provided",
"❌ Absolute Error: N/A",
"\n".join(logs))
# -----------------------------
# 4️⃣ Gradio Interface
# -----------------------------
with gr.Blocks(
theme=gr.themes.Soft(primary_hue="green", secondary_hue="lime", neutral_hue="gray"),
title="EcoGrowAI — Microalgae Dose Inference"
) as demo:
gr.Markdown(
"""
<div style='text-align:center'>
<h1 style='color:#00b16a; margin-bottom:8px;'>🌿 EcoGrowAI — Inference App</h1>
<p style='color:#555;'>Predict the optimal <b>microalgae dose (g/pot)</b> for Corn based on soil and growth parameters.</p>
</div>
<hr style='margin: 10px 0;'>
"""
)
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("### 🌾 Crop & Microalgae Selection")
crop = gr.Dropdown(["Corn"], label="Select Crop", value="Corn")
strain = gr.Dropdown(strain_names, label="Microalgae Strain", value=strain_names[0])
gr.Markdown("### 🌱 Soil Parameters")
soil_n = gr.Number(label="Soil N (ppm)")
soil_p = gr.Number(label="Soil P (ppm)")
soil_k = gr.Number(label="Soil K (ppm)")
soil_ec = gr.Number(label="Soil EC (dS/m)")
soil_moisture = gr.Number(label="Soil Moisture (%)")
gr.Markdown("### 🌾 Plant Growth Parameters")
chlorophyll = gr.Number(label="Chlorophyll (SPAD)")
shoot_length = gr.Number(label="Shoot Length (cm)")
root_length = gr.Number(label="Root Length (cm)")
yield_g = gr.Number(label="Yield (g/pot)")
relative_yield = gr.Number(label="Relative Yield (%)")
gr.Markdown("### 📏 Actual Dose (optional)")
actual_dose = gr.Number(label="Actual Dose (g/pot)")
predict_btn = gr.Button("🔍 Predict Dose", variant="primary")
with gr.Column(scale=1):
gr.Markdown("### 📊 Inference Result")
pred_box = gr.Markdown("Awaiting prediction...")
actual_box = gr.Markdown("")
abs_box = gr.Markdown("")
log_box = gr.Textbox(label="Debug Logs", lines=15) # <-- Add this
predict_btn.click(
fn=predict_dose,
inputs=[crop, strain, soil_n, soil_p, soil_k, soil_ec, soil_moisture,
chlorophyll, shoot_length, root_length, yield_g, relative_yield,
actual_dose],
outputs=[pred_box, actual_box, abs_box, log_box]
)
# -----------------------------
# 5️⃣ Launch
# -----------------------------
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=7860)
|