AbdullahImran commited on
Commit
b7608ef
·
verified ·
1 Parent(s): 071fda8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +66 -70
app.py CHANGED
@@ -3,7 +3,6 @@ import requests
3
  import pandas as pd
4
  import numpy as np
5
  import joblib
6
- import google.generativeai as genai
7
  import gradio as gr
8
  from datetime import datetime, timedelta
9
  from tensorflow.keras.models import load_model
@@ -25,131 +24,128 @@ API_URL = (
25
  "&timezone=UTC"
26
  )
27
 
28
- # --- GEMINI SETUP ---
29
- GOOGLE_API_KEY = os.environ.get('GOOGLE_API_KEY')
30
- if not GOOGLE_API_KEY:
31
- raise ValueError("Missing GOOGLE_API_KEY environment variable")
32
- genai.configure(api_key=GOOGLE_API_KEY)
33
- flash = genai.GenerativeModel('gemini-1.5-pro')
34
-
35
  # --- LOAD MODELS ---
36
  def load_models():
37
- # Load VGG16 wildfire detector
38
  vgg_model = load_model(
39
  'vgg16_focal_unfreeze_more.keras',
40
  custom_objects={'BinaryFocalCrossentropy': BinaryFocalCrossentropy}
41
  )
42
-
43
- # Load Xception severity classifier
44
  def focal_loss_fixed(gamma=2., alpha=.25):
45
  import tensorflow.keras.backend as K
46
  def loss_fn(y_true, y_pred):
47
- eps = K.epsilon()
48
- y_pred = K.clip(y_pred, eps, 1. - eps)
49
  ce = -y_true * K.log(y_pred)
50
- weight = alpha * K.pow(1 - y_pred, gamma)
51
- return K.mean(weight * ce, axis=-1)
52
  return loss_fn
53
-
54
  xce_model = load_model(
55
  'severity_post_tta.keras',
56
  custom_objects={'focal_loss_fixed': focal_loss_fixed()}
57
  )
58
-
59
- # Load ensemble models correctly with joblib
60
  rf_model = joblib.load('ensemble_rf_model.pkl')
61
  xgb_model = joblib.load('ensemble_xgb_model.pkl')
62
-
63
- # Load weather trend model
64
  lr_model = joblib.load('wildfire_logistic_model_synthetic.joblib')
65
-
66
  return vgg_model, xce_model, rf_model, xgb_model, lr_model
67
 
68
- # Load all models
69
  vgg_model, xception_model, rf_model, xgb_model, lr_model = load_models()
70
 
71
- # --- LABEL MAPS ---
72
  target_map = {0: 'mild', 1: 'moderate', 2: 'severe'}
73
  trend_map = {1: 'increase', 0: 'same', -1: 'decrease'}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
  # --- PIPELINE FUNCTIONS ---
76
-
77
  def detect_fire(img):
78
- x = keras_image.img_to_array(img.resize((128, 128)))[None]
79
  x = vgg_preprocess(x)
80
  prob = float(vgg_model.predict(x)[0][0])
81
  return prob >= 0.5, prob
82
 
 
83
  def classify_severity(img):
84
- x = keras_image.img_to_array(img.resize((224, 224)))[None]
85
  x = xce_preprocess(x)
86
  preds = xception_model.predict(x)
87
  rf_p = rf_model.predict(preds)[0]
88
  xgb_p = xgb_model.predict(preds)[0]
89
- ensemble = int(round((rf_p + xgb_p) / 2))
90
  return target_map.get(ensemble, 'moderate')
91
 
 
92
  def fetch_weather_trend(lat, lon):
93
  end = datetime.utcnow()
94
  start = end - timedelta(days=1)
95
- url = API_URL.format(
96
- lat=lat, lon=lon,
97
- start=start.strftime('%Y-%m-%d'),
98
- end=end.strftime('%Y-%m-%d')
99
- )
100
  data = requests.get(url).json().get('daily', {})
101
  df = pd.DataFrame(data)
102
-
103
- for c in ['precipitation_sum', 'temperature_2m_max', 'temperature_2m_min',
104
- 'relative_humidity_2m_max', 'relative_humidity_2m_min', 'windspeed_10m_max']:
105
- df[c] = pd.to_numeric(df.get(c, []), errors='coerce')
106
-
107
  df['precipitation'] = df['precipitation_sum'].fillna(0)
108
- df['temperature'] = (df['temperature_2m_max'] + df['temperature_2m_min']) / 2
109
- df['humidity'] = (df['relative_humidity_2m_max'] + df['relative_humidity_2m_min']) / 2
110
- df['wind_speed'] = df['windspeed_10m_max']
111
-
112
  df['fire_risk_score'] = (
113
- 0.4 * (df['temperature'] / 55) +
114
- 0.2 * (1 - df['humidity'] / 100) +
115
- 0.3 * (df['wind_speed'] / 60) +
116
- 0.1 * (1 - df['precipitation'] / 50)
117
  )
118
-
119
- feats = df[['temperature', 'humidity', 'wind_speed', 'precipitation', 'fire_risk_score']]
120
- feat = feats.fillna(feats.mean()).iloc[-1].values.reshape(1, -1)
121
-
122
  trend_cl = lr_model.predict(feat)[0]
123
  return trend_map.get(trend_cl, 'same')
124
 
125
- def generate_recommendations(wildfire_present, severity, weather_trend):
126
- prompt = f"""
127
- You are a wildfire management expert.
128
- - Wildfire Present: {wildfire_present}
129
- - Severity: {severity}
130
- - Weather Trend: {weather_trend}
131
- Provide:
132
- 1. Immediate actions
133
- 2. Evacuation guidelines
134
- 3. Short-term containment
135
- 4. Long-term prevention & recovery
136
- 5. Community education
137
- """
138
- return flash.generate_content(prompt).text
139
 
140
- # --- GRADIO INTERFACE ---
 
 
 
 
 
 
 
141
 
 
142
  def pipeline(image):
143
  img = Image.fromarray(image).convert('RGB')
144
  fire, prob = detect_fire(img)
145
  if not fire:
146
  return f"No wildfire detected (prob={prob:.2f})", "N/A", "N/A", "**No wildfire detected. Stay alert.**"
147
-
148
- severity = classify_severity(img)
149
  trend = fetch_weather_trend(*FOREST_COORDS['Pakistan Forest'])
150
- recs = generate_recommendations(True, severity, trend)
151
-
152
- return f"Fire Detected (prob={prob:.2f})", severity.title(), trend, recs
153
 
154
  interface = gr.Interface(
155
  fn=pipeline,
@@ -161,7 +157,7 @@ interface = gr.Interface(
161
  gr.Markdown(label='Recommendations')
162
  ],
163
  title='Wildfire Detection & Management Assistant',
164
- description='Upload an image from a forest region in Pakistan to determine wildfire presence, severity, weather-driven trend, and get expert recommendations.'
165
  )
166
 
167
  if __name__ == '__main__':
 
3
  import pandas as pd
4
  import numpy as np
5
  import joblib
 
6
  import gradio as gr
7
  from datetime import datetime, timedelta
8
  from tensorflow.keras.models import load_model
 
24
  "&timezone=UTC"
25
  )
26
 
 
 
 
 
 
 
 
27
  # --- LOAD MODELS ---
28
  def load_models():
29
+ # Fire detector (VGG16)
30
  vgg_model = load_model(
31
  'vgg16_focal_unfreeze_more.keras',
32
  custom_objects={'BinaryFocalCrossentropy': BinaryFocalCrossentropy}
33
  )
34
+ # Severity classifier (Xception)
 
35
  def focal_loss_fixed(gamma=2., alpha=.25):
36
  import tensorflow.keras.backend as K
37
  def loss_fn(y_true, y_pred):
38
+ eps = K.epsilon(); y_pred = K.clip(y_pred, eps, 1.-eps)
 
39
  ce = -y_true * K.log(y_pred)
40
+ w = alpha * K.pow(1-y_pred, gamma)
41
+ return K.mean(w * ce, axis=-1)
42
  return loss_fn
 
43
  xce_model = load_model(
44
  'severity_post_tta.keras',
45
  custom_objects={'focal_loss_fixed': focal_loss_fixed()}
46
  )
 
 
47
  rf_model = joblib.load('ensemble_rf_model.pkl')
48
  xgb_model = joblib.load('ensemble_xgb_model.pkl')
 
 
49
  lr_model = joblib.load('wildfire_logistic_model_synthetic.joblib')
 
50
  return vgg_model, xce_model, rf_model, xgb_model, lr_model
51
 
 
52
  vgg_model, xception_model, rf_model, xgb_model, lr_model = load_models()
53
 
54
+ # --- RULES & TEMPLATES ---
55
  target_map = {0: 'mild', 1: 'moderate', 2: 'severe'}
56
  trend_map = {1: 'increase', 0: 'same', -1: 'decrease'}
57
+ # severity transition rules
58
+ task_rules = {
59
+ 'mild': {'decrease':'mild','same':'mild','increase':'moderate'},
60
+ 'moderate':{'decrease':'mild','same':'moderate','increase':'severe'},
61
+ 'severe': {'decrease':'moderate','same':'severe','increase':'severe'}
62
+ }
63
+ # static recommendation templates per severity
64
+ templates = {
65
+ 'mild': (
66
+ "**1. Immediate actions:** Monitor fire; deploy spot crews.\n"
67
+ "**2. Evacuation:** No mass evacuation; notify nearby communities.\n"
68
+ "**3. Short-term containment:** Establish fire lines.\n"
69
+ "**4. Long-term prevention:** Controlled underburning; vegetation management.\n"
70
+ "**5. Education:** Inform public on firewatch and reporting." ),
71
+ 'moderate': (
72
+ "**1. Immediate actions:** Dispatch engines and aerial support.\n"
73
+ "**2. Evacuation:** Prepare evacuation zones; advise voluntary evacuation.\n"
74
+ "**3. Short-term containment:** Build fire breaks; water drops.\n"
75
+ "**4. Long-term prevention:** Fuel reduction programs.\n"
76
+ "**5. Education:** Community drills and awareness campaigns." ),
77
+ 'severe': (
78
+ "**1. Immediate actions:** Full suppression with air tankers.\n"
79
+ "**2. Evacuation:** Mandatory evacuation; open shelters.\n"
80
+ "**3. Short-term containment:** Fire retardant lines; backfires.\n"
81
+ "**4. Long-term prevention:** Reforestation; infrastructure hardening.\n"
82
+ "**5. Education:** Emergency response training; risk communication." )
83
+ }
84
 
85
  # --- PIPELINE FUNCTIONS ---
 
86
  def detect_fire(img):
87
+ x = keras_image.img_to_array(img.resize((128,128)))[None]
88
  x = vgg_preprocess(x)
89
  prob = float(vgg_model.predict(x)[0][0])
90
  return prob >= 0.5, prob
91
 
92
+
93
  def classify_severity(img):
94
+ x = keras_image.img_to_array(img.resize((224,224)))[None]
95
  x = xce_preprocess(x)
96
  preds = xception_model.predict(x)
97
  rf_p = rf_model.predict(preds)[0]
98
  xgb_p = xgb_model.predict(preds)[0]
99
+ ensemble = int(round((rf_p + xgb_p)/2))
100
  return target_map.get(ensemble, 'moderate')
101
 
102
+
103
  def fetch_weather_trend(lat, lon):
104
  end = datetime.utcnow()
105
  start = end - timedelta(days=1)
106
+ url = API_URL.format(lat=lat, lon=lon,
107
+ start=start.strftime('%Y-%m-%d'),
108
+ end=end.strftime('%Y-%m-%d'))
 
 
109
  data = requests.get(url).json().get('daily', {})
110
  df = pd.DataFrame(data)
111
+ for c in ['precipitation_sum','temperature_2m_max','temperature_2m_min',
112
+ 'relative_humidity_2m_max','relative_humidity_2m_min','windspeed_10m_max']:
113
+ df[c] = pd.to_numeric(df.get(c,[]), errors='coerce')
 
 
114
  df['precipitation'] = df['precipitation_sum'].fillna(0)
115
+ df['temperature'] = (df['temperature_2m_max'] + df['temperature_2m_min'])/2
116
+ df['humidity'] = (df['relative_humidity_2m_max'] + df['relative_humidity_2m_min'])/2
117
+ df['wind_speed'] = df['windspeed_10m_max']
 
118
  df['fire_risk_score'] = (
119
+ 0.4*(df['temperature']/55) +
120
+ 0.2*(1-df['humidity']/100) +
121
+ 0.3*(df['wind_speed']/60) +
122
+ 0.1*(1-df['precipitation']/50)
123
  )
124
+ feats = df[['temperature','humidity','wind_speed','precipitation','fire_risk_score']]
125
+ feat = feats.fillna(feats.mean()).iloc[-1].values.reshape(1,-1)
 
 
126
  trend_cl = lr_model.predict(feat)[0]
127
  return trend_map.get(trend_cl, 'same')
128
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
 
130
+ def generate_recommendations(original_severity, weather_trend):
131
+ # determine projected severity
132
+ proj = task_rules[original_severity][weather_trend]
133
+ rec = templates[proj]
134
+ header = f"**Original:** {original_severity.title()}
135
+ **Trend:** {weather_trend.title()}
136
+ **Projected:** {proj.title()}\n\n"
137
+ return header + rec
138
 
139
+ # --- GRADIO INTERFACE ---
140
  def pipeline(image):
141
  img = Image.fromarray(image).convert('RGB')
142
  fire, prob = detect_fire(img)
143
  if not fire:
144
  return f"No wildfire detected (prob={prob:.2f})", "N/A", "N/A", "**No wildfire detected. Stay alert.**"
145
+ sev = classify_severity(img)
 
146
  trend = fetch_weather_trend(*FOREST_COORDS['Pakistan Forest'])
147
+ recs = generate_recommendations(sev, trend)
148
+ return f"Fire Detected (prob={prob:.2f})", sev.title(), trend, recs
 
149
 
150
  interface = gr.Interface(
151
  fn=pipeline,
 
157
  gr.Markdown(label='Recommendations')
158
  ],
159
  title='Wildfire Detection & Management Assistant',
160
+ description='Upload an image from a forest region in Pakistan to determine wildfire presence, severity, weather-driven trend, projection, and get expert recommendations.'
161
  )
162
 
163
  if __name__ == '__main__':