Visitar URL original
edge case fix / rc10 (#3036) · DeepLabCut/DeepLabCut@d11f093 · GitHub
Skip to content

Commit d11f093

Browse files
authored
edge case fix / rc10 (#3036)
* edge case fix * fix * best * rc10
1 parent 9c6e208 commit d11f093

6 files changed

Lines changed: 137 additions & 18 deletions

File tree

‎deeplabcut/pose_estimation_pytorch/apis/evaluation.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,7 @@ def evaluate_snapshot(
626626
)
627627
scores_filepath = output_filename.with_suffix(".csv")
628628
scores_filepath = scores_filepath.with_stem(scores_filepath.stem + "-results")
629+
print(f"Evaluation results file: {scores_filepath.name}")
629630
save_evaluation_results(df_scores, scores_filepath, show_errors, pcutoff)
630631

631632
if per_keypoint_evaluation:
@@ -829,6 +830,7 @@ def evaluate_network(
829830
snapshot_uid=get_scorer_uid(snapshot, detector_snapshot),
830831
modelprefix=modelprefix,
831832
)
833+
print(f"Evaluation scorer: {scorer}")
832834
evaluate_snapshot(
833835
loader=loader,
834836
cfg=cfg,

‎deeplabcut/pose_estimation_pytorch/apis/videos.py‎

Lines changed: 121 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -449,9 +449,58 @@ def analyze_videos(
449449
print(f"Creating a TopDownDynamicCropper with configuration {top_down_dynamic}")
450450
dynamic = TopDownDynamicCropper(**top_down_dynamic)
451451

452-
snapshot = utils.get_model_snapshots(
453-
snapshot_index, loader.model_folder, loader.pose_task
454-
)[0]
452+
try:
453+
snapshot = utils.get_model_snapshots(
454+
snapshot_index, loader.model_folder, loader.pose_task
455+
)[0]
456+
except (ValueError, IndexError) as e:
457+
print(f"Error loading snapshot with index {snapshot_index}: {e}")
458+
print("Attempting to find available snapshots...")
459+
460+
# Try to get all available snapshots
461+
try:
462+
all_snapshots = utils.get_model_snapshots("all", loader.model_folder, loader.pose_task)
463+
if all_snapshots:
464+
# Try to find a "best" snapshot first
465+
best_snapshots = [s for s in all_snapshots if s.best]
466+
if best_snapshots:
467+
snapshot = best_snapshots[0]
468+
print(f"Found and using best snapshot: {snapshot.path}")
469+
else:
470+
# Use the last available snapshot
471+
snapshot = all_snapshots[-1]
472+
print(f"No best snapshot found, using last available: {snapshot.path}")
473+
else:
474+
raise FileNotFoundError(f"No snapshots found in {loader.model_folder}")
475+
except Exception as fallback_error:
476+
raise FileNotFoundError(f"Failed to load any snapshots from {loader.model_folder}. Original error: {e}. Fallback error: {fallback_error}")
477+
478+
# Additional validation for best snapshots
479+
if "best" in str(snapshot.path) and not snapshot.path.exists():
480+
print(f"Warning: Best snapshot path {snapshot.path} does not exist. Checking for alternative snapshots...")
481+
# Try to find any available snapshot
482+
try:
483+
all_snapshots = utils.get_model_snapshots("all", loader.model_folder, loader.pose_task)
484+
if all_snapshots:
485+
# Try to find a different best snapshot
486+
best_snapshots = [s for s in all_snapshots if s.best and s.path.exists()]
487+
if best_snapshots:
488+
snapshot = best_snapshots[0]
489+
print(f"Using alternative best snapshot: {snapshot.path}")
490+
else:
491+
# Use the last available snapshot
492+
snapshot = all_snapshots[-1]
493+
print(f"Using alternative snapshot: {snapshot.path}")
494+
else:
495+
raise FileNotFoundError(f"No snapshots found in {loader.model_folder}")
496+
except Exception as e:
497+
raise FileNotFoundError(f"Failed to find alternative snapshots: {e}")
498+
499+
# Verify the snapshot file exists
500+
if not snapshot.path.exists():
501+
raise FileNotFoundError(f"Snapshot file not found: {snapshot.path}")
502+
503+
print(f"Successfully loaded snapshot: {snapshot.path}")
455504

456505
# Load the BU model for the conditions provider
457506
cond_provider = None
@@ -497,9 +546,56 @@ def analyze_videos(
497546
if detector_batch_size is None:
498547
detector_batch_size = loader.project_cfg.get("detector_batch_size", 1)
499548

500-
detector_snapshot = utils.get_model_snapshots(
501-
detector_snapshot_index, loader.model_folder, Task.DETECT
502-
)[0]
549+
try:
550+
detector_snapshot = utils.get_model_snapshots(
551+
detector_snapshot_index, loader.model_folder, Task.DETECT
552+
)[0]
553+
except (ValueError, IndexError) as e:
554+
print(f"Error loading detector snapshot with index {detector_snapshot_index}: {e}")
555+
print("Attempting to find available detector snapshots...")
556+
557+
# Try to get all available detector snapshots
558+
try:
559+
all_detector_snapshots = utils.get_model_snapshots("all", loader.model_folder, Task.DETECT)
560+
if all_detector_snapshots:
561+
# Try to find a "best" detector snapshot first
562+
best_detector_snapshots = [s for s in all_detector_snapshots if s.best]
563+
if best_detector_snapshots:
564+
detector_snapshot = best_detector_snapshots[0]
565+
print(f"Found and using best detector snapshot: {detector_snapshot.path}")
566+
else:
567+
# Use the last available detector snapshot
568+
detector_snapshot = all_detector_snapshots[-1]
569+
print(f"No best detector snapshot found, using last available: {detector_snapshot.path}")
570+
else:
571+
raise FileNotFoundError(f"No detector snapshots found in {loader.model_folder}")
572+
except Exception as fallback_error:
573+
raise FileNotFoundError(f"Failed to load any detector snapshots from {loader.model_folder}. Original error: {e}. Fallback error: {fallback_error}")
574+
575+
# Additional validation for detector snapshots
576+
if "best" in str(detector_snapshot.path) and not detector_snapshot.path.exists():
577+
print(f"Warning: Best detector snapshot path {detector_snapshot.path} does not exist. Checking for alternative detector snapshots...")
578+
try:
579+
all_detector_snapshots = utils.get_model_snapshots("all", loader.model_folder, Task.DETECT)
580+
if all_detector_snapshots:
581+
# Try to find a different best detector snapshot
582+
best_detector_snapshots = [s for s in all_detector_snapshots if s.best and s.path.exists()]
583+
if best_detector_snapshots:
584+
detector_snapshot = best_detector_snapshots[0]
585+
print(f"Using alternative best detector snapshot: {detector_snapshot.path}")
586+
else:
587+
# Use the last available detector snapshot
588+
detector_snapshot = all_detector_snapshots[-1]
589+
print(f"Using alternative detector snapshot: {detector_snapshot.path}")
590+
else:
591+
raise FileNotFoundError(f"No detector snapshots found in {loader.model_folder}")
592+
except Exception as e:
593+
raise FileNotFoundError(f"Failed to find alternative detector snapshots: {e}")
594+
595+
# Verify the detector snapshot file exists
596+
if not detector_snapshot.path.exists():
597+
raise FileNotFoundError(f"Detector snapshot file not found: {detector_snapshot.path}")
598+
503599
print(f" -> Using detector {detector_snapshot.path}")
504600
detector_runner = utils.get_detector_inference_runner(
505601
model_config=loader.model_cfg,
@@ -509,9 +605,12 @@ def analyze_videos(
509605
)
510606

511607
dlc_scorer = loader.scorer(snapshot, detector_snapshot)
608+
print(f"Using scorer: {dlc_scorer}")
512609

513610
# Reading video and init variables
514611
videos = utils.list_videos_in_folder(videos, videotype, shuffle=in_random_order)
612+
h5_files_created = False # Track if any .h5 files were created
613+
515614
for video in videos:
516615
if destfolder is None:
517616
output_path = video.parent
@@ -583,6 +682,7 @@ def analyze_videos(
583682
output_prefix=output_prefix,
584683
save_as_csv=save_as_csv,
585684
)
685+
h5_files_created = True # .h5 file was created
586686

587687
if multi_animal:
588688
assemblies_path = output_path / f"{output_prefix}_assemblies.pickle"
@@ -631,6 +731,7 @@ def analyze_videos(
631731
output_prefix=output_prefix + "_ctd",
632732
save_as_csv=save_as_csv,
633733
)
734+
h5_files_created = True # .h5 file was created for CTD tracking
634735

635736
elif auto_track:
636737
convert_detections2tracklets(
@@ -654,14 +755,21 @@ def analyze_videos(
654755
destfolder=str(output_path),
655756
save_as_csv=save_as_csv,
656757
)
758+
h5_files_created = True # .h5 file was created by stitch_tracklets
657759

658-
print(
659-
"The videos are analyzed. Now your research can truly start!\n"
660-
"You can create labeled videos with 'create_labeled_video'.\n"
661-
"If the tracking is not satisfactory for some videos, consider expanding the "
662-
"training set. You can use the function 'extract_outlier_frames' to extract a "
663-
"few representative outlier frames.\n"
664-
)
760+
if h5_files_created:
761+
print(
762+
"The videos are analyzed. Now your research can truly start!\n"
763+
"You can create labeled videos with 'create_labeled_video'.\n"
764+
"If the tracking is not satisfactory for some videos, consider expanding the "
765+
"training set. You can use the function 'extract_outlier_frames' to extract a "
766+
"few representative outlier frames.\n"
767+
)
768+
else:
769+
print(
770+
"No .h5 files were created during video analysis. Please check your code and "
771+
"ensure that the video inference and output generation are correct.\n"
772+
)
665773

666774
return dlc_scorer
667775

‎deeplabcut/pose_estimation_pytorch/data/snapshots.py‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,21 @@ class Snapshot:
2929
path: Path
3030

3131
def uid(self) -> str:
32-
return self.path.stem.split("-")[-1]
32+
if self.best:
33+
return f"best-{self.epochs}"
34+
else:
35+
return str(self.epochs)
3336

3437
@staticmethod
3538
def from_path(path: Path) -> "Snapshot":
3639
best = "-best" in path.stem
37-
epochs = int(path.stem.split("-")[-1])
40+
# Use regex to extract epoch number more robustly
41+
match = re.search(r'-(\d+)\.pt$', path.name)
42+
if match:
43+
epochs = int(match.group(1))
44+
else:
45+
# Fallback to original method if regex fails
46+
epochs = int(path.stem.split("-")[-1])
3847
return Snapshot(best=best, epochs=epochs, path=path)
3948

4049

‎deeplabcut/version.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
# Licensed under GNU Lesser General Public License v3.0
1010
#
1111

12-
__version__ = "3.0.0rc9"
12+
__version__ = "3.0.0rc10"
1313
VERSION = __version__

‎reinstall.sh‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
pip uninstall deeplabcut
22
python3 setup.py sdist bdist_wheel
3-
pip install dist/deeplabcut-3.0.0rc9-py3-none-any.whl
3+
pip install dist/deeplabcut-3.0.0rc10-py3-none-any.whl

‎setup.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def pytorch_config_paths() -> list[str]:
4747

4848
setuptools.setup(
4949
name="deeplabcut",
50-
version="3.0.0rc9",
50+
version="3.0.0rc10",
5151
author="A. & M.W. Mathis Labs",
5252
author_email="alexander@deeplabcut.org",
5353
description="Markerless pose-estimation of user-defined features with deep learning",

0 commit comments

Comments
 (0)