-
Notifications
You must be signed in to change notification settings - Fork 2.5k
support new args.num_classes for custom training, robustly and with full back-compat #89
Conversation
Hi @lessw2020 , Thanks for the PR. On the surface it looks good, however from a design perspective I wonder if it's a good idea to have the number of classes as an extra parameters. |
Thanks for the PR @lessw2020 ! I agree with @alcinos that having a
@lessw2020 how are you using the current dataset, did you implement your own copy of Defining how we want users to use custom datasets is IMO the first thing we should do here. |
Hi @fmassa and @alcinos, One other minor but related point - I've seen a number of people thinking they have to add an additional +1 to their num_classes in order to be compat with DETR's 'no object' class vs DETR auto-handles that:
Two example dataset classes I've seen (and leveraged from) are rwightman and signatrix: and lgvaz has more of a base abstraction concept here: Anyway, definitely agree that if you are able to provide guidelines on how you want users to use custom datasets that would be a big help and supercede the args.num_classes issue here. I also think ideal if you have a base custom dataset class people can leverage off off of / inherit from directly, to let users quickly get going with training and with minimal friction which would implicitly guide how users use custom datasets. Thanks for the consideration re; supporting custom datasets! |
I think once we provide a Detectron2-compatible wrapper around DETR (which should be soon), defining a custom dataset will be delegated to Detectron2 abstractions, so that we won't need to worry about it anymore. Let me know what you think |
Hi @fmassa - having detectron2 integration will be a big plus, but also seems like a lot of unique aspects of DETR might not be exposed well there? DETR is completely unique in terms of core architecture, and how it trains (bs=2 etc), evaluates (eos_coeff, num_queries), etc. and I like the focus on light and efficient code that seems to be effused into DETR codebase. Thus, I would still prefer to see DETR with it's own minimal, lightweight support for custom training and then users can work in either Detectron2 (more simple use) or DETR (lightweight but more customized/specialized) as works best for their use case. I don't think that much net work is needed to do have that in basic form - support num_classes, have a base coco style class to inherit from or copy-modify, and maybe some tweaking tips for training ala coco eval and visualizations (example the attention decoder heatmaps that are unique to DETR)? Anyway, I think with all of DETR's unique arch and features, it still deserves it's own lightweight custom support available. I'm also happy to try and contribute to support basic custom training btw, not just asking you guys to do all the extra work :) |
@@ -29,8 +29,11 @@ def get_args_parser(): | |||
help='gradient clipping max norm') | |||
|
|||
# Model parameters | |||
parser.add_argument('--num_classes', type=int, default=20, | |||
help="Number of classes in your dataset. Overridden by coco and coco_panoptic datasets") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than "number of classes in your dataset", maybe specify that:
- it is the
max_class_id
(actually, maybe wrong), - or is it
max_class_id+1
? Confusion about num_classes #108 (comment)
This PR attempts to cleanly integrate a new args.num_classes support for custom datasets while keeping full backwards compatibility.
1 - a new args.num_classes is made in main.py, with a default of 20 for backward compat with previous code in detr::build(args) which defaulted to 20.
2 - detr::build(args) is updated to safely check for the presence of a args.num_classes. If found that num_classes is used.
If not present, num_classes is set to 20, as before.
{ I wrappered this check for args.num_classes in a try/except block because likely people already have modified main.py scripts (I did) that won't have args.num_classes present.
I tested and found that checking for args.num_classes is None, my first instinct, will throw an exception if args.num_classes does not exist, hence the try/except block is required.. }
3 - datasets coco and coco_panoptic are checked via args.dataset_file as previously, and num_classes is over-ridden if so and set as before.