Ayesha-Majeed commited on
Commit
b2e65e5
·
verified ·
1 Parent(s): 16e5909

Upload 5 files

Browse files
Dockerfile (1) ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ✅ Force Python 3.11 to match local environment
2
+ FROM python:3.11-slim
3
+
4
+ WORKDIR /app
5
+ COPY . /app
6
+
7
+ # ✅ Clean upgrade and install lightweight dependencies first
8
+ RUN apt-get update && apt-get install -y gcc g++ && rm -rf /var/lib/apt/lists/*
9
+
10
+ # ✅ Install compatible libraries
11
+ RUN pip install --upgrade pip
12
+ RUN pip install --no-cache-dir \
13
+ gradio==5.49.1 \
14
+ xgboost==2.1.0 \
15
+ scikit-learn==1.7.2 \
16
+ pandas==2.3.3 \
17
+ numpy==2.3.4 \
18
+ joblib==1.4.2 \
19
+ openpyxl==3.1.5 \
20
+ tabulate==0.9.0
21
+
22
+ EXPOSE 7860
23
+
24
+ CMD ["python", "app.py"]
25
+
26
+
app (1).py ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import numpy as np
4
+ from xgboost import XGBRegressor
5
+ import joblib
6
+ import os
7
+ import logging
8
+
9
+ # -----------------------------
10
+ # 1️⃣ File paths
11
+ # -----------------------------
12
+ MODEL_PATH = "xgb_model_corn_final.json"
13
+ SCALER_PATH = "minmax_scaler.pkl"
14
+ EXCEL_PATH = "microalgae_pot_experiment_corrected_doses.xlsx"
15
+
16
+ # Check files exist
17
+ for path in [MODEL_PATH, SCALER_PATH, EXCEL_PATH]:
18
+ if not os.path.exists(path):
19
+ raise FileNotFoundError(f"File not found: {path}")
20
+
21
+ # -----------------------------
22
+ # 2️⃣ Load model, scaler, and data
23
+ # -----------------------------
24
+ xgb_model = XGBRegressor()
25
+ xgb_model.load_model(MODEL_PATH)
26
+ scaler = joblib.load(SCALER_PATH)
27
+ df = pd.read_excel(EXCEL_PATH)
28
+
29
+ # Only one strain exists
30
+ strain_names = df['Microalgae_Strain'].unique().tolist()
31
+ single_strain_value = 0 # training used LabelEncoder -> 0
32
+
33
+ # -----------------------------
34
+ # 3️⃣ Prediction function
35
+ # -----------------------------
36
+ def predict_dose(crop, microalgae_strain, soil_n, soil_p, soil_k, soil_ec, soil_moisture,
37
+ chlorophyll, shoot_length, root_length, yield_g, relative_yield,
38
+ actual_dose):
39
+ logs = [] # Capture all debug info
40
+
41
+ # 1️⃣ Validate inputs
42
+ required = [soil_n, soil_p, soil_k, soil_ec, soil_moisture,
43
+ chlorophyll, shoot_length, root_length, yield_g, relative_yield]
44
+ if any(v is None for v in required):
45
+ logs.append("[DEBUG] Missing numeric inputs!")
46
+ return "⚠️ Please fill all numeric input fields.", None, None, "\n".join(logs)
47
+ logs.append("[DEBUG] All inputs received.")
48
+
49
+ # 2️⃣ Encode strain
50
+ strain_encoded = single_strain_value
51
+ logs.append(f"[DEBUG] Using Microalgae_Strain encoded value: {strain_encoded}")
52
+
53
+ # 3️⃣ Create DataFrame
54
+ feature_cols = ['Soil_N_ppm','Soil_P_ppm','Soil_K_ppm','Soil_EC_dS_m',
55
+ 'Soil_Moisture_%','Chlorophyll_SPAD','Shoot_Length_cm',
56
+ 'Root_Length_cm','Yield_g_per_pot','Relative_Yield_%','Microalgae_Strain']
57
+ X_input_df = pd.DataFrame([[soil_n, soil_p, soil_k, soil_ec, soil_moisture,
58
+ chlorophyll, shoot_length, root_length, yield_g,
59
+ relative_yield, strain_encoded]],
60
+ columns=feature_cols).astype(float)
61
+ logs.append(f"[DEBUG] Input DataFrame:\n{X_input_df}")
62
+
63
+ # 4️⃣ Scale
64
+ X_input_scaled = scaler.transform(X_input_df)
65
+ logs.append(f"[DEBUG] Scaled Input:\n{X_input_scaled}")
66
+
67
+ # 5️⃣ Predict
68
+ predicted_dose = xgb_model.predict(X_input_scaled)[0]
69
+ logs.append(f"[DEBUG] Predicted dose (raw): {predicted_dose}")
70
+
71
+ # 6️⃣ Compute error
72
+ if actual_dose is not None:
73
+ abs_error = abs(predicted_dose - actual_dose)
74
+ logs.append(f"[DEBUG] Actual dose: {actual_dose}")
75
+ logs.append(f"[DEBUG] Absolute Error: {abs_error}")
76
+ return (f"🌱 **Predicted Dose:** {predicted_dose:.2f} g/pot",
77
+ f"📏 **Actual Dose:** {actual_dose:.2f} g/pot",
78
+ f"❌ **Absolute Error:** {abs_error:.2f} g/pot",
79
+ "\n".join(logs))
80
+ else:
81
+ logs.append("[DEBUG] Actual dose not provided.")
82
+ return (f"🌱 **Predicted Dose:** {predicted_dose:.2f} g/pot",
83
+ "📏 Actual Dose: Not provided",
84
+ "❌ Absolute Error: N/A",
85
+ "\n".join(logs))
86
+
87
+ # -----------------------------
88
+ # 4️⃣ Gradio Interface
89
+ # -----------------------------
90
+ with gr.Blocks(
91
+ theme=gr.themes.Soft(primary_hue="green", secondary_hue="lime", neutral_hue="gray"),
92
+ title="EcoGrowAI — Microalgae Dose Inference"
93
+ ) as demo:
94
+ gr.Markdown(
95
+ """
96
+ <div style='text-align:center'>
97
+ <h1 style='color:#00b16a; margin-bottom:8px;'>🌿 EcoGrowAI — Inference App</h1>
98
+ <p style='color:#555;'>Predict the optimal <b>microalgae dose (g/pot)</b> for Corn based on soil and growth parameters.</p>
99
+ </div>
100
+ <hr style='margin: 10px 0;'>
101
+ """
102
+ )
103
+ with gr.Row():
104
+ with gr.Column(scale=1):
105
+ gr.Markdown("### 🌾 Crop & Microalgae Selection")
106
+ crop = gr.Dropdown(["Corn"], label="Select Crop", value="Corn")
107
+ strain = gr.Dropdown(strain_names, label="Microalgae Strain", value=strain_names[0])
108
+ gr.Markdown("### 🌱 Soil Parameters")
109
+ soil_n = gr.Number(label="Soil N (ppm)")
110
+ soil_p = gr.Number(label="Soil P (ppm)")
111
+ soil_k = gr.Number(label="Soil K (ppm)")
112
+ soil_ec = gr.Number(label="Soil EC (dS/m)")
113
+ soil_moisture = gr.Number(label="Soil Moisture (%)")
114
+ gr.Markdown("### 🌾 Plant Growth Parameters")
115
+ chlorophyll = gr.Number(label="Chlorophyll (SPAD)")
116
+ shoot_length = gr.Number(label="Shoot Length (cm)")
117
+ root_length = gr.Number(label="Root Length (cm)")
118
+ yield_g = gr.Number(label="Yield (g/pot)")
119
+ relative_yield = gr.Number(label="Relative Yield (%)")
120
+ gr.Markdown("### 📏 Actual Dose (optional)")
121
+ actual_dose = gr.Number(label="Actual Dose (g/pot)")
122
+ predict_btn = gr.Button("🔍 Predict Dose", variant="primary")
123
+ with gr.Column(scale=1):
124
+ gr.Markdown("### 📊 Inference Result")
125
+ pred_box = gr.Markdown("Awaiting prediction...")
126
+ actual_box = gr.Markdown("")
127
+ abs_box = gr.Markdown("")
128
+ log_box = gr.Textbox(label="Debug Logs", lines=15) # <-- Add this
129
+ predict_btn.click(
130
+ fn=predict_dose,
131
+ inputs=[crop, strain, soil_n, soil_p, soil_k, soil_ec, soil_moisture,
132
+ chlorophyll, shoot_length, root_length, yield_g, relative_yield,
133
+ actual_dose],
134
+ outputs=[pred_box, actual_box, abs_box, log_box]
135
+ )
136
+
137
+ # -----------------------------
138
+ # 5️⃣ Launch
139
+ # -----------------------------
140
+ if __name__ == "__main__":
141
+ demo.launch(server_name="0.0.0.0", server_port=7860)
microalgae_pot_experiment_corrected_doses (1).xlsx ADDED
Binary file (12.1 kB). View file
 
minmax_scaler (1).pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fc3eeaadab72cbf85ef6b7653110f9316e48e6fcdeb1fe871f133e2a44ade7b3
3
+ size 1551
xgb_model_corn_final (1).json ADDED
The diff for this file is too large to render. See raw diff