Save a checkpoint if it belongs to the top-N best (by lower data_threshold). Maintains an index file ' _top_models.json' in save_dir. Returns the path of the last saved checkpoint if a new one was saved, otherwise returns previous_name unchanged.
(
previous_name,
save_dir,
epoch,
data_threshold,
model,
model_name,
num_saved_models=3,
)
| 298 | |
| 299 | |
| 300 | def save_top_N_models( |
| 301 | previous_name, |
| 302 | save_dir, |
| 303 | epoch, |
| 304 | data_threshold, |
| 305 | model, |
| 306 | model_name, |
| 307 | num_saved_models=3, |
| 308 | ): |
| 309 | """ |
| 310 | Save a checkpoint if it belongs to the top-N best (by lower data_threshold). |
| 311 | Maintains an index file '<model_name>_top_models.json' in save_dir. |
| 312 | |
| 313 | Returns the path of the last saved checkpoint if a new one was saved, |
| 314 | otherwise returns previous_name unchanged. |
| 315 | """ |
| 316 | os.makedirs(save_dir, exist_ok=True) |
| 317 | ckpt_path = os.path.join( |
| 318 | save_dir, f"{model_name}_{epoch}_{int(data_threshold * 100)}.pth" |
| 319 | ) |
| 320 | index_path = os.path.join(save_dir, f"{model_name}_top_models.json") |
| 321 | |
| 322 | # load current list |
| 323 | top_list = [] |
| 324 | if os.path.exists(index_path): |
| 325 | with open(index_path, "r") as f: |
| 326 | top_list = json.load(f) |
| 327 | |
| 328 | # decide if we should save |
| 329 | should_save = False |
| 330 | if len(top_list) < int(num_saved_models): |
| 331 | should_save = True |
| 332 | else: |
| 333 | worst_item = max(top_list, key=lambda x: x.get("p1", float("inf"))) |
| 334 | if data_threshold < float(worst_item.get("p1", float("inf"))): |
| 335 | should_save = True |
| 336 | |
| 337 | if not should_save: |
| 338 | return previous_name |
| 339 | |
| 340 | # save new checkpoint |
| 341 | torch.save(model.state_dict(), ckpt_path) |
| 342 | |
| 343 | # append and trim to N |
| 344 | top_list.append( |
| 345 | {"p1": float(data_threshold), "path": ckpt_path, "epoch": int(epoch)} |
| 346 | ) |
| 347 | # sort ascending by p1 and keep best N |
| 348 | top_list.sort(key=lambda x: x.get("p1", float("inf"))) |
| 349 | while len(top_list) > int(num_saved_models): |
| 350 | removed = top_list.pop() # remove worst (last after sort ascending) |
| 351 | if os.path.exists(removed.get("path", "")): |
| 352 | os.remove(removed["path"]) |
| 353 | |
| 354 | # write back index |
| 355 | with open(index_path, "w") as f: |
| 356 | json.dump(top_list, f, indent=2) |
| 357 |
no outgoing calls
no test coverage detected