Repository: ultralytics/yolov5

Issue:
When I use Hyperpameter Evolution for Hyperpameter tunning, I got an error! 
### Search before asking

- [x] I have searched the YOLOv5 [issues](https://github.com/ultralytics/yolov5/issues) and [discussions](https://github.com/ultralytics/yolov5/discussions) and found no similar questions.


### Question


Of course, the training is working with "--noautoanchor"  by my custom data .

I need to use Hyperpameter Evolution for Hyperpameter tunning.

At first, I tested the example of COCO128.

python train.py --img-size 2352 --batch 1 --epochs 1 --data coco128.yaml --hyp './data/hyps/hyp.scratch.yaml' --cfg './models/yolov5x6.yaml'  --weights yolov5x6.pt --cache --evolve &

**The Hyperpameter Evolution of COCO128 is working well.**

My command for my custom data:

**python train.py  --img 2352 --batch 1 --epochs 1 --data test.yaml --cfg './models/yolov5x6.yaml' --weights yolov5x6.pt --cache --evolve 2**

After I run the command line, I meet to the error.

**AutoAnchor: ERROR: AutoAnchor: ERROR: scipy.cluster.vq.kmeans requested 12 points but returned only 9.**

I follow the instruction of  Hyperpameter Evolution Guide.

My setting:



# Name                    Version                   Build  Channel
_libgcc_mutex             0.1                        main  
absl-py                   1.0.0                     <pip>
ca-certificates           2021.10.26           h06a4308_2  
cachetools                5.0.0                     <pip>
certifi                   2021.10.8        py38h06a4308_2  
charset-normalizer        2.0.12                    <pip>
cycler                    0.11.0                    <pip>
fonttools                 4.29.1                    <pip>
google-auth               2.6.0                     <pip>
google-auth-oauthlib      0.4.6                     <pip>
grpcio                    1.43.0                    <pip>
idna                      3.3                       <pip>
importlib-metadata        4.11.1                    <pip>
kiwisolver                1.3.2                     <pip>
ld_impl_linux-64          2.35.1               h7274673_9  
libffi                    3.3                  he6710b0_2  
libgcc-ng                 9.1.0                hdf63c60_0  
libstdcxx-ng              9.1.0                hdf63c60_0  
Markdown                  3.3.6                     <pip>
matplotlib                3.5.1                     <pip>
ncurses                   6.3                  h7f8727e_2  
numpy                     1.22.2                    <pip>
oauthlib                  3.2.0                     <pip>
opencv-python             4.5.5.62                  <pip>
openssl                   1.1.1m               h7f8727e_0  
packaging                 21.3                      <pip>
pandas                    1.4.1                     <pip>
Pillow                    9.0.1                     <pip>
pip                       21.2.4           py38h06a4308_0  
protobuf                  3.19.4                    <pip>
pyasn1                    0.4.8                     <pip>
pyasn1-modules            0.2.8                     <pip>
pyparsing                 3.0.7                     <pip>
python                    3.8.12               h12debd9_0  
python-dateutil           2.8.2                     <pip>
pytz                      2021.3                    <pip>
PyYAML                    6.0                       <pip>
readline                  8.1.2                h7f8727e_1  
requests                  2.27.1                    <pip>
requests-oauthlib         1.3.1                     <pip>
rsa                       4.8                       <pip>
scipy                     1.8.0                     <pip>
seaborn                   0.11.2                    <pip>
setuptools                58.0.4           py38h06a4308_0  
six                       1.16.0                    <pip>
sqlite                    3.37.2               hc218d9a_0  
tensorboard               2.8.0                     <pip>
tensorboard-data-server   0.6.1                     <pip>
tensorboard-plugin-wit    1.8.1                     <pip>
thop-0.0.31               2005241907                <pip>
tk                        8.6.11               h1ccaba5_0  
torch                     1.10.2                    <pip>
torchvision               0.11.3                    <pip>
tqdm                      4.62.3                    <pip>
typing_extensions         4.1.1                     <pip>
urllib3                   1.26.8                    <pip>
Werkzeug                  2.0.3                     <pip>
wheel                     0.37.1             pyhd3eb1b0_0  
xz                        5.2.5                h7b6447c_0  
zipp                      3.7.0                     <pip>
zlib                      1.2.11               h7f8727e_4  

How can I use Hyperpameter Evolution for my custom data?



### Additional

a Label in my Custom data 
1 0.52 0.921 0.072 0.098

After running Hyperparameters Evolution:

train: weights=yolov5x6.pt, cfg=./models/yolov5x6.yaml, data=OP1_WW.yaml, hyp=./data/hyps/hyp.scratch.yaml, epochs=1, batch_size=1, imgsz=640, rect=False, resume=False, nosave=False, noval=False, noautoanchor=False, evolve=2, bucket=, cache=ram, image_weights=False, device=, multi_scale=False, single_cls=False, optimizer=SGD, sync_bn=False, workers=8, project=runs/train, name=exp, exist_ok=False, quad=False, linear_lr=False, label_smoothing=0.0, patience=100, freeze=[0], save_period=-1, local_rank=-1, entity=None, upload_dataset=False, bbox_interval=-1, artifact_alias=latest
github: skipping check (offline), for updates see https://github.com/ultralytics/yolov5
YOLOv5 🚀 2022-2-8 torch 1.10.2+cu102 CUDA:0 (Tesla V100-SXM2-16GB, 16160MiB)

hyperparameters: lr0=0.001, lrf=0.1, momentum=0.937, weight_decay=0.0005, warmup_epochs=3.0, warmup_momentum=0.8, warmup_bias_lr=0.1, box=0.05, cls=0.5, cls_pw=1.0, obj=1.0, obj_pw=1.0, iou_t=0.2, anchor_t=4.0, anchors=3, fl_gamma=0.0, hsv_h=0.0, hsv_s=0.0, hsv_v=0.0, degrees=0.0, translate=0.0, scale=0.0, shear=0.0, perspective=0.0, flipud=0.0, fliplr=0.0, mosaic=0.0, mixup=0.0, copy_paste=0.0
Weights & Biases: run 'pip install wandb' to automatically track and visualize YOLOv5 🚀 runs (RECOMMENDED)
Overriding model.yaml anchors with anchors=3

                 from  n    params  module                                  arguments                     
  0                -1  1      8800  models.common.Conv                      [3, 80, 6, 2, 2]              
  1                -1  1    115520  models.common.Conv                      [80, 160, 3, 2]               
  2                -1  4    309120  models.common.C3                        [160, 160, 4]                 
  3                -1  1    461440  models.common.Conv                      [160, 320, 3, 2]              
  4                -1  8   2259200  models.common.C3                        [320, 320, 8]                 
  5                -1  1   1844480  models.common.Conv                      [320, 640, 3, 2]              
  6                -1 12  13125120  models.common.C3                        [640, 640, 12]                
  7                -1  1   5531520  models.common.Conv                      [640, 960, 3, 2]              
  8                -1  4  11070720  models.common.C3                        [960, 960, 4]                 
  9                -1  1  11061760  models.common.Conv                      [960, 1280, 3, 2]             
 10                -1  4  19676160  models.common.C3                        [1280, 1280, 4]               
 11                -1  1   4099840  models.common.SPPF                      [1280, 1280, 5]               
 12                -1  1   1230720  models.common.Conv                      [1280, 960, 1, 1]             
 13                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']          
 14           [-1, 8]  1         0  models.common.Concat                    [1]                           
 15                -1  4  11992320  models.common.C3                        [1920, 960, 4, False]         
 16                -1  1    615680  models.common.Conv                      [960, 640, 1, 1]              
 17                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']          
 18           [-1, 6]  1         0  models.common.Concat                    [1]                           
 19                -1  4   5332480  models.common.C3                        [1280, 640, 4, False]         
 20                -1  1    205440  models.common.Conv                      [640, 320, 1, 1]              
 21                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']          
 22           [-1, 4]  1         0  models.common.Concat                    [1]                           
 23                -1  4   1335040  models.common.C3                        [640, 320, 4, False]          
 24                -1  1    922240  models.common.Conv                      [320, 320, 3, 2]              
 25          [-1, 20]  1         0  models.common.Concat                    [1]                           
 26                -1  4   4922880  models.common.C3                        [640, 640, 4, False]          
 27                -1  1   3687680  models.common.Conv                      [640, 640, 3, 2]              
 28          [-1, 16]  1         0  models.common.Concat                    [1]                           
 29                -1  4  11377920  models.common.C3                        [1280, 960, 4, False]         
 30                -1  1   8296320  models.common.Conv                      [960, 960, 3, 2]              
 31          [-1, 12]  1         0  models.common.Concat                    [1]                           
 32                -1  4  20495360  models.common.C3                        [1920, 1280, 4, False]        
 33  [23, 26, 29, 32]  1     67284  models.yolo.Detect                      [2, [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]], [320, 640, 960, 1280]]
Model Summary: 733 layers, 140045044 parameters, 140045044 gradients, 208.3 GFLOPs

Transferred 954/963 items from yolov5x6.pt
Scaled weight_decay = 0.0005
optimizer: SGD with parameter groups 159 weight (no decay), 163 weight, 163 bias
train: Scanning '/yolov5/datasets/OP1_test/labels/train.cache' images and labels... 14 found, 0 missing, 0 empty, 0 corrupt: 100%|██████████████████████| 14/14 [00:00<?, ?it/s]
train: Caching images (0.0GB ram): 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 14/14 [00:00<00:00, 131.07it/s]
val: Scanning '/yolov5/datasets/OP1_test/labels/train.cache' images and labels... 14 found, 0 missing, 0 empty, 0 corrupt: 100%|████████████████████████| 14/14 [00:00<?, ?it/s]

AutoAnchor: 1.71 anchors/target, 0.429 Best Possible Recall (BPR). Anchors are a poor fit to dataset ⚠️, attempting to improve...
AutoAnchor: Running kmeans for 12 anchors on 14 points...
AutoAnchor: ERROR: AutoAnchor: ERROR: scipy.cluster.vq.kmeans requested 12 points but returned only 9
Traceback (most recent call last):
  File "train.py", line 638, in <module>
    main(opt)
  File "train.py", line 616, in main
    results = train(hyp.copy(), opt, device, callbacks)
  File "train.py", line 248, in train
    check_anchors(dataset, model=model, thr=hyp['anchor_t'], imgsz=imgsz)
  File "/yolov5/utils/autoanchor.py", line 55, in check_anchors
    new_bpr = metric(anchors)[0]
  File "/yolov5/utils/autoanchor.py", line 36, in metric
    r = wh[:, None] / k[None]
RuntimeError: The size of tensor a (14) must match the size of tensor b (4) at non-singleton dimension 1
Exception in thread Thread-13:
Traceback (most recent call last):
  File "yolo_2/lib/python3.8/threading.py", line 932, in _bootstrap_inner



Discussion:

Resolving patch:
diff --git a/utils/autoanchor.py b/utils/autoanchor.py
--- a/utils/autoanchor.py
+++ b/utils/autoanchor.py
@@ -1,6 +1,6 @@
 # YOLOv5 🚀 by Ultralytics, GPL-3.0 license
 """
-Auto-anchor utils
+AutoAnchor utils
 """
 
 import random
@@ -81,6 +81,7 @@ def kmean_anchors(dataset='./data/coco128.yaml', n=9, img_size=640, thr=4.0, gen
     """
     from scipy.cluster.vq import kmeans
 
+    npr = np.random
     thr = 1 / thr
 
     def metric(k, wh):  # compute metrics
@@ -121,14 +122,15 @@ def print_results(k, verbose=True):
     if i:
         LOGGER.info(f'{PREFIX}WARNING: Extremely small objects found. {i} of {len(wh0)} labels are < 3 pixels in size.')
     wh = wh0[(wh0 >= 2.0).any(1)]  # filter > 2 pixels
-    # wh = wh * (np.random.rand(wh.shape[0], 1) * 0.9 + 0.1)  # multiply by random scale 0-1
+    # wh = wh * (npr.rand(wh.shape[0], 1) * 0.9 + 0.1)  # multiply by random scale 0-1
 
     # Kmeans calculation
     LOGGER.info(f'{PREFIX}Running kmeans for {n} anchors on {len(wh)} points...')
     s = wh.std(0)  # sigmas for whitening
-    k, dist = kmeans(wh / s, n, iter=30)  # points, mean distance
-    assert len(k) == n, f'{PREFIX}ERROR: scipy.cluster.vq.kmeans requested {n} points but returned only {len(k)}'
-    k *= s
+    k = kmeans(wh / s, n, iter=30)[0] * s  # points
+    if len(k) != n:  # kmeans may return fewer points than requested if wh is insufficient or too similar
+        LOGGER.warning(f'{PREFIX}WARNING: scipy.cluster.vq.kmeans returned only {len(k)} of {n} requested points')
+        k = np.sort(npr.rand(n * 2)).reshape(n, 2) * img_size  # random init
     wh = torch.tensor(wh, dtype=torch.float32)  # filtered
     wh0 = torch.tensor(wh0, dtype=torch.float32)  # unfiltered
     k = print_results(k, verbose=False)
@@ -146,7 +148,6 @@ def print_results(k, verbose=True):
     # fig.savefig('wh.png', dpi=200)
 
     # Evolve
-    npr = np.random
     f, sh, mp, s = anchor_fitness(k), k.shape, 0.9, 0.1  # fitness, generations, mutation prob, sigma
     pbar = tqdm(range(gen), desc=f'{PREFIX}Evolving anchors with Genetic Algorithm:')  # progress bar
     for _ in pbar:


Test patch: