-
Notifications
You must be signed in to change notification settings - Fork 1
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
Generate NN archive from training configs #17
Conversation
Test Results 6 files 6 suites 54m 2s ⏱️ Results for commit e4ca5bf. ♻️ This comment has been updated with latest results. |
Any ideas why are we getting all these import errors during the checks? Adding the missing packages to the |
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.
Nice, thank you! Just adding some comments for now since there's some questions to sort out. Will reply to those separately.
luxonis_train/core/archiver.py
Outdated
# head_outputs["prototype_output_name"] # TODO: implement | ||
elif head_name == "ObjectDetectionSSD": | ||
raise NotImplementedError | ||
# head_outputs["anchors"] # TODO: implement |
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.
I don't think we support any architectures that will require anchors at the moment, just FYI
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.
ImplicitKeypointBBoxHead
head does require anchors.
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.
Ah thanks for pointing that out. Actually need to make a change to NN archive then
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.
(But realizing I need all the object detection parameters in the keypoint head anyways in NN archive)
luxonis_train/core/archiver.py
Outdated
elif head_name == "BiSeNetHead": | ||
parameters["is_softmax"] = self._is_softmax(executable_path) # TODO: test | ||
elif head_name == "ImplicitKeypointBBoxHead": | ||
raise NotImplementedError |
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.
I think we should be able to implement this one now with latest updates. The ONNX for ImplicitKeypointBBoxHead
should just have one output, which will be predictions
in NN archive.
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.
adding support in commit 3c0ddc3
luxonis_train/core/archiver.py
Outdated
|
||
model = onnx.load(executable_path) | ||
for node in model.graph.node: | ||
if node.op_type.lower() == "softmax": |
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.
Yeah I'm not sure if this is a good general solution. I think it could just be hardcoded based on the classification or segmentation head. Unless it also becomes a training config options, then we could pull it from there (CC @kozlov721)
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.
We could run the ONNX model and check that the outputs sum to 1. It's also not an optimal solution though.
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.
Yeah that's not a bad idea either. I think we could hardcode into each classification/segmentation head to keep it simple for now though
luxonis_train/core/archiver.py
Outdated
elif head_name == "ObjectDetectionSSD": | ||
raise NotImplementedError # TODO: boxes, scores |
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.
Yeah I'm not sure we even need this case for SSD right now since AFAIK we don't have MobileNet SSD implemented in this library
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.
removing support in commit 87bd9b2
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.
I also confirmed with @tersekmatija by the way that we don't have plans of supporting MobileNet SSD in luxonis-train
luxonis_train/core/archiver.py
Outdated
elif head_name == "SegmentationHead": | ||
raise NotImplementedError # TODO: predictions | ||
elif head_name == "BiSeNetHead": | ||
raise NotImplementedError | ||
elif head_name == "ImplicitKeypointBBoxHead": | ||
raise NotImplementedError |
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.
Just noting we'll also want to implement these once questions are answered
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.
adding support in commit 04bc590
yaml_file.write(yaml_str) | ||
|
||
# make model | ||
model = torchvision.models.mobilenet_v2(pretrained=False) |
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.
I think it would make sense to use ONNX from luxonis-train instead of torchvision. It's not critical or anything, so we don't necessarily need to make the change in this PR, but I'd say the primary goal is that we want to make sure all the heads in luxonis-train can correspond to heads in NN archive.
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.
I agree, will look into it!
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.
added in commit 5e59c3a. For now, all tests are based on ClassificationModel. Later, we can extend tests for all other models.
I think this is because you |
In my opinion we only need to support ONNX, especially for now. We might still need to address the secondary executable path issue for ONNX as well, but since we don't have the instance segmentation model implemented at the moment, I wouldn't worry about it in this PR. |
Yeah I left another comment for this but in my opinion it can either be |
yolo_outputs: Yes, I think is it sensible to expect that all outputs of the model always belong here. predictions: Yeah this is the "default" configuration in NN archive where there is only one ONNX output. I think it's safe to assume only one ONNX output in this case. boxes and scores: Let's not worry about this for now since it's not implemented in luxonis-train. |
Yeah this seems good to me. It will be nice to also add tests for each type of head in luxonis-train once other questions are resolved. |
|
I've added |
You're right, seems you accidentally removed the |
☂️ Python Coverage
Overall Coverage
New Files
Modified Files
|
Based on the discussion above, two things remain unresolved:
I’d go for the option 1 for now as we could simply implement it by adding a simple enum like:
What do you think @kozlov721
If I understand correctly, tests should generate a model for each of the existing heads (ClassificationHead, SegmentationHead, BiSeNetHead, EfficientBBoxHead, ImplicitKeypointBBoxHead) and test if head parameters (also |
Yeah this is what I meant. |
I've resolved all the comments from above except adding tests for for each of the existing heads (will be added in a separate PR). We can merge as soon as @kozlov721 approves! |
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.
LGTM
* add archiver CLI * add archiver callback * add max_det parameter to EfficientBBoxHead * add enum to categorize tasks for the implemented heads * add archiver tests * adjust Archiver to new nn archive format * pre-comit formatting * add LDF creation and adjust to new nn archive format * update requirements.txt * add opencv-python to requirements.txt * add support for ImplicitKeypointBBoxHead * remove support for ObjectDetectionSSD * Update requirements.txt * Added mlflow and removed opencv * [Automated] Updated coverage badge * add support for SegmentationHead and BiSeNetHead * base archiver tests on model from luxonis-train instead of torchvision * adjust head parameters to changes in NN Archive * adjust keypoint detection head parameters to changes in NN Archive * bugfix - make sure self.max_det is used in nms * add max_det parameter to ImplicitKeypointBBoxHead * adjust task categorization for ImplicitKeypointBBoxHead * fixing Windows PermissionError occuring on file deletion * fixing Windows PermissionError occuring on file deletion due to unreleased logging handlers * add method to remove file handlers keeping the log file open * add a logging statement at the end of archiving * add optuna_integration to requirements.txt * add hard-coded solution to determining is_softmax parameter * added help --------- Co-authored-by: Martin Kozlovský <[email protected]> Co-authored-by: GitHub Actions <[email protected]>
This PR introduces a new generator class (
luxonis_train.core.Archiver
) enabling automatic generation of NN archives from training configs. This functionality is exposed both through a command-line interface (CLI) and callbacks (with uploading the NN archive to MLFlow). Furthermore, basic test coverage is included to ensure correctness of generation.The added features are functional but there are still a few open issues so any insights or suggestions regarding the current implementation would be greatly appreciated!
Open issues:
Metadata
class requires a single path to the model executable so I'm not sure what to do in case of multiple)?HeadClassification
class): Currently, decision if output is already softmaxed is based on iterating ONNX nodes and checking if there is a node named softmax. However, I'm not sure how bulletproof is that and if it is implementable for other model formats. Is there some other way to determine this parameter (OR should maybe even be hard-coded for specific architectures)?yolo_outputs
parameter inEfficientBBoxHead
. Is it sensible to expect that all outputs of the model always belong here? If not, how to determine the outputs to be listed?predictions
parameter inClassificationHead
. Is it sensible to expect that models withClassificationHead
will always only have one output? If not, how to determine which of the outputs is the right one?boxes
andscores
parameters inObjectDetectionSSD
. How to determine which output belongs to which parameter for an arbitrary SSD network?