Spaces:
Sleeping
Sleeping
| 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) | |