predict-dose / app.py
Ayesha352's picture
Update app.py
224e3c9 verified
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)