ultralytics / yolov3

YOLOv3 in PyTorch > ONNX > CoreML > TFLite
https://docs.ultralytics.com
GNU Affero General Public License v3.0
10.18k stars 3.44k forks source link

How can I convert best.pt to best.weights? #1645

Closed cyberclone12 closed 3 years ago

cyberclone12 commented 3 years ago

❔Question

I believe in archieve we can do that using 'python3 -c "from models import *; convert('cfg/yolov3-1cls.cfg', 'best.pt')"' But how can we do that in the main repo? I mean in the main branch that takes yaml? Please help

Additional context

glenn-jocher commented 3 years ago

@cyberclone12 no, master branch is not backwards compatible with darknet weights.

BRANCH NOTICE: The ultralytics/yolov3 repository is now divided into two branches:

WANGCHAO1996 commented 3 years ago

Hello, can the model trained by yolov3 (with.cfg file) in previous version be exported using export.py?@glenn-jocher

glenn-jocher commented 3 years ago

@WANGCHAO1996 archive branch and master branch are separate and not cross compatible.

WANGCHAO1996 commented 3 years ago

ch and master branch

Hello, my yolov3 is master, but it is the version of a month ago, and there is.cfg file, is that OK

glenn-jocher commented 3 years ago

@WANGCHAO1996 master branch does not use *.cfg files, only archive branch.

glenn-jocher commented 3 years ago

.cfg files have been replaced in master with newer and better .yaml files.

ardeal commented 3 years ago

with the following python code to convert pt file to onnx file. I am experiencing the following issue:

Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\site-packages\torch\onnx\utils.py", line 632, in _export
    _model_to_graph(model, args, verbose, input_names,
  File "C:\ProgramData\Anaconda3\lib\site-packages\torch\onnx\utils.py", line 449, in _model_to_graph
    params_dict = torch._C._jit_pass_onnx_constant_fold(graph, params_dict,
RuntimeError: Input, output and indices must be on the current device
from __future__ import print_function
import os
import datetime
from models.yolo import *
import numpy as np
import torch
import torch.nn as nn
from models.common import Conv, DWConv
from utils.google_utils import attempt_download

class Ensemble(nn.ModuleList):
    # Ensemble of models
    def __init__(self):
        super(Ensemble, self).__init__()

    def forward(self, x, augment=False):
        y = []
        for module in self:
            y.append(module(x, augment)[0])
        # y = torch.stack(y).max(0)[0]  # max ensemble
        # y = torch.cat(y, 1)  # nms ensemble
        y = torch.stack(y).mean(0)  # mean ensemble
        return y, None  # inference, train output

def attempt_load(weights, map_location=None):
    # Loads an ensemble of models weights=[a,b,c] or a single model weights=[a] or weights=a
    model = Ensemble()
    for w in weights if isinstance(weights, list) else [weights]:
        attempt_download(w)
        model.append(torch.load(w, map_location=map_location)['model'].float().fuse().eval())  # load FP32 model

    # Compatibility updates
    for m in model.modules():
        if type(m) in [nn.Hardswish, nn.LeakyReLU, nn.ReLU, nn.ReLU6]:
            m.inplace = True  # pytorch 1.7.0 compatibility
        elif type(m) is Conv:
            m._non_persistent_buffers_set = set()  # pytorch 1.6.0 compatibility

    if len(model) == 1:
        return model[-1]  # return model
    else:
        print('Ensemble created with %s\n' % weights)
        for k in ['names', 'stride']:
            setattr(model, k, getattr(model[-1], k))
        return model  # return ensemble

def convert_model(input_pth, output_onnx):

    print('cuda is available == {}'.format(torch.cuda.is_available()))
    device = select_device('')
    nc = 4
    torch_model = attempt_load(input_pth, map_location=device).cuda()
    torch_model = torch_model.to(device).half()
    torch_model.eval()

    batch_size = 2  # just a random number
    x = torch.rand(batch_size, 3, 640, 640, device=device).half()

    torch.onnx.export(torch_model,  # model being run
                      x.to(device).half(), #.to(device),  # model input (or a tuple for multiple inputs)
                      output_onnx,  # where to save the model (can be a file or file-like object)
                      opset_version=11,  # the ONNX version to export the model to
                      input_names=['input'],  # the model's input names
                      output_names=['output'],  # the model's output names
                      verbose=True
                  )

    return
github-actions[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

glenn-jocher commented 11 months ago

@ardeal the error RuntimeError: Input, output and indices must be on the current device is likely due to an inconsistency in device placement between the model and the input data. Ensure the model and input data are both on the same device, either CPU or GPU.

You can explicitly move the input data to the same device as the model using the .to(device) method, where device is the target device. Here's an example:

x = torch.rand(batch_size, 3, 640, 640, device=device).half().to(device)

After making this adjustment, try exporting the model to ONNX again. Let me know if you need further assistance!