Wholebody34
augmentation なしの現時点最大精度
best_e_0205_0.4140.pt
collarbone: 鎖骨
solar_plexus: みぞおち
abdomen: 丹田
hip_joint: 股関節
wrist: 手首
ankle: 足首
確認対象画像
-
7221 - 327
-
10082 - 452
-
10442 - 468
-
11065 - 499
-
12069
- 14428 - 667
- 19096 - 906
- 19318 - 912
- 19754 - 942
- 21498 - 1025
- 22935 - 1108
- 23140 - 1122
- 29519 - 1411
- 31943 - 1538
- 39538 - 1895
- 40874 - 1964
- 42760 - 2063
- 44700 - 2138
- 47801 - 2277
- 51396
- 54020 - 2603
- 54743
- 56729
- 57515 - 2778
- 59293
- 65500 - 3163
- 71038 - 3410
- 84866 - 4045
- 88754 - 4226
7,835
0000000088110 7801
肩・肘・膝の修正:7585
names:
0: body
1: adult
2: child
3: male
4: female
5: body_with_wheelchair
6: body_with_crutches
7: head
8: front
9: right-front
10: right-side
11: right-back
12: back
13: left-back
14: left-side
15: left-front
16: face
17: eye
18: nose
19: mouth
20: ear
21: collarbone
22: shoulder
23: solar_plexus
24: elbow
25: wrist
26: hand
27: hand_left
28: hand_right
29: abdomen
30: hip_joint
31: knee
32: ankle
33: foot
train.sh
#!/bin/bash
VARS=(
"e"
"c"
"s"
"t"
"n"
)
# RELU= or RELU=-relu
RELU=
########################################
# 1. 最初のコマンドを1回実行
########################################
for((i=0; i<${#VARS[@]}; i++))
do
VAR=(`echo ${VARS[i]}`)
echo "=== Run initial training ==="
python train_dual.py \
--workers 8 \
--device 0 \
--batch 2 \
--data data/original_34.yaml \
--img 640 \
--cfg models/detect/yolov9-${VAR}_original${RELU}.yaml \
--weights best-${VAR}${RELU}.pt \
--name yolov9-wholebody34-${VAR}${RELU} \
--hyp hyp.scratch-high_original.yaml \
--min-items 0 \
--epochs 100 \
--close-mosaic 15 \
--patience 0
# 戻り値をチェック
if [ $? -eq 0 ]; then
echo "Initial training success!"
else
echo "Initial training failed. Will try resume training..."
########################################
# 2. リトライ(2つ目のコマンド)を最大5回まで行う
########################################
MAX_RETRY=10
count=1
while [ $count -le $MAX_RETRY ]
do
echo "=== Resume training try #$count ==="
python train_dual.py \
--workers 8 \
--device 0 \
--batch 2 \
--data data/original_34.yaml \
--img 640 \
--cfg models/detect/yolov9-${VAR}_original${RELU}.yaml \
--resume runs/train/yolov9-wholebody34-${VAR}${RELU}/weights/last.pt \
--name yolov9-wholebody34-${VAR}${RELU} \
--hyp hyp.scratch-high_original.yaml \
--min-items 0 \
--epochs 100 \
--close-mosaic 15 \
--patience 0
# 戻り値をチェック(0なら成功)
if [ $? -eq 0 ]; then
echo "Resume training success at try #$count!"
break
else
echo "Resume training failed at try #$count."
count=$((count+1))
fi
done
fi
done
python val_dual.py \
--data data/original_34.yaml \
--img 640 \
--batch 8 \
--conf 0.001 \
--iou 0.7 \
--max-det 300 \
--device 0 \
--weights runs/train/yolov9-wholebody34-e/weights/best.pt \
--name yolov9_e_640_val
train_multigpu.sh
#!/bin/bash
VARS=(
"e"
"c"
"s"
"t"
"n"
)
# RELU= or RELU=-relu
RELU=
########################################
# 1. 最初のコマンドを1回実行
########################################
for((i=0; i<${#VARS[@]}; i++))
do
VAR=(`echo ${VARS[i]}`)
echo "=== Run initial training ==="
python -m torch.distributed.launch \
--nproc_per_node 4 \
--master_port 9527 train_dual.py \
--workers 4 \
--device 0,1,2,3 \
--sync-bn \
--batch 16 \
--data data/original_34.yaml \
--img 640 \
--cfg models/detect/yolov9-${VAR}_original${RELU}.yaml \
--weights best-${VAR}${RELU}.pt \
--name yolov9-wholebody34-${VAR}${RELU} \
--hyp hyp.scratch-high_original.yaml \
--min-items 0 \
--epochs 120 \
--close-mosaic 20 \
--patience 0
# 戻り値をチェック
if [ $? -eq 0 ]; then
echo "Initial training success!"
else
echo "Initial training failed. Will try resume training..."
########################################
# 2. リトライ(2つ目のコマンド)を最大5回まで行う
########################################
MAX_RETRY=10
count=1
while [ $count -le $MAX_RETRY ]
do
echo "=== Resume training try #$count ==="
python -m torch.distributed.launch \
--nproc_per_node 4 \
--master_port 9527 train_dual.py \
--workers 4 \
--device 0,1,2,3 \
--batch 16 \
--data data/original_34.yaml \
--img 640 \
--cfg models/detect/yolov9-${VAR}_original${RELU}.yaml \
--resume runs/train/yolov9-wholebody34-${VAR}${RELU}/weights/last.pt \
--name yolov9-wholebody34-${VAR}${RELU} \
--hyp hyp.scratch-high_original.yaml \
--min-items 0 \
--epochs 120 \
--close-mosaic 20 \
--patience 0
# 戻り値をチェック(0なら成功)
if [ $? -eq 0 ]; then
echo "Resume training success at try #$count!"
break
else
echo "Resume training failed at try #$count."
count=$((count+1))
fi
done
fi
done
E-150
Class Images Instances P R mAP50 mAP50-95
all 52 10581 0.816 0.405 0.524 0.392
body 52 1245 0.938 0.265 0.530 0.426
adult 52 1179 0.975 0.132 0.442 0.412
child 52 61 0.970 0.689 0.760 0.734
male 52 744 0.941 0.207 0.478 0.438
female 52 248 0.927 0.181 0.351 0.341
head 52 1187 0.972 0.410 0.670 0.481
front 52 435 0.931 0.055 0.216 0.181
right-front 52 77 0.929 0.532 0.662 0.609
right-side 52 32 0.608 0.375 0.412 0.382
right-back 52 20 0.891 0.400 0.635 0.521
back 52 16 0.594 0.562 0.615 0.488
left-back 52 19 0.932 0.632 0.695 0.619
left-side 52 63 0.959 0.373 0.528 0.470
left-front 52 525 0.936 0.027 0.119 0.117
face 52 363 0.934 0.320 0.534 0.455
eye 52 147 0.756 0.421 0.508 0.239
nose 52 101 0.801 0.723 0.775 0.488
mouth 52 95 0.811 0.632 0.702 0.390
ear 52 107 0.800 0.654 0.723 0.489
collarbone 52 698 0.567 0.083 0.128 0.058
shoulder 52 978 0.752 0.195 0.314 0.185
solar_plexus 52 170 0.447 0.224 0.240 0.103
elbow 52 319 0.821 0.451 0.529 0.340
wrist 52 306 0.718 0.294 0.355 0.168
hand 52 235 0.973 0.607 0.790 0.639
hand_left 52 108 0.940 0.565 0.734 0.606
hand_right 52 127 0.960 0.512 0.745 0.597
abdomen 52 144 0.528 0.299 0.321 0.140
hip_joint 52 282 0.565 0.344 0.375 0.226
knee 52 226 0.722 0.535 0.607 0.370
ankle 52 154 0.623 0.461 0.424 0.196
foot 52 170 0.899 0.794 0.864 0.629
E - 300
Class Images Instances P R mAP50 mAP50-95
all 118 10366 0.858 0.634 0.715 0.563
body 118 601 0.986 0.867 0.961 0.909
adult 118 492 0.983 0.797 0.902 0.869
child 118 72 0.984 0.830 0.906 0.876
male 118 357 0.970 0.852 0.924 0.888
female 118 122 0.963 0.862 0.915 0.886
body_with_wheelchair 118 2 0.737 1.000 0.995 0.951
head 118 548 0.960 0.934 0.975 0.837
front 118 115 0.816 0.500 0.612 0.544
right-front 118 109 0.908 0.542 0.631 0.590
right-side 118 85 0.894 0.793 0.855 0.768
right-back 118 41 0.938 0.733 0.821 0.705
back 118 34 0.783 0.471 0.623 0.536
left-back 118 20 0.920 0.550 0.579 0.548
left-side 118 60 0.897 0.650 0.755 0.660
left-front 118 84 0.859 0.579 0.668 0.597
face 118 333 0.962 0.880 0.923 0.760
eye 118 333 0.808 0.366 0.474 0.227
nose 118 300 0.913 0.547 0.646 0.385
mouth 118 240 0.833 0.475 0.568 0.293
ear 118 276 0.862 0.587 0.690 0.434
collarbone 118 504 0.611 0.356 0.360 0.135
shoulder 118 841 0.797 0.611 0.692 0.391
solar_plexus 118 433 0.513 0.289 0.308 0.138
elbow 118 612 0.852 0.576 0.665 0.394
wrist 118 565 0.721 0.398 0.448 0.216
hand 118 468 0.993 0.669 0.883 0.724
hand_left 118 234 0.943 0.712 0.840 0.695
hand_right 118 234 0.978 0.667 0.852 0.693
abdomen 118 324 0.666 0.383 0.431 0.219
hip_joint 118 596 0.738 0.512 0.566 0.335
knee 118 497 0.816 0.633 0.709 0.435
ankle 118 425 0.764 0.481 0.521 0.268
foot 118 409 0.937 0.839 0.900 0.689
E - 600
Class Images Instances P R mAP50 mAP50-95
all 235 23281 0.838 0.557 0.656 0.503
body 235 1752 0.954 0.604 0.774 0.720
adult 235 1485 0.943 0.685 0.827 0.749
child 235 141 0.951 0.823 0.877 0.853
male 235 933 0.929 0.610 0.745 0.711
female 235 421 0.944 0.682 0.794 0.754
head 235 1552 0.938 0.644 0.779 0.668
front 235 406 0.890 0.293 0.446 0.411
right-front 235 214 0.860 0.556 0.677 0.614
right-side 235 148 0.889 0.574 0.689 0.619
right-back 235 65 0.890 0.615 0.687 0.622
back 235 86 0.888 0.419 0.555 0.491
left-back 235 60 0.922 0.595 0.697 0.612
left-side 235 149 0.889 0.594 0.697 0.644
left-front 235 424 0.773 0.226 0.357 0.315
face 235 739 0.947 0.748 0.837 0.696
eye 235 556 0.807 0.486 0.597 0.303
nose 235 480 0.894 0.671 0.733 0.462
mouth 235 401 0.838 0.606 0.684 0.387
ear 235 477 0.856 0.639 0.737 0.484
collarbone 235 1301 0.619 0.301 0.343 0.144
shoulder 235 1942 0.772 0.543 0.631 0.360
solar_plexus 235 892 0.556 0.337 0.353 0.163
elbow 235 1201 0.759 0.533 0.601 0.352
wrist 235 1121 0.740 0.398 0.452 0.220
hand 235 906 0.937 0.678 0.844 0.689
hand_left 235 460 0.945 0.636 0.807 0.664
hand_right 235 446 0.913 0.614 0.779 0.641
abdomen 235 726 0.617 0.416 0.459 0.238
hip_joint 235 1284 0.676 0.489 0.530 0.285
knee 235 952 0.736 0.585 0.652 0.371
ankle 235 821 0.686 0.462 0.503 0.231
foot 235 740 0.866 0.777 0.849 0.632
E - 800
Class Images Instances P R mAP50 mAP50-95
all 312 35882 0.828 0.560 0.653 0.484
body 312 2694 0.901 0.754 0.881 0.751
adult 312 1909 0.952 0.650 0.831 0.770
child 312 300 0.946 0.826 0.888 0.838
male 312 1371 0.851 0.772 0.862 0.769
female 312 560 0.943 0.796 0.886 0.834
head 312 2287 0.908 0.853 0.921 0.729
front 312 588 0.910 0.485 0.638 0.543
right-front 312 419 0.893 0.465 0.599 0.531
right-side 312 243 0.912 0.576 0.688 0.630
right-back 312 86 0.837 0.547 0.661 0.578
back 312 127 0.861 0.362 0.496 0.419
left-back 312 90 0.950 0.427 0.546 0.487
left-side 312 272 0.868 0.419 0.530 0.478
left-front 312 462 0.741 0.314 0.433 0.368
face 312 1036 0.939 0.914 0.946 0.780
eye 312 1101 0.821 0.348 0.448 0.194
nose 312 923 0.898 0.638 0.720 0.403
mouth 312 789 0.815 0.496 0.578 0.285
ear 312 892 0.814 0.570 0.657 0.375
collarbone 312 2272 0.606 0.304 0.336 0.136
shoulder 312 3234 0.778 0.551 0.619 0.332
solar_plexus 312 1570 0.519 0.308 0.311 0.132
elbow 312 1886 0.741 0.510 0.559 0.307
wrist 312 1598 0.726 0.392 0.433 0.195
hand 312 1292 0.950 0.630 0.841 0.647
hand_left 312 652 0.931 0.622 0.802 0.630
hand_right 312 640 0.921 0.584 0.782 0.599
abdomen 312 1029 0.604 0.428 0.447 0.222
hip_joint 312 1801 0.656 0.490 0.518 0.276
knee 312 1454 0.743 0.575 0.631 0.354
ankle 312 1185 0.698 0.506 0.535 0.254
foot 312 1120 0.861 0.810 0.865 0.640
E - 900
Class Images Instances P R mAP50 mAP50-95
all 312 35882 0.842 0.525 0.632 0.481
body 312 2694 0.945 0.686 0.826 0.744
adult 312 1909 0.961 0.631 0.803 0.766
child 312 300 0.967 0.771 0.850 0.809
male 312 1371 0.895 0.709 0.810 0.759
female 312 560 0.962 0.774 0.864 0.822
head 312 2287 0.931 0.768 0.863 0.715
front 312 588 0.928 0.423 0.601 0.522
right-front 312 419 0.913 0.453 0.596 0.539
right-side 312 243 0.921 0.580 0.688 0.640
right-back 312 86 0.840 0.547 0.669 0.583
back 312 127 0.863 0.362 0.508 0.435
left-back 312 90 0.950 0.426 0.536 0.486
left-side 312 272 0.883 0.419 0.555 0.505
left-front 312 462 0.776 0.303 0.426 0.381
face 312 1036 0.944 0.830 0.896 0.744
eye 312 1101 0.810 0.287 0.413 0.190
nose 312 923 0.890 0.532 0.650 0.375
mouth 312 789 0.822 0.402 0.522 0.272
ear 312 892 0.835 0.442 0.564 0.336
collarbone 312 2272 0.612 0.260 0.314 0.133
shoulder 312 3234 0.795 0.499 0.600 0.335
solar_plexus 312 1570 0.555 0.280 0.302 0.134
elbow 312 1886 0.756 0.492 0.565 0.318
wrist 312 1598 0.741 0.382 0.443 0.203
hand 312 1292 0.959 0.620 0.824 0.652
hand_left 312 652 0.943 0.604 0.788 0.635
hand_right 312 640 0.931 0.575 0.760 0.599
abdomen 312 1029 0.614 0.415 0.453 0.228
hip_joint 312 1801 0.676 0.484 0.524 0.283
knee 312 1454 0.753 0.554 0.628 0.362
ankle 312 1185 0.705 0.491 0.533 0.258
foot 312 1120 0.880 0.792 0.851 0.644
E - 1200
Class Images Instances P R mAP50 mAP50-95
all 469 46122 0.835 0.592 0.681 0.514
body 469 2916 0.960 0.817 0.940 0.843
adult 469 2298 0.943 0.767 0.918 0.842
child 469 299 0.926 0.846 0.906 0.873
male 469 1518 0.920 0.848 0.938 0.864
female 469 710 0.922 0.861 0.937 0.869
head 469 2573 0.937 0.891 0.946 0.777
front 469 485 0.865 0.551 0.677 0.602
right-front 469 443 0.799 0.549 0.660 0.596
right-side 469 350 0.919 0.600 0.731 0.646
right-back 469 164 0.821 0.543 0.657 0.564
back 469 201 0.889 0.359 0.530 0.430
left-back 469 105 0.860 0.467 0.543 0.488
left-side 469 369 0.883 0.469 0.612 0.541
left-front 469 456 0.831 0.443 0.561 0.498
face 469 1370 0.940 0.910 0.943 0.778
eye 469 1330 0.827 0.447 0.544 0.261
nose 469 1210 0.875 0.607 0.692 0.423
mouth 469 1002 0.789 0.536 0.599 0.327
ear 469 1121 0.837 0.590 0.673 0.421
collarbone 469 2471 0.621 0.384 0.405 0.169
shoulder 469 3753 0.760 0.576 0.639 0.346
solar_plexus 469 2130 0.567 0.344 0.353 0.151
elbow 469 2571 0.757 0.485 0.541 0.309
wrist 469 2290 0.743 0.400 0.439 0.208
hand 469 1927 0.925 0.645 0.828 0.638
hand_left 469 982 0.935 0.610 0.783 0.622
hand_right 469 945 0.941 0.590 0.763 0.597
abdomen 469 1701 0.682 0.515 0.558 0.302
hip_joint 469 2936 0.669 0.474 0.509 0.279
knee 469 2046 0.748 0.528 0.593 0.322
ankle 469 1793 0.735 0.504 0.545 0.245
foot 469 1657 0.895 0.772 0.847 0.613
E - 1200-fine
Class Images Instances P R mAP50 mAP50-95
all 470 47921 0.845 0.578 0.675 0.522
body 470 3212 0.941 0.776 0.883 0.801
adult 470 2325 0.951 0.760 0.874 0.823
child 470 329 0.924 0.772 0.842 0.802
male 470 1645 0.939 0.757 0.861 0.817
female 470 728 0.959 0.777 0.878 0.826
body_with_wheelchair 470 1 0.620 1.000 0.995 0.995
head 470 2633 0.947 0.864 0.929 0.780
front 470 580 0.882 0.478 0.635 0.572
right-front 470 511 0.854 0.479 0.586 0.524
right-side 470 348 0.927 0.532 0.659 0.599
right-back 470 133 0.821 0.624 0.699 0.637
back 470 167 0.895 0.358 0.524 0.443
left-back 470 88 0.838 0.534 0.599 0.531
left-side 470 320 0.926 0.549 0.661 0.589
left-front 470 486 0.867 0.496 0.614 0.557
face 470 1591 0.953 0.858 0.915 0.744
eye 470 1334 0.833 0.379 0.506 0.231
nose 470 1373 0.909 0.523 0.641 0.388
mouth 470 1081 0.835 0.468 0.571 0.302
ear 470 1204 0.852 0.513 0.622 0.401
collarbone 470 2475 0.659 0.362 0.406 0.165
shoulder 470 4263 0.791 0.544 0.622 0.338
solar_plexus 470 2082 0.587 0.310 0.332 0.142
elbow 470 2797 0.788 0.489 0.568 0.322
wrist 470 2289 0.760 0.385 0.450 0.216
hand 470 1915 0.953 0.614 0.817 0.654
hand_left 470 944 0.946 0.607 0.785 0.624
hand_right 470 971 0.948 0.607 0.786 0.625
abdomen 470 1656 0.709 0.461 0.524 0.287
hip_joint 470 2895 0.679 0.432 0.483 0.262
knee 470 2236 0.762 0.519 0.598 0.334
ankle 470 1736 0.731 0.485 0.543 0.260
foot 470 1573 0.897 0.776 0.855 0.629
E - 1500
Class Images Instances P R mAP50 mAP50-95
all 587 56162 0.797 0.547 0.641 0.482
body 587 3876 0.908 0.704 0.815 0.731
adult 587 2954 0.954 0.637 0.794 0.753
child 587 379 0.942 0.778 0.846 0.819
male 587 2141 0.947 0.678 0.808 0.763
female 587 813 0.920 0.722 0.823 0.789
body_with_wheelchair 587 1 0.606 1.000 0.995 0.995
head 587 3312 0.927 0.738 0.848 0.695
front 587 805 0.757 0.458 0.585 0.491
right-front 587 430 0.799 0.519 0.625 0.553
right-side 587 348 0.930 0.612 0.731 0.652
right-back 587 164 0.818 0.591 0.702 0.606
back 587 196 0.752 0.401 0.524 0.455
left-back 587 152 0.858 0.517 0.623 0.552
left-side 587 431 0.867 0.513 0.646 0.561
left-front 587 784 0.768 0.304 0.452 0.391
face 587 1681 0.904 0.794 0.867 0.684
eye 587 1453 0.784 0.370 0.485 0.221
nose 587 1369 0.896 0.531 0.637 0.378
mouth 587 1109 0.806 0.487 0.591 0.307
ear 587 1411 0.843 0.469 0.579 0.340
collarbone 587 2977 0.592 0.290 0.314 0.101
shoulder 587 5066 0.749 0.478 0.544 0.265
solar_plexus 587 2384 0.426 0.172 0.166 0.050
elbow 587 3140 0.727 0.459 0.520 0.258
wrist 587 2518 0.658 0.381 0.418 0.166
hand 587 2150 0.946 0.631 0.824 0.628
hand_left 587 1075 0.910 0.618 0.804 0.622
hand_right 587 1075 0.935 0.563 0.744 0.573
abdomen 587 1876 0.605 0.477 0.513 0.222
hip_joint 587 3330 0.593 0.399 0.429 0.183
knee 587 2718 0.695 0.509 0.566 0.292
ankle 587 2103 0.635 0.479 0.506 0.214
foot 587 1941 0.859 0.778 0.832 0.593
E - 1800
Class Images Instances P R mAP50 mAP50-95
all 705 70084 0.796 0.560 0.651 0.490
body 705 4412 0.945 0.745 0.859 0.782
adult 705 3554 0.941 0.676 0.821 0.771
child 705 485 0.922 0.738 0.845 0.810
male 705 2668 0.931 0.734 0.843 0.791
female 705 959 0.932 0.729 0.837 0.796
body_with_wheelchair 705 2 0.709 1.000 0.995 0.995
head 705 3980 0.929 0.789 0.879 0.719
front 705 967 0.831 0.480 0.617 0.536
right-front 705 611 0.822 0.571 0.687 0.608
right-side 705 430 0.902 0.693 0.794 0.699
right-back 705 204 0.805 0.544 0.657 0.559
back 705 238 0.750 0.408 0.528 0.456
left-back 705 207 0.837 0.551 0.645 0.567
left-side 705 460 0.790 0.549 0.646 0.574
left-front 705 863 0.780 0.340 0.485 0.422
face 705 2250 0.936 0.830 0.897 0.713
eye 705 2071 0.808 0.350 0.481 0.210
nose 705 1923 0.888 0.544 0.662 0.388
mouth 705 1584 0.851 0.487 0.594 0.303
ear 705 1907 0.838 0.491 0.597 0.360
collarbone 705 3670 0.587 0.311 0.331 0.108
shoulder 705 6304 0.726 0.495 0.557 0.267
solar_plexus 705 3063 0.395 0.178 0.161 0.047
elbow 705 3873 0.703 0.468 0.525 0.259
wrist 705 3227 0.664 0.401 0.439 0.179
hand 705 2734 0.930 0.620 0.809 0.619
hand_left 705 1373 0.911 0.637 0.791 0.611
hand_right 705 1361 0.902 0.594 0.763 0.586
abdomen 705 2420 0.583 0.452 0.482 0.208
hip_joint 705 4283 0.574 0.376 0.400 0.166
knee 705 3298 0.676 0.482 0.543 0.276
ankle 705 2464 0.626 0.467 0.485 0.198
foot 705 2239 0.862 0.766 0.833 0.593
E - 2100
Class Images Instances P R mAP50 mAP50-95
all 822 72900 0.802 0.588 0.677 0.511
body 822 4372 0.950 0.824 0.915 0.839
adult 822 3432 0.945 0.782 0.891 0.843
child 822 462 0.943 0.751 0.843 0.815
male 822 2460 0.925 0.826 0.905 0.852
female 822 1069 0.935 0.857 0.922 0.874
body_with_wheelchair 822 2 0.423 1.000 0.995 0.921
head 822 3827 0.929 0.901 0.950 0.788
front 822 786 0.878 0.560 0.696 0.609
right-front 822 690 0.878 0.541 0.667 0.603
right-side 822 538 0.862 0.606 0.712 0.635
right-back 822 279 0.843 0.520 0.641 0.562
back 822 227 0.753 0.405 0.525 0.451
left-back 822 225 0.755 0.520 0.611 0.548
left-side 822 476 0.859 0.542 0.668 0.585
left-front 822 606 0.817 0.537 0.654 0.584
face 822 2306 0.931 0.877 0.925 0.748
eye 822 2351 0.830 0.371 0.512 0.225
nose 822 2064 0.908 0.553 0.679 0.419
mouth 822 1672 0.863 0.542 0.642 0.337
ear 822 2042 0.854 0.502 0.622 0.377
collarbone 822 3744 0.603 0.328 0.351 0.114
shoulder 822 6348 0.741 0.529 0.593 0.284
solar_plexus 822 3288 0.421 0.168 0.173 0.052
elbow 822 4164 0.734 0.481 0.550 0.263
wrist 822 3593 0.695 0.413 0.457 0.189
hand 822 3055 0.929 0.638 0.826 0.639
hand_left 822 1574 0.918 0.630 0.795 0.621
hand_right 822 1481 0.918 0.629 0.795 0.615
abdomen 822 2594 0.601 0.463 0.499 0.215
hip_joint 822 4564 0.593 0.377 0.409 0.170
knee 822 3457 0.693 0.497 0.558 0.281
ankle 822 2708 0.666 0.475 0.513 0.216
foot 822 2444 0.871 0.770 0.834 0.584
E - 2400
Class Images Instances P R mAP50 mAP50-95
all 940 88154 0.829 0.582 0.676 0.524
body 940 5844 0.930 0.738 0.842 0.767
adult 940 4470 0.955 0.718 0.844 0.801
child 940 516 0.888 0.808 0.865 0.839
male 940 3121 0.920 0.746 0.833 0.785
female 940 1417 0.955 0.788 0.871 0.834
body_with_wheelchair 940 2 0.599 1.000 0.995 0.995
head 940 4959 0.932 0.821 0.889 0.751
front 940 895 0.774 0.482 0.586 0.526
right-front 940 995 0.880 0.455 0.585 0.542
right-side 940 640 0.891 0.558 0.682 0.628
right-back 940 309 0.926 0.576 0.695 0.623
back 940 243 0.827 0.494 0.599 0.526
left-back 940 253 0.871 0.508 0.624 0.571
left-side 940 588 0.897 0.561 0.676 0.616
left-front 940 1033 0.884 0.360 0.513 0.471
face 940 2596 0.898 0.881 0.922 0.763
eye 940 2400 0.834 0.437 0.577 0.273
nose 940 2207 0.896 0.596 0.705 0.443
mouth 940 1811 0.850 0.574 0.659 0.360
ear 940 2057 0.870 0.584 0.692 0.422
collarbone 940 4839 0.632 0.297 0.339 0.122
shoulder 940 8015 0.784 0.513 0.590 0.318
solar_plexus 940 3970 0.488 0.148 0.187 0.061
elbow 940 5043 0.755 0.487 0.557 0.311
wrist 940 4226 0.739 0.420 0.480 0.224
hand 940 3575 0.961 0.628 0.844 0.674
hand_left 940 1816 0.947 0.648 0.824 0.665
hand_right 940 1759 0.944 0.637 0.810 0.643
abdomen 940 3070 0.674 0.482 0.541 0.269
hip_joint 940 5431 0.661 0.415 0.470 0.228
knee 940 4110 0.726 0.539 0.604 0.346
ankle 940 3120 0.704 0.506 0.553 0.257
foot 940 2824 0.875 0.800 0.858 0.637
E - 2700
Class Images Instances P R mAP50 mAP50-95
all 1058 95756 0.836 0.595 0.686 0.530
body 1058 6037 0.939 0.813 0.892 0.809
adult 1058 4481 0.952 0.763 0.875 0.836
child 1058 569 0.945 0.801 0.869 0.844
male 1058 3226 0.920 0.812 0.878 0.827
female 1058 1421 0.962 0.826 0.893 0.855
body_with_wheelchair 1058 4 0.378 0.750 0.659 0.650
head 1058 5059 0.917 0.922 0.956 0.798
front 1058 918 0.879 0.493 0.625 0.582
right-front 1058 967 0.937 0.523 0.656 0.610
right-side 1058 592 0.908 0.576 0.691 0.639
right-back 1058 344 0.901 0.544 0.659 0.597
back 1058 275 0.874 0.385 0.511 0.456
left-back 1058 323 0.837 0.489 0.603 0.545
left-side 1058 653 0.884 0.565 0.689 0.631
left-front 1058 987 0.916 0.429 0.573 0.526
face 1058 2732 0.918 0.890 0.931 0.773
eye 1058 2464 0.817 0.447 0.580 0.267
nose 1058 2257 0.906 0.651 0.747 0.465
mouth 1058 1844 0.837 0.586 0.673 0.364
ear 1058 2098 0.864 0.603 0.712 0.435
collarbone 1058 5289 0.656 0.337 0.383 0.148
shoulder 1058 8683 0.805 0.535 0.613 0.350
solar_plexus 1058 4638 0.574 0.225 0.257 0.089
elbow 1058 5632 0.772 0.504 0.574 0.331
wrist 1058 4695 0.711 0.459 0.505 0.241
hand 1058 4019 0.960 0.637 0.853 0.683
hand_left 1058 2049 0.959 0.617 0.827 0.665
hand_right 1058 1970 0.932 0.638 0.815 0.644
abdomen 1058 3573 0.686 0.538 0.595 0.315
hip_joint 1058 6342 0.710 0.464 0.527 0.280
knee 1058 4779 0.719 0.538 0.605 0.357
ankle 1058 3562 0.723 0.508 0.562 0.272
foot 1058 3274 0.880 0.775 0.838 0.619
E - 3000
Class Images Instances P R mAP50 mAP50-95
all 1183 124031 0.842 0.548 0.653 0.498
body 1183 8571 0.955 0.671 0.795 0.724
adult 1183 6374 0.946 0.624 0.782 0.743
child 1183 853 0.923 0.701 0.793 0.768
male 1183 4621 0.933 0.699 0.802 0.753
female 1183 1976 0.933 0.735 0.823 0.778
body_with_wheelchair 1183 6 0.301 0.833 0.813 0.522
head 1183 7266 0.939 0.791 0.871 0.720
front 1183 1543 0.845 0.388 0.541 0.490
right-front 1183 1435 0.909 0.396 0.533 0.492
right-side 1183 782 0.895 0.537 0.640 0.592
right-back 1183 450 0.923 0.481 0.621 0.562
back 1183 303 0.867 0.399 0.523 0.463
left-back 1183 374 0.836 0.455 0.552 0.499
left-side 1183 883 0.902 0.488 0.618 0.564
left-front 1183 1497 0.891 0.315 0.483 0.442
face 1183 3842 0.915 0.808 0.877 0.713
eye 1183 2958 0.839 0.427 0.561 0.267
nose 1183 2931 0.919 0.540 0.664 0.420
mouth 1183 2366 0.870 0.504 0.612 0.340
ear 1183 2690 0.872 0.542 0.653 0.410
collarbone 1183 7401 0.675 0.313 0.376 0.161
shoulder 1183 11508 0.797 0.474 0.559 0.326
solar_plexus 1183 5922 0.603 0.267 0.310 0.129
elbow 1183 6793 0.783 0.497 0.571 0.343
wrist 1183 5652 0.761 0.465 0.529 0.274
hand 1183 4649 0.955 0.616 0.827 0.666
hand_left 1183 2332 0.942 0.606 0.805 0.658
hand_right 1183 2317 0.926 0.604 0.784 0.630
abdomen 1183 4202 0.759 0.572 0.641 0.368
hip_joint 1183 7421 0.756 0.513 0.579 0.333
knee 1183 5561 0.778 0.546 0.623 0.374
ankle 1183 4462 0.749 0.517 0.572 0.296
foot 1183 4090 0.881 0.760 0.826 0.604
E - 3000 - refine
Class Images Instances P R mAP50 mAP50-95
all 1207 119055 0.824 0.554 0.656 0.480
body 1207 7747 0.940 0.727 0.834 0.743
adult 1207 5679 0.940 0.664 0.812 0.757
child 1207 849 0.911 0.726 0.818 0.768
male 1207 4286 0.905 0.738 0.831 0.764
female 1207 1834 0.888 0.746 0.830 0.769
body_with_wheelchair 1207 8 0.267 0.500 0.481 0.320
head 1207 6670 0.922 0.820 0.889 0.712
front 1207 1400 0.862 0.434 0.591 0.515
right-front 1207 1219 0.879 0.463 0.615 0.546
right-side 1207 802 0.865 0.570 0.701 0.623
right-back 1207 414 0.843 0.505 0.609 0.525
back 1207 368 0.768 0.332 0.468 0.399
left-back 1207 368 0.851 0.524 0.628 0.555
left-side 1207 788 0.847 0.521 0.632 0.556
left-front 1207 1309 0.764 0.381 0.509 0.436
face 1207 3566 0.922 0.822 0.891 0.711
eye 1207 3028 0.847 0.411 0.541 0.255
nose 1207 2845 0.900 0.571 0.682 0.421
mouth 1207 2309 0.837 0.507 0.609 0.324
ear 1207 2712 0.859 0.526 0.628 0.378
collarbone 1207 7306 0.713 0.383 0.446 0.185
shoulder 1207 10858 0.791 0.473 0.557 0.295
solar_plexus 1207 6191 0.705 0.423 0.473 0.209
elbow 1207 6585 0.768 0.473 0.550 0.297
wrist 1207 5675 0.749 0.456 0.513 0.240
hand 1207 4663 0.945 0.610 0.808 0.607
hand_left 1207 2375 0.929 0.573 0.764 0.584
hand_right 1207 2288 0.918 0.581 0.756 0.567
abdomen 1207 4114 0.755 0.582 0.647 0.350
hip_joint 1207 7358 0.749 0.513 0.580 0.306
knee 1207 5356 0.754 0.532 0.602 0.329
ankle 1207 4290 0.738 0.490 0.553 0.255
foot 1207 3795 0.861 0.712 0.784 0.531
E - 3300
Class Images Instances P R mAP50 mAP50-95
all 1302 127919 0.858 0.591 0.689 0.534
body 1302 8228 0.941 0.772 0.866 0.780
adult 1302 5866 0.954 0.760 0.868 0.825
child 1302 702 0.902 0.775 0.831 0.792
male 1302 4300 0.935 0.790 0.862 0.808
female 1302 1953 0.913 0.798 0.861 0.808
body_with_wheelchair 1302 6 0.112 0.500 0.501 0.460
head 1302 6731 0.935 0.883 0.933 0.776
front 1302 1191 0.882 0.521 0.634 0.582
right-front 1302 1435 0.899 0.446 0.579 0.536
right-side 1302 931 0.930 0.557 0.673 0.618
right-back 1302 468 0.875 0.519 0.619 0.562
back 1302 360 0.873 0.401 0.532 0.465
left-back 1302 394 0.885 0.508 0.617 0.560
left-side 1302 796 0.907 0.549 0.679 0.620
left-front 1302 1154 0.877 0.488 0.598 0.545
face 1302 3609 0.950 0.883 0.929 0.774
eye 1302 3275 0.857 0.433 0.567 0.274
nose 1302 3084 0.914 0.603 0.710 0.449
mouth 1302 2497 0.866 0.570 0.676 0.371
ear 1302 2976 0.878 0.552 0.656 0.405
collarbone 1302 7476 0.791 0.434 0.518 0.251
shoulder 1302 11532 0.845 0.541 0.630 0.377
solar_plexus 1302 6525 0.797 0.480 0.554 0.286
elbow 1302 7367 0.824 0.509 0.597 0.370
wrist 1302 6288 0.806 0.483 0.552 0.299
hand 1302 5122 0.956 0.612 0.811 0.649
hand_left 1302 2603 0.947 0.591 0.771 0.629
hand_right 1302 2519 0.944 0.579 0.766 0.610
abdomen 1302 4695 0.810 0.599 0.678 0.419
hip_joint 1302 8341 0.820 0.541 0.620 0.382
knee 1302 6068 0.814 0.568 0.648 0.406
ankle 1302 4959 0.770 0.525 0.591 0.322
foot 1302 4468 0.890 0.744 0.817 0.598
E - 3600 - 4 batch
Class Images Instances P R mAP50 mAP50-95
all 1421 146644 0.841 0.576 0.680 0.511
body 1421 9756 0.937 0.714 0.826 0.740
adult 1421 7060 0.956 0.704 0.839 0.790
child 1421 891 0.937 0.720 0.819 0.791
male 1421 5399 0.915 0.746 0.840 0.775
female 1421 2202 0.901 0.762 0.843 0.790
body_with_wheelchair 1421 6 0.550 0.833 0.847 0.724
head 1421 8241 0.904 0.866 0.919 0.740
front 1421 1514 0.875 0.423 0.588 0.534
right-front 1421 1767 0.870 0.366 0.533 0.480
right-side 1421 1111 0.880 0.536 0.665 0.600
right-back 1421 572 0.874 0.507 0.633 0.561
back 1421 441 0.856 0.376 0.537 0.475
left-back 1421 447 0.859 0.532 0.645 0.568
left-side 1421 981 0.873 0.533 0.673 0.606
left-front 1421 1404 0.846 0.406 0.555 0.499
face 1421 4230 0.918 0.851 0.906 0.726
eye 1421 3569 0.821 0.410 0.545 0.247
nose 1421 3544 0.893 0.570 0.683 0.417
mouth 1421 2805 0.806 0.512 0.612 0.331
ear 1421 3328 0.865 0.562 0.663 0.395
collarbone 1421 9065 0.717 0.406 0.478 0.215
shoulder 1421 13611 0.799 0.490 0.572 0.323
solar_plexus 1421 7593 0.722 0.456 0.514 0.243
elbow 1421 8277 0.773 0.500 0.571 0.318
wrist 1421 6945 0.754 0.484 0.539 0.262
hand 1421 5658 0.944 0.607 0.794 0.610
hand_left 1421 2809 0.925 0.587 0.768 0.595
hand_right 1421 2849 0.904 0.585 0.751 0.580
abdomen 1421 5149 0.762 0.595 0.664 0.379
hip_joint 1421 9252 0.766 0.532 0.601 0.337
knee 1421 6498 0.755 0.556 0.618 0.354
ankle 1421 5124 0.723 0.527 0.584 0.288
foot 1421 4546 0.872 0.744 0.811 0.570
E - 3600 - 16 batch
Class Images Instances P R mAP50 mAP50-95
all 587 56162 0.882 0.593 0.705 0.548
body 587 3876 0.959 0.717 0.842 0.769
adult 587 2954 0.967 0.662 0.817 0.781
child 587 379 0.983 0.782 0.880 0.858
male 587 2141 0.954 0.730 0.845 0.803
female 587 813 0.966 0.774 0.857 0.826
body_with_wheelchair 587 1 0.610 1.000 0.995 0.895
head 587 3312 0.943 0.742 0.850 0.724
front 587 805 0.904 0.421 0.593 0.530
right-front 587 430 0.922 0.540 0.663 0.616
right-side 587 348 0.954 0.644 0.760 0.703
right-back 587 164 0.922 0.591 0.699 0.647
back 587 196 0.896 0.439 0.602 0.535
left-back 587 152 0.964 0.539 0.680 0.618
left-side 587 431 0.899 0.534 0.678 0.615
left-front 587 784 0.861 0.327 0.496 0.446
face 587 1681 0.942 0.779 0.866 0.714
eye 587 1453 0.813 0.367 0.494 0.237
nose 587 1369 0.911 0.541 0.658 0.403
mouth 587 1109 0.842 0.496 0.612 0.334
ear 587 1411 0.881 0.486 0.588 0.354
collarbone 587 2977 0.755 0.399 0.477 0.206
shoulder 587 5066 0.846 0.526 0.621 0.375
solar_plexus 587 2384 0.711 0.424 0.480 0.210
elbow 587 3140 0.831 0.541 0.619 0.373
wrist 587 2518 0.808 0.497 0.569 0.291
hand 587 2150 0.960 0.637 0.827 0.665
hand_left 587 1075 0.954 0.602 0.794 0.648
hand_right 587 1075 0.953 0.571 0.767 0.618
abdomen 587 1876 0.839 0.672 0.750 0.467
hip_joint 587 3330 0.851 0.621 0.704 0.433
knee 587 2718 0.820 0.612 0.690 0.432
ankle 587 2103 0.788 0.579 0.644 0.334
foot 587 1941 0.904 0.794 0.854 0.636
- MIT-T
┏━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┓ ┃ Epoch ┃ Avg. Precision ┃ % ┃ Avg. Recall ┃ % ┃ ┡━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━┩ │ 194 │ AP @ .5:.95 │ 32.56 │ AP @ .5 │ 48.91 │ │ 195 │ AP @ .5:.95 │ 32.60 │ AP @ .5 │ 48.97 │ │ 196 │ AP @ .5:.95 │ 32.68 │ AP @ .5 │ 49.06 │ │ 197 │ AP @ .5:.95 │ 32.70 │ AP @ .5 │ 49.08 │ │ 198 │ AP @ .5:.95 │ 32.78 │ AP @ .5 │ 49.19 │ │ │ │ │ │ │ │ 199 │ AP @ .5:.95 │ 32.80 │ AR maxDets 1 │ 29.14 │ │ 199 │ AP @ .5 │ 49.21 │ AR maxDets 10 │ 47.33 │ │ 199 │ AP @ .75 │ 34.06 │ AR maxDets 100 │ 49.98 │ │ 199 │ AP (small) │ 11.48 │ AR (small) │ 26.43 │ │ 199 │ AP (medium) │ 40.26 │ AR (medium) │ 65.01 │ │ 199 │ AP (large) │ 57.57 │ AR (large) │ 75.35 │ └───────┴────────────────┴───────┴────────────────┴───────┘
- 3,785個
env
sudo apt update
sudo apt install gh
gh auth login
git clone https://github.com/PINTO0309/YOLO && cd YOLO
pip install einops==0.7.0 faster-coco-eval==1.6.5 graphviz==0.21 hydra-core==1.3.2 lightning==2.2.3 loguru==0.7.0 numpy==1.26.4 opencv-python==4.11.0.86 albumentations==2.0.8 pillow==10.4.0 pycocotools==2.0.6 requests==2.28.2 rich==14.1.0 tensorboard==2.20.0 wandb==0.16.6 gdown==5.2.0
mkdir -p data && cd data
gdown --id xxx
tar -zxvf dataset.tar.gz \
&& mv dataset wholebody34 \
&& rm dataset.tar.gz
tar -zcvf v9-e.tar.gz v9-e
scp -i ~/.ssh/xxx.pem ubuntu@xxx.xxx.xxx.xxx:/home/ubuntu/yolov9mit/runs/train/v9-e.tar.gz .
tar -zxvf v9-e.tar.gz
cd v9-e/lightning_logs/version_0/
scp -i ~/.ssh/xxx.pem ubuntu@xxx.xxx.xxx.xxx:/home/ubuntu/yolov9mit/runs/train/v9-e/lightning_logs/version_0/events.out.tfevents.xxx.xxx-xxx-xxx-xxx.xxx.0 .
V9-N
VARIANT=n
EPOCH=200
BATCHSIZE=8
uv run python yolo/lazy.py \
task=train \
name=v9-${VARIANT} \
task.epoch=${EPOCH} \
task.data.batch_size=${BATCHSIZE} \
model=v9-${VARIANT} \
weight="runs/train/v9-n-wholebody25/lightning_logs/version_3/checkpoints/best_n_0470_0.2904.pt" \
dataset=wholebody34 \
device=cuda \
use_wandb=False \
use_tensorboard=True
VARIANT=n
EPOCH=2
BATCHSIZE=8
uv run python yolo/lazy.py \
task=train \
name=v9-${VARIANT} \
task.epoch=${EPOCH} \
task.data.batch_size=${BATCHSIZE} \
task.data.class_biased_oversampling=True \
model=v9-${VARIANT} \
weight=False \
dataset=wholebody34 \
device=cuda \
use_wandb=False \
use_tensorboard=True
VARIANT=n
EPOCH=2
BATCHSIZE=8
uv run python yolo/lazy.py \
task=train \
name=v9-${VARIANT} \
task.epoch=${EPOCH} \
task.data.batch_size=${BATCHSIZE} \
task.data.class_biased_batch_formation=True \
model=v9-${VARIANT} \
weight=False \
dataset=wholebody34 \
device=cuda \
use_wandb=False \
use_tensorboard=True
┏━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ Epoch ┃ Avg. Precision ┃ % ┃ Avg. Recall ┃ % ┃
┡━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ 194 │ AP @ .5:.95 │ 23.98 │ AP @ .5 │ 37.53 │
│ 195 │ AP @ .5:.95 │ 23.99 │ AP @ .5 │ 37.53 │
│ 196 │ AP @ .5:.95 │ 23.99 │ AP @ .5 │ 37.53 │
│ 197 │ AP @ .5:.95 │ 23.99 │ AP @ .5 │ 37.56 │
│ 198 │ AP @ .5:.95 │ 24.00 │ AP @ .5 │ 37.58 │
│ │ │ │ │ │
│ 199 │ AP @ .5:.95 │ 24.02 │ AR maxDets 1 │ 24.25 │
│ 199 │ AP @ .5 │ 37.62 │ AR maxDets 10 │ 39.93 │
│ 199 │ AP @ .75 │ 24.79 │ AR maxDets 100 │ 42.77 │
│ 199 │ AP (small) │ 7.28 │ AR (small) │ 19.60 │
│ 199 │ AP (medium) │ 29.77 │ AR (medium) │ 56.19 │
│ 199 │ AP (large) │ 45.77 │ AR (large) │ 66.92 │
└───────┴────────────────┴───────┴────────────────┴───────┘
┏━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ ID┃Name ┃ AP┃ ID┃Name ┃ AP┃ ID┃Name ┃ AP┃
┡━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ 0│body │ 0.5342│ 20│ear │ 0.1629│ │ │ │
│ 1│adult │ 0.5000│ 21│collarbone │ 0.0475│ │ │ │
│ 2│child │ 0.2701│ 22│shoulder │ 0.1467│ │ │ │
│ 3│male │ 0.4899│ 23│solar_plexus │ 0.0277│ │ │ │
│ 4│female │ 0.3362│ 24│elbow │ 0.0862│ │ │ │
│ 5│body_with_wheelchair │ 0.1000│ 25│wrist │ 0.0403│ │ │ │
│ 6│body_with_crutches │ 0.1779│ 26│hand │ 0.2483│ │ │ │
│ 7│head │ 0.5673│ 27│hand_left │ 0.1939│ │ │ │
│ 8│front │ 0.4322│ 28│hand_right │ 0.1875│ │ │ │
│ 9│right-front │ 0.4214│ 29│abdomen │ 0.0717│ │ │ │
│ 10│right-side │ 0.4072│ 30│hip_joint │ 0.0455│ │ │ │
│ 11│right-back │ 0.3150│ 31│knee │ 0.0955│ │ │ │
│ 12│back │ 0.1175│ 32│ankle │ 0.0571│ │ │ │
│ 13│left-back │ 0.2341│ 33│foot │ 0.1867│ │ │ │
│ 14│left-side │ 0.3780│ │ │ │ │ │ │
│ 15│left-front │ 0.4119│ │ │ │ │ │ │
│ 16│face │ 0.4720│ │ │ │ │ │ │
│ 17│eye │ 0.0884│ │ │ │ │ │ │
│ 18│nose │ 0.1900│ │ │ │ │ │ │
│ 19│mouth │ 0.1268│ │ │ │ │ │ │
└───┴─────────────────────────┴───────┴───┴─────────────────────────┴───────┴───┴─────────────────────────┴───────┘
VARIANT=n
EPOCH=200
BATCHSIZE=8
uv run python yolo/lazy.py \
task=train \
name=v9-${VARIANT} \
task.epoch=${EPOCH} \
task.data.batch_size=${BATCHSIZE} \
task.kd.enable=True \
model=v9-${VARIANT} \
weight=True \
dataset=wholebody34 \
device=cuda \
use_wandb=False \
use_tensorboard=True
V9-E
VARIANT=e
EPOCH=500
BATCHSIZE=32
python yolo/lazy.py \
task=train \
name=v9-${VARIANT} \
task.epoch=${EPOCH} \
task.data.batch_size=${BATCHSIZE} \
cpu_num=32 \
model=v9-${VARIANT} \
weight=False \
dataset=wholebody34 \
device=cuda \
use_wandb=False \
use_tensorboard=True
VARIANT=e
EPOCH=500
BATCHSIZE=32
python yolo/lazy.py \
task=train \
name=v9-${VARIANT} \
task.epoch=${EPOCH} \
task.data.batch_size=${BATCHSIZE} \
model=v9-${VARIANT} \
task.resume_ckpt="runs/train/v9-e/lightning_logs/version_2/checkpoints/epoch38.ckpt" \
dataset=wholebody34 \
device=cuda \
use_wandb=False \
use_tensorboard=True
python yolo/lazy.py \
task=train \
name=v9-${VARIANT} \
task.epoch=${EPOCH} \
task.data.batch_size=${BATCHSIZE} \
model=v9-${VARIANT} \
weight="runs/train/v9-e/lightning_logs/version_4/checkpoints/best_e_0222_0.4418.pt" \
dataset=wholebody34 \
device=cuda \
use_wandb=False \
use_tensorboard=True
観測結果
TensorBoardログ runs/train/v9-e/lightning_logs/version_4/events.out.tfevents.1758026693.192-222-51-150.199968.0 から、epoch 221→222で mAP が 0.4418→0.4291、map_medium が 0.5436→0.5308、map_large が 0.6716→0.6642 へ急落し、242でも同様に 0.4353→0.4252 / 0.5377→0.5269 / 0.6716→0.6452 に下がっている一方で map_small の変動はごく小さい。
同区間の mar_medium・mar_large はむしろ微増しており(例: epoch 221→222 で 0.7077→0.7089 / 0.7995→0.8002)、コントラストしている。損失 (Loss/11_BCELoss_epoch 等) も滑らかに減少しており、学習が破綻した兆候は見られない。
検証データ構成は .hydra/config.yaml にあるとおり data/wholebody34(例: runs/train/v9-e/.hydra/config.yaml:152)で、実測すると val のバウンディングボックス 201,578 個のうち small 77%、medium 16%、large 7% と強いサイズ偏りがある。large の大半は少数クラス(例: クラスID 5,6 で 158 件/84 件)に集中し、クラス別 large 割合が 0% に近いものも多い。
考察
mar が維持されていることから、検出漏れではなく中~大サイズでの偽検出(precision低下)が一時的に増えたと推定できる。
サンプル数の少ない medium/large クラスで数件の誤検出が出ると AP が一気に悪化するため、記録された落ち込み幅は統計的揺らぎの範囲と考えられる。実際、数エポック後には元の水準に戻っている。
したがって学習進捗が異常というより、データ分布と評価指標の性質による高頻度ノイズが顕在化したケースと見るのが自然。
medium/large を多く含むクラスを oversampling するには、「そのクラスのバウンディングボックスが多い画像を学習ミニバッチで高頻度に出す」処理を入れます。やり方はいくつかあります。
画像レベルの重み付けサンプリング
キャッシュ(例: train.pache)を解析して、各画像に含まれる medium/large ボックスの個数を数え、WeightedRandomSampler などで「その数に比例する重み」を設定します。YOLO 的には、ラベルテキストを読む段階で weight = 1 + α*(medium_large_boxes) のように計算し、データローダーの sampler に渡すと、当該画像が他より多く登場するようになります。
クラス別リストを作って追加複製
medium/large クラスごとに画像パスのリストを作り、通常データに対して一定割合で重複挿入します。たとえば 1 エポックのデータ列を組む際に、重複させたリストを合体してシャッフルする方法です。
バッチ組成時のカスタムロジック
データセットから getitem で取り出す際に、medium/large を含む画像が一定割合入るまでループするなど、バッチ形成を制御します。やや動的ですが、バッチの中に必ず medium/large が入るよう強制できます。
いずれの場合も、単にサンプル数を増やすだけでなく「どのクラスがどのサイズ帯を持っているか」を事前に集計し、過剰な偏りにならないよう重みや複製数を調整するのがポイントです。
data/wholebody34/train.pache を分析してみてほしい。
Train Cache 概要
画像枚数: 9,229 (data/wholebody34/train.pache)
バウンディングボックス総数: 816,466
サイズ別内訳: small 629,173 (77.1%)・medium 128,762 (15.8%)・large 58,531 (7.2%)
1枚あたりの分布
medium を少なくとも1つ含む画像: 8,940 (96.9%)
large を少なくとも1つ含む画像: 8,711 (94.4%)
large 0個の画像は 518 枚(5.6%)で、逆に large 3個の画像が最頻 (2,692 枚)。
クラス別の傾向(抜粋)
body (ID 0): 52,312 boxes, small 36.2% / medium 31.5% / large 32.3%
adult (ID 1): 39,416 boxes, small 30.0% / medium 34.4% / large 35.6%
child (ID 2): 4,387 boxes, small 18.6% / medium 34.6% / large 46.8%
body_with_wheelchair (ID 5): 713 boxes, large 87.4% と大型主体
上半身/手足系(例: shoulder ID 22, wrist ID 25)は small が 90% 以上で medium/large が非常に少ない
所感
検証セットよりサンプル数が多いため medium/large も一定数あるものの、全体は small 偏重。特に人体全体を扱うクラス(body, adult 等)で medium/large が多く、部位系は small だらけという構図です。medium/large を強化したい場合は、これら人体全体クラスや車椅子・杖といった大きめクラスを重点的に oversampling するのが効果的と考えられます。
クラス別サイズ内訳 (train.pache 全 34 クラス)
COCO の定義に従うと、バウンディングボックスの面積(ピクセル数)でサイズ帯を分けています。
small: 32×32 ピクセル未満(<1,024 px²)
medium: 32×32~96×96 ピクセル(1,024~9,216 px²)
large: 96×96 ピクセルより大きい(>9,216 px²)
ID | Name | Total | Small | Medium | Large | ID | Name | Total | Small | Medium | Large |
---|---|---|---|---|---|---|---|---|---|---|---|
00 | body | 52,312 | 36.2% | 31.5% | 32.3% | 20 | ear | 19,362 | 97.4% | 2.6% | 0.0% |
01 | adult | 39,416 | 30.0% | 34.4% | 35.6% | 21 | collarbone | 48,054 | 97.7% | 2.3% | 0.0% |
02 | child | 4,387 | 18.6% | 34.6% | 46.8% | 22 | shoulder | 74,427 | 90.8% | 8.7% | 0.5% |
03 | male | 28,777 | 28.9% | 34.1% | 37.1% | 23 | solar_plexus | 41,724 | 93.8% | 6.2% | 0.0% |
04 | female | 12,061 | 25.3% | 34.7% | 40.0% | 24 | elbow | 45,274 | 93.1% | 6.9% | 0.0% |
05 | wheelchair | 713 | 0.8% | 11.8% | 87.4% | 25 | wrist | 38,092 | 97.8% | 2.2% | 0.0% |
06 | crutches | 323 | 0.9% | 9.3% | 89.8% | 26 | hand | 31,833 | 79.4% | 19.6% | 1.0% |
07 | head | 44,647 | 64.1% | 29.3% | 6.5% | 27 | hand_left | 15,977 | 79.4% | 19.5% | 1.1% |
08 | front | 8,348 | 66.5% | 26.7% | 6.7% | 28 | hand_right | 15,856 | 79.4% | 19.7% | 0.9% |
09 | right-front | 9,121 | 66.9% | 26.2% | 7.0% | 29 | abdomen | 28,824 | 77.0% | 22.4% | 0.5% |
10 | right-side | 4,932 | 56.3% | 36.5% | 7.2% | 30 | hip_joint | 52,711 | 84.8% | 15.0% | 0.2% |
11 | right-back | 3,308 | 61.7% | 33.0% | 5.3% | 31 | knee | 37,282 | 91.0% | 8.9% | 0.1% |
12 | back | 2,508 | 72.3% | 24.2% | 3.5% | 32 | ankle | 30,947 | 95.8% | 3.5% | 0.6% |
13 | left-back | 2,929 | 62.9% | 32.5% | 4.7% | 33 | foot | 27,845 | 81.8% | 15.0% | 3.2% |
14 | left-side | 5,216 | 57.2% | 34.4% | 8.4% | ||||||
15 | left-front | 8,282 | 66.7% | 26.8% | 6.4% | ||||||
16 | face | 23,925 | 71.8% | 24.7% | 3.6% | ||||||
17 | eye | 21,056 | 99.1% | 0.9% | 0.0% | ||||||
18 | nose | 19,973 | 97.5% | 2.3% | 0.2% | ||||||
19 | mouth | 16,024 | 98.0% | 1.9% | 0.1% |
GPL
C
Class Images Instances P R mAP50 mAP50-95
all 2446 200648 0.694 0.517 0.574 0.428
body 2446 12499 0.906 0.713 0.832 0.726
adult 2446 9500 0.883 0.708 0.816 0.732
child 2446 1100 0.816 0.704 0.771 0.723
male 2446 7133 0.862 0.774 0.848 0.761
female 2446 2789 0.727 0.738 0.763 0.693
body_with_wheelchair 2446 156 0.928 0.942 0.967 0.909
body_with_crutches 2446 98 0.954 0.980 0.980 0.947
head 2446 10580 0.912 0.873 0.925 0.717
front 2446 1962 0.674 0.449 0.539 0.463
right-front 2446 2015 0.672 0.411 0.501 0.427
right-side 2446 1241 0.690 0.516 0.550 0.466
right-back 2446 860 0.777 0.453 0.569 0.468
back 2446 512 0.563 0.320 0.373 0.310
left-back 2446 697 0.665 0.443 0.514 0.434
left-side 2446 1332 0.725 0.488 0.579 0.498
left-front 2446 1958 0.708 0.422 0.524 0.452
face 2446 5932 0.893 0.867 0.907 0.684
eye 2446 5515 0.697 0.381 0.459 0.195
nose 2446 5191 0.846 0.543 0.637 0.350
mouth 2446 4163 0.722 0.494 0.562 0.269
ear 2446 5084 0.804 0.509 0.606 0.346
collarbone 2446 11567 0.394 0.157 0.141 0.040
shoulder 2446 18142 0.623 0.463 0.491 0.211
solar_plexus 2446 10143 0.2460.0226 0.530 0.016
elbow 2446 11321 0.533 0.382 0.402 0.173
wrist 2446 9556 0.458 0.193 0.190 0.068
hand 2446 7997 0.896 0.634 0.785 0.548
hand_left 2446 3995 0.843 0.571 0.714 0.504
hand_right 2446 4002 0.859 0.570 0.713 0.510
abdomen 2446 7067 0.335 0.192 0.172 0.061
hip_joint 2446 12909 0.330 0.154 0.132 0.043
knee 2446 9099 0.495 0.446 0.446 0.197
ankle 2446 7672 0.406 0.349 0.295 0.100
foot 2446 6861 0.757 0.705 0.756 0.496
E
Class Images Instances P R mAP50 mAP50-95
all 2446 200648 0.812 0.561 0.649 0.491
body 2446 12499 0.934 0.759 0.854 0.770
adult 2446 9500 0.927 0.723 0.834 0.784
child 2446 1100 0.870 0.746 0.804 0.775
male 2446 7133 0.895 0.794 0.856 0.797
female 2446 2789 0.859 0.762 0.820 0.767
body_with_wheelchair 2446 156 0.635 0.436 0.498 0.305
body_with_crutches 2446 98 0 0 0 0
head 2446 10580 0.937 0.880 0.930 0.774
front 2446 1962 0.842 0.491 0.619 0.559
right-front 2446 2015 0.853 0.457 0.574 0.522
right-side 2446 1241 0.877 0.577 0.682 0.630
right-back 2446 860 0.835 0.545 0.661 0.590
back 2446 512 0.798 0.406 0.491 0.439
left-back 2446 697 0.849 0.469 0.578 0.517
left-side 2446 1332 0.855 0.541 0.668 0.604
left-front 2446 1958 0.811 0.474 0.585 0.529
face 2446 5932 0.920 0.872 0.918 0.738
eye 2446 5515 0.821 0.422 0.539 0.252
nose 2446 5191 0.880 0.592 0.691 0.422
mouth 2446 4163 0.818 0.529 0.614 0.330
ear 2446 5084 0.859 0.569 0.664 0.410
collarbone 2446 11567 0.714 0.425 0.471 0.219
shoulder 2446 18142 0.824 0.538 0.609 0.352
solar_plexus 2446 10143 0.690 0.416 0.465 0.243
elbow 2446 11321 0.797 0.500 0.571 0.333
wrist 2446 9556 0.756 0.479 0.531 0.276
hand 2446 7997 0.947 0.619 0.805 0.616
hand_left 2446 3995 0.907 0.569 0.758 0.584
hand_right 2446 4002 0.900 0.596 0.758 0.586
abdomen 2446 7067 0.775 0.569 0.642 0.389
hip_joint 2446 12909 0.792 0.497 0.572 0.339
knee 2446 9099 0.787 0.555 0.631 0.380
ankle 2446 7672 0.774 0.520 0.580 0.300
foot 2446 6861 0.854 0.740 0.793 0.563
VARIANT=e
BATCHSIZE=64
MAXDET=5000
┏━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━┓
┃Epoch┃Avg. Precision ┃ %╇Avg. Recall ┃ %┃
┡━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━┩
│ 0│AP @ .5:.95 │046.57╎AR maxDets 1 │036.06│
│ 0│AP @ .5 │065.50╎AR maxDets 10 │058.37│
│ 0│AP @ .75 │048.53╎AR maxDets 100 │060.58│
│ 0│AP (small) │022.98╎AR (small) │040.79│
│ 0│AP (medium) │056.95╎AR (medium) │073.22│
│ 0│AP (large) │065.96╎AR (large) │080.74│
└─────┴────────────────┴──────┴────────────────┴──────┘
┏━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ ID┃Name ┃ AP┃ ID┃Name ┃ AP┃
┡━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ 0│body │ 0.7495│ 20│ear │ 0.3605│
│ 1│adult │ 0.7416│ 21│collarbone │ 0.1624│
│ 2│child │ 0.6877│ 22│shoulder │ 0.3472│
│ 3│male │ 0.7709│ 23│solar_plexus │ 0.1826│
│ 4│female │ 0.7357│ 24│elbow │ 0.3234│
│ 5│body_with_wheelchair │ 0.5766│ 25│wrist │ 0.1840│
│ 6│body_with_crutches │ 0.5472│ 26│hand │ 0.5169│
│ 7│head │ 0.7378│ 27│hand_left │ 0.4878│
│ 8│front │ 0.6392│ 28│hand_right │ 0.4855│
│ 9│right-front │ 0.6349│ 29│abdomen │ 0.2624│
│ 10│right-side │ 0.6214│ 30│hip_joint │ 0.2395│
│ 11│right-back │ 0.5416│ 31│knee │ 0.3241│
│ 12│back │ 0.4005│ 32│ankle │ 0.2107│
│ 13│left-back │ 0.5085│ 33│foot │ 0.4525│
│ 14│left-side │ 0.6382│ │ │ │
│ 15│left-front │ 0.6480│ │ │ │
│ 16│face │ 0.6718│ │ │ │
│ 17│eye │ 0.2214│ │ │ │
│ 18│nose │ 0.3663│ │ │ │
│ 19│mouth │ 0.2911│ │ │ │
└───┴─────────────────────────┴───────┴───┴─────────────────────────┴───────┘
class_biased_batch_formation を true にした場合、学習用データローダーは次のような流れで “希少サイズ” を意識したバッチ編成を行います。
データセット読み込み時に全サンプルを走査し、クラスごと・サイズ帯(small / medium / large)ごとのバウンディングボックス数を集計します。進捗は「Analyzing dataset size buckets」として表示され、どの画像がどのサイズを含んでいるかも記録されます。
oversampling フラグが同時に有効なら、その統計を基に「不足サイズ」を補うための複製処理が実行されます(こちらも progress 表示)。false の場合は複製は行わず、元データの統計結果だけを保持します。
サイズ構成の偏りが少ないサイズ帯が “希少サイズ” として rare_buckets に選ばれます。この際、利用可能なサイズの中からシェアがしきい値(デフォルト 20%)を下回るもの、なければ最もシェアの低いサイズが対象になります。
DataLoader は標準のバッチシャッフルではなく ClassBiasedBatchSampler を使用します。各バッチを組む際に、まず希少サイズの画像から順に最低1枚ずつ採用し(複数の希少サイズがあればその分だけ)、残りのスロットを通常のシャッフル済み候補で埋めます。こうして「毎バッチに希少サイズが混入する」ことを保証します。
使い切った希少サイズ画像は、再度シャッフルしながら最後のサンプルまでバッチに行き渡るようローテーションされます。エポック終盤で希少サイズが不足した場合は、残りを通常画像で補います(drop_last はデフォルト false なので余りバッチも出力)。
サイズ分布(oversampling 前後)が表形式でコンソールに出力され、調整状況を把握できます。progress bar による進捗表示も含め、学習開始前に必ず表示されます。
まとめると、flag を立てるだけで統計分析→(任意の oversampling)→希少サイズを必ず含むバッチ生成までを自動でこなし、small 偏重データでも medium / large を効率よくバッチ内に混ぜ込む仕組みになります。
8GPU DDP 時の分割とシャッフル
トレーナーは PyTorch Lightning なので、Trainer(strategy="ddp") で 8 プロセス(GPU)を立ち上げると、Lightning が自動で DistributedSampler を挿入します。create_dataloader が素の DataLoader を返しても気にする必要はありません。
DistributedSampler はデータセットを “世界サイズ (world size)” で等分します。1 エポック内の各バッチで プロセス 0‑7 は互いに重複しないサンプルを受け取り、全体として全サンプルがちょうど一巡します。
task.data.shuffle=True の場合、1 エポック開始時に DistributedSampler が同じ乱数シード(Lightning が rank0 で set_epoch(epoch) を呼ぶ)でデータ順序をシャッフルし、そこから 8 等分します。つまり「全体でシャッフル → rank ごとに均等分割」という流れです。
データ数が world size で割り切れない場合、PyTorch 標準のサンプラー仕様に従い末尾にラップしたサンプルで埋めてバランスを取ります (drop_last=False のとき)。
shuffle=False にすると DistributedSampler は同じ先頭順序を 8 分割するだけになるので、DDP で汎化させたいときは shuffle=True を維持するのが推奨です。
学習中は各 rank が自分で GPU に転送し、勾配を同期しているため、分割の仕組み以外に追加の調整は不要です。
なお class_biased_batch_formation を有効にして自前のバッチサンプラーを渡した場合は Lightning がサンプラーを差し替えないので、DDP と組み合わせる際は別途分割ロジックを用意する必要があります。
了解です。同一データセットで WongKinYiu/yolov9 は安定、yolov9mit(MIT 版)だけが「Loss 低下/AR 上昇なのに AP が途中で大きく落ちる」──この差は、MIT 版の アサイナー(Matcher)/Loss/前後処理(NMS/リサイズ)/バリデータがオリジナルと微妙に異なることが主因になり得ます。実際、MIT 系の上流リポジトリでは BoxMatcher と Loss 周りのバグ報告が挙がっています。以下、原因候補 → どこを確認/修正するか → すぐ試す最小ABテストの順でまとめます。
0) 事実関係(参照元)
-
オリジナル: WongKinYiu/yolov9(GPL) (GitHub)
-
MIT 系: MultimediaTechLab/YOLO(MIT、yolov9mit の上流)および PINTO0309/yolov9mit(fork) (GitHub)
-
MIT 系で報告済みの問題例(要点のみ)
-
BoxMatcher の
align_cls
正規化が top‑k マスクや重複解決後の行列と整合していない可能性、重複解決を full cost でやっている点が他実装と違う、CIoU のペナルティ項に no_grad がない/eps が小さすぎて半精度で不安定、等。(GitHub) - バリデーション・ラベル扱いの不具合修正 PR(重複ラベル除去/validator の TXT 対応修正 など)が後追いで入っている(=古いコミットだと評価が壊れやすい)。(GitHub)
- MIT 系の後処理は
task.nms.*
で設定可能(例:task.nms.min_confidence
)。設定がオリジナルと異なると AP の挙動が変わる。(GitHub)
-
BoxMatcher の
-
オリジナル側では letterbox の挙動差がエクスポートや推論で食い違いを生む事例報告(実装差があると AP に影響)。(GitHub)
1) 症状からの当たり(large AP が大きく落ち、全体も断続的に低下)
想定メカニズム
-
Matcher の割当ての歪み → 大物体は正例候補が多いので、重複解決や
align_cls
正規化のわずかなズレで 高IoU側の割当てが崩れて IoU 精度低下 → AP_large ↓(AR は維持/上昇)。 -
Loss の数値安定性 → CIoU のペナルティに勾配が流れすぎる/
eps=1e-9
が半精度で不安定 → 学習後期に 出力分布が揺れて AP がギザギザ。(GitHub) - 評価系差分(NMS/score 合成/letterbox) → 同じ重みでも AP 曲線が不連続に落ち得る(AR は高止まり)。
2) MIT 版で重点的に洗うべきチェックポイント
A. BoxMatcher / Assigner
-
align_cls
の正規化位置と対象- top‑k マスク適用後/重複解決後の行列に対して正規化しているか(先に正規化→あとで top‑k/重複解決だと、正例重みが崩れて FP が増えやすい)。(GitHub)
-
重複解決の規準
- MIT 版は full cost で重複解決する実装差が指摘あり。他実装は (C)IoU コストのみで解決する例が多い。full cost だと 分類コストが暴れた瞬間に割当てが誤誘導されやすい。(GitHub)
-
topk
の十分性- あなたのデータは 1枚に最大 3,700 small、large は 7.2% と少数。
topk=10
は大物体に不足。20–50
を推奨(100 は要観察、1000 は非推奨)。←これは既に議論済み -
topk
を上げても モデルのパラメータ数は変わらない(学習時計算量のみ増)。
- あなたのデータは 1枚に最大 3,700 small、large は 7.2% と少数。
B. Loss(CIoU/DFL/BCE)
-
CIoU のペナルティ項に
no_grad
を適用-
参考: torchvision 実装。ペナルティに勾配を流さないことで安定。
eps
も 1e-7 程度に上げると半精度で安定しやすい。(GitHub) -
パッチ例(擬似コード)
# before ciou = iou - (rho2 / (cw**2 + ch**2 + eps)) - v**2 * alpha # after with torch.no_grad(): penalty = rho2 / (cw**2 + ch**2 + eps) # eps=1e-7 推奨 ciou = iou - penalty - v**2 * alpha
-
-
Box/DFL の比率
- 現在
BoxLoss=7.5, DFL=1.5
は妥当寄りだが、large IoU を稼ぐなら Box/DFL を小幅↑(例: 8.5/2.0)で高IoU帯の精度を優先。
- 現在
C. 前後処理(前: letterbox/後: NMS・スコア合成)
-
letterbox の幾何学的一致
- パディング色(114,114,114)、端数の丸め、
scaleup
の有無、auto
オプションの挙動を オリジナルと一致させる。オリジナル側でも挙動差が AP に効く報告あり。(GitHub)
- パディング色(114,114,114)、端数の丸め、
-
スコア合成規則の一致
- 物体信頼度
obj
とクラス確率cls
の合成が 積(obj×cls) か、別定義かを確認。ここが違うと 同じ出力でもランキングが変わり AP が落ちやすい。
- 物体信頼度
-
NMS の既定値
- MIT 版は
task.nms.min_confidence
などで後処理が動く(README 例)。オリジナル相当のconf_thres
/nms_iou
に合わせて検証する。(GitHub)
- MIT 版は
D. バリデーション/ラベルローディング
-
ラベル重複・不正の処理
- MIT 上流の PR に 重複ラベル除去/validator 修正 がある。古いコミットだと val 側の FP/FN カウントが歪む可能性。該当PRを含む最新版で再検。(GitHub)
E. アンカー・ストライド検出/変換
- MIT 版には Vec2Box / Anc2Box 変換や 自動ストライド検出の動作が入っており、ここがズレると boxデコード → NMS までの一連が狂う。該当コンポーネントでの不具合報告もあるため、固定ストライドでの A/B を推奨。(GitHub)
3) すぐできる 最小 A/B テスト手順(原因切り分けの順番)
-
評価だけ統一
-
同一 image_size(例 640 or 896), 同一 letterbox, 同一
conf_thres
/nms_iou
, クラス別/非別 NMS 同一に固定。 - MIT 版の
task=validation
とオリジナルのval.py
で 同じ後処理条件に合わせ、AP_large / AP@0.5 / AP@0.75–0.95 を比較。
→ ここで差が縮むなら 前後処理の差が主因。(GitHub)
-
同一 image_size(例 640 or 896), 同一 letterbox, 同一
-
Matcher のみ差し替え
- MIT 版の BoxMatcherを修正(
align_cls
正規化の位置・重複解決規準を Issue #103 提案どおりに)→ 学習 3–5 epoch だけ追加。 - 併せて
topk: 20–50
に引き上げ。
→ AP_large が回復すれば アサイナー起因が濃厚。(GitHub)
- MIT 版の BoxMatcherを修正(
-
Loss の安定化だけ適用
-
CIoU の no_grad+eps=1e-7 に変更、Box/DFL 比率を小幅↑。
→ ギザ落ち(断続的低下)が減るなら 数値安定性が原因。
-
CIoU の no_grad+eps=1e-7 に変更、Box/DFL 比率を小幅↑。
-
データ拡張の強度だけ下げる
- あなたの現設定は
RandomScale: [0.1, 1.9]
とやや強め。[0.5, 1.5] に絞る、Blur/Fog 系の合成確率を一旦 0 で検証。
→ AP_large が戻るなら 大物体の境界学習不足が主因。
- あなたの現設定は
4) 具体的な設定・パッチの提案(yolov9mit 側)
設定(Hydra の例)
# matcher
loss:
matcher:
topk: 30 # ← 20–50 の中から。まずは 30 を推奨
iou: CIoU
factor:
iou: 6.0
cls: 0.5
# data augment
data:
data_augment:
RandomScale:
prob: 1.0
scale_range: [0.5, 1.5] # ← まずは緩める
keep_aspect_ratio: true
# Blur/Fog/SunFlare/GaussNoise などは一旦 0 に(AB 比較用)
# loss weight(小幅)
loss:
objective:
BoxLoss: 8.5 # 7.5 → 8.5
DFLoss: 2.0 # 1.5 → 2.0
# validation (後処理)
task:
nms:
min_confidence: 0.01 # オリジナル相当の conf sweep 0.001–0.1 で比較
iou_threshold: 0.50 # 0.45–0.65 を sweep
コードの修正(概念パッチ)
-
BoxMatcher
-
align_cls
の正規化は top‑k マスク適用後かつ重複解決後のターゲット行列に対して行う。 - 重複解決は (C)IoU コストのみで行う(full cost だと cls コストの揺れに引っ張られやすい)。(GitHub)
-
-
CIoU Loss
- ペナルティ項に
no_grad
を適用、eps=1e-7
に引き上げ(半精度安定性)。(GitHub)
- ペナルティ項に
-
letterbox
-
Wong リポジトリの挙動と一致させる(特に
auto
/丸め/パディング色)。(GitHub)
-
Wong リポジトリの挙動と一致させる(特に
-
Validator / Label Loader
- MIT 上流の 重複ラベル除去/TXT 対応修正 PR の取り込みを確認。(GitHub)
5) なぜ MIT 版だけで崩れるのか(まとめ)
- **アサイナーと損失の“わずかな差”**が、大物体(large)に不利な割当て/勾配の揺れを誘発 → 高IoU 帯 Precision 低下(= AP 低下、AR は維持/上昇)。
- **評価パイプライン(NMS/スコア合成/letterbox)**の既定値差分・実装差が、AP の断続的な落ち込みを増幅。
-
バリデータ/ラベルローダの不整合が、**極端にラベル密度の高い(1枚 3,700 small)**データで顕在化しやすい。
→ これらは MIT 上流の Issue/PR でも指摘・修正が進んでいる。(GitHub)
最後に(実行順の提案)
- 評価条件の完全固定(letterbox・conf/nms・image_size)で両者を比較。(GitHub)
-
Matcher 修正(align_cls/重複解決)+
topk=30
を適用。(GitHub) - CIoU 安定化(no_grad+eps=1e-7)。(GitHub)
- RandomScale の緩和と large 寄りの微調整(Box/DFL 比率↑)。
- MIT 上流の Validator/Label 修正 PR を取り込む。(GitHub)
必要なら、**yolov9mit の該当ファイル名(Matcher / Loss / letterbox / NMS)**の場所当てと最小差分パッチ例もこちらで用意します。上の順で 1つずつ当てると、どこで AP_large が戻るかがはっきり見えるはずです。
以下は 物体検出の“出力づくり”での single‑label と multi‑label の違いを、実務で効く観点に絞って整理したものです。ポイントは 「1つのアンカー(候補)から、最終的に何クラスぶんの検出を生成するか」 です。
ざっくり一言で
-
single‑label:各アンカーにつき 最も確からしい1クラスだけを残す(Top‑1)。
→ 候補が絞られ、安定・軽量・重複少。ただし同じ領域を複数クラスで出したい場合には不向き。 -
multi‑label:各アンカーで しきい値を超えた複数クラスすべてを検出として展開。
→ 再現寄りだが、候補が爆発しNMS・上限capに敏感、FP(誤クラス)増でAPを落としやすい。
データフローの違い(あなたの関数に沿って)
入力
-
cls_dist
:各アンカーのクラスロジット[A, C]
(sigmoid後は確率) -
confidence
:オブジェクトネス[A, 1]
-
bbox
:回帰済みボックス[A, 4]
single‑label の振る舞い
- 各アンカーで
argmax
による Top‑1 クラスを選ぶ - スコア=
sigmoid(cls_top1) * sigmoid(obj)
- しきい値で間引き → 1アンカー=最大1検出
- (通常)クラス別NMS → 同じ箱の「別クラス重複」はそもそも出ない
特徴
-
候補数が少ない:NMSやpost‑cap(
max_bbox
)に余裕 - ランキングが安定:上位域で順位がひっくり返りにくい → APの“谷”が出にくい
- クラス被りのFPが減る:余計な複製がない
- 弱点:1つの実体に「人(body)」「男性(male)」「大人(adult)」など 複数クラスを同時に出したい場合には成立しづらい
multi‑label の振る舞い
- 各アンカーで すべてのクラスに対し
score = sigmoid(cls_c) * sigmoid(obj)
を計算 -
score > conf_thres
の (アンカー, クラス)組を全部展開 -
クラス別NMS(batched_nms の
group_id=class
)
→ 同位置・同形状でも別クラスは抑制されない(=複数クラスが残る)
特徴
- 候補が爆発:small が多いほど × クラス数ぶん増える
-
post‑cap(例
max_bbox=1000
)に到達しやすい:
→ 小物体の大量候補に大物体が埋もれる → epochごとの僅差で large が落ちる“谷” - FPが増えやすい:近い領域に似たクラスが多いほど、誤クラスで出やすい
- 利点:1つの領域に複数クラスを出したい用途(階層・属性ラベル)には必要
直感例(数値で比較)
アンカー #42 に対し:obj=0.7
、クラス確率(sigmoid後)
- person=0.90, adult=0.60, male=0.55, wheelchair=0.10
single‑label
- Top‑1 = person → score=0.90×0.70=0.63 → 1件だけNMSへ
multi‑label(conf=0.001)
- person 0.63、adult 0.42、male 0.385 → 3件NMSへ(wheelchairは0.07で除外)
- 画像全体ではこうした重複が雪だるま式に増え、NMS前/後の上限にぶつかりやすい
mAP/AR・安定性・計算量の違い
観点 | single‑label | multi‑label |
---|---|---|
候補数(NMS前) | 少ない | 多い(×平均ラベル数) |
post‑cap感度 | 低い(余裕あり) | 高い(境界で大物体が落ちやすい) |
精度(Precision) | 上がりやすい(余計なクラスが出ない) | 下がりやすい(誤クラスが出やすい) |
再現(Recall) | 下がることあり(必要な複数ラベルを1つに潰す) | 上がりやすい(複数ラベルを保持) |
APの安定性 | 高い(ギザ落ちしにくい) | 低い(スコア僅差×capで“谷”が出やすい) |
計算/メモリ | 軽い | 重い |
用途 | 1物体=1クラス | 階層・属性を同時に出したい |
あなたのデータ(smallが極端に多い・属性系クラスあり)に即した助言
-
安定性優先(AP_largeの“突然の谷”を避けたい):
→ single‑labelを既定にし、必要なら**属性は別ヘッド(マルチタスク)**で出す。
→ どうしても multi‑label が必要なら、**pre‑NMS 上位K(例 20,000)**と post‑NMS上限(例 3,000) を十分に確保し、サイズ弱バイアス(score *= area^0.05
)や class‑agnostic NMS オプションで大物体の取りこぼしを緩和。 -
多ラベル前提(例:“body / adult / male / front / head ...”を同フレームで評価):
→ multi‑labelを使用。ただし候補爆発対策は必須:-
pre_topk
を導入(例 20,000〜50,000) -
max_bbox
を拡大(例 3,000〜無制限) - クラス別quota(クラスごとに最低/最大keep数を割り当て)やサイズ別keep(S/M/Lで事前に上位N確保)
- スコア温度Tを固定(evalのみ T=1.3〜1.6)→ ランキングの揺れを緩和
-
bbox_nms
への当て方)
実装スイッチ(あなたの -
single‑label:各アンカーで
cls.argmax()
のみ残す →multi_label=False
-
multi‑label:
(cls×obj > conf)
のペアを全部展開 →multi_label=True
- どちらでも:
pre_topk
を導入し、max_bbox
を十分に大きく/再ソート後に[:max_bbox]
で切る
まとめ
- single‑label=「1アンカー1クラス」:安定・高速・重複少。大物体のAPが急に落ちる問題の回避策として有効。
- multi‑label=「1アンカー多クラス」:再現寄り・候補爆発。設定次第でAPのギザ落ちが起きやすい。
- あなたの状況(smallが非常に多い+largeで谷が出る)では、single‑label既定+必要時だけmulti‑label、あるいは multi‑ラベルは別タスク化が最も堅実です。
結論から:
標準的な YOLO 系(1検出=1クラスの前提)で学習・評価するなら、同一位置・同一サイズに複数クラスが重なる GT は“1つに正規化”すべきです。
どれを残すかは 「物体の同一性(Identity)」を表す“基底クラス” を優先し、属性的なラベル(年齢・性別・向きなど)は検出クラスから外すのが最も安定します。
なぜ“1つに正規化”が必要か
- 学習の一貫性:同じ箱に adult と male と body が同時に付いていると、1つの場所に複数の教師が矛盾し、分類頭が不安定になります(クラス間の重複・競合)。
- NMS とランキング:multi‑label で展開すると候補が爆発し、post‑NMS上限やスコア僅差で large のTPが落ちやすい(あなたの症状の主因になり得ます)。
- 評価の整合性:GT が多重ラベルのままだと、モデルが1つだけ当てても他のラベルがFN扱いになり、APを不当に下げます。
どれを残す?— 実務的ルール
1) 基底クラス優先(おすすめ)
-
残す: 物体そのものを表すクラス(例:
body
,face
,hand
,knee
, …) -
外す(属性):
adult/child
,male/female
,front/right-front/right-side/...
など同一領域に重なる属性 - 理由: “検出”は物体の存在を返すタスク。属性は別ヘッド(マルチタスク)や後段の属性分類で推定する方が、AP/安定性ともに良い。
2) クラスが“同義 or 階層”の場合
- 例:
body
とadult
が同一箱 →body
に正規化 - 例:
male
とfemale
が同一箱(矛盾)→ 基底クラスに落として属性は欠損扱い(どちらも検出クラスにしない)
3) 本当に“別物体”なら別箱にすべき
-
wheelchair
やcrutches
は通常、人と同一箱ではないはず。もし同一箱ならアノテーションエラーとして分離(別GTに) - “部位”は位置・サイズが違うのが普通。同一箱で複数部位が重なるのは整備対象。
データ前処理:同一箱の多重ラベルを正規化する手順(推奨)
-
画像内で同一箱グループ化
- IoU≥0.999 かつ 中心差≤1px などでクラスタリング
-
グループごとにクラスを仕分け
BASE_CLASSES = {body, face, hand, foot, knee, elbow, wrist, shoulder, ...}
ATTR_CLASSES = {adult, child, male, female, front, right-front, right-side, right-back, back, left-back, left-side, left-front}
-
ルール
- グループ内に
BASE_CLASSES
があれば → その1つだけ残す(同義が複数なら優先順位で1つ) -
ATTR_CLASSES
は 属性メタデータとして別に保存(使わないなら破棄) -
BASE_CLASSES
が無くATTR_CLASSES
しか無い場合 → 学習データから除外(基底物体が無い検出は不整合)
- グループ内に
-
評価GTも同じ正規化
- 学習だけでなく評価用アノテーションも同じ変換を適用(でないと mAP が不公平に下がる)
参考の優先度例(同一箱で複数 BASE が来たとき)
body
>head/face
>hand/foot
>joint/part(wrist, knee, ankle…)
※ データ仕様によって調整
どうしても multi‑label 検出が必要な場合(属性も“検出”として出したい)
-
パイプライン側での対策が必須(先にご提案した通り)
- pre‑NMS 上位K(例
pre_topk=20000
) - post‑NMS 上限(例
max_bbox=3000
以上) -
クラス別 quota や サイズ弱バイアス(
score *= area^0.05
) - class‑agnostic NMS オプション(ケースによって有効)
- 評価メトリクスも multi‑label 前提(同一箱・別クラスを許容)に揃える
- pre‑NMS 上位K(例
-
それでも AP の安定性は single‑labelより劣るのが通例。ミッションが許せば、検出は基底クラスのみ+属性は別ヘッド/後段分類がベター。
実装スニペット(疑似コード)
# 同一箱(xyxy)重複を正規化
BASE = {"body","face","hand","foot","knee","elbow","wrist","shoulder","abdomen","hip_joint", ...}
ATTR = {"adult","child","male","female","front","right-front","right-side","right-back",
"back","left-back","left-side","left-front"}
def dedup_same_box(labels):
# labels: list of dict {cls:str, box:[x1,y1,x2,y2]}
groups = cluster_by_iou(labels, iou_thr=0.999, center_px=1.0)
new_labels, attr_meta = [], []
for g in groups:
base = [l for l in g if l["cls"] in BASE]
attr = [l for l in g if l["cls"] in ATTR]
if base:
# 優先度で1つ選ぶ(ここでは body を最優先)
base.sort(key=lambda l: 0 if l["cls"]=="body" else 1)
keep = base[0]
new_labels.append(keep)
if attr:
attr_meta.append({"box": keep["box"], "attrs":[l["cls"] for l in attr]})
else:
# 基底が無ければスキップ or ルールに応じて処理
pass
return new_labels, attr_meta
まとめ
- 同一位置・同一サイズの多重ラベルは、そのままでは学習・評価ともに不安定。
- 検出の“基底クラス”を1つだけ残すのが基本方針。属性は別ヘッド/後段分類に回すか、メタデータとして保持。
- もし multi‑label 検出を残すなら、NMSと評価設定を multi‑label 前提にチューニングし、pre/post capや**ランキング安定化(温度・サイズバイアス)**を必ず入れる。
必要なら、あなたの 34クラス定義に合わせて BASE / ATTR の具体的な割当て表をこちらで作成し、正規化スクリプトを完成版でお渡しします。
multi_label と class_agnostic の動作の違いがよくわからない。
いい質問です。multi_label と class_agnostic は「まったく別のスイッチ」で、効く場所も目的も違います。
まず一言で
- multi_label … 各アンカー から 複数クラスの検出を“増やすか” のスイッチ(出力を“増やす/増やさない”)。
- class_agnostic … NMS のときに クラスを“無視して”重複抑制するか のスイッチ(重複を“まとめる/まとめない”)。
どこに効くか(処理位置の違い)
[クラスロジット/obj] → しきい値で候補作成(★multi_label) → NMS(★class_agnostic) → 最終検出
-
multi_label=True: 1つのアンカーでも、しきい値を超えた 複数クラスぶんを全部「候補」に展開
multi_label=False: 1つのアンカーにつき Top-1 クラスだけを候補に採用(= single-label) -
class_agnostic=True: NMS が クラス無視で重複抑制(同じ場所なら別クラスでも潰す)
class_agnostic=False: NMS が クラス別に実行(別クラス同士は抑制されない)
具体例
同じアンカー・同じ箱で、
-
person=0.63, adult=0.42, male=0.38
(= cls*obj のスコア)
設定 | 候補(NMS入力) | NMSの抑制範囲 | 最終出力の傾向 |
---|---|---|---|
multi_label=False, class_agnostic=False | person 1件 | person 同士だけ | 1件(安定・軽量) |
multi_label=True, class_agnostic=False | person / adult / male の3件 | 同クラス内のみ抑制 | 3件残りやすい(候補が爆発) |
multi_label=True, class_agnostic=True | person / adult / male の3件 | クラス無視で抑制 | 最高スコア1件に絞られやすい |
multi_label=False, class_agnostic=True | person 1件 | クラス無視(ただし1件のみ) | 実質同じ(効果ほぼ無し) |
ポイント
- multi_label は候補数を増やす/増やさない。
- class_agnostic は候補の重複をまとめる/まとめない(NMSの比較相手にクラスを含めるか)。
長所・短所(あなたの“smallが非常に多い”データ想定)
multi_label=True(候補を増やす)
- 長所: 同じ位置で“複数クラスを同時に出したい”ときに必要(属性併記など)
-
短所: 候補が爆発 → pre-NMS / post-NMS の上限(pre_topk, max_bbox)に敏感
→ small が多いと large の候補が上限で切られやすく、AP_large が“たまに”落ちる
class_agnostic=True(クラス無視NMS)
-
長所: 同じ場所の別クラス重複をまとめて潰せる → 候補のふくらみを抑制
→ multi_label で生じる“同位置・別クラスの複製”を減らす - 短所: 本当に別物体・別クラスが強く重なる場面(例:person と backpack が高IoU)でも、片方が潰れる可能性 → 再現率低下のリスク
どう使い分ける?
-
検出は“基底クラス”だけ出したい(属性は別ヘッドor後段)
→ multi_label=False / class_agnostic=False(YOLOの定番。安定・高速・APが安定) -
同じ箱で複数クラスを同時に出したい(多ラベル検出が必須)
→ multi_label=True を使う。ただし- pre_topk を大きく(例 20,000)
- max_bbox を大きく(例 3,000〜無制限)
- 必要なら class_agnostic=True で同位置の別クラス重複を抑える
- それでも 本当に別物体の重なりが多いデータでは
class_agnostic
はほどほどに
-
AP_large の“突然の谷”対策(small密度が極端に高いとき)
- まず multi_label=False(= single-label)で安定化
- multi_label が必要なら class_agnostic=True + pre_topk / max_bbox の拡大で“候補爆発”を抑える
コード上の違い(あなたの関数に対応)
-
multi_label 分岐
- False:
cls.argmax()
で Top‑1 のみ - True :
(cls×obj > conf)
の (アンカー, クラス) 全組みを列挙
- False:
-
class_agnostic 分岐(batched_nmsのグループID)
- False:
ids = class_id
(クラス別NMS) - True :
ids = 0
(全クラスまとめてNMS)
- False:
まとめ
- multi_label は “候補を増やす”(出力を多クラス化する)スイッチ。
- class_agnostic は “クラスを無視して重複を潰す”(NMSの抑制範囲を広げる)スイッチ。
- 組合せで性格が変わります。安定重視なら
multi_label=False, class_agnostic=False
。 -
多ラベルが必要なら
multi_label=True
だが、pre_topk/max_bbox を拡大し、場合によりclass_agnostic=True
を併用して候補爆発を抑えるのが安全です。
multi_label: True class_agnostic: True として学習した場合、わずかにずれた位置あるいはわずかに異なるサイズのアンカーが body, adult, male それぞれに割り当てられるということか?
短答:はい(ただし、その理由は multi_label / class_agnostic の設定ではなく、アサイナーの設計によるものです)。
YOLOv9系の学習では、各アンカー(=各予測位置)は最終的に「1つのGT(=1クラス)」だけに割り当てられます。同一座標・同一サイズの GT が body/adult/male と3つ並んでいると、それぞれのGTに対して “別々のアンカー(/格子セル/レベル)” が割り当てられるのが通常の挙動です。結果として、わずかに位置がずれた、あるいは別ストライド層のアンカーが body/adult/male をそれぞれ担当します。
まず前提の整理(用語)
-
multi_label と class_agnostic は NMS(推論/評価時) の挙動を切り替えるスイッチです。
- multi_label=True:1アンカーから複数クラス候補を展開
- class_agnostic=True:NMSをクラス無視でかける
-
学習時の割り当て(BoxMatcher/Assigner) はこれらのフラグの影響を受けません。
学習では「1アンカー=1ターゲット(1クラス)」が守られ、同一アンカーを複数GTに割り当てないよう重複解消が入ります。
同一場所に3ラベル(body/adult/male)があると学習時に何が起きるか
-
候補集合は同じ
3つのGTは同じ箱なので、どれも同じ周辺アンカー群を候補として持ちます。 -
アンカー→GT は最終的に一意化
マッチャは top‑k 候補を作った後、各アンカーが複数GTに重複しないように一意化します。
→ 同じアンカーが “bodyとadultを同時に担当” することはありません。 -
結果:GTごとに “別のアンカー” が割り当て
3つのGT(=3クラス)は、近傍の別セル/別レベルのアンカーをそれぞれ獲得します。
それぞれのアンカーは 自分に割り当てられたクラスだけを正例(one‑hot)として学習し、他のクラスは負例になります。
(ボックス回帰は3つとも同じ座標に引っ張られるため、学習が進むほど予測ボックスは互いにほぼ一致します。)
つまりご質問の「わずかにずれた位置やサイズのアンカーが body/adult/male にそれぞれ割り当てられるのか?」に対しては、
はい、アサイナーが “1アンカー1GT” 制約を守るため、通常そうなります。
推論/評価時(NMS)に multi_label=True, class_agnostic=True を使うと…
- multi_label=True:同一アンカーから 複数クラス候補(body・adult・maleなど)を NMS 前に展開。
-
class_agnostic=True:クラスを無視して重複抑制するので、同一位置の別クラス候補は1つに潰れやすい。
→ 出力は結局 最もスコアの高い1件に収束しやすく、他クラスは抑制されます。
(ただしこれはNMSの話で、学習の割り当てには影響しません。)
実務上の注意
-
同一点・同一サイズで 基底クラス(例:body)と属性(adult/male)が重複定義されていると、
学習では 周辺の複数アンカーが同じ幾何に回帰するため、重複検出が出やすく、評価設定(pre_topk/max_det/NMS)次第で APが揺れやすいです。 -
安定運用を優先するなら:
- 検出クラスは “基底クラス” のみに正規化(例:body)
- adult/male などの属性は別ヘッド(多タスク)や後段分類で推定
- どうしても多ラベル検出にするなら、pre‑NMS上位Kの導入と post‑NMS上限拡大、必要に応じて class‑agnostic NMS を併用
まとめ
- 学習時は 1アンカー=1クラス。同一場所に3ラベルあれば、3つの別アンカーがそれぞれ担当します(少し位置/レベルがずれるのが普通)。
- multi_label/class_agnostic は NMS(推論/評価) のスイッチであり、学習時の割り当てには関与しません。
- データ仕様がそのままだと重複予測・APの揺れを招きやすいので、基底クラスへの正規化 or 属性を別タスク化が安定策です。
class_agnostic=True:クラスを無視して重複抑制するので、同一位置の別クラス候補は1つに潰れやすい。 → 出力は結局 最もスコアの高い1件に収束しやすく、他クラスは抑制されます。 (ただしこれはNMSの話で、学習の割り当てには影響しません。
の部分は、バリデーション時の mAP の評価のみに影響を与えるという理解で合っているか?
結論:ほぼ合っていますが、“バリデーションだけ”に限定されません。
class_agnostic=True
は NMS を実行する局面すべて(= バリデーション、テスト、実運用の推論、擬似ラベリング等)で出力に影響します。一方で、学習の割り当て(アサイナー/損失計算)には影響しません。
どこに効く/効かない
影響する
-
バリデーションの mAP
- class-agnostic NMS は クラス無視で重複抑制するため、同一領域で別クラスの予測があっても 上位1件だけを残しがちです。
- その結果、他クラス側の GT が未検出(FN)になりやすく、クラス別 APに影響します(改善にも悪化にも振れ得ます)。
-
推論(デプロイ時の出力)
- 実運用で NMS を class-agnostic にしていれば、同一領域の別クラス出力は潰される(1件に収束)。
-
オフライン処理
- 擬似ラベル生成、教師モデル出力(KD)など、NMS を通す前提の処理全般。
影響しない
-
学習の割り当て/損失
- 通常、学習中は NMS を使いません。1アンカー=1GT の一意化はアサイナーで行われ、
class_agnostic
の on/off は ここに関与しません。
- 通常、学習中は NMS を使いません。1アンカー=1GT の一意化はアサイナーで行われ、
あなたのデータ特性で何が起こるか
- 同一点・同サイズに
body
/adult
/male
など複数クラスの GT が重なる場合、
class-agnostic=True の評価では、その領域の予測は基本的に1件(最も高スコアのクラス)へ潰れます。
→ 例えば body が残って adult/male が抑制されると、adult/male クラスの AP/AR が落ちる可能性があります。 - multi_label=True で候補を増やすほど、class-agnostic NMS の横断抑制が強く働き、**どれか1クラスに“収束”**しやすくなります。
実務上のおすすめ
-
評価方針と実運用を合わせる
- デプロイで class-agnostic を使うなら、評価も 同設定で測る(逆も然り)。
- 設定不一致は「評価では出ていたクラスが本番では消える」などの齟齬に直結。
-
多ラベルを正当に評価したい(同一領域で複数クラスを残したい)
-
class_agnostic=False
(クラス別 NMS) を推奨。 - 併せて pre‑NMS 上位K(pre_topk)と post‑NMS 上限(max_bbox) を十分に大きくして、候補切り捨ての副作用を減らす。
-
-
重複出力を抑えたい/最終的に1件だけにしたい
-
class_agnostic=True
を使う。ただし 重なり合う“別物体・別クラス”も抑制されうるため、リコール低下に注意。
-
まとめ
- あなたの理解:「class-agnostic は NMS の話であり、学習割り当てには影響しない」→ 正しい。
- ただし 影響範囲は“バリデーション時の mAP”に限らず、NMS を使うすべての局面(推論・擬似ラベル等)に及びます。
- データに同一領域の多クラス GTがあるなら、評価目的に合わせて class-agnostic の on/off を選択し、
その設定と pre_topk / max_bbox を一緒に最適化するのが安定への近道です。
multi_label: True class_agnostic: False は学習時のバリデーションにとても時間がかかるため、学習時の各epochごとのバリデーションは multi_label: True class_agnostic: True で評価して概ねの性能を把握しつつ、学習後に multi_label: True class_agnostic: False で再評価するのは現実的か?mAPがブレるのは理解している。
結論:現実的にアリです。ただし“傾向を見るための代理(proxy)評価”として割り切り、最終指標は必ず本番設定で再評価してください。
multi_label=True, class_agnostic=True
は候補が大幅に減るので(同一位置の別クラスをまとめて潰すため)速くなりますが、クラス間の重複を抑えすぎるぶん mAP の絶対値やクラス別APの関係が歪む点は受け入れる必要があります。
どう歪むか(心得)
-
class_agnostic=True:同一位置の別クラスを1件に潰す →
- Precision が相対的に上がる/下がるどちらも起こり得る(重複FPが減る一方、別クラスGTを潰してFN化する場合もある)。
- クラス別APの順位や AP_large の谷の出方が、class‑wise NMS 時とズレることがある。
-
multi_label=True:候補が(クラス数ぶん)爆発しやすい →
- class‑agnostic にすると候補がかなり減るため 高速化に効くが、クラス別の再現・誤分類の見え方が変わる。
つまり、epochごとの代理評価(class_agnostic=True)での上下は、最終評価(class_agnostic=False)での上下と完全には一致しません。
ただし、多くのケースで大局的なトレンド(上がっているか/過学習か)を見るには十分です。
推奨運用(2段階評価)
1) 速い“代理評価”(各 epoch)
-
設定:
multi_label=True, class_agnostic=True
-
さらに時短用の小技(代理評価に限る)
-
conf を少し上げる:例
conf=0.005~0.01
-
pre_topk を導入:例
pre_topk=10000
(NMS前の候補を上位だけに絞る) -
max_bbox をやや小さく:例
max_bbox=1500
- imgsz を一段下げる:例 896→640(傾向を見るだけなら十分な相関が出ることが多い)
- val データのサブセット(クラス/サイズで層化した10~30%)
-
conf を少し上げる:例
-
監視する指標:
- mAP 全体、AP_large, AR_large(large の谷の早期検知)
- 過学習検知用に val loss も並行監視
2) 正式評価(学習完了時/節目のみ)
- 設定:
multi_label=True, class_agnostic=False
(=本番/提出指標) - conf/iou、pre_topk、max_bbox、imgsz も 本番既定に揃える
- 可能なら 学習途中でも数エポックに1回正式評価を回し、代理評価との相関を確認
“ブレ”を管理するための実務ガードレール
-
相関の校正:初期・中盤・後半の3時点で、代理設定と正式設定を同じサブセット(例 500枚)に当てて、
Spearman/Pearson 相関や 差分(ΔmAP) を記録 → 代理指標の“信頼区間”を把握。 -
EVAL_SIG の固定ログ:eval 設定(imgsz/auto/scaleup/pad_color/conf/iou/pre_topk/max_bbox/NMS mode/TTA/EMA)を文字列化→ハッシュ出力。
→ 同じハッシュで評価しているかを毎回確認(設定ブレの混入を防止)。 - 早期停止やモデル選択は正式設定の mAPで最終決定(代理評価は“通知灯”に徹する)。
代替の時短策(class‑wise を保ったまま速くしたい場合)
- per‑class pre_topk(各クラス上位 K のみ保持→結合→class‑wise NMS)
- Top‑k per anchor の multi‑label 展開(各アンカーにつき上位2クラスのみ展開)
- max_det の段階的拡大(通常は 1000→1500、正式は 3000)
- imgsz の 2段階(通常 640、正式 896/1024)
これらは class_agnostic=False のまま速度を稼げるので、代理と正式のズレが小さくなります。
結論
-
はい、現実的です。各 epoch の“代理評価”を
multi_label=True, class_agnostic=True
で回し、
最終(および節目)でclass_agnostic=False
による正式評価に切り替える運用は十分に有効。 - ただし 数値の絶対値やクラス別の序列がズレることは織り込み、相関の校正と設定固定のガードレールを入れて運用してください。
- もし代理と正式の乖離が大きいと分かったら、per‑class pre_topk や Top‑k per anchor 展開などの“class‑wise のまま速くする”策を検討するのが安全です。
nms:
min_confidence: 0.0001 # 0.0001
min_iou: 0.7
pre_topk: 20000 # pre-nms bboxes, Limit to top K pre-NMS per image (disable with None), (Default)None
max_bbox: 20000 # post-nms bboxes, (Default)1000
# multi_label=True: Expand all classes exceeding the threshold for a single anchor to "candidates"
# multi_label=False: Select only the top-ranked class per anchor as a candidate (= single-label)
# class_agnostic=True: NMS ignores classes and suppresses duplicates (rejects different classes even if they are in the same location)
# class_agnostic=False: NMS runs by class (different classes are not suppressed)
# True: multi-label expansion, (Default)False : Top-1 only
multi_label: True
# (Default)True: Class-ignoring NMS, False: Class-specific NMS
# After training using a dataset with multiple classes defined in the same position and size, you should change it to False and re-run validation.
class_agnostic: True
size_bias_alpha: 0.0 # >0 to slightly increase large (e.g. 0.05)
┏━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ Epoch ┃ Avg. Precision ┃ % ┃ Avg. Recall ┃ % ┃
┡━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ 0 │ AP @ .5:.95 │ 22.48 │ AR maxDets 1 │ 17.81 │
│ 0 │ AP @ .5 │ 40.16 │ AR maxDets 10 │ 30.82 │
│ 0 │ AP @ .75 │ 20.28 │ AR maxDets 100 │ 33.17 │
│ 0 │ AP (small) │ 12.65 │ AR (small) │ 23.25 │
│ 0 │ AP (medium) │ 31.18 │ AR (medium) │ 43.76 │
│ 0 │ AP (large) │ 38.71 │ AR (large) │ 47.30 │
└───────┴────────────────┴───────┴────────────────┴───────┘
┏━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ ID┃Name ┃ AP┃ ID┃Name ┃ AP┃ ID┃Name ┃ AP┃
┡━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ 0│body │ 0.4111│ 20│ear │ 0.3113│ │ │ │
│ 1│adult │ 0.1324│ 21│collarbone │ 0.1069│ │ │ │
│ 2│child │ 0.1992│ 22│shoulder │ 0.2724│ │ │ │
│ 3│male │ 0.2230│ 23│solar_plexus │ 0.0884│ │ │ │
│ 4│female │ 0.1716│ 24│elbow │ 0.2263│ │ │ │
│ 5│body_with_wheelchair │ 0.6111│ 25│wrist │ 0.1168│ │ │ │
│ 6│body_with_crutches │ 0.3256│ 26│hand │ 0.2876│ │ │ │
│ 7│head │ 0.6031│ 27│hand_left │ 0.1787│ │ │ │
│ 8│front │ 0.1112│ 28│hand_right │ 0.1768│ │ │ │
│ 9│right-front │ 0.1325│ 29│abdomen │ 0.1736│ │ │ │
│ 10│right-side │ 0.1209│ 30│hip_joint │ 0.1195│ │ │ │
│ 11│right-back │ 0.0766│ 31│knee │ 0.2264│ │ │ │
│ 12│back │ 0.0197│ 32│ankle │ 0.1585│ │ │ │
│ 13│left-back │ 0.0827│ 33│foot │ 0.3767│ │ │ │
│ 14│left-side │ 0.1341│ │ │ │ │ │ │
│ 15│left-front │ 0.1868│ │ │ │ │ │ │
│ 16│face │ 0.6300│ │ │ │ │ │ │
│ 17│eye │ 0.1759│ │ │ │ │ │ │
│ 18│nose │ 0.2913│ │ │ │ │ │ │
│ 19│mouth │ 0.1851│ │ │ │ │ │ │
└───┴─────────────────────────┴───────┴───┴─────────────────────────┴───────┴───┴─────────────────────────┴───────┘
nms:
min_confidence: 0.0001 # 0.0001
min_iou: 0.7
pre_topk: 20000 # pre-nms bboxes, Limit to top K pre-NMS per image (disable with None), (Default)None
max_bbox: 20000 # post-nms bboxes, (Default)1000
# multi_label=True: Expand all classes exceeding the threshold for a single anchor to "candidates"
# multi_label=False: Select only the top-ranked class per anchor as a candidate (= single-label)
# class_agnostic=True: NMS ignores classes and suppresses duplicates (rejects different classes even if they are in the same location)
# class_agnostic=False: NMS runs by class (different classes are not suppressed)
# True: multi-label expansion, (Default)False : Top-1 only
multi_label: True
# (Default)True: Class-ignoring NMS, False: Class-specific NMS
# After training using a dataset with multiple classes defined in the same position and size, you should change it to False and re-run validation.
class_agnostic: False
size_bias_alpha: 0.0 # >0 to slightly increase large (e.g. 0.05)
┏━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ Epoch ┃ Avg. Precision ┃ % ┃ Avg. Recall ┃ % ┃
┡━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ 0 │ AP @ .5:.95 │ 39.75 │ AR maxDets 1 │ 32.82 │
│ 0 │ AP @ .5 │ 58.55 │ AR maxDets 10 │ 53.48 │
│ 0 │ AP @ .75 │ 41.11 │ AR maxDets 100 │ 57.28 │
│ 0 │ AP (small) │ 15.10 │ AR (small) │ 37.71 │
│ 0 │ AP (medium) │ 47.49 │ AR (medium) │ 69.45 │
│ 0 │ AP (large) │ 65.28 │ AR (large) │ 77.39 │
└───────┴────────────────┴───────┴────────────────┴───────┘
┏━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ ID┃Name ┃ AP┃ ID┃Name ┃ AP┃ ID┃Name ┃ AP┃
┡━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ 0│body │ 0.6886│ 20│ear │ 0.2923│ │ │ │
│ 1│adult │ 0.6739│ 21│collarbone │ 0.0969│ │ │ │
│ 2│child │ 0.5361│ 22│shoulder │ 0.2485│ │ │ │
│ 3│male │ 0.6964│ 23│solar_plexus │ 0.0787│ │ │ │
│ 4│female │ 0.5941│ 24│elbow │ 0.1952│ │ │ │
│ 5│body_with_wheelchair │ 0.7689│ 25│wrist │ 0.1057│ │ │ │
│ 6│body_with_crutches │ 0.7016│ 26│hand │ 0.4076│ │ │ │
│ 7│head │ 0.7010│ 27│hand_left │ 0.3421│ │ │ │
│ 8│front │ 0.5773│ 28│hand_right │ 0.3536│ │ │ │
│ 9│right-front │ 0.5549│ 29│abdomen │ 0.1516│ │ │ │
│ 10│right-side │ 0.5110│ 30│hip_joint │ 0.1065│ │ │ │
│ 11│right-back │ 0.4290│ 31│knee │ 0.1916│ │ │ │
│ 12│back │ 0.2558│ 32│ankle │ 0.1373│ │ │ │
│ 13│left-back │ 0.3917│ 33│foot │ 0.3528│ │ │ │
│ 14│left-side │ 0.5467│ │ │ │ │ │ │
│ 15│left-front │ 0.5781│ │ │ │ │ │ │
│ 16│face │ 0.6169│ │ │ │ │ │ │
│ 17│eye │ 0.1706│ │ │ │ │ │ │
│ 18│nose │ 0.2819│ │ │ │ │ │ │
│ 19│mouth │ 0.1784│ │ │ │ │ │ │
└───┴─────────────────────────┴───────┴───┴─────────────────────────┴───────┴───┴─────────────────────────┴───────┘
nms:
min_confidence: 0.0001 # 0.0001
min_iou: 0.7
pre_topk: 20000 # pre-nms bboxes, Limit to top K pre-NMS per image (disable with None), (Default)None
max_bbox: 20000 # post-nms bboxes, (Default)1000
# multi_label=True: Expand all classes exceeding the threshold for a single anchor to "candidates"
# multi_label=False: Select only the top-ranked class per anchor as a candidate (= single-label)
# class_agnostic=True: NMS ignores classes and suppresses duplicates (rejects different classes even if they are in the same location)
# class_agnostic=False: NMS runs by class (different classes are not suppressed)
# True: multi-label expansion, (Default)False : Top-1 only
multi_label: False
# (Default)True: Class-ignoring NMS, False: Class-specific NMS
# After training using a dataset with multiple classes defined in the same position and size, you should change it to False and re-run validation.
class_agnostic: False
size_bias_alpha: 0.0 # >0 to slightly increase large (e.g. 0.05)
┏━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ Epoch ┃ Avg. Precision ┃ % ┃ Avg. Recall ┃ % ┃
┡━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ 0 │ AP @ .5:.95 │ 38.72 │ AR maxDets 1 │ 31.89 │
│ 0 │ AP @ .5 │ 57.10 │ AR maxDets 10 │ 50.10 │
│ 0 │ AP @ .75 │ 39.94 │ AR maxDets 100 │ 52.29 │
│ 0 │ AP (small) │ 14.28 │ AR (small) │ 27.07 │
│ 0 │ AP (medium) │ 46.48 │ AR (medium) │ 64.14 │
│ 0 │ AP (large) │ 64.50 │ AR (large) │ 75.32 │
└───────┴────────────────┴───────┴────────────────┴───────┘
┏━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ ID┃Name ┃ AP┃ ID┃Name ┃ AP┃ ID┃Name ┃ AP┃
┡━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ 0│body │ 0.6823│ 20│ear │ 0.2920│ │ │ │
│ 1│adult │ 0.6577│ 21│collarbone │ 0.0967│ │ │ │
│ 2│child │ 0.4876│ 22│shoulder │ 0.2482│ │ │ │
│ 3│male │ 0.6820│ 23│solar_plexus │ 0.0786│ │ │ │
│ 4│female │ 0.5525│ 24│elbow │ 0.1946│ │ │ │
│ 5│body_with_wheelchair │ 0.7686│ 25│wrist │ 0.1055│ │ │ │
│ 6│body_with_crutches │ 0.6936│ 26│hand │ 0.4004│ │ │ │
│ 7│head │ 0.7005│ 27│hand_left │ 0.3170│ │ │ │
│ 8│front │ 0.5569│ 28│hand_right │ 0.3284│ │ │ │
│ 9│right-front │ 0.5375│ 29│abdomen │ 0.1504│ │ │ │
│ 10│right-side │ 0.4859│ 30│hip_joint │ 0.1060│ │ │ │
│ 11│right-back │ 0.4101│ 31│knee │ 0.1909│ │ │ │
│ 12│back │ 0.2404│ 32│ankle │ 0.1369│ │ │ │
│ 13│left-back │ 0.3754│ 33│foot │ 0.3522│ │ │ │
│ 14│left-side │ 0.5284│ │ │ │ │ │ │
│ 15│left-front │ 0.5605│ │ │ │ │ │ │
│ 16│face │ 0.6165│ │ │ │ │ │ │
│ 17│eye │ 0.1706│ │ │ │ │ │ │
│ 18│nose │ 0.2814│ │ │ │ │ │ │
│ 19│mouth │ 0.1781│ │ │ │ │ │ │
└───┴─────────────────────────┴───────┴───┴─────────────────────────┴───────┴───┴─────────────────────────┴───────┘
nms:
min_confidence: 0.0001 # 0.0001
min_iou: 0.7
pre_topk: 20000 # pre-nms bboxes, Limit to top K pre-NMS per image (disable with None), (Default)None
max_bbox: 20000 # post-nms bboxes, (Default)1000
# multi_label=True: Expand all classes exceeding the threshold for a single anchor to "candidates"
# multi_label=False: Select only the top-ranked class per anchor as a candidate (= single-label)
# class_agnostic=True: NMS ignores classes and suppresses duplicates (rejects different classes even if they are in the same location)
# class_agnostic=False: NMS runs by class (different classes are not suppressed)
# True: multi-label expansion, (Default)False : Top-1 only
multi_label: False
# (Default)True: Class-ignoring NMS, False: Class-specific NMS
# After training using a dataset with multiple classes defined in the same position and size, you should change it to False and re-run validation.
class_agnostic: True
size_bias_alpha: 0.0 # >0 to slightly increase large (e.g. 0.05)
┏━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ Epoch ┃ Avg. Precision ┃ % ┃ Avg. Recall ┃ % ┃
┡━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ 0 │ AP @ .5:.95 │ 22.48 │ AR maxDets 1 │ 17.81 │
│ 0 │ AP @ .5 │ 40.16 │ AR maxDets 10 │ 30.82 │
│ 0 │ AP @ .75 │ 20.28 │ AR maxDets 100 │ 33.17 │
│ 0 │ AP (small) │ 12.65 │ AR (small) │ 23.25 │
│ 0 │ AP (medium) │ 31.18 │ AR (medium) │ 43.76 │
│ 0 │ AP (large) │ 38.71 │ AR (large) │ 47.31 │
└───────┴────────────────┴───────┴────────────────┴───────┘
┏━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ ID┃Name ┃ AP┃ ID┃Name ┃ AP┃ ID┃Name ┃ AP┃
┡━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ 0│body │ 0.4111│ 20│ear │ 0.3113│ │ │ │
│ 1│adult │ 0.1324│ 21│collarbone │ 0.1069│ │ │ │
│ 2│child │ 0.1992│ 22│shoulder │ 0.2724│ │ │ │
│ 3│male │ 0.2231│ 23│solar_plexus │ 0.0884│ │ │ │
│ 4│female │ 0.1716│ 24│elbow │ 0.2263│ │ │ │
│ 5│body_with_wheelchair │ 0.6111│ 25│wrist │ 0.1168│ │ │ │
│ 6│body_with_crutches │ 0.3256│ 26│hand │ 0.2876│ │ │ │
│ 7│head │ 0.6031│ 27│hand_left │ 0.1787│ │ │ │
│ 8│front │ 0.1112│ 28│hand_right │ 0.1768│ │ │ │
│ 9│right-front │ 0.1325│ 29│abdomen │ 0.1736│ │ │ │
│ 10│right-side │ 0.1209│ 30│hip_joint │ 0.1195│ │ │ │
│ 11│right-back │ 0.0765│ 31│knee │ 0.2264│ │ │ │
│ 12│back │ 0.0197│ 32│ankle │ 0.1585│ │ │ │
│ 13│left-back │ 0.0827│ 33│foot │ 0.3767│ │ │ │
│ 14│left-side │ 0.1341│ │ │ │ │ │ │
│ 15│left-front │ 0.1868│ │ │ │ │ │ │
│ 16│face │ 0.6300│ │ │ │ │ │ │
│ 17│eye │ 0.1759│ │ │ │ │ │ │
│ 18│nose │ 0.2913│ │ │ │ │ │ │
│ 19│mouth │ 0.1851│ │ │ │ │ │ │
└───┴─────────────────────────┴───────┴───┴─────────────────────────┴───────┴───┴─────────────────────────┴───────┘
┏━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ Epoch ┃ Avg. Precision ┃ % ┃ Avg. Recall ┃ % ┃
┡━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ 128 │ AP @ .5:.95 │ 41.95 │ AP @ .5 │ 58.44 │
│ 129 │ AP @ .5:.95 │ 42.00 │ AP @ .5 │ 58.51 │
│ 130 │ AP @ .5:.95 │ 42.05 │ AP @ .5 │ 58.51 │
│ 131 │ AP @ .5:.95 │ 42.08 │ AP @ .5 │ 58.58 │
│ 132 │ AP @ .5:.95 │ 42.13 │ AP @ .5 │ 58.61 │
│ │ │ │ │ │
│ 133 │ AP @ .5:.95 │ 42.13 │ AR maxDets 1 │ 32.79 │
│ 133 │ AP @ .5 │ 58.61 │ AR maxDets 10 │ 48.45 │
│ 133 │ AP @ .75 │ 43.66 │ AR maxDets 100 │ 48.90 │
│ 133 │ AP (small) │ 15.04 │ AR (small) │ 21.10 │
│ 133 │ AP (medium) │ 51.92 │ AR (medium) │ 60.04 │
│ 133 │ AP (large) │ 68.22 │ AR (large) │ 73.49 │
└───────┴────────────────┴───────┴────────────────┴───────┘
┏━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ ID┃Name ┃ AP┃ ID┃Name ┃ AP┃ ID┃Name ┃ AP┃
┡━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ 0│body │ 0.7462│ 20│ear │ 0.3506│ │ │ │
│ 1│adult │ 0.7472│ 21│collarbone │ 0.1513│ │ │ │
│ 2│child │ 0.6911│ 22│shoulder │ 0.3417│ │ │ │
│ 3│male │ 0.7699│ 23│solar_plexus │ 0.1669│ │ │ │
│ 4│female │ 0.7237│ 24│elbow │ 0.3050│ │ │ │
│ 5│body_with_wheelchair │ 0.8101│ 25│wrist │ 0.1666│ │ │ │
│ 6│body_with_crutches │ 0.7408│ 26│hand │ 0.5060│ │ │ │
│ 7│head │ 0.7386│ 27│hand_left │ 0.4570│ │ │ │
│ 8│front │ 0.6229│ 28│hand_right │ 0.4651│ │ │ │
│ 9│right-front │ 0.6087│ 29│abdomen │ 0.2585│ │ │ │
│ 10│right-side │ 0.5818│ 30│hip_joint │ 0.2065│ │ │ │
│ 11│right-back │ 0.5035│ 31│knee │ 0.3162│ │ │ │
│ 12│back │ 0.3662│ 32│ankle │ 0.2029│ │ │ │
│ 13│left-back │ 0.4705│ 33│foot │ 0.4421│ │ │ │
│ 14│left-side │ 0.6136│ │ │ │ │ │ │
│ 15│left-front │ 0.6408│ │ │ │ │ │ │
│ 16│face │ 0.6710│ │ │ │ │ │ │
│ 17│eye │ 0.2135│ │ │ │ │ │ │
│ 18│nose │ 0.3456│ │ │ │ │ │ │
│ 19│mouth │ 0.2546│ │ │ │ │ │ │
└───┴─────────────────────────┴───────┴───┴─────────────────────────┴───────┴───┴─────────────────────────┴───────┘
Valid | mAP : 74.47 | mAP50 : 94.56 | ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 77/77 0:03:04 • 0:00:00 0.84it/s
┏━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ Epoch ┃ Avg. Precision ┃ % ┃ Avg. Recall ┃ % ┃
┡━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ 0 │ AP @ .5:.95 │ 46.73 │ AR maxDets 1 │ 36.06 │
│ 0 │ AP @ .5 │ 66.35 │ AR maxDets 10 │ 59.18 │
│ 0 │ AP @ .75 │ 48.37 │ AR maxDets 100 │ 61.88 │
│ 0 │ AP (small) │ 19.38 │ AR (small) │ 43.42 │
│ 0 │ AP (medium) │ 57.15 │ AR (medium) │ 74.63 │
│ 0 │ AP (large) │ 70.99 │ AR (large) │ 80.78 │
└───────┴────────────────┴───────┴────────────────┴───────┘
データセット難易度の特徴
1. 小物体の比率が極端に高い
-
eye
,nose
,mouth
,ear
,collarbone
,wrist
,ankle
など → 90〜99% が small - 小物体は IoU が下がりやすい & DFL が誤差に敏感 → 学習が難しく、Loss が大きめに残りやすい。
2. クラスごとにサイズ分布が極端
-
wheelchair
やcrutches
はほぼ large(90% 近くが大型) -
ear
やeye
はほぼ small(97〜99%)
→ モデルが「マルチスケール同時対応」を強いられている。
3. クラス間バランス
-
adult
39,416 vscrutches
323 のように、データ数の差が桁違い。 - DFL や IoU はデータ不均衡下では「少数派のクラスの収束」が後回しになる。
これが意味すること
-
DFL Loss = 1.0 前後に残るのは、
単に「学習不足」ではなく 小物体タスクの難易度そのものに起因している可能性大。 -
AP の分解結果でも small AP が 20% 以下で弱い → この表の分布と一致。
-
→ なので DFL=1.0 は “高難度データセットとしては自然な値” と解釈できる。
対策(Loss/データ両面)
A. 小物体対策
-
高解像度学習
- 640 → 896 / 960 / 1024 に上げる。
- ただし VRAM 消費が爆発するので、BatchSize との兼ね合い要調整。
-
データ拡張
- Copy-Paste/MixUp で小物体を強調。
- Mosaic のサイズ調整(小物体が潰れすぎないようにする)。
-
サンプリング
- 小物体クラスを oversample して バッチに必ず含めるようにする。
- BalancedBatchSampler で小物体クラス比率を強制的に上げる。
B. Loss バランス
-
dfl_weight を増やす(例: 1.5 → 2.5〜3.0)
→ 境界分布をより重視して小物体の位置精度を強化。 -
box_weight をやや減らす(例: 7.5 → 5〜6)
→ IoU ロスは大物体寄りに効きやすいので、バランスを取る。 -
focal loss / varifocal loss の導入
→ 小物体での hard negative を抑制しやすい。
C. モデルアーキテクチャ
- 高解像度対応の backbone(EfficientNet-Lite, CSP 系 deep 層)
- より細かい FPN レベルを追加(P2 層以下を強調して小物体対応)
実務的な見方
- このデータセットでは「DFL Loss が 0.1〜0.2 に落ちる」のは ほぼ不可能。
- 1.0 前後で止まっても、AP@0.5:.95 が 40〜50% 出ていれば十分“高精度”の部類。
- 評価は Loss の絶対値ではなく mAP/AR を主指標にするのが正しい。
✅ まとめると:
あなたのケースでは DFL Loss=1.0 は “異常に高い”のではなく、データセット難易度(小物体率の高さ)の反映です。
- First training
┏━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┓ ┃ Epoch ┃ Avg. Precision ┃ % ┃ Avg. Recall ┃ % ┃ ┡━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━┩ │ 295 │ AP @ .5:.95 │ 47.56 │ AP @ .5 │ 63.74 │ │ 296 │ AP @ .5:.95 │ 47.59 │ AP @ .5 │ 63.73 │ │ 297 │ AP @ .5:.95 │ 47.60 │ AP @ .5 │ 63.75 │ │ 298 │ AP @ .5:.95 │ 47.61 │ AP @ .5 │ 63.72 │ │ 299 │ AP @ .5:.95 │ 47.65 │ AP @ .5 │ 63.79 │ │ │ │ │ │ │ │ 300 │ AP @ .5:.95 │ 52.33 │ AR maxDets 1 │ 38.26 │ │ 300 │ AP @ .5 │ 71.57 │ AR maxDets 10 │ 62.73 │ │ 300 │ AP @ .75 │ 54.24 │ AR maxDets 100 │ 65.00 │ │ 300 │ AP (small) │ 25.56 │ AR (small) │ 47.47 │ │ 300 │ AP (medium) │ 62.95 │ AR (medium) │ 75.41 │ │ 300 │ AP (large) │ 73.09 │ AR (large) │ 79.45 │ └───────┴────────────────┴───────┴────────────────┴───────┘ ┏━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓ ┃ ID┃Name ┃ AP┃ ID┃Name ┃ AP┃ ID┃Name ┃ AP┃ ┡━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩ │ 0│body │ 0.7644│ 20│ear │ 0.3830│ │ │ │ │ 1│adult │ 0.7579│ 21│collarbone │ 0.2275│ │ │ │ │ 2│child │ 0.7176│ 22│shoulder │ 0.4125│ │ │ │ │ 3│male │ 0.7872│ 23│solar_plexus │ 0.2654│ │ │ │ │ 4│female │ 0.7501│ 24│elbow │ 0.3703│ │ │ │ │ 5│body_with_wheelchair │ 0.8203│ 25│wrist │ 0.2294│ │ │ │ │ 6│body_with_crutches │ 0.8337│ 26│hand │ 0.5272│ │ │ │ │ 7│head │ 0.7636│ 27│hand_left │ 0.4975│ │ │ │ │ 8│front │ 0.6874│ 28│hand_right │ 0.5027│ │ │ │ │ 9│right-front │ 0.6701│ 29│abdomen │ 0.3514│ │ │ │ │ 10│right-side │ 0.6479│ 30│hip_joint │ 0.3099│ │ │ │ │ 11│right-back │ 0.5608│ 31│knee │ 0.3805│ │ │ │ │ 12│back │ 0.4587│ 32│ankle │ 0.2815│ │ │ │ │ 13│left-back │ 0.5522│ 33│foot │ 0.5038│ │ │ │ │ 14│left-side │ 0.6723│ │ │ │ │ │ │ │ 15│left-front │ 0.6894│ │ │ │ │ │ │ │ 16│face │ 0.7010│ │ │ │ │ │ │ │ 17│eye │ 0.2583│ │ │ │ │ │ │ │ 18│nose │ 0.3900│ │ │ │ │ │ │ │ 19│mouth │ 0.3092│ │ │ │ │ │ │ └───┴─────────────────────────┴───────┴───┴─────────────────────────┴───────┴───┴─────────────────────────┴───────┘
- Fine tuning
┏━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┓ ┃ Epoch ┃ Avg. Precision ┃ % ┃ Avg. Recall ┃ % ┃ ┡━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━┩ │ 55 │ AP @ .5:.95 │ 61.85 │ AP @ .5 │ 75.57 │ │ 56 │ AP @ .5:.95 │ 61.85 │ AP @ .5 │ 75.56 │ │ 57 │ AP @ .5:.95 │ 61.87 │ AP @ .5 │ 75.60 │ │ 58 │ AP @ .5:.95 │ 61.86 │ AP @ .5 │ 75.56 │ │ 59 │ AP @ .5:.95 │ 61.86 │ AP @ .5 │ 75.58 │ │ │ │ │ │ │ │ 60 │ AP @ .5:.95 │ 67.49 │ AR maxDets 1 │ 44.10 │ │ 60 │ AP @ .5 │ 84.32 │ AR maxDets 10 │ 74.47 │ │ 60 │ AP @ .75 │ 70.52 │ AR maxDets 100 │ 76.35 │ │ 60 │ AP (small) │ 37.36 │ AR (small) │ 58.97 │ │ 60 │ AP (medium) │ 85.49 │ AR (medium) │ 91.03 │ │ 60 │ AP (large) │ 93.85 │ AR (large) │ 95.52 │ └───────┴────────────────┴───────┴────────────────┴───────┘ ┏━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓ ┃ ID┃Name ┃ AP┃ ID┃Name ┃ AP┃ ID┃Name ┃ AP┃ ┡━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩ │ 0│body │ 0.8932│ 20│ear │ 0.4764│ │ │ │ │ 1│adult │ 0.8889│ 21│collarbone │ 0.3748│ │ │ │ │ 2│child │ 0.9058│ 22│shoulder │ 0.6209│ │ │ │ │ 3│male │ 0.9310│ 23│solar_plexus │ 0.4597│ │ │ │ │ 4│female │ 0.9305│ 24│elbow │ 0.5889│ │ │ │ │ 5│body_with_wheelchair │ 0.9542│ 25│wrist │ 0.3741│ │ │ │ │ 6│body_with_crutches │ 0.9479│ 26│hand │ 0.6906│ │ │ │ │ 7│head │ 0.8835│ 27│hand_left │ 0.6686│ │ │ │ │ 8│front │ 0.7947│ 28│hand_right │ 0.6742│ │ │ │ │ 9│right-front │ 0.8298│ 29│abdomen │ 0.5764│ │ │ │ │ 10│right-side │ 0.8155│ 30│hip_joint │ 0.5414│ │ │ │ │ 11│right-back │ 0.7192│ 31│knee │ 0.6210│ │ │ │ │ 12│back │ 0.6214│ 32│ankle │ 0.4384│ │ │ │ │ 13│left-back │ 0.7484│ 33│foot │ 0.6697│ │ │ │ │ 14│left-side │ 0.7995│ │ │ │ │ │ │ │ 15│left-front │ 0.8317│ │ │ │ │ │ │ │ 16│face │ 0.8039│ │ │ │ │ │ │ │ 17│eye │ 0.3268│ │ │ │ │ │ │ │ 18│nose │ 0.4896│ │ │ │ │ │ │ │ 19│mouth │ 0.4121│ │ │ │ │ │ │ └───┴─────────────────────────┴───────┴───┴─────────────────────────┴───────┴───┴─────────────────────────┴───────┘
クラス不均衡対策
サイズ別内訳: small 629,173 (77.1%)・medium 128,762 (15.8%)・large 58,531 (7.2%)
回答1
以下は、いただいた学習結果とサンプル画像(人が多数+細部クラスが大量に出そうなシーン)から読める現象を踏まえた提案です。ポイントは 「推論段階での上位K制限とNMSまわり」 と 「学習時の勾配配分(小物体に支配されがち)」 の2軸で対処することです。
まず現象の見立て(重要)
- 追加した 6 クラス(collarbone, solar_plexus, wrist, abdomen, hip_joint, ankle)は ほぼすべて小物体。
- 団体写真のような画像では、1人あたり 耳/目/鼻/口/肩/肘/手首/手/腹/股関節/膝/足首/足/顔/頭 …だけで 1人20~30個規模の候補 が出ます。10人写れば候補は数百になります。
- YOLO 系のデフォルト推論は
max_det
(NMS後に残す検出の上限) があり、Ultralytics 実装では既定値 300(※COCO 指標は AR@maxDets=100 で計測)。小物体の高スコア候補が上位を占有すると、max_det
上限で body が丸ごと切り捨てられることが起こり得ます。
→ 「mAP は高いのに、画像によっては body がほとんど出ない」という矛盾に合致します。
1. アーキテクチャ変更なし(ハイパラ/推論設定だけ)で効く手法
A) 推論側の対策(即効性が高い順)
-
max_det
を大幅に引き上げる(最重要)-
例:
max_det=2000~5000
。団体写真+細部クラスの多発でも body が上限で落ちにくくなります。 -
コマンド例(Ultralytics YOLOv9-E)
yolo predict model=your_v9e.pt source=path/to/images \ imgsz=1280 conf=0.15 iou=0.65 agnostic_nms=False max_det=3000
-
チェック:
save_txt=True save_conf=True
で生出力を見て、max_det
増で body が復活するかをまず確認。
-
-
クラス別しきい値の“二段推論”(簡単で効く)
-
Pass-A(body系のみ):
classes=[0,5,6]
(body, body_with_wheelchair, body_with_crutches)に絞り、**低めのconf
(0.05~0.15)**+max_det
大。 -
Pass-B(細部クラス):それ以外のクラスを 高めの
conf
(0.25~0.35) で実行。 -
2 パスの結果を結合(WBF かクラス別NMSでマージ)。これで body の取りこぼしを抑えつつ、細部の過剰候補を抑制できます。
-
例:
# A: body系 yolo predict model=your_v9e.pt source=... classes=[0,5,6] conf=0.10 max_det=3000 save_txt save_conf # B: 細部系 yolo predict model=your_v9e.pt source=... classes=[7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33] \ conf=0.30 max_det=3000 save_txt save_conf
(簡易には A/B の結果を連結後、通常 NMS をもう一度かけるだけでも十分効きます)
-
-
NMS の見直し
-
agnostic_nms=False
(クラス別 NMS) を明示(デフォルトが True 環境なら特に要注意)。
クラス間で潰し合いが起きないようにします。 - NMS IoU を 0.65~0.70 に調整。body と細部は包含関係で IoU が小さいことが多いので、過度に低いと冗長候補が残り、上位Kを圧迫します。
- 実装できるなら Soft-NMS(or WBF)も有効。重なり候補のスコアを緩やかに落として 突然死(全落ち)を防ぐ効果があります。
-
-
TTA(スケール&反転)を併用
-
tta=True
(またはaugment=True
)で推論。body の 見逃し削減(リコール↑) に効きやすいです(計算は増えます)。
-
B) 学習側の対策(“bodyの声”を強くする)
-
データローダの重み付け(Repeat-Factor / Weighted Sampling)
- 各画像の GT総数に占める“body系(0,5,6)”の比率でサンプル重みを付ける。
細部が大量にある画像ばかりで学習が上書きされるのを抑え、body の勾配寄与を底上げします。 - 実装例:PyTorch
WeightedRandomSampler
を使い、アノテーション統計からサンプル重みを作る(モデルはそのまま)。
- 各画像の GT総数に占める“body系(0,5,6)”の比率でサンプル重みを付ける。
-
クラス重み(loss の class-weight)を導入/強化
- ラベル頻度に逆比例(例:
1/sqrt(freq)
)で body系のクラス重みを>1 に。Ultralytics の損失計算を軽く拡張するだけで可能です(アーキは不変)。 - これにより 細部クラスの“数の暴力”に対して body の分類損失が相殺されます。
- ラベル頻度に逆比例(例:
-
画像サイズ/Aug の再調整
-
imgsz
を 1280~1536 に上げ、小物体狙いの解像度を確保しつつ、
過激な Mosaic / RandomCrop を弱める(mosaic≈0.1~0.2
,mixup=0
,erasing=0
,perspective=0
,translate≤0.05
など)。
→ body の全体像が欠けた学習サンプルを減らし、body の回帰・分類を安定化。
-
-
ラベルスムージング少量(例:0.05)+Focal γ 微調整
- クラス競合が強いときに有効。偽陰性(FN)に寄与する過学習的な境界の鋭さを緩和します。
まずは A-1(
max_det↑
)と A-2(二段推論)だけで挙動が大きく改善するケースが多いです。学習をやり直さずに確認できるので、最初に試す価値が高いです。
2. 「わずかなアーキ変更」を許容する場合の手法
2-1) クラス群でヘッドを分ける(Decoupled / Grouped Head) *軽微で効果大
-
バックボーンとFPNは共有しつつ、検出ヘッドだけを 2 つに複製:
-
Head-A(“マクロ”):
{body, body_with_wheelchair, body_with_crutches, head, face}
など“全体・大物体寄り” - Head-B(“細部”):残りの部位クラス
-
Head-A(“マクロ”):
-
損失は ヘッドごとに独立集計、推論後は出力を連結。
さらに NMS もヘッド(=グループ)ごとに実行し、max_det_per_group
(例:A=400, B=1600)を設ければ、細部が上限を食い尽くして body が落ちる問題を原理的に回避できます。 -
変更点は 検出ヘッドの複製と前後処理の分岐のみ(層構造はほぼ既存のまま)。学習・重みの流れは YOLOv9-E と同様なので安全。
2-2) 2段カスケード(Body→Parts の ROI 検出) *実装容易・効果安定
- Model-A:body系のみ(3クラス) を学習(軽量でも可)。
- Model-B:細部のみ を学習。
- 推論は Aでbody検出 → 各bodyのROIを切出し → Bで細部検出 → 元座標へマップして結合。
- メリット:探索空間を“人体の中だけ”に限定でき、細部の FP も減り、body と細部の相互干渉がほぼ消えます。
学習済みの現在モデルをそのまま B として使い、A だけ軽く追加学習する運用も可能。
2-3) グループ別NMS(コード数行の後処理改造)
-
アーキはそのまま、NMS を「クラス群」単位で別々に回すだけの変更。
- 例:
group_A = {0,5,6,16,7}
,group_B = その他
- それぞれに
max_det_A
,max_det_B
,conf_A
,conf_B
を設定可能に。
- 例:
-
実装は NMS 呼び出し直前で 出力をグルーピング→各群に batched_nms→連結。
→ 2-1 の簡易版として 最小の改造で body の保護ができます。
2-4) (オプション)P2 出力の追加
- 小物体向けに stride 4 (P2) を追加(head/neckに1段増)。
- 小物体AP/ARの底上げに効きますが、候補総数がさらに増えるため、
max_det
とグループNMSの併用が前提です。
すぐに試す実験順(最短で効果確認)
-
推論だけ変更:
max_det=3000
、agnostic_nms=False
、conf=0.15
、iou=0.65
→ サンプル画像で body が復活するか確認。 - 二段推論:A=body低閾値 / B=細部高閾値 → 併合。
- 改善が足りなければ グループ別NMS を導入(後処理だけの小改造)。
- 継続運用するなら Weighted Sampling + クラス重み を学習に導入。
- さらに強くするなら ヘッド分離(2-1) か Body→Parts カスケード(2-2) を採用。
補足(指標の読み方)
- mAP は高く見えても、
AR@maxDets=100
が 76.35 と上限依存の指標で頭打ち(=中~大規模画像で上位K飽和の疑い)。 - Large の AR は 95.52 と高い一方、「特定画像で body がごっそり落ちる」のは 画像内候補数の多さに起因する上位K切りが最も整合的です。
必要なら、max_det
上げ+二段推論の 簡易マージスクリプト(WBF or クラス別NMS) も提示します。まずは 推論パラメータだけ変えて挙動を見てください。改善が確認できれば、学習側の重み付けや小改造(グループ別NMS/ヘッド分離)を段階的に入れるのがコスト対効果の良い進め方です。
回答2
各画像の GT総数に占める“body系(0,5,6)”の比率でサンプル重みを付ける。 細部が大量にある画像ばかりで学習が上書きされるのを抑え、body の勾配寄与を底上げします。 実装例:PyTorch WeightedRandomSampler を使い、アノテーション統計からサンプル重みを作る(モデルはそのまま)。 上記の提案をもう少し具体的に教えてほしい。
了解です。**「各画像の GT 総数に占める body 系(ID: 0,5,6)の比率でサンプル重みを付け、WeightedRandomSampler で学習時の取り出し確率を変える」**を、実装しやすい順に 2 通り(A: 新しい train.txt を生成するだけ、B: PyTorch の Sampler を直接使う)で具体化します。どちらも モデルはそのまま で動きます。
前提:重みの考え方(式)
各画像 i のラベルから
-
body_cnt_i
= {0,5,6} に属する GT の数 -
total_i
= その画像の全 GT 数 -
ratio_i = body_cnt_i / total_i
(total_i=0 の場合は 0 とする)
を求め、ratio が大きい画像ほど取り出し確率を上げるように重みをつけます。過度な偏りを避けるために、次のスムージングと上下限をおすすめします。
w_i_raw = ((ratio_i + eps) / (mean_ratio + eps)) ** beta * (1 + presence_boost * 1[body_cnt_i > 0])
# 安定化(暴れ防止)
w_i_clipped = clip(w_i_raw, w_min, w_max)
# 正規化(平均 1 に整える)
w_i = w_i_clipped / mean(w_i_clipped)
- 推奨初期値:
eps=1e-3
,beta=1.5
,presence_boost=0.3
,w_min=0.5
,w_max=3.0
(強めたいときはbeta=2.0
、弱めたいときはbeta=1.0
)
目的:「細部 GT が大量の画像」による勾配の“数の暴力”を緩和し、バッチ中に一定量の body を常に含ませやすくする。
共通の前処理:画像別の重みを作るスクリプト
入力:YOLO 形式の
train.txt
(学習画像のフルパスが 1 行 1 件)とlabels/
(images/
と同階層で、同名 .txt に [class x y w h] の行が入っている前提)
# make_weights.py
import os, random
from pathlib import Path
import numpy as np
BODY_IDS = {0, 5, 6} # body, body_with_wheelchair, body_with_crutches
EPS = 1e-3; BETA = 1.5; PRESENCE_BOOST = 0.3
W_MIN = 0.5; W_MAX = 3.0
def img_to_label(img_path: str) -> str:
# .../images/train/xxx.jpg -> .../labels/train/xxx.txt
p = Path(img_path)
parts = list(p.parts)
# 画像パス中の "images" を "labels" に置換する(環境に合わせて調整)
for i, q in enumerate(parts):
if q == "images":
parts[i] = "labels"
break
label_path = Path(*parts).with_suffix(".txt")
return str(label_path)
def count_body_ratio(label_path: str):
if not os.path.exists(label_path):
return 0, 0, 0.0
total = 0
body = 0
with open(label_path, "r") as f:
for line in f:
s = line.strip().split()
if not s:
continue
cls = int(float(s[0]))
total += 1
if cls in BODY_IDS:
body += 1
ratio = (body / total) if total > 0 else 0.0
return body, total, ratio
def compute_weights(train_txt_path: str, out_np_path: str):
with open(train_txt_path, "r") as f:
imgs = [l.strip() for l in f if l.strip()]
ratios, bodies = [], []
for img in imgs:
lab = img_to_label(img)
b, t, r = count_body_ratio(lab)
ratios.append(r)
bodies.append(b > 0)
ratios = np.array(ratios, dtype=np.float64)
bodies = np.array(bodies, dtype=bool)
mean_ratio = max(ratios[ratios > 0].mean() if (ratios > 0).any() else 0.0, EPS)
w = ((ratios + EPS) / (mean_ratio + EPS)) ** BETA
w *= (1.0 + PRESENCE_BOOST * bodies.astype(np.float64))
w = np.clip(w, W_MIN, W_MAX)
w = w / w.mean() # 平均 1 に正規化
np.save(out_np_path, w)
print(f"Saved weights to {out_np_path} (mean={w.mean():.3f}, min={w.min():.3f}, max={w.max():.3f})")
return imgs, w
if __name__ == "__main__":
# 例: python make_weights.py
train_txt = "path/to/train.txt"
out = "path/to/train_weights.npy"
compute_weights(train_txt, out)
A. 最も簡単:重み付きの “複製 train.txt” を作って CLI でそのまま学習
Ultralytics は data.yaml
の train:
に 画像リスト(.txt) を渡せます。
そこで、重みに応じて行を複製した 新しい train.txt を作れば、YOLO の実装に手を入れずに 擬似 Weighted Sampling を実現できます。
# make_weighted_train_txt.py
import numpy as np, random
from pathlib import Path
def write_weighted_list(imgs, weights, out_txt):
N = len(imgs)
# 合計件数が元とほぼ同じになるようスケール
scaled = weights * N / weights.sum()
reps = np.maximum(1, np.round(scaled)).astype(int) # 最低1回は出す
weighted_paths = []
for p, k in zip(imgs, reps):
weighted_paths.extend([p] * int(k))
random.shuffle(weighted_paths)
Path(out_txt).write_text("\n".join(weighted_paths))
print(f"wrote {len(weighted_paths)} lines to {out_txt} (orig {N})")
if __name__ == "__main__":
imgs, w = ... # 上の make_weights.py で計算した値を使う
write_weighted_list(imgs, w, "path/to/train_weighted.txt")
-
data.yaml
のtrain:
をtrain_weighted.txt
に差し替えて学習開始するだけです。 - 長所: ライブラリ改造不要。
- 短所: 1 エポック中の集合が固定(WeightedRandomSampler のような毎エポック再サンプリングではない)。→ それでも Mosaic 有効時は 4 画像が混ざるため十分効きます。
WeightedRandomSampler
を直接使う(Python API 学習)
B. 正攻法:Ultralytics の Trainer をサブクラス化し、get_dataloader
を上書きして Sampler を差し込みます。
(バージョンによりファイル名が微妙に異なりますが、概念は同じです)
# weighted_trainer.py
import numpy as np, torch
from torch.utils.data import WeightedRandomSampler, DataLoader
from ultralytics.models.yolo.detect.train import DetectionTrainer
from ultralytics.data.dataset import YOLODataset
from ultralytics.data.build import build_yolo_dataset
from ultralytics.utils import LOGGER
class WeightedSamplerTrainer(DetectionTrainer):
def get_dataloader(self, dataset_path, batch_size=16, rank=0, mode="train"):
assert mode == "train", "Sampler は学習時のみ"
# Ultralytics のユーティリティで Dataset を構築
dataset = build_yolo_dataset(self.args, img_path=dataset_path, batch=batch_size, mode=mode, rank=rank)
# 画像順と weights.npy の順を一致させる必要あり
weights = np.load(self.args.weights_npy) # make_weights.py で作成
assert len(weights) == len(dataset), f"weights size {len(weights)} != dataset size {len(dataset)}"
sampler = WeightedRandomSampler(
weights=torch.as_tensor(weights, dtype=torch.double),
num_samples=len(dataset), # 1エポックのサンプル数は元と同じに
replacement=True
)
# shuffle=False にして Sampler を有効化
dataloader = DataLoader(
dataset, batch_size=batch_size, shuffle=False, sampler=sampler,
num_workers=self.args.workers, pin_memory=True, collate_fn=dataset.collate_fn
)
LOGGER.info("Using WeightedRandomSampler for training.")
return dataloader
学習の起動例:
from ultralytics import YOLO
from weighted_trainer import WeightedSamplerTrainer
model = YOLO("yolov9e.pt")
model.train(
data="path/to/data.yaml",
epochs=...,
imgsz=...,
trainer=WeightedSamplerTrainer, # ここがポイント
weights_npy="path/to/train_weights.npy",
mosaic=0.2, mixup=0.0, translate=0.05, perspective=0.0, # body を壊しにくい Aug 推奨
)
マルチ GPU(DDP)の場合
WeightedRandomSampler
はプロセス分割をしないので、各 rank で同じ系列を引いてしまう恐れがあります。
DDP では、次のような WeightedDistributedSampler を使います(必要最小限の実装)。
# weighted_distributed_sampler.py
import torch
from torch.utils.data import Sampler
class WeightedDistributedSampler(Sampler):
def __init__(self, weights, num_replicas=None, rank=None, replacement=True, num_samples=None):
if num_replicas is None:
num_replicas = torch.distributed.get_world_size()
if rank is None:
rank = torch.distributed.get_rank()
self.weights = torch.as_tensor(weights, dtype=torch.double)
self.num_replicas = num_replicas
self.rank = rank
self.replacement = replacement
self.num_samples = num_samples or int(len(self.weights) // num_replicas)
self.total_size = self.num_samples * num_replicas
self.epoch = 0
def __iter__(self):
g = torch.Generator()
g.manual_seed(self.epoch) # 各エポックで異なる系列
# 全体から total_size 抽出し、プロセスで分割
indices = torch.multinomial(self.weights, self.total_size, self.replacement, generator=g).tolist()
# rank ごとにストライドで切り分け
indices = indices[self.rank:self.total_size:self.num_replicas]
return iter(indices)
def __len__(self):
return self.num_samples
def set_epoch(self, epoch):
self.epoch = epoch
get_dataloader
で rank/world_size を見て Sampler を差し替えます。
実運用のコツ
-
重みの強さを段階的に上げる
- まずは
beta=1.5, presence_boost=0.3
、w_min=0.5, w_max=3.0
。 - body の Recall が十分に上がらなければ
beta
を 2.0 へ。 - 小物体の mAP が落ち過ぎるなら
w_max
を 2.0 に下げて効きを弱める。
- まずは
-
Mosaic を弱める
-
mosaic=0.1~0.2
、translate<=0.05
。body の全身が切れにくく、重み付けの効果が素直に出る。
-
-
バッチ診断(効果の可視化)
- Collate 内で
body_cnt_in_batch
をログに出し、**「body を含まないバッチ率」**が激減していることを確認。 - 併せて
max_det
を 3000 程度で推論し、取りこぼしが改善するかも評価してください。
- Collate 内で
-
検証セットは通常分布のまま
-
val
側は重み付け・複製なし。過学習や分布ねじれの影響を正しく監視できます。
-
代替(バッチ制約型)※必要なら
「各バッチに最低 k 枚は body を含む画像」という BalancedBatchSampler を自前実装する方法もあります。
Weighted より振る舞いを直接制御できますが、まずは上記の A または B を試すのが実装コストと効果のバランスが良いです。
まとめ
- 作業最小で効果を出すなら A(複製 train.txt 方式)。
- より正確にエポックごとに再サンプリングしたいなら B(WeightedRandomSampler)。
- どちらも body の露出頻度(=勾配寄与)を底上げし、細部の“数の暴力”を緩和できます。
- 併せて推論時は
max_det
を拡大・二段推論(body 低閾値/細部高閾値) を適用すると、現象の原因(上位 K 飽和)にも直接効きます。
必要なら、あなたの train.txt
とパス構成に合わせた 実行用スクリプトの完成版 を整えてお渡しします。
回答3
単純に、下記のデータセット全体の構成比を使用して、large を 10倍 に増量、medium を 5倍に増量 するために、各画像のごとのラベルのサイズを算定したうえで large に分類されるクラスは 10倍、medium に分類されるクラスは 5倍に .txt 内の行を複写するのとどれほど差があるのか? サイズ別内訳: small 629,173 (77.1%)・medium 128,762 (15.8%)・large 58,531 (7.2%)
結論から先に――
「.txt の行(GT)を Medium×5、Large×10 で複写する」=“各 GT の損失に固定重みを掛ける”のと等価です。
一方で 画像単位の重み付け(WeightedRandomSampler など) は “その画像に含まれる 全 GT の寄与をまとめて増やす(=文脈を増やす)”という違いがあります。
両者は 期待値上のサイズ別重み付けは似るものの、学習の安定性・計算コスト・一般化において差が出ます。
数字でみる影響(行複写を Medium×5、Large×10 で実施した場合)
与えられた全体構成:
Small 629,173(77.1%) / Medium 128,762(15.8%) / Large 58,531(7.2%)
-
行複写後の実効カウント
- Small:×1 → 629,173
- Medium:×5 → 128,762×5 = 643,810
- Large:×10 → 58,531×10 = 585,310
-
新しいサイズ分布(正規化)
- Small 33.86%、Medium 34.65%、Large 31.50%
→ ほぼ三等分に近いバランスへ(狙いどおり Medium/Large を底上げ)。
- Small 33.86%、Medium 34.65%、Large 31.50%
-
1 バッチあたりの “正例(GT)個数” が増える倍率
- 元の総数:629,173 + 128,762 + 58,531
- 複写後総数:629,173 + 5×128,762 + 10×58,531
-
増加倍率 ≈ 2.28 倍
→ 学習の計算時間・メモリが約 2.3 倍(正例数に概ね比例)になります。
学習が荒れやすくなるので 学習率は ~0.44 倍(=1/2.28)に下げると安定しやすいです。
(正確には、以下の「平均1に正規化した重み」を使えば LR 調整は最小で済みます)
-
(参考)平均1に正規化した等価重み
Multipliers をS=1, M=5, L=10
としたとき、全体平均が 1 になる係数c ≈ 0.4384
。
→ 実効重みは S=0.438、M=2.19、L=4.38。
損失側でこの重みを掛けるだけで「行複写」と同等の効果を、計算量を増やさずに得られます。
行複写(ラベル複写)方式と、画像重み方式の本質的な差
観点 | 行複写(GT複写:M×5/L×10) | 画像重み(WeightedRandomSampler等) |
---|---|---|
何を増やすか | 同一 GT の寄与(同じ画素・同じボックスを繰り返し最適化) | 画像の出現頻度(文脈・背景・組合せが増える) |
計算コスト | GT数が ~2.3× → そのまま重くなる | ほぼ同等(画像の選ばれ方が変わるだけ) |
安定性 | 同一 GT の重複割当が発生(割当/マッチングが競合しがち) | 競合しにくい。Mosaic 等とも相性が良い |
一般化 | バリエーション増えず同じ画素に過適合しやすい | 文脈の多様化で過適合しにくい |
実装の手軽さ | 非常に簡単(.txt 行を複写) | スクリプト or Sampler の導入が必要 |
推奨度 | 低〜中(やるなら小さめ倍率+正規化) | 高(まずはこちらを推奨) |
技術的には、行複写は「損失の ターゲット別重み付け」と等価ですが、
同一画像・同一 GT が 2 つの正解として同時に存在することになり、
一部のアサイン戦略(動的Kやバッグベース)では 同一物体に複数の予測を強要し、学習を不安定にすることがあります。
また、同一変換(拡大縮小/平行移動/反転)が複写 GT に等しく掛かるため、バリエーションは増えません。
では「どれほど差が出るのか?」
-
サイズ比の是正だけを見るなら、両者の“期待値”は近くできます。
ただし 行複写は 2.3× の正例密度による副作用(学習時間↑、メモリ↑、割当競合、過適合)をほぼ必ず伴います。 -
実運用の体感差は、(1)学習の安定性、(2)小物体の mAP 下落の出方、(3)速度に現れます。
私の経験則では、画像重み方式の方が安定しやすく、速度ペナルティも小。
行複写で同等の成果を目指す場合、倍率を抑える(例:M×2〜3、L×3〜5)+正規化が現実的です。
「同じ効果」を安全に得る代替案(実装最小でおすすめ)
-
損失にサイズ重みを掛ける(=行複写の数式的等価、でも計算量は据え置き)
-
size ∈ {S,M,L}
に対してw_S=0.44, w_M=2.19, w_L=4.38
(上の正規化重み)を lbox/lcls/ldfl に乗算。 - Ultralytics の
ComputeLoss
に数行追加で可能(アーキ変更なし)。 - これなら LR の再スケールは不要で、割当競合も起きにくい。
-
-
画像重み(先に提案した Sampler)× サイズ比率
- 画像ごとに
(Medium+Large)/Total
比率で重みを付ける(body 比率も併用可)。 - 目標分布(例:S/M/L ≈ 34/35/31)に近づくまで 重みを自動キャリブレーションするのも簡単です。
- 画像ごとに
どうしても行複写でやるなら(ダメージを減らすコツ)
- 倍率は控えめ(例:M×2、L×3)から開始。
- 画像単位で上限:1 画像の総 GT 倍増が一定以上(例:×1.5)を超えないようにクリップ。
- 小さな座標ノイズ(±1〜2%)を複写 GT に与える:完全重複を避け、割当の競合を緩和。
- 学習率を 0.4〜0.5 倍に下げる(前述の 0.44 目安)。
- val は素のまま(複写なし)で行い、サイズ別 AP/AR の上下を必ず確認。
まとめ
- 行複写(M×5/L×10)は 分布是正の効果は強い一方、正例数が ≈2.3×になり、計算・安定性・過適合の面でコストが大きい。
- 同等の効果は「損失のサイズ重み」や「画像重みサンプリング」で、計算負担や不安定さを増やさずに実現可能。
- まずは 損失のサイズ重み(正規化済) か 画像重みサンプリングで試し、必要なら穏当な倍率の行複写に留める、という順がおすすめです。
オーバーサンプリング後
サイズ別内訳: small 592,085 件 (65.2%)・212,507 件 (23.4%)・103,543 件 (11.4%)
┏━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ Epoch ┃ Avg. Precision ┃ % ┃ Avg. Recall ┃ % ┃
┡━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ 25 │ AP @ .5:.95 │ 58.93 │ AP @ .5 │ 73.03 │
│ 26 │ AP @ .5:.95 │ 58.90 │ AP @ .5 │ 72.98 │
│ 27 │ AP @ .5:.95 │ 58.91 │ AP @ .5 │ 73.09 │
│ 28 │ AP @ .5:.95 │ 58.91 │ AP @ .5 │ 73.07 │
│ 29 │ AP @ .5:.95 │ 58.92 │ AP @ .5 │ 73.12 │
│ │ │ │ │ │
│ 30 │ AP @ .5:.95 │ 64.98 │ AR maxDets 1 │ 43.25 │
│ 30 │ AP @ .5 │ 82.59 │ AR maxDets 10 │ 72.15 │
│ 30 │ AP @ .75 │ 68.66 │ AR maxDets 100 │ 74.16 │
│ 30 │ AP (small) │ 34.78 │ AR (small) │ 57.52 │
│ 30 │ AP (medium) │ 81.38 │ AR (medium) │ 88.53 │
│ 30 │ AP (large) │ 91.20 │ AR (large) │ 93.49 │
└───────┴────────────────┴───────┴────────────────┴───────┘
┏━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ ID┃Name ┃ AP┃ ID┃Name ┃ AP┃ ID┃Name ┃ AP┃
┡━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ 0│body │ 0.8872│ 20│ear │ 0.4687│ │ │ │
│ 1│adult │ 0.8791│ 21│collarbone │ 0.3451│ │ │ │
│ 2│child │ 0.8610│ 22│shoulder │ 0.5821│ │ │ │
│ 3│male │ 0.9222│ 23│solar_plexus │ 0.4359│ │ │ │
│ 4│female │ 0.9259│ 24│elbow │ 0.5643│ │ │ │
│ 5│body_with_wheelchair │ 0.9506│ 25│wrist │ 0.3357│ │ │ │
│ 6│body_with_crutches │ 0.9046│ 26│hand │ 0.6721│ │ │ │
│ 7│head │ 0.8648│ 27│hand_left │ 0.6442│ │ │ │
│ 8│front │ 0.7906│ 28│hand_right │ 0.6498│ │ │ │
│ 9│right-front │ 0.7923│ 29│abdomen │ 0.5463│ │ │ │
│ 10│right-side │ 0.7899│ 30│hip_joint │ 0.4966│ │ │ │
│ 11│right-back │ 0.7138│ 31│knee │ 0.5834│ │ │ │
│ 12│back │ 0.6014│ 32│ankle │ 0.4167│ │ │ │
│ 13│left-back │ 0.6934│ 33│foot │ 0.6565│ │ │ │
│ 14│left-side │ 0.7913│ │ │ │ │ │ │
│ 15│left-front │ 0.8023│ │ │ │ │ │ │
│ 16│face │ 0.7511│ │ │ │ │ │ │
│ 17│eye │ 0.3058│ │ │ │ │ │ │
│ 18│nose │ 0.4568│ │ │ │ │ │ │
│ 19│mouth │ 0.3803│ │ │ │ │ │ │
└───┴─────────────────────────┴───────┴───┴─────────────────────────┴───────┴───┴─────────────────────────┴───────┘
オーバーサンプリング + Horizontal Flip
┏━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ Epoch ┃ Avg. Precision ┃ % ┃ Avg. Recall ┃ % ┃
┡━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ 195 │ AP @ .5:.95 │ 46.83 │ AP @ .5 │ 62.90 │
│ 196 │ AP @ .5:.95 │ 46.80 │ AP @ .5 │ 62.84 │
│ 197 │ AP @ .5:.95 │ 46.78 │ AP @ .5 │ 62.81 │
│ 198 │ AP @ .5:.95 │ 46.77 │ AP @ .5 │ 62.81 │
│ 199 │ AP @ .5:.95 │ 46.87 │ AP @ .5 │ 62.93 │
│ │ │ │ │ │
│ 200 │ AP @ .5:.95 │ 52.50 │ AR maxDets 1 │ 38.54 │
│ 200 │ AP @ .5 │ 72.29 │ AR maxDets 10 │ 62.92 │
│ 200 │ AP @ .75 │ 54.51 │ AR maxDets 100 │ 65.05 │
│ 200 │ AP (small) │ 24.62 │ AR (small) │ 48.13 │
│ 200 │ AP (medium) │ 63.56 │ AR (medium) │ 75.79 │
│ 200 │ AP (large) │ 73.95 │ AR (large) │ 79.87 │
└───────┴────────────────┴───────┴────────────────┴───────┘
┏━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ ID┃Name ┃ AP┃ ID┃Name ┃ AP┃ ID┃Name ┃ AP┃
┡━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ 0│body │ 0.7817│ 20│ear │ 0.4041│ │ │ │
│ 1│adult │ 0.7762│ 21│collarbone │ 0.2077│ │ │ │
│ 2│child │ 0.7377│ 22│shoulder │ 0.4030│ │ │ │
│ 3│male │ 0.7991│ 23│solar_plexus │ 0.2383│ │ │ │
│ 4│female │ 0.7584│ 24│elbow │ 0.3629│ │ │ │
│ 5│body_with_wheelchair │ 0.8431│ 25│wrist │ 0.2229│ │ │ │
│ 6│body_with_crutches │ 0.8387│ 26│hand │ 0.5509│ │ │ │
│ 7│head │ 0.7611│ 27│hand_left │ 0.5098│ │ │ │
│ 8│front │ 0.6862│ 28│hand_right │ 0.5141│ │ │ │
│ 9│right-front │ 0.6674│ 29│abdomen │ 0.3382│ │ │ │
│ 10│right-side │ 0.6459│ 30│hip_joint │ 0.2886│ │ │ │
│ 11│right-back │ 0.5596│ 31│knee │ 0.3706│ │ │ │
│ 12│back │ 0.4866│ 32│ankle │ 0.2626│ │ │ │
│ 13│left-back │ 0.5513│ 33│foot │ 0.5109│ │ │ │
│ 14│left-side │ 0.6672│ │ │ │ │ │ │
│ 15│left-front │ 0.6816│ │ │ │ │ │ │
│ 16│face │ 0.6798│ │ │ │ │ │ │
│ 17│eye │ 0.2634│ │ │ │ │ │ │
│ 18│nose │ 0.4081│ │ │ │ │ │ │
│ 19│mouth │ 0.3241│ │ │ │ │ │ │
└───┴─────────────────────────┴───────┴───┴─────────────────────────┴───────┴───┴─────────────────────────┴───────┘