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

Exporting yolo models does not include Class Labels #43

Open
gustavofuhr opened this issue Jul 10, 2024 · 15 comments
Open

Exporting yolo models does not include Class Labels #43

gustavofuhr opened this issue Jul 10, 2024 · 15 comments

Comments

@gustavofuhr
Copy link

Hello, thanks for this project, it's very useful.

I tried to export the models using the following code:

from ultralytics import YOLO

model_name = "yolov8n"

# Load a model
model = YOLO("yolov8n.pt")  # load an official model

# Export the model
model.export(format="coreml",  int8=True, nms=True, imgsz=[640, 384])

that did work, but when using it on the app, it fails in the following:

guard let classLabels = mlModel.modelDescription.classLabels as? [String] else {
    fatalError("Class labels are missing from the model description")
}

I verified the model and it turns out that the exported model does not include anymore the classLabels as the models in the current release. There is some option in model.export to include classLabels or maybe it's possible to read names from the model's additional metadata?

@pderrenger
Copy link
Member

@gustavofuhr hello,

Thank you for your kind words and for using our project! 😊

Regarding your issue with exporting YOLO models and missing class labels, it appears that the class labels are not being included in the exported model's metadata. Unfortunately, the current export functionality does not automatically include class labels in the exported model's metadata.

However, you can manually add the class labels to the model's metadata before exporting. Here’s an example of how you can achieve this:

from ultralytics import YOLO

# Load a model
model = YOLO("yolov8n.pt")  # load an official model

# Define class labels
class_labels = ["class1", "class2", "class3", ...]  # replace with your actual class labels

# Add class labels to model's metadata
model.names = class_labels

# Export the model with the updated metadata
model.export(format="coreml", int8=True, nms=True, imgsz=[640, 384])

This way, the class labels will be included in the exported model's metadata, and you should be able to access them in your app as expected.

If you continue to experience issues, please ensure you are using the latest version of the Ultralytics package. If the problem persists, providing a minimum reproducible example would be very helpful for us to diagnose the issue further. You can find more information on creating a reproducible example here: Minimum Reproducible Example.

Feel free to reach out if you have any more questions or need further assistance!

@VladKovalski
Copy link

@pderrenger Hi,
Have the same problem with yolov8xobb export to coreml.
I try you solution but have error in Visual Studio Code:
AttributeError: can't set attribute 'names'

How to fix that ? plese help

@pderrenger
Copy link
Member

Hi @VladKovalski,

To fix the error, ensure you're setting model.names directly after loading the model. If the issue persists, please verify you're using the latest version of the Ultralytics package. Let me know if you need further assistance!

@hydra1983
Copy link

hydra1983 commented Dec 15, 2024

@pderrenger

for code below

from ultralytics import YOLO

class_labels = ["person", "bicycle", "car", "motorcycle", "airplane", "bus", "train",
                "truck", "boat", "traffic light", "fire hydrant", "stop sign",
                "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep",
                "cow", "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella",
                "handbag", "tie", "suitcase", "frisbee", "skis", "snowboard", "sports ball",
                "kite", "baseball bat", "baseball glove", "skateboard", "surfboard",
                "tennis racket", "bottle", "wine glass", "cup", "fork", "knife",
                "spoon", "bowl", "banana", "apple", "sandwich", "orange", "broccoli",
                "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch",
                "potted plant", "bed", "dining table", "toilet", "TV", "laptop",
                "mouse", "remote", "keyboard", "cell phone", "microwave", "oven",
                "toaster", "sink", "refrigerator", "book", "clock", "vase",
                "scissors", "teddy bear", "hair drier", "toothbrush"]

# Export all YOLOv8 models to CoreML INT8
for size in ("n", "s", "m", "l", "x"):  # all YOLOv8 model sizes
    model = YOLO(f"Models/Original/yolo11{size}.pt")
    model.names = class_labels
    model.export(format="coreml", verbose=True)

print("All models have been successfully exported with updated class labels.")

it reports

/yolov11-iphone/lib/python3.10/site-packages/torch/nn/modules/module.py", line 2032, in __setattr__
    super().__setattr__(name, value)
AttributeError: can't set attribute 'names'
python --version                                                                                                                                                       ─╯
Python 3.10.13
pip list                                                                                                                                                               ─╯
Package            Version
------------------ -----------
attrs              24.2.0
cattrs             24.1.2
certifi            2024.12.14
charset-normalizer 3.4.0
contourpy          1.3.1
coremltools        8.1
cycler             0.12.1
exceptiongroup     1.2.2
filelock           3.16.1
fonttools          4.55.3
fsspec             2024.10.0
idna               3.10
Jinja2             3.1.4
joblib             1.4.2
kiwisolver         1.4.7
markdown-it-py     3.0.0
MarkupSafe         3.0.2
matplotlib         3.10.0
mdurl              0.1.2
mpmath             1.3.0
networkx           3.4.2
numpy              1.26.4
onnx               1.17.0
onnxsim            0.4.36
opencv-python      4.10.0.84
packaging          24.2
pandas             2.2.3
pillow             11.0.0
pip                23.0.1
protobuf           5.29.1
psutil             6.1.0
py-cpuinfo         9.0.0
pyaml              24.12.1
Pygments           2.18.0
pyparsing          3.2.0
python-dateutil    2.9.0.post0
pytz               2024.2
PyYAML             6.0.2
requests           2.32.3
rich               13.9.4
scikit-learn       1.6.0
scipy              1.14.1
seaborn            0.13.2
setuptools         65.5.0
six                1.17.0
sympy              1.13.1
threadpoolctl      3.5.0
torch              2.5.1
torchvision        0.20.1
tqdm               4.67.1
typing_extensions  4.12.2
tzdata             2024.2
ultralytics        8.3.49
ultralytics-thop   2.0.13
urllib3            2.2.3

@pderrenger
Copy link
Member

It seems you're encountering the error because model.names is a read-only property and cannot be directly modified. Instead, you should update the model's names metadata through its data attribute. Here's how you can fix the issue:

from ultralytics import YOLO

class_labels = ["person", "bicycle", "car", "motorcycle", "airplane", "bus", "train",
                "truck", "boat", "traffic light", "fire hydrant", "stop sign",
                "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep",
                "cow", "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella",
                "handbag", "tie", "suitcase", "frisbee", "skis", "snowboard", "sports ball",
                "kite", "baseball bat", "baseball glove", "skateboard", "surfboard",
                "tennis racket", "bottle", "wine glass", "cup", "fork", "knife",
                "spoon", "bowl", "banana", "apple", "sandwich", "orange", "broccoli",
                "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch",
                "potted plant", "bed", "dining table", "toilet", "TV", "laptop",
                "mouse", "remote", "keyboard", "cell phone", "microwave", "oven",
                "toaster", "sink", "refrigerator", "book", "clock", "vase",
                "scissors", "teddy bear", "hair drier", "toothbrush"]

# Export all YOLOv8 models to CoreML INT8
for size in ("n", "s", "m", "l", "x"):  # all YOLOv8 model sizes
    model = YOLO(f"Models/Original/yolo11{size}.pt")
    model.overrides['names'] = class_labels  # Update class labels
    model.export(format="coreml", verbose=True)

print("All models have been successfully exported with updated class labels.")

This approach ensures the labels are properly updated before exporting. If the issue persists, ensure you're using the latest version of the ultralytics package (pip install -U ultralytics). Let me know if you have further questions!

@hydra1983
Copy link

It seems you're encountering the error because model.names is a read-only property and cannot be directly modified. Instead, you should update the model's names metadata through its data attribute. Here's how you can fix the issue:

from ultralytics import YOLO

class_labels = ["person", "bicycle", "car", "motorcycle", "airplane", "bus", "train",
                "truck", "boat", "traffic light", "fire hydrant", "stop sign",
                "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep",
                "cow", "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella",
                "handbag", "tie", "suitcase", "frisbee", "skis", "snowboard", "sports ball",
                "kite", "baseball bat", "baseball glove", "skateboard", "surfboard",
                "tennis racket", "bottle", "wine glass", "cup", "fork", "knife",
                "spoon", "bowl", "banana", "apple", "sandwich", "orange", "broccoli",
                "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch",
                "potted plant", "bed", "dining table", "toilet", "TV", "laptop",
                "mouse", "remote", "keyboard", "cell phone", "microwave", "oven",
                "toaster", "sink", "refrigerator", "book", "clock", "vase",
                "scissors", "teddy bear", "hair drier", "toothbrush"]

# Export all YOLOv8 models to CoreML INT8
for size in ("n", "s", "m", "l", "x"):  # all YOLOv8 model sizes
    model = YOLO(f"Models/Original/yolo11{size}.pt")
    model.overrides['names'] = class_labels  # Update class labels
    model.export(format="coreml", verbose=True)

print("All models have been successfully exported with updated class labels.")

This approach ensures the labels are properly updated before exporting. If the issue persists, ensure you're using the latest version of the ultralytics package (pip install -U ultralytics). Let me know if you have further questions!

got an error again

python main.py                                                                                                                                                                                                  ─╯
Traceback (most recent call last):
  File "/Users/edison/Downloads/RTObjRec/main.py", line 21, in <module>
    model.export(format="coreml", verbose=True)
  File "/Users/edison/.pyenv/versions/yolov11-iphone/lib/python3.10/site-packages/ultralytics/engine/model.py", line 738, in export
    return Exporter(overrides=args, _callbacks=self.callbacks)(model=self.model)
  File "/Users/edison/.pyenv/versions/yolov11-iphone/lib/python3.10/site-packages/ultralytics/engine/exporter.py", line 169, in __init__
    self.args = get_cfg(cfg, overrides)
  File "/Users/edison/.pyenv/versions/yolov11-iphone/lib/python3.10/site-packages/ultralytics/cfg/__init__.py", line 297, in get_cfg
    check_dict_alignment(cfg, overrides)
  File "/Users/edison/.pyenv/versions/yolov11-iphone/lib/python3.10/site-packages/ultralytics/cfg/__init__.py", line 485, in check_dict_alignment
    raise SyntaxError(string + CLI_HELP_MSG) from e
SyntaxError: 'names' is not a valid YOLO argument. Similar arguments are i.e. ['name', 'nms=False'].

    Arguments received: ['yolo']. Ultralytics 'yolo' commands use the following syntax:

        yolo TASK MODE ARGS

        Where   TASK (optional) is one of {'classify', 'detect', 'segment', 'obb', 'pose'}
                MODE (required) is one of {'train', 'track', 'predict', 'val', 'export', 'benchmark'}
                ARGS (optional) are any number of custom 'arg=value' pairs like 'imgsz=320' that override defaults.
                    See all ARGS at https://docs.ultralytics.com/usage/cfg or with 'yolo cfg'

    1. Train a detection model for 10 epochs with an initial learning_rate of 0.01
        yolo train data=coco8.yaml model=yolo11n.pt epochs=10 lr0=0.01

    2. Predict a YouTube video using a pretrained segmentation model at image size 320:
        yolo predict model=yolo11n-seg.pt source='https://youtu.be/LNwODJXcvt4' imgsz=320

    3. Val a pretrained detection model at batch-size 1 and image size 640:
        yolo val model=yolo11n.pt data=coco8.yaml batch=1 imgsz=640

    4. Export a YOLO11n classification model to ONNX format at image size 224 by 128 (no TASK required)
        yolo export model=yolo11n-cls.pt format=onnx imgsz=224,128

    5. Streamlit real-time webcam inference GUI
        yolo streamlit-predict

    6. Ultralytics solutions usage
        yolo solutions count or in ['heatmap', 'queue', 'speed', 'workout', 'analytics', 'trackzone'] source="path/to/video/file.mp4"

    7. Run special commands:
        yolo help
        yolo checks
        yolo version
        yolo settings
        yolo copy-cfg
        yolo cfg
        yolo solutions help

    Docs: https://docs.ultralytics.com
    Solutions: https://docs.ultralytics.com/solutions/
    Community: https://community.ultralytics.com
    GitHub: https://github.com/ultralytics/ultralytics
    ```

@pderrenger
Copy link
Member

The error occurs because names is not a valid argument in the overrides dictionary for the export method. Instead, you should update the model's names metadata through its model.names attribute (which is a dict) before exporting.

Here's the corrected approach:

from ultralytics import YOLO

class_labels = ["person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light",
                "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow",
                "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee",
                "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard",
                "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple",
                "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch",
                "potted plant", "bed", "dining table", "toilet", "TV", "laptop", "mouse", "remote", "keyboard",
                "cell phone", "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase",
                "scissors", "teddy bear", "hair drier", "toothbrush"]

# Export all YOLOv8 models to CoreML INT8
for size in ("n", "s", "m", "l", "x"):  # all YOLOv8 model sizes
    model = YOLO(f"Models/Original/yolo11{size}.pt")
    model.model.names = {i: name for i, name in enumerate(class_labels)}  # Update the class labels
    model.export(format="coreml", verbose=True)

print("All models have been successfully exported with updated class labels.")

This updates the model.names attribute directly and ensures compatibility during the export process. If the issue persists, confirm you are using the latest ultralytics package version (pip install -U ultralytics). Let me know if you have further concerns!

@hydra1983
Copy link

The error occurs because names is not a valid argument in the overrides dictionary for the export method. Instead, you should update the model's names metadata through its model.names attribute (which is a dict) before exporting.

Here's the corrected approach:

from ultralytics import YOLO

class_labels = ["person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light",
                "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow",
                "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee",
                "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard",
                "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple",
                "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch",
                "potted plant", "bed", "dining table", "toilet", "TV", "laptop", "mouse", "remote", "keyboard",
                "cell phone", "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase",
                "scissors", "teddy bear", "hair drier", "toothbrush"]

# Export all YOLOv8 models to CoreML INT8
for size in ("n", "s", "m", "l", "x"):  # all YOLOv8 model sizes
    model = YOLO(f"Models/Original/yolo11{size}.pt")
    model.model.names = {i: name for i, name in enumerate(class_labels)}  # Update the class labels
    model.export(format="coreml", verbose=True)

print("All models have been successfully exported with updated class labels.")

This updates the model.names attribute directly and ensures compatibility during the export process. If the issue persists, confirm you are using the latest ultralytics package version (pip install -U ultralytics). Let me know if you have further concerns!

Cool! it's working, thank you so much.

@hydra1983
Copy link

hydra1983 commented Dec 17, 2024

However, it seems the models still has no classLabels included.

python main.py                                                                                                                                                       ─╯
Ultralytics 8.3.49 🚀 Python-3.10.13 torch-2.5.1 CPU (Apple M1 Max)
YOLO11n summary (fused): 238 layers, 2,616,248 parameters, 0 gradients, 6.5 GFLOPs

PyTorch: starting from 'Models/Original/yolo11n.pt' with input shape (1, 3, 640, 640) BCHW and output shape(s) (1, 84, 8400) (5.4 MB)
scikit-learn version 1.6.0 is not supported. Minimum required version: 0.17. Maximum required version: 1.5.1. Disabling scikit-learn conversion API.
Torch version 2.5.1 has not been tested with coremltools. You may run into unexpected errors. Torch 2.4.0 is the most recent version that has been tested.

CoreML: starting export with coremltools 8.1...
Converting PyTorch Frontend ==> MIL Ops: 100%|██████████████████████████████████████████████████████████████████████████████████████▉| 791/792 [00:00<00:00, 5783.77 ops/s]
Running MIL frontend_pytorch pipeline: 100%|███████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<00:00, 105.77 passes/s]
Running MIL default pipeline: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████| 89/89 [00:01<00:00, 72.29 passes/s]
Running MIL backend_mlprogram pipeline: 100%|████████████████████████████████████████████████████████████████████████████████████████| 12/12 [00:00<00:00, 107.03 passes/s]
CoreML: export success ✅ 12.0s, saved as 'Models/Original/yolo11n.mlpackage' (5.2 MB)

Export complete (12.4s)
Results saved to /Users/edison/Downloads/RTObjRec/Models/Original
Predict:         yolo predict task=detect model=Models/Original/yolo11n.mlpackage imgsz=640  
Validate:        yolo val task=detect model=Models/Original/yolo11n.mlpackage imgsz=640 data=/usr/src/ultralytics/ultralytics/cfg/datasets/coco.yaml  
Visualize:       https://netron.app
Ultralytics 8.3.49 🚀 Python-3.10.13 torch-2.5.1 CPU (Apple M1 Max)
YOLO11s summary (fused): 238 layers, 9,443,760 parameters, 0 gradients, 21.5 GFLOPs

PyTorch: starting from 'Models/Original/yolo11s.pt' with input shape (1, 3, 640, 640) BCHW and output shape(s) (1, 84, 8400) (18.4 MB)

CoreML: starting export with coremltools 8.1...
Converting PyTorch Frontend ==> MIL Ops: 100%|██████████████████████████████████████████████████████████████████████████████████████▉| 794/795 [00:00<00:00, 4915.95 ops/s]
Running MIL frontend_pytorch pipeline: 100%|████████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<00:00, 95.42 passes/s]
Running MIL default pipeline: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████| 89/89 [00:01<00:00, 57.74 passes/s]
Running MIL backend_mlprogram pipeline: 100%|█████████████████████████████████████████████████████████████████████████████████████████| 12/12 [00:00<00:00, 99.76 passes/s]
CoreML: export success ✅ 10.9s, saved as 'Models/Original/yolo11s.mlpackage' (18.2 MB)

Export complete (11.2s)
Results saved to /Users/edison/Downloads/RTObjRec/Models/Original
Predict:         yolo predict task=detect model=Models/Original/yolo11s.mlpackage imgsz=640  
Validate:        yolo val task=detect model=Models/Original/yolo11s.mlpackage imgsz=640 data=/usr/src/ultralytics/ultralytics/cfg/datasets/coco.yaml  
Visualize:       https://netron.app
Ultralytics 8.3.49 🚀 Python-3.10.13 torch-2.5.1 CPU (Apple M1 Max)
YOLO11m summary (fused): 303 layers, 20,091,712 parameters, 0 gradients, 68.0 GFLOPs

PyTorch: starting from 'Models/Original/yolo11m.pt' with input shape (1, 3, 640, 640) BCHW and output shape(s) (1, 84, 8400) (38.8 MB)

CoreML: starting export with coremltools 8.1...
Converting PyTorch Frontend ==> MIL Ops: 100%|██████████████████████████████████████████████████████████████████████████████████████▉| 958/959 [00:00<00:00, 5619.36 ops/s]
Running MIL frontend_pytorch pipeline: 100%|████████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<00:00, 80.97 passes/s]
Running MIL default pipeline: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████| 89/89 [00:02<00:00, 41.75 passes/s]
Running MIL backend_mlprogram pipeline: 100%|█████████████████████████████████████████████████████████████████████████████████████████| 12/12 [00:00<00:00, 80.52 passes/s]
CoreML: export success ✅ 13.8s, saved as 'Models/Original/yolo11m.mlpackage' (38.6 MB)

Export complete (14.3s)
Results saved to /Users/edison/Downloads/RTObjRec/Models/Original
Predict:         yolo predict task=detect model=Models/Original/yolo11m.mlpackage imgsz=640  
Validate:        yolo val task=detect model=Models/Original/yolo11m.mlpackage imgsz=640 data=/ultralytics/ultralytics/cfg/datasets/coco.yaml  
Visualize:       https://netron.app
Ultralytics 8.3.49 🚀 Python-3.10.13 torch-2.5.1 CPU (Apple M1 Max)
YOLO11l summary (fused): 464 layers, 25,340,992 parameters, 0 gradients, 86.9 GFLOPs

PyTorch: starting from 'Models/Original/yolo11l.pt' with input shape (1, 3, 640, 640) BCHW and output shape(s) (1, 84, 8400) (49.0 MB)

CoreML: starting export with coremltools 8.1...
Converting PyTorch Frontend ==> MIL Ops: 100%|████████████████████████████████████████████████████████████████████████████████████▉| 1379/1380 [00:00<00:00, 4108.59 ops/s]
Running MIL frontend_pytorch pipeline: 100%|████████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<00:00, 51.02 passes/s]
Running MIL default pipeline: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████| 89/89 [00:02<00:00, 30.06 passes/s]
Running MIL backend_mlprogram pipeline: 100%|█████████████████████████████████████████████████████████████████████████████████████████| 12/12 [00:00<00:00, 52.72 passes/s]
CoreML: export success ✅ 20.1s, saved as 'Models/Original/yolo11l.mlpackage' (48.7 MB)

Export complete (20.9s)
Results saved to /Users/edison/Downloads/RTObjRec/Models/Original
Predict:         yolo predict task=detect model=Models/Original/yolo11l.mlpackage imgsz=640  
Validate:        yolo val task=detect model=Models/Original/yolo11l.mlpackage imgsz=640 data=/ultralytics/ultralytics/cfg/datasets/coco.yaml  
Visualize:       https://netron.app
Ultralytics 8.3.49 🚀 Python-3.10.13 torch-2.5.1 CPU (Apple M1 Max)
YOLO11x summary (fused): 464 layers, 56,919,424 parameters, 0 gradients, 194.9 GFLOPs

PyTorch: starting from 'Models/Original/yolo11x.pt' with input shape (1, 3, 640, 640) BCHW and output shape(s) (1, 84, 8400) (109.3 MB)

CoreML: starting export with coremltools 8.1...
Converting PyTorch Frontend ==> MIL Ops: 100%|████████████████████████████████████████████████████████████████████████████████████▉| 1379/1380 [00:00<00:00, 3972.23 ops/s]
Running MIL frontend_pytorch pipeline: 100%|████████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<00:00, 45.61 passes/s]
Running MIL default pipeline: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████| 89/89 [00:03<00:00, 24.86 passes/s]
Running MIL backend_mlprogram pipeline: 100%|█████████████████████████████████████████████████████████████████████████████████████████| 12/12 [00:00<00:00, 58.94 passes/s]
CoreML: export success ✅ 22.5s, saved as 'Models/Original/yolo11x.mlpackage' (108.9 MB)

Export complete (23.7s)
Results saved to /Users/edison/Downloads/RTObjRec/Models/Original
Predict:         yolo predict task=detect model=Models/Original/yolo11x.mlpackage imgsz=640  
Validate:        yolo val task=detect model=Models/Original/yolo11x.mlpackage imgsz=640 data=/ultralytics/ultralytics/cfg/datasets/coco.yaml  
Visualize:       https://netron.app
All models have been successfully exported with updated class labels.
image image image

@dev-xdyang
Copy link

dev-xdyang commented Dec 17, 2024

The error occurs because names is not a valid argument in the overrides dictionary for the export method. Instead, you should update the model's names metadata through its model.names attribute (which is a dict) before exporting.

Here's the corrected approach:

from ultralytics import YOLO

class_labels = ["person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light",
                "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow",
                "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee",
                "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard",
                "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple",
                "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch",
                "potted plant", "bed", "dining table", "toilet", "TV", "laptop", "mouse", "remote", "keyboard",
                "cell phone", "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase",
                "scissors", "teddy bear", "hair drier", "toothbrush"]

# Export all YOLOv8 models to CoreML INT8
for size in ("n", "s", "m", "l", "x"):  # all YOLOv8 model sizes
    model = YOLO(f"Models/Original/yolo11{size}.pt")
    model.model.names = {i: name for i, name in enumerate(class_labels)}  # Update the class labels
    model.export(format="coreml", verbose=True)

print("All models have been successfully exported with updated class labels.")

This updates the model.names attribute directly and ensures compatibility during the export process. If the issue persists, confirm you are using the latest ultralytics package version (pip install -U ultralytics). Let me know if you have further concerns!

The above script could export Yolov8 models succ with class labels, but when export yolo11 models, still not have class labels

@john-rocky
Copy link
Contributor

john-rocky commented Dec 17, 2024

@hydra1983
@dev-xdyang

To add class labels to a CoreML Yolo Detection model,, please add nms (Non Max Suppression) to your CoreML model when exporting, which will automatically add the class labels as well.

for size in ("n", "s", "m", "l", "x"):  # all YOLOv8 model sizes
    model = YOLO(f"yolo11{size}.pt")
    model.export(format="coreml", nms=True) # please add nms=True

@hydra1983
Copy link

hydra1983 commented Dec 17, 2024

@hydra1983 @dev-xdyang

To add class labels to a CoreML Yolo Detection model,, please add nms (Non Max Suppression) to your CoreML model when exporting, which will automatically add the class labels as well.

for size in ("n", "s", "m", "l", "x"):  # all YOLOv8 model sizes
    model = YOLO(f"yolo11{size}.pt")
    model.export(format="coreml", nms=True) # please add nms=True

It's fixed! thank both of you @john-rocky, @pderrenger!

the final lines are below:

from ultralytics import YOLO

class_labels = ["person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light",
                "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow",
                "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee",
                "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard",
                "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple",
                "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch",
                "potted plant", "bed", "dining table", "toilet", "TV", "laptop", "mouse", "remote", "keyboard",
                "cell phone", "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase",
                "scissors", "teddy bear", "hair drier", "toothbrush"]

# Export all YOLOv11 models to CoreML INT8
for size in ("n", "s", "m", "l", "x"):  # all YOLOv8 model sizes
    model = YOLO(f"Models/Original/yolo11{size}.pt")
    model.model.names = {i: name for i, name in enumerate(class_labels)}  # Update the class labels
    model.export(format="mlpackage", verbose=True, nms=True)

print("All models have been successfully exported with updated class labels.")

@pderrenger
Copy link
Member

Glad to hear it worked for you! Adding nms=True is indeed the key to including class labels in the exported CoreML models. Thanks for sharing your final solution—it will surely help others in the community. If you encounter any further issues, feel free to reach out. Great work!

@dev-xdyang
Copy link

It works after I update Ultralytics to 8.3.50 . My environment is Python-3.8.20 torch-2.4.1 CPU (Apple M1 Pro).

@pderrenger
Copy link
Member

Great to hear it's working now! If you run into any other issues, feel free to reach out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants