AgAiSpace / app.py
rhit-leistemb
added theme and multiple models
88d5ff1
import gradio as gr
import huggingface_hub
from huggingface_hub import hf_hub_download
from joblib import load
import numpy as np
import pandas as pd
import xgboost as xgb
import pickle
# CONSTANTS------------------------------------------------------------------------------------------
# Background image
image_filename = "farm.JPG"
# Change these values to switch the model you are using and the name of the weights file in this model
model_repo_id = "AgAiPpl/AgAi"
weights1_id = "lr2.joblib"
weights2_id = "xgb_model.json"
weights3_id = "best_knnr_no_pca.joblib"
weights4_id = "best_knnr_pca.joblib"
# should ad a constant for standardizatioin file
# LOGIC----------------------------------------------------------------------------------------------
# 1. Load the model from Hugging Face Hub
def load_model(weights_id, model_type):
try:
# Download the model weights from the repo
weights_path = hf_hub_download(repo_id=model_repo_id, filename=weights_id)
# Initialize the model
if(model_type == "lr"):
model = load(weights_path)
elif(model_type == "xgb"):
model = xgb.XGBRegressor()
model.load_model(weights_path)
elif(model_type == "knn"):
model = load(weights_path)
else:
raise ValueError("Did note recognize model type")
return model
except Exception as e:
print(f"Error loading model: {e}")
return None
# 2. Load model
modelLR = load_model(weights1_id, "lr")
modelXGB = load_model(weights2_id, "xgb")
modelKNN_raw = load_model(weights3_id, "knn")
modelKNN_pca = load_model(weights4_id, "knn")
# 3. Define prediction function
def interpretModelChoice(model_input):
models_chosen = {}
if "Linear Regression" in model_input:
models_chosen["Linear Regression"] = modelLR
if "XGBoost" in model_input:
models_chosen["XGBoost"] = modelXGB
if "KNN (raw)" in model_input:
models_chosen["KNN (raw)"] = modelKNN_raw
if "KNN (PCA)" in model_input:
models_chosen["KNN (PCA)"] = modelKNN_pca
return models_chosen
def scaleNumFeatures(rainfall, temp, days_to_harvest):
scaler_path = hf_hub_download(repo_id=model_repo_id, filename='standard_scaler.pkl')
loaded_scaler = pickle.load(open(scaler_path, 'rb'))
new_data = np.array([[rainfall, temp, days_to_harvest]])
feature_names = ['Rainfall_mm', 'Temperature_Celsius', 'Days_to_Harvest'] # Use the correct names
df_new_data = pd.DataFrame(new_data, columns=feature_names)
scaled_new_data = loaded_scaler.transform(df_new_data)
# print("Original new data:", new_data)
# print("Standardized new data:", scaled_new_data)
return scaled_new_data
def interpretInputs(rainfall, temp, days_to_Harvest, fertilizer_Used, irrigation_Used, region, crop, soil, weather):
# Numbers
scaled_data = scaleNumFeatures(float(rainfall), float(temp), int(days_to_Harvest))
rainfall_num = scaled_data[0][0]
temp_num = scaled_data[0][1]
days_to_Harvest_num = scaled_data[0][2]
# Boolean
fertilizer_used_bool = 1 if fertilizer_Used == "True" else 0
irrigation_used_bool = 1 if irrigation_Used == "True" else 0
# Region
region_East = 1 if region == "East" else 0
region_North = 1 if region == "North" else 0
region_South = 1 if region == "South" else 0
region_West = 1 if region == "West" else 0
# Crop
crop_Barley = 1 if crop == "Barley" else 0
crop_Cotton = 1 if crop == "Cotton" else 0
crop_Maize = 1 if crop == "Maize" else 0
crop_Rice = 1 if crop == "Rice" else 0
crop_Soybean = 1 if crop == "Soybean" else 0
crop_Wheat = 1 if crop == "Wheat" else 0
# Soil
soil_Chalky = 1 if soil == "Chalky" else 0
soil_Clay = 1 if soil == "Clay" else 0
soil_Loam = 1 if soil == "Loam" else 0
soil_Peaty = 1 if soil == "Peaty" else 0
soil_Sandy = 1 if soil == "Sandy" else 0
soil_Silt = 1 if soil == "Silt" else 0
# Weather
weather_Cloudy = 1 if weather == "Cloudy" else 0
weather_Rainy = 1 if weather == "Rainy" else 0
weather_Sunny = 1 if weather == "Sunny" else 0
inputList = [rainfall_num, temp_num, days_to_Harvest_num,
fertilizer_used_bool, irrigation_used_bool,
region_East, region_North, region_South, region_West,
soil_Chalky, soil_Clay, soil_Loam, soil_Peaty, soil_Sandy, soil_Silt,
crop_Barley, crop_Cotton, crop_Maize, crop_Rice, crop_Soybean, crop_Wheat,
weather_Cloudy, weather_Rainy, weather_Sunny,
]
return inputList
def prediction(models, rainfall, temp, days_to_Harvest, fertilizer_Used, irrigation_Used, region, crop, soil, weather): # takes in values from Gradio components
models_chosen = interpretModelChoice(models)
interpretedValues = interpretInputs(rainfall, temp, days_to_Harvest, fertilizer_Used, irrigation_Used, region, crop, soil, weather) # One hot encode and stuff
feature_names = ['Rainfall_mm', 'Temperature_Celsius', 'Days_to_Harvest',
'Fertilizer_Used', 'Irrigation_Used',
'Region_East', 'Region_North', 'Region_South', 'Region_West',
'Soil_Type_Chalky', 'Soil_Type_Clay', 'Soil_Type_Loam', 'Soil_Type_Peaty', 'Soil_Type_Sandy', 'Soil_Type_Silt',
'Crop_Barley', 'Crop_Cotton', 'Crop_Maize', 'Crop_Rice', 'Crop_Soybean', 'Crop_Wheat',
'Weather_Condition_Cloudy', 'Weather_Condition_Rainy', 'Weather_Condition_Sunny'
]
# Need to turn the input into a dataframe to match the input of the model when it was trained
data2 = dict(zip(feature_names, [rainfall, temp, days_to_Harvest, fertilizer_Used, irrigation_Used, region, crop, soil, weather]))
df2 = pd.DataFrame([data2])
# print("Datframe before processing:\n")
# print(df2)
data = dict(zip(feature_names, interpretedValues))
df = pd.DataFrame([data])
# print("Datframe after processing:\n")
# print(df)
output_str = ""
for model_name in models_chosen:
model = models_chosen.get(model_name)
yield_prediction = model.predict(df)[0]
output = f"{model_name}: Predicted Crop Yield is {yield_prediction:.2f} tons per Hectare\n\n"
output_str += output
return output_str
# 4. Define inputs
check0 = gr.CheckboxGroup(value="Linear Regression", choices=["Linear Regression", "XGBoost", "KNN (raw)", "KNN (PCA)"], label="Which model would you like to use?")
slider1 = gr.Slider(value=147.998, minimum=0, maximum=2000, label="Rainfall (mm)")
slider2 = gr.Slider(value=29.79, minimum=0, maximum=100, label="Temperature (°C)")
slider3 = gr.Slider(value=106, minimum=0, maximum=200, label="Days to Harvest")
# TODO: make preset values for these too
radio1 = gr.Radio(value="False", choices=["True", "False"], label="Fertilizer Used?")
radio2 = gr.Radio(value="False", choices=["True", "False"], label="Irrigation Used?")
radio3 = gr.Radio(value="North", choices=["North", "South", "East", "West"], label="Region")
radio4 = gr.Radio(value="Barley", choices=["Barley", "Cotton", "Maize", "Rice", "Soybean", "Wheat"], label="Crop Type")
radio5 = gr.Radio(value="Loam", choices=["Sandy", "Loam", "Silt", "Clay", "Peaty"], label="Soil Type")
radio6 = gr.Radio(value="Sunny", choices=["Cloudy", "Rainy", "Sunny"], label="Weather")
inputs = [check0, slider1, slider2, slider3, radio1, radio2, radio3, radio4, radio5, radio6]
output = gr.Textbox(
label="Text 2",
info="Text to compare",
lines=3
)
# 5. Define custom CSS
# Removed because this was a headache
# 6. Create the gradio interface
# demo = gr.Interface(
# fn=prediction, # Function to process the image
# inputs=inputs, # Upload input
# outputs=output, # Display output
# title="Agriculture Ai",
# description="Predict crop yield based on a number of environmental and care metrics",
# theme=gr.themes.Citrus()
# )
gif_url = 'https://media2.giphy.com/media/v1.Y2lkPTc5MGI3NjExNmQwcXQwdmFvdnB2MHFvczQxZXB5ZnMxeDdhZGhkaHo1ODU1YWJyayZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/MXr43BnexrRay5R4TO/giphy.gif'
def create_interface():
with gr.Blocks(theme=gr.themes.Citrus()) as demo:
# Title
gr.Markdown("<h1 style='text-align: center;'>Agriculture AI</h1>")
gr.Markdown("<p style='text-align: center;'>Predict crop yield based on a number of environmental and care metrics</p>")
# Create a row layout for the input components
with gr.Row():
with gr.Column():
gr.Markdown("## Input") # Added a title for the input section
for input_component in inputs:
input_component.render() # Render each input component
# Column for output and GIF on the right
with gr.Column():
gr.Markdown("## Output") # Added a title for the output section
output.render()
# Add the GIF using gr.HTML below the output
gr.HTML(f"<img src='{gif_url}' alt='Crop Yield Prediction' style='max-width:100%; height:auto; margin-inline: auto;'>")
# Button to trigger prediction
predict_button = gr.Button("Predict Crop Yield")
predict_button.click(
fn=prediction,
inputs=inputs,
outputs=output
)
return demo
# 7. Launch the app
if __name__ == "__main__":
demo = create_interface()
demo.launch()