Reinforcement Learning
stable-baselines3
deep-reinforcement-learning
agricultural-ai
weather-modelling
curriculum-learning
edge-ai
Instructions to use DHDRL/monsoon-rl with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- stable-baselines3
How to use DHDRL/monsoon-rl with stable-baselines3:
from huggingface_sb3 import load_from_hub checkpoint = load_from_hub( repo_id="DHDRL/monsoon-rl", filename="{MODEL FILENAME}.zip", ) - Notebooks
- Google Colab
- Kaggle
Update zone_observation.py
Browse files- zone_observation.py +59 -0
zone_observation.py
CHANGED
|
@@ -143,6 +143,9 @@ class ForecastConfig:
|
|
| 143 |
belief_update_radius: int = 2 # spatial propagation radius (zone cells)
|
| 144 |
belief_increase_rate: float = 0.30 # update magnitude when event confirmed
|
| 145 |
belief_decrease_rate: float = 0.05 # update magnitude when event absent
|
|
|
|
|
|
|
|
|
|
| 146 |
|
| 147 |
# --- Economics ---
|
| 148 |
alert_value: float = 100.0 # reward for correct advisory issuance
|
|
@@ -154,6 +157,10 @@ class ForecastConfig:
|
|
| 154 |
zone_visit_bonus: float = 1.5 # raw bonus, first visit to a zone only
|
| 155 |
unvisited_zone_penalty: float = 40.0 # raw penalty * (unvisited/active) at terminate
|
| 156 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 157 |
economic_randomization: bool = False
|
| 158 |
clean_episode_ratio: float = 0.7
|
| 159 |
event_spatial_correlation: float = 0.85
|
|
@@ -194,6 +201,20 @@ class ForecastConfig:
|
|
| 194 |
raise ValueError(f"ForecastConfig: zone_visit_bonus must be >= 0")
|
| 195 |
if self.unvisited_zone_penalty < 0:
|
| 196 |
raise ValueError(f"ForecastConfig: unvisited_zone_penalty must be >= 0")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 197 |
if self.horizon_days < 1:
|
| 198 |
raise ValueError(f"ForecastConfig: horizon_days must be >= 1")
|
| 199 |
if self.n_zones < 1:
|
|
@@ -230,6 +251,10 @@ class ForecastConfig:
|
|
| 230 |
self.inspection_cost = float(_clip(self.inspection_cost, 0.01, 1_000.0))
|
| 231 |
self.zone_visit_bonus = float(_clip(self.zone_visit_bonus, 0.0, 1_000.0))
|
| 232 |
self.unvisited_zone_penalty = float(_clip(self.unvisited_zone_penalty, 0.0, 10_000.0))
|
|
|
|
|
|
|
|
|
|
|
|
|
| 233 |
self.prior_belief = float(_clip(self.prior_belief, 0.001, 0.999))
|
| 234 |
self.belief_floor = float(_clip(self.belief_floor, 0.001, 0.5))
|
| 235 |
self.clean_episode_ratio = float(_clip(self.clean_episode_ratio, 0.0, 1.0))
|
|
@@ -263,12 +288,16 @@ class ForecastConfig:
|
|
| 263 |
"belief_update_radius": self.belief_update_radius,
|
| 264 |
"belief_increase_rate": self.belief_increase_rate,
|
| 265 |
"belief_decrease_rate": self.belief_decrease_rate,
|
|
|
|
| 266 |
"alert_value": self.alert_value,
|
| 267 |
"false_alert_penalty": self.false_alert_penalty,
|
| 268 |
"miss_penalty": self.miss_penalty,
|
| 269 |
"inspection_cost": self.inspection_cost,
|
| 270 |
"zone_visit_bonus": self.zone_visit_bonus,
|
| 271 |
"unvisited_zone_penalty": self.unvisited_zone_penalty,
|
|
|
|
|
|
|
|
|
|
| 272 |
"economic_randomization": self.economic_randomization,
|
| 273 |
"clean_episode_ratio": self.clean_episode_ratio,
|
| 274 |
"event_spatial_correlation": self.event_spatial_correlation,
|
|
@@ -1378,6 +1407,36 @@ if __name__ == "__main__":
|
|
| 1378 |
_assert(False, "ForecastConfig accepted invalid forecast_backend")
|
| 1379 |
except ValueError:
|
| 1380 |
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1381 |
print(f" ForecastConfig rational_threshold={cfg.rational_termination_threshold:.4f}"
|
| 1382 |
f" belief_floor={cfg.belief_floor:.4f} pipeline fields OK")
|
| 1383 |
|
|
|
|
| 143 |
belief_update_radius: int = 2 # spatial propagation radius (zone cells)
|
| 144 |
belief_increase_rate: float = 0.30 # update magnitude when event confirmed
|
| 145 |
belief_decrease_rate: float = 0.05 # update magnitude when event absent
|
| 146 |
+
belief_prior_weight: float = 0.70 # weight on episode prior vs. zone signal when
|
| 147 |
+
# seeding zone_belief at reset:
|
| 148 |
+
# prior_w*prior + (1-prior_w)*signal
|
| 149 |
|
| 150 |
# --- Economics ---
|
| 151 |
alert_value: float = 100.0 # reward for correct advisory issuance
|
|
|
|
| 157 |
zone_visit_bonus: float = 1.5 # raw bonus, first visit to a zone only
|
| 158 |
unvisited_zone_penalty: float = 40.0 # raw penalty * (unvisited/active) at terminate
|
| 159 |
|
| 160 |
+
uncertainty_decay: float = 0.70 # forecast_uncertainty[zone] *= this on inspection
|
| 161 |
+
info_gain_scale: float = 5.0 # multiplier on belief info-gain in step reward
|
| 162 |
+
uncertainty_penalty_scale: float = 5.0 # multiplier on mean uncertainty at termination
|
| 163 |
+
|
| 164 |
economic_randomization: bool = False
|
| 165 |
clean_episode_ratio: float = 0.7
|
| 166 |
event_spatial_correlation: float = 0.85
|
|
|
|
| 201 |
raise ValueError(f"ForecastConfig: zone_visit_bonus must be >= 0")
|
| 202 |
if self.unvisited_zone_penalty < 0:
|
| 203 |
raise ValueError(f"ForecastConfig: unvisited_zone_penalty must be >= 0")
|
| 204 |
+
if not (0.0 <= self.belief_prior_weight <= 1.0):
|
| 205 |
+
raise ValueError(
|
| 206 |
+
f"ForecastConfig: belief_prior_weight={self.belief_prior_weight} "
|
| 207 |
+
f"must be in [0, 1]"
|
| 208 |
+
)
|
| 209 |
+
if not (0.0 <= self.uncertainty_decay <= 1.0):
|
| 210 |
+
raise ValueError(
|
| 211 |
+
f"ForecastConfig: uncertainty_decay={self.uncertainty_decay} "
|
| 212 |
+
f"must be in [0, 1]"
|
| 213 |
+
)
|
| 214 |
+
if self.info_gain_scale < 0:
|
| 215 |
+
raise ValueError(f"ForecastConfig: info_gain_scale must be >= 0")
|
| 216 |
+
if self.uncertainty_penalty_scale < 0:
|
| 217 |
+
raise ValueError(f"ForecastConfig: uncertainty_penalty_scale must be >= 0")
|
| 218 |
if self.horizon_days < 1:
|
| 219 |
raise ValueError(f"ForecastConfig: horizon_days must be >= 1")
|
| 220 |
if self.n_zones < 1:
|
|
|
|
| 251 |
self.inspection_cost = float(_clip(self.inspection_cost, 0.01, 1_000.0))
|
| 252 |
self.zone_visit_bonus = float(_clip(self.zone_visit_bonus, 0.0, 1_000.0))
|
| 253 |
self.unvisited_zone_penalty = float(_clip(self.unvisited_zone_penalty, 0.0, 10_000.0))
|
| 254 |
+
self.belief_prior_weight = float(_clip(self.belief_prior_weight, 0.0, 1.0))
|
| 255 |
+
self.uncertainty_decay = float(_clip(self.uncertainty_decay, 0.0, 1.0))
|
| 256 |
+
self.info_gain_scale = float(_clip(self.info_gain_scale, 0.0, 1_000.0))
|
| 257 |
+
self.uncertainty_penalty_scale = float(_clip(self.uncertainty_penalty_scale, 0.0, 1_000.0))
|
| 258 |
self.prior_belief = float(_clip(self.prior_belief, 0.001, 0.999))
|
| 259 |
self.belief_floor = float(_clip(self.belief_floor, 0.001, 0.5))
|
| 260 |
self.clean_episode_ratio = float(_clip(self.clean_episode_ratio, 0.0, 1.0))
|
|
|
|
| 288 |
"belief_update_radius": self.belief_update_radius,
|
| 289 |
"belief_increase_rate": self.belief_increase_rate,
|
| 290 |
"belief_decrease_rate": self.belief_decrease_rate,
|
| 291 |
+
"belief_prior_weight": self.belief_prior_weight,
|
| 292 |
"alert_value": self.alert_value,
|
| 293 |
"false_alert_penalty": self.false_alert_penalty,
|
| 294 |
"miss_penalty": self.miss_penalty,
|
| 295 |
"inspection_cost": self.inspection_cost,
|
| 296 |
"zone_visit_bonus": self.zone_visit_bonus,
|
| 297 |
"unvisited_zone_penalty": self.unvisited_zone_penalty,
|
| 298 |
+
"uncertainty_decay": self.uncertainty_decay,
|
| 299 |
+
"info_gain_scale": self.info_gain_scale,
|
| 300 |
+
"uncertainty_penalty_scale": self.uncertainty_penalty_scale,
|
| 301 |
"economic_randomization": self.economic_randomization,
|
| 302 |
"clean_episode_ratio": self.clean_episode_ratio,
|
| 303 |
"event_spatial_correlation": self.event_spatial_correlation,
|
|
|
|
| 1407 |
_assert(False, "ForecastConfig accepted invalid forecast_backend")
|
| 1408 |
except ValueError:
|
| 1409 |
pass
|
| 1410 |
+
|
| 1411 |
+
_assert(cfg2.belief_prior_weight == 0.70, "belief_prior_weight default round-trip")
|
| 1412 |
+
_assert(cfg2.uncertainty_decay == 0.70, "uncertainty_decay default round-trip")
|
| 1413 |
+
_assert(cfg2.info_gain_scale == 5.0, "info_gain_scale default round-trip")
|
| 1414 |
+
_assert(cfg2.uncertainty_penalty_scale == 5.0, "uncertainty_penalty_scale default round-trip")
|
| 1415 |
+
cfg_belief = ForecastConfig(
|
| 1416 |
+
belief_prior_weight=0.35,
|
| 1417 |
+
uncertainty_decay=0.5,
|
| 1418 |
+
info_gain_scale=2.0,
|
| 1419 |
+
uncertainty_penalty_scale=8.0,
|
| 1420 |
+
)
|
| 1421 |
+
cfg_belief_back = ForecastConfig.from_dict(cfg_belief.to_dict())
|
| 1422 |
+
_assert(cfg_belief_back.belief_prior_weight == 0.35,
|
| 1423 |
+
"non-default belief_prior_weight round-trip")
|
| 1424 |
+
_assert(cfg_belief_back.uncertainty_decay == 0.5,
|
| 1425 |
+
"non-default uncertainty_decay round-trip")
|
| 1426 |
+
_assert(cfg_belief_back.info_gain_scale == 2.0,
|
| 1427 |
+
"non-default info_gain_scale round-trip")
|
| 1428 |
+
_assert(cfg_belief_back.uncertainty_penalty_scale == 8.0,
|
| 1429 |
+
"non-default uncertainty_penalty_scale round-trip")
|
| 1430 |
+
try:
|
| 1431 |
+
ForecastConfig(belief_prior_weight=1.5)
|
| 1432 |
+
_assert(False, "ForecastConfig accepted belief_prior_weight out of [0,1]")
|
| 1433 |
+
except ValueError:
|
| 1434 |
+
pass
|
| 1435 |
+
try:
|
| 1436 |
+
ForecastConfig(info_gain_scale=-1.0)
|
| 1437 |
+
_assert(False, "ForecastConfig accepted negative info_gain_scale")
|
| 1438 |
+
except ValueError:
|
| 1439 |
+
pass
|
| 1440 |
print(f" ForecastConfig rational_threshold={cfg.rational_termination_threshold:.4f}"
|
| 1441 |
f" belief_floor={cfg.belief_floor:.4f} pipeline fields OK")
|
| 1442 |
|