bulentsoykan commited on
Commit
7822c8e
Β·
1 Parent(s): a86b789

Add application file

Browse files
Files changed (5) hide show
  1. README.md +448 -9
  2. gradio_app.py +1028 -0
  3. launch_gradio.bat +59 -0
  4. launch_gradio.sh +56 -0
  5. requirements.txt +33 -0
README.md CHANGED
@@ -1,12 +1,451 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
- title: AI4DM Gradio App
3
- emoji: 🌍
4
- colorFrom: gray
5
- colorTo: blue
6
- sdk: gradio
7
- sdk_version: 6.0.0
8
- app_file: app.py
9
- pinned: false
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🌍 NATO ASI - AI for Disaster Management: Interactive Gradio App
2
+
3
+ **A state-of-the-art interactive web application for exploring AI-powered disaster management techniques.**
4
+
5
+ ---
6
+
7
+ ## πŸ“– Overview
8
+
9
+ This Gradio application provides an **interactive learning platform** for participants of the NATO Advanced Study Institute on *"AI for Disaster Management"*. It showcases the key concepts, models, and techniques taught throughout the 7-day curriculum.
10
+
11
+ ### 🎯 Key Features
12
+
13
+ - **πŸ“š Curriculum Explorer**: Navigate through the complete 7-day course structure
14
+ - **πŸ—οΈ Building Damage Detection**: Interactive CNN-based damage classification demo
15
+ - **🌊 Flood Mapping**: Semantic segmentation with U-Net for flood extent mapping
16
+ - **πŸš€ Transfer Learning**: Compare pre-trained models (ResNet50, EfficientNet, etc.)
17
+ - **βš–οΈ Deployment & Ethics**: Learn about production deployment and responsible AI
18
+ - **πŸ“š Resources**: Comprehensive links to datasets, papers, and learning materials
19
+
20
+ ---
21
+
22
+ ## πŸš€ Quick Start
23
+
24
+ ### Prerequisites
25
+
26
+ - Python 3.8 or higher
27
+ - pip package manager
28
+
29
+ ### Installation
30
+
31
+ 1. **Clone the repository** (if you haven't already):
32
+ ```bash
33
+ git clone https://github.com/AI4DM/Geospatial-AI-for-Humanitarian-Response.git
34
+ cd Geospatial-AI-for-Humanitarian-Response
35
+ ```
36
+
37
+ 2. **Install dependencies**:
38
+ ```bash
39
+ pip install -r requirements.txt
40
+ ```
41
+
42
+ 3. **Launch the app**:
43
+ ```bash
44
+ python gradio_app.py
45
+ ```
46
+
47
+ 4. **Access the app**:
48
+ - Open your browser and navigate to: `http://localhost:7860`
49
+ - Or use the public Gradio link that appears in the terminal (if sharing is enabled)
50
+
51
+ ### Docker Installation (Alternative)
52
+
53
+ ```bash
54
+ # Build the Docker image
55
+ docker build -t nato-asi-gradio .
56
+
57
+ # Run the container
58
+ docker run -p 7860:7860 nato-asi-gradio
59
+ ```
60
+
61
+ ---
62
+
63
+ ## 🎨 Application Structure
64
+
65
+ ### Tab 1: Welcome 🏠
66
+ - Overview of the NATO ASI curriculum
67
+ - Learning philosophy and objectives
68
+ - Quick links to different sections
69
+
70
+ ### Tab 2: Curriculum πŸ“š
71
+ - Detailed day-by-day breakdown
72
+ - Learning outcomes for each module
73
+ - Key concepts and techniques
74
+
75
+ ### Tab 3: Damage Detection πŸ—οΈ
76
+ - **Functionality**: Upload building images or generate samples
77
+ - **Model**: CNN-based classification (4 damage levels)
78
+ - **Output**: Damage level prediction with confidence scores
79
+ - **Learning**: Days 2-3 content (CNN basics and production systems)
80
+
81
+ ### Tab 4: Flood Mapping 🌊
82
+ - **Functionality**: Upload satellite imagery or generate flood scenarios
83
+ - **Model**: U-Net semantic segmentation
84
+ - **Output**: Pixel-wise flood extent maps with IoU scores
85
+ - **Learning**: Days 4-5 content (semantic segmentation)
86
+
87
+ ### Tab 5: Transfer Learning πŸš€
88
+ - **Functionality**: Compare different pre-trained architectures
89
+ - **Models**: ResNet50, VGG16, MobileNetV2, EfficientNetB0
90
+ - **Output**: Performance metrics and training time comparisons
91
+ - **Learning**: Day 6 content (transfer learning techniques)
92
+
93
+ ### Tab 6: Deployment & Ethics βš–οΈ
94
+ - Model optimization techniques (TFLite, quantization)
95
+ - Deployment strategies (cloud, edge, hybrid)
96
+ - Human-in-the-loop workflows
97
+ - Ethical AI principles for disaster management
98
+
99
+ ### Tab 7: Resources πŸ“š
100
+ - Curated datasets for practice
101
+ - Online courses and tutorials
102
+ - Academic papers and research
103
+ - Humanitarian organizations and communities
104
+
105
+ ---
106
+
107
+ ## πŸ”§ Customization & Extension
108
+
109
+ ### Integrating Your Trained Models
110
+
111
+ The app currently uses **simulated predictions** for demonstration purposes. To integrate your actual trained models:
112
+
113
+ #### 1. Load Your Model
114
+
115
+ ```python
116
+ import tensorflow as tf
117
+
118
+ # Load your trained model
119
+ damage_model = tf.keras.models.load_model('path/to/your/damage_model.h5')
120
+ flood_model = tf.keras.models.load_model('path/to/your/flood_model.h5')
121
+ ```
122
+
123
+ #### 2. Replace Simulation Functions
124
+
125
+ Update the `simulate_damage_detection()` and `simulate_flood_segmentation()` functions:
126
+
127
+ ```python
128
+ def real_damage_detection(image, confidence_threshold=0.7):
129
+ """Real damage detection using trained model"""
130
+ # Preprocess image
131
+ img_array = np.array(image.resize((224, 224))) / 255.0
132
+ img_array = np.expand_dims(img_array, axis=0)
133
+
134
+ # Predict
135
+ predictions = damage_model.predict(img_array)
136
+ damage_level = np.argmax(predictions[0])
137
+ confidence = predictions[0][damage_level]
138
+
139
+ # Visualize results
140
+ result_img = create_visualization(image, damage_level, confidence)
141
+
142
+ return result_img, damage_level, confidence
143
+ ```
144
+
145
+ #### 3. Update Gradio Interface
146
+
147
+ Replace the function calls in the Gradio interface:
148
+
149
+ ```python
150
+ detect_btn.click(
151
+ fn=real_damage_detection, # Changed from simulate_damage_detection
152
+ inputs=[input_image, confidence_slider],
153
+ outputs=[output_image, damage_output, confidence_output]
154
+ )
155
+ ```
156
+
157
+ ### Adding New Features
158
+
159
+ **Example: Add a New Tab for Temporal Analysis**
160
+
161
+ ```python
162
+ def create_temporal_analysis_tab():
163
+ with gr.Column():
164
+ gr.Markdown("# πŸ“… Temporal Change Detection")
165
+
166
+ with gr.Row():
167
+ before_image = gr.Image(type="pil", label="Before Disaster")
168
+ after_image = gr.Image(type="pil", label="After Disaster")
169
+
170
+ analyze_btn = gr.Button("Analyze Changes")
171
+ change_map = gr.Image(type="pil", label="Change Detection Map")
172
+
173
+ analyze_btn.click(
174
+ fn=detect_changes,
175
+ inputs=[before_image, after_image],
176
+ outputs=[change_map]
177
+ )
178
+
179
+ # Add to main app
180
+ with gr.Tab("πŸ“… Change Detection"):
181
+ create_temporal_analysis_tab()
182
+ ```
183
+
184
  ---
185
+
186
+ ## πŸŽ“ Educational Use
187
+
188
+ ### For Instructors
189
+
190
+ This app is designed to complement the Jupyter notebooks:
191
+
192
+ 1. **Pre-Session**: Show the app during course introduction to demonstrate what students will build
193
+ 2. **During Session**: Use interactive demos to visualize concepts before coding
194
+ 3. **Post-Session**: Let students experiment with different parameters and scenarios
195
+ 4. **Assessment**: Have students integrate their trained models into the app
196
+
197
+ ### For Students
198
+
199
+ Recommended learning workflow:
200
+
201
+ 1. **Explore** β†’ Use the app to understand what you'll be building
202
+ 2. **Learn** β†’ Work through the corresponding Jupyter notebook
203
+ 3. **Build** β†’ Train your own models using the notebooks
204
+ 4. **Deploy** β†’ Integrate your models into this Gradio app
205
+ 5. **Share** β†’ Demonstrate your results to peers and instructors
206
+
207
  ---
208
 
209
+ ## 🌐 Deployment Options
210
+
211
+ ### Local Development
212
+ ```bash
213
+ python gradio_app.py
214
+ # Access at http://localhost:7860
215
+ ```
216
+
217
+ ### Public Sharing (Gradio)
218
+ The app automatically creates a public link when launched:
219
+ ```bash
220
+ python gradio_app.py
221
+ # Look for: "Running on public URL: https://xxxxx.gradio.live"
222
+ ```
223
+
224
+ ### Hugging Face Spaces
225
+
226
+ Deploy to Hugging Face Spaces for permanent hosting:
227
+
228
+ 1. Create a new Space at https://huggingface.co/spaces
229
+ 2. Upload `gradio_app.py` and `requirements.txt`
230
+ 3. Space will automatically detect and run the Gradio app
231
+
232
+ ### Google Cloud Run
233
+
234
+ ```bash
235
+ # Build container
236
+ gcloud builds submit --tag gcr.io/PROJECT_ID/nato-asi-app
237
+
238
+ # Deploy
239
+ gcloud run deploy nato-asi-app \
240
+ --image gcr.io/PROJECT_ID/nato-asi-app \
241
+ --platform managed \
242
+ --region us-central1 \
243
+ --allow-unauthenticated
244
+ ```
245
+
246
+ ### AWS EC2
247
+
248
+ ```bash
249
+ # SSH into EC2 instance
250
+ ssh -i your-key.pem ec2-user@your-instance-ip
251
+
252
+ # Install dependencies
253
+ sudo yum update -y
254
+ sudo yum install python3 -y
255
+ pip3 install -r requirements.txt
256
+
257
+ # Run with nohup for persistent execution
258
+ nohup python3 gradio_app.py > gradio.log 2>&1 &
259
+ ```
260
+
261
+ ---
262
+
263
+ ## πŸ› οΈ Technical Details
264
+
265
+ ### Architecture
266
+
267
+ ```
268
+ gradio_app.py
269
+ β”œβ”€β”€ CONSTANTS & CONFIGURATION
270
+ β”‚ β”œβ”€β”€ CURRICULUM_DAYS (course structure)
271
+ β”‚ └── DAMAGE_LEVELS (classification labels)
272
+ β”‚
273
+ β”œβ”€β”€ UTILITY FUNCTIONS
274
+ β”‚ β”œβ”€β”€ create_sample_building_image() - Generate synthetic buildings
275
+ β”‚ β”œβ”€β”€ create_flood_map_sample() - Generate flood scenarios
276
+ β”‚ β”œβ”€β”€ simulate_damage_detection() - Mock AI predictions
277
+ β”‚ └── simulate_flood_segmentation() - Mock segmentation
278
+ β”‚
279
+ β”œβ”€β”€ GRADIO INTERFACE COMPONENTS
280
+ β”‚ β”œβ”€β”€ create_welcome_tab()
281
+ β”‚ β”œβ”€β”€ create_curriculum_tab()
282
+ β”‚ β”œβ”€β”€ create_damage_detection_tab()
283
+ β”‚ β”œβ”€β”€ create_flood_mapping_tab()
284
+ β”‚ β”œβ”€β”€ create_transfer_learning_tab()
285
+ β”‚ β”œβ”€β”€ create_deployment_tab()
286
+ β”‚ └── create_resources_tab()
287
+ β”‚
288
+ └── MAIN APPLICATION
289
+ └── create_app() - Assembles all components
290
+ ```
291
+
292
+ ### Dependencies
293
+
294
+ **Core** (Required):
295
+ - `gradio` - Web interface framework
296
+ - `numpy` - Numerical computations
297
+ - `Pillow` - Image processing
298
+
299
+ **Optional** (For real model integration):
300
+ - `tensorflow` / `keras` - Deep learning
301
+ - `rasterio` - Geospatial raster data
302
+ - `geopandas` - Vector geospatial data
303
+
304
+ ### Performance
305
+
306
+ - **Launch Time**: ~2-3 seconds
307
+ - **Inference** (simulated): <100ms
308
+ - **Inference** (real TensorFlow model): 50-200ms on CPU, 10-50ms on GPU
309
+ - **Memory**: ~200MB base, +2-4GB with loaded models
310
+
311
+ ---
312
+
313
+ ## πŸ› Troubleshooting
314
+
315
+ ### Issue: Port 7860 already in use
316
+
317
+ ```bash
318
+ # Kill existing process
319
+ lsof -ti:7860 | xargs kill -9
320
+
321
+ # Or use a different port
322
+ python gradio_app.py --server-port 7861
323
+ ```
324
+
325
+ ### Issue: Module not found errors
326
+
327
+ ```bash
328
+ # Ensure all dependencies are installed
329
+ pip install --upgrade -r requirements.txt
330
+
331
+ # If using conda
332
+ conda install -c conda-forge gradio numpy pillow
333
+ ```
334
+
335
+ ### Issue: Images not displaying
336
+
337
+ - Check that PIL/Pillow is properly installed
338
+ - Verify image file paths are correct
339
+ - Ensure uploaded images are in supported formats (JPG, PNG)
340
+
341
+ ### Issue: Slow performance
342
+
343
+ - Use GPU acceleration for model inference (requires TensorFlow GPU)
344
+ - Reduce image resolution before processing
345
+ - Enable model caching for repeated predictions
346
+
347
+ ---
348
+
349
+ ## πŸ“Š Usage Analytics
350
+
351
+ To track how participants use the app, you can integrate analytics:
352
+
353
+ ```python
354
+ import gradio as gr
355
+
356
+ def track_interaction(action, details):
357
+ timestamp = datetime.now().isoformat()
358
+ log_entry = f"{timestamp} | {action} | {details}\n"
359
+ with open("usage_analytics.log", "a") as f:
360
+ f.write(log_entry)
361
+
362
+ # Example usage
363
+ detect_btn.click(
364
+ fn=lambda img, threshold: (
365
+ track_interaction("damage_detection", f"threshold={threshold}"),
366
+ detect_damage(img, threshold)
367
+ )[1],
368
+ inputs=[input_image, confidence_slider],
369
+ outputs=[output_image, damage_output, confidence_output]
370
+ )
371
+ ```
372
+
373
+ ---
374
+
375
+ ## 🀝 Contributing
376
+
377
+ We welcome contributions from the community!
378
+
379
+ ### How to Contribute
380
+
381
+ 1. **Fork** the repository
382
+ 2. **Create** a feature branch: `git checkout -b feature/new-demo`
383
+ 3. **Make** your changes
384
+ 4. **Test** thoroughly
385
+ 5. **Commit**: `git commit -m "Add new demo for landslide detection"`
386
+ 6. **Push**: `git push origin feature/new-demo`
387
+ 7. **Open** a Pull Request
388
+
389
+ ### Contribution Ideas
390
+
391
+ - πŸ†• **New Demos**: Landslide detection, wildfire mapping, infrastructure damage
392
+ - 🎨 **UI Improvements**: Better visualizations, responsive design
393
+ - πŸ“š **Documentation**: Tutorials, video guides, translations
394
+ - πŸ”§ **Features**: Real-time inference, batch processing, API endpoints
395
+ - πŸ› **Bug Fixes**: Report issues or submit fixes
396
+
397
+ ---
398
+
399
+ ## πŸ“„ License
400
+
401
+ This project is licensed under the **MIT License**. See [LICENSE](LICENSE) for details.
402
+
403
+ ---
404
+
405
+ ## πŸ™ Acknowledgments
406
+
407
+ **Developed for**: NATO Advanced Study Institute on AI for Disaster Management
408
+
409
+ **Special Thanks**:
410
+ - Disaster response professionals who provided real-world insights
411
+ - Open-source contributors of Gradio, TensorFlow, and geospatial libraries
412
+ - Organizations sharing satellite imagery and disaster datasets
413
+
414
+ ---
415
+
416
+ ## πŸ“ž Support
417
+
418
+ ### Questions or Issues?
419
+
420
+ - **GitHub Issues**: [Report bugs or request features](https://github.com/AI4DM/Geospatial-AI-for-Humanitarian-Response/issues)
421
+ - **Email**: Contact the course instructor
422
+ - **Slack/Discord**: Join the NATO ASI community channel
423
+
424
+ ### Citation
425
+
426
+ If you use this application in your work:
427
+
428
+ ```bibtex
429
+ @software{nato_asi_gradio_2025,
430
+ title={NATO ASI - AI for Disaster Management: Interactive Gradio App},
431
+ author={Bulent Soykan},
432
+ year={2025},
433
+ url={https://github.com/AI4DM/Geospatial-AI-for-Humanitarian-Response}
434
+ }
435
+ ```
436
+
437
+ ---
438
+
439
+ ## 🌟 Final Note
440
+
441
+ This application demonstrates that **AI for disaster management** is not just about algorithmsβ€”it's about creating accessible, interpretable, and actionable tools that empower humanitarian responders to save lives.
442
+
443
+ **Every feature in this app reflects a real-world need in disaster response.**
444
+
445
+ <div align="center">
446
+
447
+ **Built with ❀️ for humanitarian AI applications**
448
+
449
+ *Making the world more resilient to disasters, one model at a time.*
450
+
451
+ </div>
gradio_app.py ADDED
@@ -0,0 +1,1028 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ NATO Advanced Study Institute - AI for Disaster Management
3
+ Interactive Gradio Application
4
+
5
+ This state-of-the-art Gradio app provides an interactive interface for participants
6
+ to explore the curriculum, try AI models, and visualize disaster response scenarios.
7
+ """
8
+
9
+ import gradio as gr
10
+ import numpy as np
11
+ from PIL import Image, ImageDraw, ImageFont, ImageFilter, ImageEnhance
12
+ import io
13
+ import random
14
+ from datetime import datetime
15
+
16
+ # ============================================================================
17
+ # CONSTANTS AND CONFIGURATION
18
+ # ============================================================================
19
+
20
+ CURRICULUM_DAYS = {
21
+ "Day 0: Setup Check": {
22
+ "title": "Environment Setup & Pre-Flight Check",
23
+ "description": "Verify Google Colab environment, GPU availability, and library imports",
24
+ "notebook": "00_Setup_Check.ipynb",
25
+ "key_concepts": ["Environment verification", "GPU testing", "Dependency checks"],
26
+ "icon": "πŸ”§"
27
+ },
28
+ "Day 1: Foundations": {
29
+ "title": "Introduction to AI and Imagery",
30
+ "description": "Understanding digital images, RGB vs multispectral imagery, geospatial data formats",
31
+ "notebook": "01_Intro_to_AI_and_Imagery.ipynb",
32
+ "key_concepts": ["Image arrays", "GeoTIFF", "Coordinate systems", "Vector overlays"],
33
+ "icon": "🌍"
34
+ },
35
+ "Day 2: CNN Basics": {
36
+ "title": "Image Classification with CNNs",
37
+ "description": "Build CNNs from scratch for binary classification (damaged vs undamaged buildings)",
38
+ "notebook": "02_Image_Classification_CNN_Basics.ipynb",
39
+ "key_concepts": ["Conv2D layers", "MaxPooling", "Binary classification", "Feature visualization"],
40
+ "icon": "πŸ—οΈ"
41
+ },
42
+ "Day 3: Production Systems": {
43
+ "title": "End-to-End Workflow for Damage Detection",
44
+ "description": "Multi-class damage classification with data augmentation and class balancing",
45
+ "notebook": "03_End_to_End_Workflow_Damage_Detection.ipynb",
46
+ "key_concepts": ["Multi-class classification", "Data augmentation", "Class weights", "F1-score"],
47
+ "icon": "🎯"
48
+ },
49
+ "Day 4-5: Segmentation": {
50
+ "title": "Semantic Segmentation for Flood Mapping",
51
+ "description": "U-Net architecture for pixel-level flood detection from satellite imagery",
52
+ "notebook": "04_Semantic_Segmentation_Flood_Mapping.ipynb",
53
+ "key_concepts": ["U-Net", "Encoder-decoder", "IoU metric", "Pixel-wise classification"],
54
+ "icon": "🌊"
55
+ },
56
+ "Day 6: Transfer Learning": {
57
+ "title": "Transfer Learning for Efficiency",
58
+ "description": "Leverage pre-trained models (ResNet50, VGG16, EfficientNet) for rapid development",
59
+ "notebook": "05_Transfer_Learning_for_Efficiency.ipynb",
60
+ "key_concepts": ["Feature extraction", "Fine-tuning", "Pre-trained models", "Limited data"],
61
+ "icon": "πŸš€"
62
+ },
63
+ "Day 7: Deployment": {
64
+ "title": "Deployment Considerations & Ethics",
65
+ "description": "Model optimization, deployment strategies, human-in-the-loop, responsible AI",
66
+ "notebook": "06_Deployment_Considerations.ipynb",
67
+ "key_concepts": ["Model optimization", "TFLite", "Edge deployment", "AI ethics"],
68
+ "icon": "βš–οΈ"
69
+ }
70
+ }
71
+
72
+ DAMAGE_LEVELS = {
73
+ 0: {"name": "No Damage", "color": "#00FF00", "description": "Building intact"},
74
+ 1: {"name": "Minor Damage", "color": "#FFFF00", "description": "Minor structural issues"},
75
+ 2: {"name": "Major Damage", "color": "#FFA500", "description": "Significant structural damage"},
76
+ 3: {"name": "Destroyed", "color": "#FF0000", "description": "Building destroyed"}
77
+ }
78
+
79
+ # ============================================================================
80
+ # UTILITY FUNCTIONS
81
+ # ============================================================================
82
+
83
+ def create_sample_building_image(damage_level=0):
84
+ """Create a synthetic building image with specified damage level"""
85
+ img = Image.new('RGB', (256, 256), color='skyblue')
86
+ draw = ImageDraw.Draw(img)
87
+
88
+ # Draw ground
89
+ draw.rectangle([(0, 180), (256, 256)], fill='#228B22')
90
+
91
+ # Draw building based on damage level
92
+ if damage_level == 0: # No damage
93
+ # Intact building
94
+ draw.rectangle([(80, 100), (176, 180)], fill='#8B4513', outline='black', width=2)
95
+ # Windows
96
+ for i in range(3):
97
+ for j in range(2):
98
+ draw.rectangle([(95 + i*25, 115 + j*25), (110 + i*25, 135 + j*25)],
99
+ fill='lightblue', outline='black', width=1)
100
+ # Roof
101
+ draw.polygon([(70, 100), (128, 60), (186, 100)], fill='#A0522D', outline='black')
102
+
103
+ elif damage_level == 1: # Minor damage
104
+ draw.rectangle([(80, 100), (176, 180)], fill='#8B4513', outline='black', width=2)
105
+ # Some broken windows
106
+ for i in range(3):
107
+ for j in range(2):
108
+ if random.random() > 0.5:
109
+ draw.rectangle([(95 + i*25, 115 + j*25), (110 + i*25, 135 + j*25)],
110
+ fill='lightblue', outline='black', width=1)
111
+ else:
112
+ draw.rectangle([(95 + i*25, 115 + j*25), (110 + i*25, 135 + j*25)],
113
+ fill='gray', outline='black', width=1)
114
+ # Slightly damaged roof
115
+ draw.polygon([(70, 100), (128, 65), (186, 100)], fill='#8B4513', outline='black')
116
+
117
+ elif damage_level == 2: # Major damage
118
+ # Partially collapsed building
119
+ draw.polygon([(80, 180), (80, 120), (140, 110), (176, 140), (176, 180)],
120
+ fill='#654321', outline='black', width=2)
121
+ # Debris
122
+ for _ in range(10):
123
+ x, y = random.randint(70, 180), random.randint(160, 180)
124
+ draw.rectangle([(x, y), (x+10, y+10)], fill='gray')
125
+ # Damaged roof
126
+ draw.polygon([(70, 120), (110, 85), (150, 110)], fill='#654321', outline='black')
127
+
128
+ else: # Destroyed
129
+ # Rubble pile
130
+ for _ in range(30):
131
+ x, y = random.randint(60, 190), random.randint(140, 180)
132
+ size = random.randint(5, 20)
133
+ color = random.choice(['#696969', '#808080', '#A9A9A9', '#654321'])
134
+ draw.rectangle([(x, y), (x+size, y+size)], fill=color)
135
+ # Scattered debris
136
+ for _ in range(20):
137
+ x, y = random.randint(40, 210), random.randint(120, 185)
138
+ draw.circle((x, y), random.randint(2, 8), fill='#404040')
139
+
140
+ return img
141
+
142
+
143
+ def create_flood_map_sample(flood_percentage=30):
144
+ """Create a synthetic satellite image with flood overlay"""
145
+ # Base satellite-like image
146
+ img = Image.new('RGB', (512, 512), color='#90EE90')
147
+ draw = ImageDraw.Draw(img)
148
+
149
+ # Add terrain variation
150
+ np.random.seed(42)
151
+ pixels = np.array(img)
152
+ noise = np.random.randint(-30, 30, pixels.shape)
153
+ pixels = np.clip(pixels.astype(int) + noise, 0, 255).astype(np.uint8)
154
+ img = Image.fromarray(pixels)
155
+ draw = ImageDraw.Draw(img, 'RGBA')
156
+
157
+ # Add roads
158
+ draw.rectangle([(100, 0), (120, 512)], fill='#696969')
159
+ draw.rectangle([(0, 250), (512, 270)], fill='#696969')
160
+
161
+ # Add buildings
162
+ for i in range(15):
163
+ x, y = random.randint(0, 480), random.randint(0, 480)
164
+ w, h = random.randint(20, 40), random.randint(20, 40)
165
+ draw.rectangle([(x, y), (x+w, y+h)], fill='#8B4513', outline='black')
166
+
167
+ # Add flood areas (semi-transparent blue)
168
+ flood_regions = int((flood_percentage / 100) * 10)
169
+ for _ in range(flood_regions):
170
+ x, y = random.randint(0, 400), random.randint(0, 400)
171
+ w, h = random.randint(80, 150), random.randint(80, 150)
172
+ draw.ellipse([(x, y), (x+w, y+h)], fill=(0, 100, 255, 120))
173
+
174
+ return img
175
+
176
+
177
+ def simulate_damage_detection(image, confidence_threshold=0.7):
178
+ """Simulate building damage detection on an uploaded image"""
179
+ # Simulate AI prediction
180
+ damage_level = random.randint(0, 3)
181
+ confidence = random.uniform(confidence_threshold, 0.99)
182
+
183
+ # Create result visualization
184
+ result_img = image.copy()
185
+ draw = ImageDraw.Draw(result_img)
186
+
187
+ # Draw bounding box with damage level color
188
+ width, height = result_img.size
189
+ margin = 20
190
+ color = DAMAGE_LEVELS[damage_level]["color"]
191
+ draw.rectangle([(margin, margin), (width-margin, height-margin)],
192
+ outline=color, width=5)
193
+
194
+ # Add label
195
+ label = f"{DAMAGE_LEVELS[damage_level]['name']}: {confidence:.2%}"
196
+
197
+ # Create label background
198
+ try:
199
+ font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 20)
200
+ except:
201
+ font = ImageFont.load_default()
202
+
203
+ bbox = draw.textbbox((margin, margin-30), label, font=font)
204
+ draw.rectangle(bbox, fill=color)
205
+ draw.text((margin, margin-30), label, fill='black', font=font)
206
+
207
+ return result_img, damage_level, confidence
208
+
209
+
210
+ def simulate_flood_segmentation(image):
211
+ """Simulate flood segmentation on an uploaded image"""
212
+ # Convert to numpy array
213
+ img_array = np.array(image)
214
+
215
+ # Create synthetic flood mask (detect blue-ish areas)
216
+ # This is a simple heuristic, not actual ML
217
+ blue_channel = img_array[:, :, 2]
218
+ green_channel = img_array[:, :, 1]
219
+ red_channel = img_array[:, :, 0]
220
+
221
+ # Areas where blue is dominant
222
+ flood_mask = (blue_channel > 100) & (blue_channel > red_channel + 20)
223
+
224
+ # Create overlay
225
+ overlay = image.copy()
226
+ overlay_array = np.array(overlay)
227
+ overlay_array[flood_mask] = [0, 150, 255] # Blue overlay for flood
228
+
229
+ # Blend
230
+ result = Image.blend(image, Image.fromarray(overlay_array), alpha=0.4)
231
+
232
+ flood_percentage = (np.sum(flood_mask) / flood_mask.size) * 100
233
+ iou_score = random.uniform(0.75, 0.95)
234
+
235
+ return result, flood_percentage, iou_score
236
+
237
+
238
+ # ============================================================================
239
+ # GRADIO INTERFACE COMPONENTS
240
+ # ============================================================================
241
+
242
+ def create_welcome_tab():
243
+ """Create the welcome/overview tab"""
244
+ with gr.Column():
245
+ gr.Markdown("""
246
+ # 🌍 NATO Advanced Study Institute
247
+ ## AI for Disaster Management: Interactive Learning Platform
248
+
249
+ Welcome to the interactive demonstration platform for the **NATO ASI on AI for Disaster Management**!
250
+
251
+ ### 🎯 What is this platform?
252
+
253
+ This application provides hands-on demonstrations of the AI techniques covered in our 7-day curriculum
254
+ on **Geospatial AI for Humanitarian Response**. You can:
255
+
256
+ - πŸ“š **Explore the Curriculum**: Navigate through each day's content and learning objectives
257
+ - πŸ€– **Try AI Models**: Interactive demos of damage detection, flood mapping, and more
258
+ - πŸ“Š **Visualize Results**: See how AI analyzes satellite imagery for disaster response
259
+ - πŸš€ **Learn by Doing**: Upload your own images and experiment with the models
260
+
261
+ ### πŸ† Learning Philosophy
262
+
263
+ > *"What I cannot create, I do not understand."* β€” Richard Feynman
264
+
265
+ This curriculum emphasizes **practical implementation** over theoretical knowledge. Every concept
266
+ is taught through hands-on coding, building real systems that address actual disaster management challenges.
267
+
268
+ ### πŸ“ˆ Course Overview
269
+
270
+ Our 7-day curriculum takes you from fundamentals to deployment:
271
+
272
+ | Day | Topic | Key Technology |
273
+ |-----|-------|----------------|
274
+ | **0** | Environment Setup | Google Colab, GPU, Libraries |
275
+ | **1** | Foundations | Image Processing, Geospatial Data |
276
+ | **2** | CNN Basics | Convolutional Neural Networks |
277
+ | **3** | Production Systems | Multi-class Classification, Augmentation |
278
+ | **4-5** | Segmentation | U-Net, Flood Mapping |
279
+ | **6** | Transfer Learning | ResNet50, EfficientNet |
280
+ | **7** | Deployment & Ethics | TFLite, Responsible AI |
281
+
282
+ ### 🌟 Real-World Impact
283
+
284
+ The techniques you'll learn are used by humanitarian organizations worldwide:
285
+
286
+ - **πŸ—οΈ Building Damage Assessment**: Classify 100,000+ buildings in hours after earthquakes
287
+ - **🌊 Flood Mapping**: Identify inundated areas to direct rescue operations
288
+ - **πŸ›£οΈ Infrastructure Analysis**: Locate blocked roads and damaged bridges
289
+ - **πŸ“ Resource Allocation**: Prioritize areas for relief distribution
290
+
291
+ ### πŸš€ Get Started
292
+
293
+ 1. **Explore Curriculum**: Check out the detailed day-by-day breakdown
294
+ 2. **Try Demos**: Experiment with damage detection and flood mapping models
295
+ 3. **Upload Images**: Test the models on your own satellite/aerial imagery
296
+ 4. **Review Notebooks**: Access the complete Jupyter notebooks for hands-on coding
297
+
298
+ ---
299
+
300
+ **Built with ❀️ for humanitarian AI applications**
301
+
302
+ *Making the world more resilient to disasters, one model at a time.*
303
+ """)
304
+
305
+ with gr.Row():
306
+ gr.Button("πŸ“š View Curriculum", size="lg", variant="primary")
307
+ gr.Button("πŸ€– Try Damage Detection", size="lg", variant="secondary")
308
+ gr.Button("🌊 Try Flood Mapping", size="lg", variant="secondary")
309
+
310
+
311
+ def create_curriculum_tab():
312
+ """Create the curriculum explorer tab"""
313
+ with gr.Column():
314
+ gr.Markdown("# πŸ“š Curriculum Explorer")
315
+ gr.Markdown("Detailed breakdown of each day's content, learning objectives, and key concepts.")
316
+
317
+ for day, info in CURRICULUM_DAYS.items():
318
+ with gr.Accordion(f"{info['icon']} {day}: {info['title']}", open=False):
319
+ gr.Markdown(f"""
320
+ ### {info['title']}
321
+
322
+ **{info['description']}**
323
+
324
+ **πŸ““ Notebook**: `{info['notebook']}`
325
+
326
+ **πŸ”‘ Key Concepts**:
327
+ {chr(10).join([f'- {concept}' for concept in info['key_concepts']])}
328
+
329
+ **πŸ’‘ Learning Outcomes**:
330
+ By the end of this module, you will be able to apply these concepts to real-world
331
+ disaster management scenarios and build production-ready systems.
332
+ """)
333
+
334
+
335
+ def create_damage_detection_tab():
336
+ """Create the building damage detection demo tab"""
337
+ with gr.Column():
338
+ gr.Markdown("""
339
+ # πŸ—οΈ Building Damage Detection
340
+
341
+ This demo simulates the CNN-based damage classification system taught in **Days 2-3**.
342
+
343
+ ## How it works:
344
+ 1. **Upload** an image of a building or generate a sample
345
+ 2. The AI model classifies damage into 4 levels: None, Minor, Major, Destroyed
346
+ 3. **View** the results with confidence scores and visualizations
347
+
348
+ ## Damage Classification Levels:
349
+ - 🟒 **No Damage**: Building structurally intact
350
+ - 🟑 **Minor Damage**: Superficial damage, building functional
351
+ - 🟠 **Major Damage**: Significant structural damage, unsafe
352
+ - πŸ”΄ **Destroyed**: Building collapsed or completely destroyed
353
+ """)
354
+
355
+ with gr.Row():
356
+ with gr.Column():
357
+ damage_level_choice = gr.Radio(
358
+ choices=["No Damage", "Minor Damage", "Major Damage", "Destroyed"],
359
+ label="Generate Sample Building",
360
+ value="No Damage"
361
+ )
362
+ generate_btn = gr.Button("🎨 Generate Sample Image", variant="secondary")
363
+
364
+ gr.Markdown("### Or Upload Your Own Image")
365
+ input_image = gr.Image(type="pil", label="Upload Building Image")
366
+
367
+ confidence_slider = gr.Slider(
368
+ minimum=0.5, maximum=0.99, value=0.7, step=0.05,
369
+ label="Confidence Threshold"
370
+ )
371
+
372
+ detect_btn = gr.Button("πŸ” Detect Damage", variant="primary", size="lg")
373
+
374
+ with gr.Column():
375
+ output_image = gr.Image(type="pil", label="Detection Results")
376
+
377
+ with gr.Row():
378
+ damage_output = gr.Textbox(label="Predicted Damage Level", interactive=False)
379
+ confidence_output = gr.Textbox(label="Confidence Score", interactive=False)
380
+
381
+ gr.Markdown("""
382
+ ### πŸ“Š Model Performance Metrics
383
+
384
+ In the actual training notebooks, you'll achieve:
385
+ - **Accuracy**: 85-92% on validation set
386
+ - **F1-Score**: 0.82-0.89 (balanced across classes)
387
+ - **Inference Time**: ~50ms per image on GPU
388
+
389
+ ### πŸŽ“ What You'll Learn
390
+
391
+ **Day 2**: Build basic CNNs for binary classification
392
+ **Day 3**: Implement production systems with:
393
+ - Multi-class classification (4 damage levels)
394
+ - Data augmentation for robustness
395
+ - Class balancing techniques
396
+ - Comprehensive evaluation metrics
397
+ """)
398
+
399
+ def generate_sample(damage_choice):
400
+ damage_map = {
401
+ "No Damage": 0,
402
+ "Minor Damage": 1,
403
+ "Major Damage": 2,
404
+ "Destroyed": 3
405
+ }
406
+ return create_sample_building_image(damage_map[damage_choice])
407
+
408
+ def detect_damage(image, threshold):
409
+ if image is None:
410
+ return None, "No image provided", "N/A"
411
+
412
+ result_img, damage_level, confidence = simulate_damage_detection(image, threshold)
413
+ damage_text = DAMAGE_LEVELS[damage_level]["name"]
414
+ confidence_text = f"{confidence:.2%}"
415
+
416
+ return result_img, damage_text, confidence_text
417
+
418
+ generate_btn.click(
419
+ fn=generate_sample,
420
+ inputs=[damage_level_choice],
421
+ outputs=[input_image]
422
+ )
423
+
424
+ detect_btn.click(
425
+ fn=detect_damage,
426
+ inputs=[input_image, confidence_slider],
427
+ outputs=[output_image, damage_output, confidence_output]
428
+ )
429
+
430
+
431
+ def create_flood_mapping_tab():
432
+ """Create the flood segmentation demo tab"""
433
+ with gr.Column():
434
+ gr.Markdown("""
435
+ # 🌊 Flood Mapping with Semantic Segmentation
436
+
437
+ This demo simulates the **U-Net segmentation** system taught in **Days 4-5**.
438
+
439
+ ## How it works:
440
+ 1. **Upload** satellite imagery or generate a sample flood scenario
441
+ 2. The U-Net model performs pixel-wise classification
442
+ 3. **View** the flood extent map with percentage coverage and IoU scores
443
+
444
+ ## Why Segmentation?
445
+
446
+ Unlike classification (which gives one label per image), **semantic segmentation**
447
+ provides a label for *every pixel*, enabling:
448
+ - Precise flood extent mapping
449
+ - Area calculations for affected regions
450
+ - Integration with GIS systems for rescue planning
451
+ """)
452
+
453
+ with gr.Row():
454
+ with gr.Column():
455
+ flood_slider = gr.Slider(
456
+ minimum=0, maximum=80, value=30, step=5,
457
+ label="Flood Coverage % (for sample generation)"
458
+ )
459
+ generate_flood_btn = gr.Button("🌊 Generate Flood Scenario", variant="secondary")
460
+
461
+ gr.Markdown("### Or Upload Satellite Imagery")
462
+ flood_input = gr.Image(type="pil", label="Upload Satellite Image")
463
+
464
+ segment_btn = gr.Button("πŸ—ΊοΈ Map Flood Extent", variant="primary", size="lg")
465
+
466
+ with gr.Column():
467
+ flood_output = gr.Image(type="pil", label="Flood Segmentation Results")
468
+
469
+ with gr.Row():
470
+ flood_percent_output = gr.Textbox(label="Flood Coverage %", interactive=False)
471
+ iou_output = gr.Textbox(label="IoU Score", interactive=False)
472
+
473
+ gr.Markdown("""
474
+ ### πŸ“Š U-Net Architecture
475
+
476
+ ```
477
+ Encoder (Downsampling) Decoder (Upsampling)
478
+ ↓ ↑
479
+ Conv β†’ Pool β†’ Conv β†’ Pool Upconv β†’ Concat β†’ Conv
480
+ ↓ ↓ ↑
481
+ Bottleneck Skip Connections
482
+ ```
483
+
484
+ **Key Innovation**: Skip connections preserve spatial information
485
+
486
+ ### πŸ“ˆ Model Performance
487
+
488
+ - **IoU (Intersection over Union)**: 0.78-0.92
489
+ - **Dice Coefficient**: 0.85-0.94
490
+ - **Pixel Accuracy**: 88-95%
491
+
492
+ ### πŸŽ“ What You'll Learn
493
+
494
+ **Days 4-5**: Implement U-Net for flood mapping
495
+ - Encoder-decoder architecture
496
+ - Skip connections for spatial preservation
497
+ - Custom loss functions (Dice loss, Focal loss)
498
+ - Post-processing techniques
499
+
500
+ ### 🌍 Real-World Applications
501
+
502
+ - **Hurricane Harvey (2017)**: Mapped 300+ sq km of flooding
503
+ - **Kerala Floods (2018)**: Prioritized rescue operations
504
+ - **Mozambique Cyclone (2019)**: Infrastructure damage assessment
505
+ """)
506
+
507
+ def generate_flood_sample(flood_pct):
508
+ return create_flood_map_sample(flood_pct)
509
+
510
+ def segment_flood(image):
511
+ if image is None:
512
+ return None, "No image provided", "N/A"
513
+
514
+ result_img, flood_pct, iou = simulate_flood_segmentation(image)
515
+
516
+ return result_img, f"{flood_pct:.2f}%", f"{iou:.3f}"
517
+
518
+ generate_flood_btn.click(
519
+ fn=generate_flood_sample,
520
+ inputs=[flood_slider],
521
+ outputs=[flood_input]
522
+ )
523
+
524
+ segment_btn.click(
525
+ fn=segment_flood,
526
+ inputs=[flood_input],
527
+ outputs=[flood_output, flood_percent_output, iou_output]
528
+ )
529
+
530
+
531
+ def create_transfer_learning_tab():
532
+ """Create the transfer learning comparison tab"""
533
+ with gr.Column():
534
+ gr.Markdown("""
535
+ # πŸš€ Transfer Learning: Standing on the Shoulders of Giants
536
+
537
+ This demo illustrates the power of **transfer learning** taught in **Day 6**.
538
+
539
+ ## Why Transfer Learning?
540
+
541
+ Training deep neural networks from scratch requires:
542
+ - ❌ Millions of labeled images
543
+ - ❌ Days/weeks of training time
544
+ - ❌ Expensive GPU resources
545
+
546
+ Transfer learning allows you to:
547
+ - βœ… Use pre-trained models (ImageNet, COCO, etc.)
548
+ - βœ… Train with 10x less data
549
+ - βœ… Achieve better accuracy in less time
550
+
551
+ ## Available Pre-trained Models
552
+ """)
553
+
554
+ with gr.Row():
555
+ with gr.Column():
556
+ model_choice = gr.Radio(
557
+ choices=["ResNet50", "VGG16", "MobileNetV2", "EfficientNetB0"],
558
+ label="Select Pre-trained Model",
559
+ value="ResNet50"
560
+ )
561
+
562
+ training_mode = gr.Radio(
563
+ choices=["Feature Extraction", "Fine-Tuning"],
564
+ label="Transfer Learning Mode",
565
+ value="Feature Extraction"
566
+ )
567
+
568
+ dataset_size = gr.Slider(
569
+ minimum=100, maximum=10000, value=1000, step=100,
570
+ label="Training Dataset Size"
571
+ )
572
+
573
+ compare_btn = gr.Button("πŸ“Š Compare Models", variant="primary", size="lg")
574
+
575
+ with gr.Column():
576
+ gr.Markdown("### πŸ“ˆ Model Comparison Results")
577
+
578
+ comparison_output = gr.Markdown()
579
+
580
+ gr.Markdown("""
581
+ ### 🎯 Model Characteristics
582
+
583
+ | Model | Parameters | Speed | Accuracy | Best For |
584
+ |-------|-----------|-------|----------|----------|
585
+ | **ResNet50** | 25.6M | Medium | High | General purpose |
586
+ | **VGG16** | 138M | Slow | High | Feature extraction |
587
+ | **MobileNetV2** | 3.5M | Fast | Medium | Edge devices |
588
+ | **EfficientNetB0** | 5.3M | Medium | Very High | Best trade-off |
589
+
590
+ ### πŸ”§ Two Approaches
591
+
592
+ **Feature Extraction**:
593
+ - Freeze pre-trained layers
594
+ - Only train final classifier
595
+ - ⚑ Fast training (minutes)
596
+ - Works with small datasets
597
+
598
+ **Fine-Tuning**:
599
+ - Unfreeze some layers
600
+ - Adjust pre-trained weights
601
+ - 🎯 Higher accuracy
602
+ - Needs more data & time
603
+ """)
604
+
605
+ def compare_models(model, mode, size):
606
+ # Simulate comparison results
607
+ base_accuracy = {
608
+ "ResNet50": 0.87,
609
+ "VGG16": 0.85,
610
+ "MobileNetV2": 0.82,
611
+ "EfficientNetB0": 0.90
612
+ }
613
+
614
+ base_time = {
615
+ "ResNet50": 45,
616
+ "VGG16": 80,
617
+ "MobileNetV2": 25,
618
+ "EfficientNetB0": 50
619
+ }
620
+
621
+ # Adjust based on mode and dataset size
622
+ accuracy = base_accuracy[model]
623
+ if mode == "Fine-Tuning":
624
+ accuracy += 0.03
625
+
626
+ accuracy *= (1 + np.log10(size / 1000) * 0.05)
627
+ accuracy = min(accuracy, 0.98)
628
+
629
+ training_time = base_time[model] * (size / 1000)
630
+ if mode == "Fine-Tuning":
631
+ training_time *= 2.5
632
+
633
+ # From-scratch comparison
634
+ scratch_accuracy = accuracy - 0.15
635
+ scratch_time = training_time * 5
636
+
637
+ result = f"""
638
+ ### πŸ† Results for {model} ({mode})
639
+
640
+ **Transfer Learning Performance**:
641
+ - βœ… **Accuracy**: {accuracy:.1%}
642
+ - ⏱️ **Training Time**: {training_time:.1f} minutes
643
+ - πŸ“Š **Dataset Size**: {size:,} images
644
+
645
+ **vs. Training from Scratch**:
646
+ - ⚠️ **Accuracy**: {scratch_accuracy:.1%} ({(accuracy - scratch_accuracy):.1%} worse)
647
+ - ⏱️ **Training Time**: {scratch_time:.1f} minutes ({scratch_time/training_time:.1f}x slower)
648
+ - πŸ“Š **Dataset Needed**: {size * 10:,} images ({10}x more data)
649
+
650
+ ---
651
+
652
+ ### πŸ’‘ Insights
653
+
654
+ {"**Feature Extraction** is ideal for this dataset size. You're freezing the convolutional base and only training the classification head, which is fast and prevents overfitting." if mode == "Feature Extraction" else "**Fine-Tuning** can achieve higher accuracy but requires more data and training time. Consider this if you have >5000 labeled examples."}
655
+
656
+ ### πŸ“ˆ Improvement Over Baseline
657
+
658
+ Transfer learning gives you a **{(accuracy - scratch_accuracy) / scratch_accuracy * 100:.1f}% accuracy boost** while training **{scratch_time/training_time:.1f}x faster**!
659
+ """
660
+
661
+ return result
662
+
663
+ compare_btn.click(
664
+ fn=compare_models,
665
+ inputs=[model_choice, training_mode, dataset_size],
666
+ outputs=[comparison_output]
667
+ )
668
+
669
+
670
+ def create_deployment_tab():
671
+ """Create the deployment and ethics tab"""
672
+ with gr.Column():
673
+ gr.Markdown("""
674
+ # βš–οΈ Deployment Considerations & Responsible AI
675
+
676
+ Day 7 focuses on the **critical final step**: deploying AI systems that work reliably
677
+ in real disaster scenarios while maintaining ethical standards.
678
+
679
+ ## πŸš€ Deployment Pipeline
680
+ """)
681
+
682
+ with gr.Row():
683
+ with gr.Column():
684
+ gr.Markdown("""
685
+ ### 1️⃣ Model Optimization
686
+
687
+ **TensorFlow Lite Conversion**:
688
+ ```python
689
+ converter = tf.lite.TFLiteConverter.from_saved_model(model_path)
690
+ converter.optimizations = [tf.lite.Optimize.DEFAULT]
691
+ tflite_model = converter.convert()
692
+ ```
693
+
694
+ **Benefits**:
695
+ - πŸ“‰ 4x smaller model size
696
+ - ⚑ 3x faster inference
697
+ - πŸ“± Runs on mobile/edge devices
698
+
699
+ ### 2️⃣ Quantization
700
+
701
+ - **Float16**: 50% size reduction, minimal accuracy loss
702
+ - **Int8**: 75% size reduction, 1-2% accuracy loss
703
+ - **Dynamic Range**: Best balance for most cases
704
+ """)
705
+
706
+ with gr.Column():
707
+ gr.Markdown("""
708
+ ### 3️⃣ Deployment Strategies
709
+
710
+ | Strategy | Latency | Scale | Cost | Best For |
711
+ |----------|---------|-------|------|----------|
712
+ | **Cloud** | 100-500ms | High | $$$ | Central processing |
713
+ | **Edge** | 10-50ms | Medium | $ | Field operations |
714
+ | **Hybrid** | Variable | Very High | $$ | Resilient systems |
715
+
716
+ ### 4️⃣ Human-in-the-Loop
717
+
718
+ ```python
719
+ if confidence < threshold:
720
+ # Route to human expert
721
+ queue_for_review(image, prediction)
722
+ else:
723
+ # Auto-approve high-confidence predictions
724
+ process_automatically(image, prediction)
725
+ ```
726
+ """)
727
+
728
+ gr.Markdown("""
729
+ ---
730
+
731
+ ## βš–οΈ Ethical AI Principles
732
+
733
+ ### 🎯 Core Tenets for Disaster Response AI
734
+
735
+ **1. Transparency**
736
+ - Explain model decisions to stakeholders
737
+ - Document limitations and failure modes
738
+ - Make confidence scores visible
739
+
740
+ **2. Fairness & Bias**
741
+ - Test on diverse geographies and building types
742
+ - Avoid over-representing certain regions
743
+ - Monitor for demographic disparities in accuracy
744
+
745
+ **3. Privacy & Security**
746
+ - Protect personally identifiable information (PII)
747
+ - Secure data transmission and storage
748
+ - Comply with data protection regulations
749
+
750
+ **4. Accountability**
751
+ - Maintain audit trails
752
+ - Enable human oversight
753
+ - Design fail-safes for critical decisions
754
+
755
+ **5. Beneficence**
756
+ - Prioritize humanitarian impact
757
+ - Avoid dual-use concerns
758
+ - Share knowledge with disaster response community
759
+
760
+ ---
761
+
762
+ ## πŸ›‘οΈ Responsible Deployment Checklist
763
+
764
+ Before deploying your disaster management AI system:
765
+
766
+ - [ ] **Validation**: Test on held-out disaster events
767
+ - [ ] **Robustness**: Evaluate on different sensors, seasons, lighting
768
+ - [ ] **Calibration**: Ensure confidence scores reflect true accuracy
769
+ - [ ] **Monitoring**: Set up performance tracking in production
770
+ - [ ] **Fallback**: Design graceful degradation when AI fails
771
+ - [ ] **Documentation**: Create user guides for non-technical operators
772
+ - [ ] **Ethics Review**: Assess potential harms and mitigation strategies
773
+ - [ ] **Stakeholder Buy-in**: Get approval from response teams who'll use it
774
+
775
+ ---
776
+
777
+ ## πŸ’­ Final Reflection
778
+
779
+ > *"The best AI model is one that helps people, not one that achieves
780
+ > the highest accuracy on a benchmark."*
781
+
782
+ In disaster management, a model that:
783
+ - βœ… Works reliably in the field
784
+ - βœ… Integrates with human workflows
785
+ - βœ… Earns trust through transparency
786
+ - βœ… Fails gracefully
787
+
788
+ ...is far more valuable than one with perfect test set performance.
789
+
790
+ **This curriculum emphasizes practical deployment, ethical considerations,
791
+ and human oversightβ€”because when lives are at stake, responsible AI is
792
+ the only acceptable approach.**
793
+ """)
794
+
795
+
796
+ def create_resources_tab():
797
+ """Create the resources and documentation tab"""
798
+ with gr.Column():
799
+ gr.Markdown("""
800
+ # πŸ“š Resources & Further Learning
801
+
802
+ ## πŸŽ“ Course Materials
803
+
804
+ All notebooks are available in this repository:
805
+
806
+ - `00_Setup_Check.ipynb` - Environment verification
807
+ - `01_Intro_to_AI_and_Imagery.ipynb` - Image fundamentals
808
+ - `02_Image_Classification_CNN_Basics.ipynb` - CNN basics
809
+ - `03_End_to_End_Workflow_Damage_Detection.ipynb` - Production systems
810
+ - `04_Semantic_Segmentation_Flood_Mapping.ipynb` - U-Net segmentation
811
+ - `05_Transfer_Learning_for_Efficiency.ipynb` - Transfer learning
812
+ - `06_Deployment_Considerations.ipynb` - Deployment & ethics
813
+
814
+ ---
815
+
816
+ ## πŸ“Š Datasets for Practice
817
+
818
+ ### Building Damage Assessment
819
+ - **xView2 (xBD)**: 850,000+ building annotations across multiple disaster types
820
+ - [https://xview2.org/](https://xview2.org/)
821
+ - **RescueNet**: Damaged buildings from natural disasters
822
+
823
+ ### Flood Mapping
824
+ - **SEN12-FLOOD**: Global flood detection dataset
825
+ - **FloodNet**: High-resolution flood imagery
826
+
827
+ ### Satellite Imagery
828
+ - **Sentinel-2**: Free 10m resolution multispectral imagery
829
+ - [https://scihub.copernicus.eu/](https://scihub.copernicus.eu/)
830
+ - **Landsat**: Historical satellite archive (30m resolution)
831
+ - **Planet Labs**: High-frequency imaging (commercial)
832
+
833
+ ### Geospatial Data
834
+ - **OpenStreetMap**: Building footprints, roads, infrastructure
835
+ - **USGS Earth Explorer**: Topography and elevation data
836
+
837
+ ---
838
+
839
+ ## πŸŽ₯ Online Courses
840
+
841
+ ### Deep Learning Fundamentals
842
+ - **fast.ai**: Practical Deep Learning for Coders
843
+ - **Stanford CS231n**: Convolutional Neural Networks for Visual Recognition
844
+ - **Coursera Deeplearning.ai**: Deep Learning Specialization (Andrew Ng)
845
+
846
+ ### Computer Vision
847
+ - **PyImageSearch**: Extensive CV tutorials and courses
848
+ - **Udacity**: Computer Vision Nanodegree
849
+
850
+ ### Geospatial Analysis
851
+ - **NASA ARSET**: Applied Remote Sensing Training
852
+ - **Geo For Good**: Google Earth Engine tutorials
853
+
854
+ ---
855
+
856
+ ## 🏒 Organizations & Communities
857
+
858
+ ### Humanitarian Tech
859
+ - **Humanitarian OpenStreetMap Team (HOT)**: Community mapping for disasters
860
+ - **Missing Maps**: Mapping vulnerable places before disasters
861
+ - **UN OCHA Centre for Humanitarian Data**: Data-driven disaster response
862
+
863
+ ### Space Agencies
864
+ - **European Space Agency (ESA)**: Copernicus Emergency Management Service
865
+ - **NASA Disasters Program**: Earth observation for disaster response
866
+ - **JAXA**: Asian disaster monitoring
867
+
868
+ ### Research Initiatives
869
+ - **AI for Good**: UN initiative for AI in humanitarian applications
870
+ - **Data Science for Social Good**: Fellowship programs
871
+
872
+ ---
873
+
874
+ ## πŸ“– Academic Papers
875
+
876
+ ### Building Damage Detection
877
+ - **"xBD: A Dataset for Assessing Building Damage from Satellite Imagery"** (Gupta et al., 2019)
878
+ - **"RescueNet: Joint Building Segmentation and Damage Detection"** (Weber & KanΓ©, 2020)
879
+
880
+ ### Semantic Segmentation
881
+ - **"U-Net: Convolutional Networks for Biomedical Image Segmentation"** (Ronneberger et al., 2015)
882
+ - **"DeepLabv3+: Encoder-Decoder with Atrous Separable Convolution"** (Chen et al., 2018)
883
+
884
+ ### Transfer Learning
885
+ - **"A Survey on Transfer Learning"** (Pan & Yang, 2010)
886
+ - **"EfficientNet: Rethinking Model Scaling for CNNs"** (Tan & Le, 2019)
887
+
888
+ ### AI for Disaster Management
889
+ - **"Artificial Intelligence for Humanitarian Assistance and Disaster Response"** (Sun et al., 2020)
890
+ - **"Deep Learning for Multi-temporal Satellite Image Change Detection"** (Daudt et al., 2018)
891
+
892
+ ---
893
+
894
+ ## πŸ› οΈ Software & Tools
895
+
896
+ ### Deep Learning Frameworks
897
+ - **TensorFlow / Keras**: Industry-standard framework
898
+ - **PyTorch**: Research-friendly framework
899
+ - **FastAI**: High-level library built on PyTorch
900
+
901
+ ### Geospatial Libraries
902
+ - **Rasterio**: Read/write geospatial raster data
903
+ - **GeoPandas**: Geospatial data manipulation
904
+ - **GDAL**: Geospatial data abstraction library
905
+ - **Shapely**: Geometric operations
906
+
907
+ ### Visualization
908
+ - **Matplotlib / Seaborn**: Statistical visualization
909
+ - **Folium**: Interactive maps
910
+ - **Plotly**: Interactive plots
911
+
912
+ ### Deployment
913
+ - **Gradio**: Rapid ML demos (used for this app!)
914
+ - **Streamlit**: Data app framework
915
+ - **TensorFlow Serving**: Production ML serving
916
+ - **ONNX**: Model interoperability
917
+
918
+ ---
919
+
920
+ ## πŸ“ž Getting Help
921
+
922
+ - **GitHub Issues**: [Report bugs or request features](https://github.com/AI4DM/Geospatial-AI-for-Humanitarian-Response/issues)
923
+ - **Stack Overflow**: Use tags `tensorflow`, `computer-vision`, `geospatial`
924
+ - **Reddit**: r/MachineLearning, r/learnmachinelearning, r/gis
925
+
926
+ ---
927
+
928
+ ## πŸ“œ Citation
929
+
930
+ If you use this curriculum in your research or teaching:
931
+
932
+ ```bibtex
933
+ @misc{ai4dm_nato_asi_2025,
934
+ title={AI for Disaster Management: NATO ASI Curriculum},
935
+ author={Bulent Soykan},
936
+ year={2025},
937
+ publisher={GitHub},
938
+ url={https://github.com/AI4DM/Geospatial-AI-for-Humanitarian-Response}
939
+ }
940
+ ```
941
+
942
+ ---
943
+
944
+ ## 🌟 Stay Connected
945
+
946
+ - ⭐ **Star** this repository for updates
947
+ - πŸ‘€ **Watch** for new releases
948
+ - 🍴 **Fork** to customize for your courses
949
+
950
+ **Built with ❀️ for humanitarian AI applications**
951
+ """)
952
+
953
+
954
+ # ============================================================================
955
+ # MAIN APPLICATION
956
+ # ============================================================================
957
+
958
+ def create_app():
959
+ """Create the main Gradio application"""
960
+
961
+ with gr.Blocks(
962
+ title="NATO ASI - AI for Disaster Management",
963
+ theme=gr.themes.Soft(
964
+ primary_hue="blue",
965
+ secondary_hue="cyan",
966
+ ),
967
+ css="""
968
+ .gradio-container {
969
+ max-width: 1400px !important;
970
+ }
971
+ footer {
972
+ visibility: hidden;
973
+ }
974
+ """
975
+ ) as demo:
976
+
977
+ gr.Markdown("""
978
+ <div style="text-align: center; padding: 20px;">
979
+ <h1>🌍 NATO Advanced Study Institute</h1>
980
+ <h2>AI for Disaster Management: Interactive Learning Platform</h2>
981
+ <p style="font-size: 18px; color: #666;">
982
+ A comprehensive hands-on curriculum on Geospatial AI for Humanitarian Response
983
+ </p>
984
+ </div>
985
+ """)
986
+
987
+ with gr.Tabs() as tabs:
988
+ with gr.Tab("🏠 Welcome"):
989
+ create_welcome_tab()
990
+
991
+ with gr.Tab("πŸ“š Curriculum"):
992
+ create_curriculum_tab()
993
+
994
+ with gr.Tab("πŸ—οΈ Damage Detection"):
995
+ create_damage_detection_tab()
996
+
997
+ with gr.Tab("🌊 Flood Mapping"):
998
+ create_flood_mapping_tab()
999
+
1000
+ with gr.Tab("πŸš€ Transfer Learning"):
1001
+ create_transfer_learning_tab()
1002
+
1003
+ with gr.Tab("βš–οΈ Deployment & Ethics"):
1004
+ create_deployment_tab()
1005
+
1006
+ with gr.Tab("πŸ“š Resources"):
1007
+ create_resources_tab()
1008
+
1009
+ gr.Markdown("""
1010
+ ---
1011
+ <div style="text-align: center; padding: 20px; color: #666;">
1012
+ <p><strong>Built with ❀️ for humanitarian AI applications</strong></p>
1013
+ <p><em>Making the world more resilient to disasters, one model at a time.</em></p>
1014
+ <p>Β© 2025 NATO Advanced Study Institute | Developed by Bulent Soykan</p>
1015
+ </div>
1016
+ """)
1017
+
1018
+ return demo
1019
+
1020
+
1021
+ if __name__ == "__main__":
1022
+ app = create_app()
1023
+ app.launch(
1024
+ server_name="0.0.0.0",
1025
+ server_port=7860,
1026
+ share=True,
1027
+ show_error=True
1028
+ )
launch_gradio.bat ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @echo off
2
+ REM NATO ASI - AI for Disaster Management
3
+ REM Gradio App Launcher Script (Windows)
4
+
5
+ echo ================================================
6
+ echo NATO ASI - AI for Disaster Management
7
+ echo Interactive Gradio Application
8
+ echo ================================================
9
+ echo.
10
+
11
+ REM Check if Python is installed
12
+ python --version >nul 2>&1
13
+ if errorlevel 1 (
14
+ echo Error: Python is not installed.
15
+ echo Please install Python 3.8+ from https://www.python.org/
16
+ pause
17
+ exit /b 1
18
+ )
19
+
20
+ echo [OK] Python found
21
+ echo.
22
+
23
+ REM Check if virtual environment exists
24
+ if not exist "venv" (
25
+ echo Creating virtual environment...
26
+ python -m venv venv
27
+ echo [OK] Virtual environment created
28
+ ) else (
29
+ echo [OK] Virtual environment found
30
+ )
31
+ echo.
32
+
33
+ REM Activate virtual environment
34
+ echo Activating virtual environment...
35
+ call venv\Scripts\activate.bat
36
+ echo [OK] Virtual environment activated
37
+ echo.
38
+
39
+ REM Install/update dependencies
40
+ echo Installing dependencies...
41
+ python -m pip install -q --upgrade pip
42
+ python -m pip install -q -r requirements.txt
43
+ echo [OK] Dependencies installed
44
+ echo.
45
+
46
+ REM Launch the app
47
+ echo ================================================
48
+ echo Launching Gradio App...
49
+ echo ================================================
50
+ echo.
51
+ echo The app will open in your browser automatically.
52
+ echo If not, navigate to: http://localhost:7860
53
+ echo.
54
+ echo Press Ctrl+C to stop the server.
55
+ echo.
56
+
57
+ python gradio_app.py
58
+
59
+ pause
launch_gradio.sh ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+ # NATO ASI - AI for Disaster Management
4
+ # Gradio App Launcher Script (Linux/Mac)
5
+
6
+ echo "================================================"
7
+ echo "NATO ASI - AI for Disaster Management"
8
+ echo "Interactive Gradio Application"
9
+ echo "================================================"
10
+ echo ""
11
+
12
+ # Check if Python is installed
13
+ if ! command -v python3 &> /dev/null; then
14
+ echo "Error: Python 3 is not installed."
15
+ echo "Please install Python 3.8+ from https://www.python.org/"
16
+ exit 1
17
+ fi
18
+
19
+ echo "βœ“ Python found: $(python3 --version)"
20
+ echo ""
21
+
22
+ # Check if virtual environment exists
23
+ if [ ! -d "venv" ]; then
24
+ echo "Creating virtual environment..."
25
+ python3 -m venv venv
26
+ echo "βœ“ Virtual environment created"
27
+ else
28
+ echo "βœ“ Virtual environment found"
29
+ fi
30
+ echo ""
31
+
32
+ # Activate virtual environment
33
+ echo "Activating virtual environment..."
34
+ source venv/bin/activate
35
+ echo "βœ“ Virtual environment activated"
36
+ echo ""
37
+
38
+ # Install/update dependencies
39
+ echo "Installing dependencies..."
40
+ pip install -q --upgrade pip
41
+ pip install -q -r requirements.txt
42
+ echo "βœ“ Dependencies installed"
43
+ echo ""
44
+
45
+ # Launch the app
46
+ echo "================================================"
47
+ echo "Launching Gradio App..."
48
+ echo "================================================"
49
+ echo ""
50
+ echo "The app will open in your browser automatically."
51
+ echo "If not, navigate to: http://localhost:7860"
52
+ echo ""
53
+ echo "Press Ctrl+C to stop the server."
54
+ echo ""
55
+
56
+ python3 gradio_app.py
requirements.txt ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # NATO ASI - AI for Disaster Management
2
+ # Gradio App Requirements
3
+
4
+ # Core Dependencies
5
+ gradio>=4.0.0
6
+ numpy>=1.24.0
7
+ Pillow>=10.0.0
8
+
9
+ # Deep Learning (Optional - for actual model inference)
10
+ # Uncomment these if you want to integrate real trained models
11
+ # tensorflow>=2.13.0
12
+ # keras>=2.13.0
13
+
14
+ # Geospatial Libraries (Optional - for advanced features)
15
+ # Uncomment these if you want to add geospatial processing
16
+ # rasterio>=1.3.0
17
+ # geopandas>=0.14.0
18
+ # shapely>=2.0.0
19
+ # fiona>=1.9.0
20
+ # pyproj>=3.6.0
21
+
22
+ # Data Science
23
+ # pandas>=2.0.0
24
+ # matplotlib>=3.7.0
25
+ # seaborn>=0.12.0
26
+ # scikit-learn>=1.3.0
27
+
28
+ # Visualization
29
+ # opencv-python>=4.8.0
30
+ # earthpy>=0.9.4
31
+
32
+ # Utilities
33
+ python-dateutil>=2.8.0