Update app.py
Browse files
app.py
CHANGED
|
@@ -1,130 +1,138 @@
|
|
| 1 |
-
import numpy as np
|
| 2 |
-
import pandas as pd
|
| 3 |
-
import gradio as gr
|
| 4 |
-
import joblib
|
| 5 |
-
import tensorflow as tf
|
| 6 |
-
|
| 7 |
-
# Load artifacts
|
| 8 |
-
model = tf.keras.models.load_model('model/my_model_low_build.keras')
|
| 9 |
-
scaler = joblib.load('model/scaler_minor_low_build.pkl')
|
| 10 |
-
soil_encoder = joblib.load('model/soil_encoder_low_build.pkl')
|
| 11 |
-
crop_encoder = joblib.load('model/crop_encoder_low_build.pkl')
|
| 12 |
-
fertilizer_encoder = joblib.load('model/fertilizer_encoder_low_build.pkl')
|
| 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 |
-
recommendations.append(f"
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
recommendations.append(f"
|
| 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 |
-
gr.
|
| 121 |
-
gr.
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
gr.
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
).launch()
|
|
|
|
| 1 |
+
import numpy as np
|
| 2 |
+
import pandas as pd
|
| 3 |
+
import gradio as gr
|
| 4 |
+
import joblib
|
| 5 |
+
import tensorflow as tf
|
| 6 |
+
|
| 7 |
+
# Load artifacts
|
| 8 |
+
# model = tf.keras.models.load_model('model/my_model_low_build.keras')
|
| 9 |
+
# scaler = joblib.load('model/scaler_minor_low_build.pkl')
|
| 10 |
+
# soil_encoder = joblib.load('model/soil_encoder_low_build.pkl')
|
| 11 |
+
# crop_encoder = joblib.load('model/crop_encoder_low_build.pkl')
|
| 12 |
+
# fertilizer_encoder = joblib.load('model/fertilizer_encoder_low_build.pkl')
|
| 13 |
+
|
| 14 |
+
model = tf.keras.models.load_model('model/my_model.keras')
|
| 15 |
+
scaler = joblib.load('model/scaler.pkl')
|
| 16 |
+
soil_encoder = joblib.load('model/soil_encoder.pkl')
|
| 17 |
+
crop_encoder = joblib.load('model/crop_encoder.pkl')
|
| 18 |
+
fertilizer_encoder = joblib.load('model/fertilizer_encoder.pkl')
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
# Crop requirements (same as before)
|
| 23 |
+
crop_requirements = {
|
| 24 |
+
'cotton': {'Nitrogen': (80, 120), 'Phosphorus': (40, 60), 'Potassium': (80, 120)},
|
| 25 |
+
'orange': {'Nitrogen': (120, 150), 'Phosphorus': (50, 70), 'Potassium': (150, 200)},
|
| 26 |
+
'wheat': {'Nitrogen': (100, 150), 'Phosphorus': (40, 60), 'Potassium': (40, 60)},
|
| 27 |
+
'maize': {'Nitrogen': (150, 200), 'Phosphorus': (50, 80), 'Potassium': (50, 80)},
|
| 28 |
+
'rice': {'Nitrogen': (80, 120), 'Phosphorus': (40, 60), 'Potassium': (60, 80)},
|
| 29 |
+
'potato': {'Nitrogen': (150, 200), 'Phosphorus': (60, 80), 'Potassium': (150, 200)},
|
| 30 |
+
'tomato': {'Nitrogen': (100, 150), 'Phosphorus': (50, 70), 'Potassium': (150, 200)},
|
| 31 |
+
'carrot': {'Nitrogen': (60, 100), 'Phosphorus': (30, 50), 'Potassium': (60, 80)},
|
| 32 |
+
'cabbage': {'Nitrogen': (150, 200), 'Phosphorus': (70, 100), 'Potassium': (150, 200)},
|
| 33 |
+
'banana': {'Nitrogen': (150, 200), 'Phosphorus': (70, 100), 'Potassium': (200, 250)},
|
| 34 |
+
'onion': {'Nitrogen': (80, 120), 'Phosphorus': (40, 60), 'Potassium': (80, 100)},
|
| 35 |
+
'pepper': {'Nitrogen': (100, 150), 'Phosphorus': (50, 70), 'Potassium': (150, 200)},
|
| 36 |
+
'lettuce': {'Nitrogen': (60, 100), 'Phosphorus': (30, 50), 'Potassium': (40, 60)},
|
| 37 |
+
'sunflower': {'Nitrogen': (80, 120), 'Phosphorus': (40, 60), 'Potassium': (60, 80)},
|
| 38 |
+
'soybean': {'Nitrogen': (0, 20), 'Phosphorus': (40, 60), 'Potassium': (40, 60)}, # Legume: fixes its own N
|
| 39 |
+
'tobacco': {'Nitrogen': (120, 150), 'Phosphorus': (40, 60), 'Potassium': (60, 80)},
|
| 40 |
+
'sugarcane': {'Nitrogen': (100, 150), 'Phosphorus': (40, 60), 'Potassium': (150, 200)},
|
| 41 |
+
'peanut': {'Nitrogen': (0, 20), 'Phosphorus': (40, 60), 'Potassium': (60, 80)}, # Legume: fixes N
|
| 42 |
+
'coffee': {'Nitrogen': (80, 120), 'Phosphorus': (40, 60), 'Potassium': (80, 120)},
|
| 43 |
+
'tea': {'Nitrogen': (100, 150), 'Phosphorus': (50, 70), 'Potassium': (100, 150)}
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
def crop_specific_recommendation(raw_input):
|
| 48 |
+
recommendations = []
|
| 49 |
+
crop = raw_input[5].lower()
|
| 50 |
+
|
| 51 |
+
if crop in crop_requirements:
|
| 52 |
+
ideal = crop_requirements[crop]
|
| 53 |
+
n = raw_input[2]
|
| 54 |
+
p = raw_input[3]
|
| 55 |
+
k = raw_input[4]
|
| 56 |
+
|
| 57 |
+
# Nitrogen check
|
| 58 |
+
if n < ideal['Nitrogen'][0]:
|
| 59 |
+
recommendations.append(f"Nitrogen is low for {crop} (current: {n}, ideal: {ideal['Nitrogen'][0]}-{ideal['Nitrogen'][1]})")
|
| 60 |
+
elif n > ideal['Nitrogen'][1]:
|
| 61 |
+
recommendations.append(f"Nitrogen is high for {crop} (current: {n}, ideal: {ideal['Nitrogen'][0]}-{ideal['Nitrogen'][1]})")
|
| 62 |
+
|
| 63 |
+
# Phosphorus check
|
| 64 |
+
if p < ideal['Phosphorus'][0]:
|
| 65 |
+
recommendations.append(f"Phosphorus is low for {crop} (current: {p}, ideal: {ideal['Phosphorus'][0]}-{ideal['Phosphorus'][1]})")
|
| 66 |
+
elif p > ideal['Phosphorus'][1]:
|
| 67 |
+
recommendations.append(f"Phosphorus is high for {crop} (current: {p}, ideal: {ideal['Phosphorus'][0]}-{ideal['Phosphorus'][1]})")
|
| 68 |
+
|
| 69 |
+
# Potassium check
|
| 70 |
+
if k < ideal['Potassium'][0]:
|
| 71 |
+
recommendations.append(f"Potassium is low for {crop} (current: {k}, ideal: {ideal['Potassium'][0]}-{ideal['Potassium'][1]})")
|
| 72 |
+
elif k > ideal['Potassium'][1]:
|
| 73 |
+
recommendations.append(f"Potassium is high for {crop} (current: {k}, ideal: {ideal['Potassium'][0]}-{ideal['Potassium'][1]})")
|
| 74 |
+
else:
|
| 75 |
+
recommendations.append(f"No specific recommendations available for {crop}")
|
| 76 |
+
|
| 77 |
+
return "\n".join(recommendations) if recommendations else f"All nutrient levels are optimal for {crop}"
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
def predict_fertilizer(temperature, soil, nitrogen, phosphorus, potassium, crop):
|
| 81 |
+
try:
|
| 82 |
+
# Validate inputs
|
| 83 |
+
crop = crop.lower()
|
| 84 |
+
if soil not in soil_encoder.classes_:
|
| 85 |
+
raise ValueError(f"Invalid soil type. Choose from {list(soil_encoder.classes_)}")
|
| 86 |
+
if crop not in crop_encoder.classes_:
|
| 87 |
+
raise ValueError(f"Invalid crop type. Choose from {list(crop_encoder.classes_)}")
|
| 88 |
+
|
| 89 |
+
# Prepare input
|
| 90 |
+
num_features = np.array([[temperature, nitrogen, phosphorus, potassium]])
|
| 91 |
+
scaled_num = scaler.transform(num_features)
|
| 92 |
+
encoded_soil = soil_encoder.transform([soil])[0]
|
| 93 |
+
encoded_crop = crop_encoder.transform([crop])[0]
|
| 94 |
+
|
| 95 |
+
model_input = np.array([[
|
| 96 |
+
scaled_num[0][0], # Temperature
|
| 97 |
+
encoded_soil, # Soil
|
| 98 |
+
scaled_num[0][1], # Nitrogen
|
| 99 |
+
scaled_num[0][2], # Phosphorus
|
| 100 |
+
scaled_num[0][3], # Potassium
|
| 101 |
+
encoded_crop # Crop
|
| 102 |
+
]])
|
| 103 |
+
|
| 104 |
+
# Predict
|
| 105 |
+
pred = model.predict(model_input)
|
| 106 |
+
fertilizer = fertilizer_encoder.inverse_transform([np.argmax(pred)])[0]
|
| 107 |
+
|
| 108 |
+
# Generate recommendations
|
| 109 |
+
raw_input = [temperature, soil, nitrogen, phosphorus, potassium, crop]
|
| 110 |
+
crop_advice = crop_specific_recommendation(raw_input)
|
| 111 |
+
|
| 112 |
+
return fertilizer, crop_advice
|
| 113 |
+
|
| 114 |
+
except Exception as e:
|
| 115 |
+
return str(e), ""
|
| 116 |
+
|
| 117 |
+
# Create Gradio interface
|
| 118 |
+
inputs = [
|
| 119 |
+
gr.Number(label="Temperature (°C)"),
|
| 120 |
+
gr.Dropdown(label="Soil Type", choices=list(soil_encoder.classes_)),
|
| 121 |
+
gr.Number(label="Nitrogen Level (kg/ha)"),
|
| 122 |
+
gr.Number(label="Phosphorus Level (kg/ha)"),
|
| 123 |
+
gr.Number(label="Potassium Level (kg/ha)"),
|
| 124 |
+
gr.Dropdown(label="Crop Type", choices=list(crop_encoder.classes_))
|
| 125 |
+
]
|
| 126 |
+
|
| 127 |
+
outputs = [
|
| 128 |
+
gr.Textbox(label="Recommended Fertilizer"),
|
| 129 |
+
gr.Textbox(label="Crop Advice")
|
| 130 |
+
]
|
| 131 |
+
|
| 132 |
+
gr.Interface(
|
| 133 |
+
fn=predict_fertilizer,
|
| 134 |
+
inputs=inputs,
|
| 135 |
+
outputs=outputs,
|
| 136 |
+
title="Fertilizer Recommendation System",
|
| 137 |
+
description="Predict optimal fertilizer based on soil and crop conditions"
|
| 138 |
).launch()
|