Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The autoanchor result is not same as anchors in model? #6966

Closed
1 task done
PonyPC opened this issue Mar 13, 2022 · 13 comments · Fixed by #7060
Closed
1 task done

The autoanchor result is not same as anchors in model? #6966

PonyPC opened this issue Mar 13, 2022 · 13 comments · Fixed by #7060
Labels
bug Something isn't working question Further information is requested

Comments

@PonyPC
Copy link

PonyPC commented Mar 13, 2022

Search before asking

Question

v6.1
The autoanchor result is not same as anchors in model.
I trained my data with autoanchor, and get this:

�[34m�[1mAutoAnchor: �[0mn=9, img_size=640, metric_all=0.571/0.910-mean/best, past_thr=0.583-mean: 25,97, 95,33, 35,95, 45,90, 86,52, 58,82, 73,68, 52,135, 106,81

After training, I print anchor from model but get:

YOLOv5  2022-2-22 torch 1.8.1+cu111 CPU

tensor([[[ 18.29688,  17.03125],
         [ 12.88281,  33.62500],
         [ 26.46875,  20.29688]],

        [[ 44.90625,  90.37500],
         [ 85.81250,  51.71875],
         [ 58.37500,  81.87500]],

        [[100.62500, 388.50000],
         [381.25000, 132.25000],
         [139.75000, 379.50000]]])

Only P4 same.

Additional

I got the log from models\hub\anchors.yaml but P3/P4/P5/P6 are same:

# P6-640:  thr=0.25: 0.9964 BPR, 5.54 anchors past thr, n=12, img_size=640, metric_all=0.281/0.716-mean/best, past_thr=0.469-mean: 9,11,  21,19,  17,41,  43,32,  39,70,  86,64,  65,131,  134,130,  120,265,  282,180,  247,354,  512,387
anchors_p6_640:
  - [9,11,  21,19,  17,41]  # P3/8
  - [43,32,  39,70,  86,64]  # P4/16
  - [65,131,  134,130,  120,265]  # P5/32
  - [282,180,  247,354,  512,387]  # P6/64

I also print the offical release model yolov5n.pt, both anchors in model and trainning autoanchor prints are same.

Is it normal?

@PonyPC PonyPC added the question Further information is requested label Mar 13, 2022
@PonyPC
Copy link
Author

PonyPC commented Mar 13, 2022

It seems only P4/16 are same.

@zhiqwang
Copy link
Contributor

Hi @PonyPC

Could you try the following method to compute the anchor_grids:

num_anchors = checkpoint_yolov5.model[-1].anchors.shape[1]
anchor_grids = (
    (checkpoint_yolov5.model[-1].anchors * checkpoint_yolov5.model[-1].stride.view(-1, 1, 1))
    .reshape(1, -1, 2 * num_anchors)
    .tolist()[0]
)

@PonyPC
Copy link
Author

PonyPC commented Mar 13, 2022

@zhiqwang Hi, I got same result as above

@zhiqwang
Copy link
Contributor

You show more than one result above, I can't determine which one it is, is it convenient to post a more detailed result?

@PonyPC
Copy link
Author

PonyPC commented Mar 13, 2022

[[18.296875, 17.03125, 12.8828125, 33.625, 26.46875, 20.296875], [44.90625, 90.375, 85.8125, 51.71875, 58.375, 81.875], [100.625, 388.5, 381.25, 132.25, 139.75, 379.5]]

@zhiqwang This is what your code output

@zhiqwang
Copy link
Contributor

Hi @PonyPC

Got it, the result in "anchors.yaml" should be calculated from the coco dataset, I guess the result here is normal. The actual computation will automatically determine the actual anchors computed by the AutoAnchor mechanism:

- [18.296875,17.03125, 12.8828125,33.625, 26.46875,20.296875]  # P3/8
- [44.90625,90.375, 85.8125,51.71875, 58.375,81.875]  # P4/16
- [100.625,388.5, 381.25,132.25, 139.75,379.5  # P5/32

@PonyPC
Copy link
Author

PonyPC commented Mar 13, 2022

@zhiqwang
But autoanchor.py printed is

�[34m�[1mAutoAnchor: �[0mthr=0.25: 1.0000 best possible recall, 8.71 anchors past thr
�[34m�[1mAutoAnchor: �[0mn=9, img_size=640, metric_all=0.571/0.910-mean/best, past_thr=0.583-mean: 25,97, 95,33, 35,95, 45,90, 86,52, 58,82, 73,68, 52,135, 106,81
�[34m�[1mAutoAnchor: �[0mReversing anchor order
�[34m�[1mAutoAnchor: �[0mNew anchors saved to model. Update model *.yaml to use these anchors in the future.

@PonyPC
Copy link
Author

PonyPC commented Mar 13, 2022

I assume it should be past_thr=0.583-mean: 18,17, 13,34, 26,22, 45,90, 86,52, 58,82, 101, 389, 381,132, 140,380
Only P4 same. I tried offical coco model yolov5n.pt, they are same.
As you can see models\hub\anchors.yml is also same.
So I doubt something is wrong with it?

@PonyPC
Copy link
Author

PonyPC commented Mar 13, 2022

@glenn-jocher

@glenn-jocher
Copy link
Member

@PonyPC YOLOv5 🚀 anchors are saved as Detect() layer attributes on model creation, and updated as necessary by AutoAnchor before training starts. Their exact location is here:

self.register_buffer('anchors', torch.tensor(anchors).float().view(self.nl, -1, 2)) # shape(nl,na,2)

You can examine the anchors of any trained YOLOv5 model like this:

Input

import torch

# Model
model = torch.hub.load('ultralytics/yolov5', 'yolov5s', autoshape=False)  # official model
model = torch.hub.load('ultralytics/yolov5', 'custom', 'path/to/best.pt',  autoshape=False)  # custom model

# Anchors
m = model.model.model[-1]  # Detect() layer
print(m.anchors * m.stride.view(-1, 1, 1))  # print anchors

Output

YOLOv5 🚀 2021-11-22 torch 1.10.0+cu111 CUDA:0 (Tesla V100-SXM2-16GB, 16160MiB)
#           x     y
tensor([[[ 10.,  13.],
         [ 16.,  30.],
         [ 33.,  23.]],  # P3/8-small

        [[ 30.,  61.],
         [ 62.,  45.],
         [ 59., 119.]],  # P4/16-medium

        [[116.,  90.],
         [156., 198.],
         [373., 326.]]], dtype=torch.float16)  # P5/32-large

Example

Screenshot 2022-03-14 at 10 37 19

Good luck 🍀 and let us know if you have any other questions!

@PonyPC
Copy link
Author

PonyPC commented Mar 15, 2022

I know what you mean. But there are different in my case which you circled it at last image.
@glenn-jocher

@glenn-jocher
Copy link
Member

glenn-jocher commented Mar 15, 2022

@PonyPC 👋 hi, thanks for letting us know about this possible problem with YOLOv5 🚀. We've created a few short guidelines below to help users provide what we need in order to get started investigating a possible problem.

How to create a Minimal, Reproducible Example

When asking a question, people will be better able to provide help if you provide code that they can easily understand and use to reproduce the problem. This is referred to by community members as creating a minimum reproducible example. Your code that reproduces the problem should be:

  • Minimal – Use as little code as possible to produce the problem
  • Complete – Provide all parts someone else needs to reproduce the problem
  • Reproducible – Test the code you're about to provide to make sure it reproduces the problem

For Ultralytics to provide assistance your code should also be:

  • Current – Verify that your code is up-to-date with GitHub master, and if necessary git pull or git clone a new copy to ensure your problem has not already been solved in master.
  • Unmodified – Your problem must be reproducible using official YOLOv5 code without changes. Ultralytics does not provide support for custom code ⚠️.

If you believe your problem meets all the above criteria, please close this issue and raise a new one using the 🐛 Bug Report template with a minimum reproducible example to help us better understand and diagnose your problem.

Thank you! 😃

@glenn-jocher
Copy link
Member

@PonyPC @zhiqwang good news 😃! Your original issue may now be fixed ✅ in PR #7060.

I investigated AutoAnchor behavior when started with --weights and when starting from scratch with --weights '' --cfg yolov5s.yaml and observed that in the second cases check_anchor_order() was running with grid-space anchors (pixel-space divided by stride) rather than pixel-space anchors. This is a silent-error bug (this is my fault) that may have caused some trainings from scratch to accidentally reverse their anchor order, resulting in lower recall and lower mAP. This should all be resolved now in #7060.

To receive this update:

  • Gitgit pull from within your yolov5/ directory or git clone https://github.com/ultralytics/yolov5 again
  • PyTorch Hub – Force-reload model = torch.hub.load('ultralytics/yolov5', 'yolov5s', force_reload=True)
  • Notebooks – View updated notebooks Open In Colab Open In Kaggle
  • Dockersudo docker pull ultralytics/yolov5:latest to update your image Docker Pulls

Thank you for spotting this issue and informing us of the problem. Please let us know if this update resolves the issue for you, and feel free to inform us of any other issues you discover or feature requests that come to mind. Happy trainings with YOLOv5 🚀!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants