zoukankan      html  css  js  c++  java
  • LibTorch实战六:C++版本YOLOV5.4的部署<二>

    yolo5.4,不多比比

    这里训练完模型之后,咱们使用pytorch写一个小案例,可以和下面libtorch版本对比下:

     1 import  cv2
     2 import torch
     3 import torch.backends.cudnn as cudnn
     4 from numpy import random
     5 
     6 from utils.datasets import LoadImages
     7 from models.experimental import attempt_load
     8 
     9 from utils.general import check_img_size, non_max_suppression, scale_coords, xyxy2xywh
    10 from utils.plots import plot_one_box
    11 
    12 # device
    13 device = torch.device('cpu') # cuda:0,cpu = FP32
    14 # load model
    15 model = attempt_load(['weights/yolov5s.pt'], map_location = device)
    16 #model = torch.jit.load("weights/yolo-5S-face-wg.torchscript.pt")
    17 #model = model.to(device)
    18 #model.eval()
    19 
    20 # reference
    21 stride = int(model.stride.max())
    22 imgsz = 638 # note:我故意设置为638
    23 imgsz = check_img_size(imgsz, s=stride)
    24 # read the image datasets.py 191 行
    25 dataset = LoadImages('D:/Data/yolo/4-320-314.jpg', img_size=imgsz, stride=stride)
    26 # get class names
    27 names = model.names
    28 # anchors' color
    29 colors = [[random.randint(0, 255) for _ in range(3)] for _ in names]
    30 # img resize
    31 # img:srcImg
    32 # im0s:dstImg
    33 for path, img, im0s, vid_cap in dataset:
    34     img = torch.from_numpy(img).to(device)
    35     img = img.float()
    36     img /= 255.0
    37     if img.ndimension() == 3:
    38         img = img.unsqueeze(0)
    39     # img:torch.Size([1, 3, 256, 640])
    40     pred = model(img, augment=False)[0] # defaults: no-augment
    41     # NMS
    42     pred = non_max_suppression(pred, conf_thres=0.25, iou_thres=0.45, classes=None, agnostic=False)
    43 
    44     # Process detections
    45     for i, det in enumerate(pred):
    46         # im0(source image) (360, 900, 3)
    47         # gn tensor([900, 360, 900, 360])
    48         im0 = im0s
    49         gn = torch.tensor(im0.shape)[[1, 0, 1, 0]]
    50         if len(det): # 检测到框个数
    51             # Rescale boxes from img_size to im0 size
    52             # 调整框大小,缩放到实际原图中去
    53             det[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0.shape).round()
    54             # conf:置信度得分 cls:类别
    55             for *xyxy, conf, cls in reversed(det):
    56                 # 框的几何信息转换:xyxy -> xywh
    57                 xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist()  # normalized xywh
    58                 label = f'{names[int(cls)]} {conf:.2f}'
    59                 plot_one_box(xyxy, im0, label=label, color=colors[int(cls)], line_thickness=3)
    60         cv2.namedWindow("dst_img", cv2.WINDOW_NORMAL)
    61         cv2.imshow("dst_img", im0)
    62         cv2.waitKey(0)
    View Code

    一、libtorch+cpu版本

    CPU版本导出模型脚本export-libtorch-cpu.py

    相对官方原本的export.py,我们仅需修改54行就行了。

      1 """Exports a YOLOv5 *.pt model to ONNX and TorchScript formats
      2 
      3 Usage:
      4     $ export PYTHONPATH="$PWD" && python models/export.py --weights ./weights/yolov5s.pt --img 640 --batch 1
      5 """
      6 
      7 import argparse
      8 import sys
      9 import time
     10 
     11 sys.path.append('./')  # to run '$ python *.py' files in subdirectories
     12 
     13 import torch
     14 import torch.nn as nn
     15 
     16 import models
     17 from models.experimental import attempt_load
     18 from utils.activations import Hardswish, SiLU
     19 from utils.general import set_logging, check_img_size
     20 
     21 if __name__ == '__main__':
     22     parser = argparse.ArgumentParser()
     23     parser.add_argument('--weights', type=str, default='./yolov5s.pt', help='weights path')  # from yolov5/models/
     24     parser.add_argument('--img-size', nargs='+', type=int, default=[640, 640], help='image size')  # height, width
     25     parser.add_argument('--dynamic', action='store_true', help='dynamic ONNX axes')
     26     parser.add_argument('--batch-size', type=int, default=1, help='batch size')
     27     opt = parser.parse_args()
     28     opt.img_size *= 2 if len(opt.img_size) == 1 else 1  # expand
     29     print(opt)
     30     set_logging()
     31     t = time.time()
     32 
     33     # Load PyTorch model
     34     model = attempt_load(opt.weights, map_location=torch.device('cpu'))  # load FP32 model
     35     labels = model.names
     36 
     37     # Checks
     38     gs = int(max(model.stride))  # grid size (max stride)
     39     opt.img_size = [check_img_size(x, gs) for x in opt.img_size]  # verify img_size are gs-multiples
     40 
     41     # Input
     42     img = torch.zeros(opt.batch_size, 3, *opt.img_size)  # image size(1,3,320,192) iDetection
     43 
     44     # Update model
     45     for k, m in model.named_modules():
     46         m._non_persistent_buffers_set = set()  # pytorch 1.6.0 compatibility
     47         if isinstance(m, models.common.Conv):  # assign export-friendly activations
     48             if isinstance(m.act, nn.Hardswish):
     49                 m.act = Hardswish()
     50             elif isinstance(m.act, nn.SiLU):
     51                 m.act = SiLU()
     52         # elif isinstance(m, models.yolo.Detect):
     53         #     m.forward = m.forward_export  # assign forward (optional)
     54     model.model[-1].export = False  # set Detect() layer export=True
     55     y = model(img)  # dry run
     56 
     57     # TorchScript export
     58     try:
     59         print('
    Starting TorchScript export with torch %s...' % torch.__version__)
     60         f = opt.weights.replace('.pt', '.torchscript.pt')  # filename
     61         ts = torch.jit.trace(model, img)
     62         ts.save(f)
     63         print('TorchScript export success, saved as %s' % f)
     64     except Exception as e:
     65         print('TorchScript export failure: %s' % e)
     66 
     67     # ONNX export
     68     try:
     69         import onnx
     70 
     71         print('
    Starting ONNX export with onnx %s...' % onnx.__version__)
     72         f = opt.weights.replace('.pt', '.onnx')  # filename
     73         torch.onnx.export(model, img, f, verbose=False, opset_version=12, input_names=['images'],
     74                           output_names=['classes', 'boxes'] if y is None else ['output'],
     75                           dynamic_axes={'images': {0: 'batch', 2: 'height', 3: 'width'},  # size(1,3,640,640)
     76                                         'output': {0: 'batch', 2: 'y', 3: 'x'}} if opt.dynamic else None)
     77 
     78         # Checks
     79         onnx_model = onnx.load(f)  # load onnx model
     80         onnx.checker.check_model(onnx_model)  # check onnx model
     81         # print(onnx.helper.printable_graph(onnx_model.graph))  # print a human readable model
     82         print('ONNX export success, saved as %s' % f)
     83     except Exception as e:
     84         print('ONNX export failure: %s' % e)
     85 
     86     # CoreML export
     87     try:
     88         import coremltools as ct
     89 
     90         print('
    Starting CoreML export with coremltools %s...' % ct.__version__)
     91         # convert model from torchscript and apply pixel scaling as per detect.py
     92         model = ct.convert(ts, inputs=[ct.ImageType(name='image', shape=img.shape, scale=1 / 255.0, bias=[0, 0, 0])])
     93         f = opt.weights.replace('.pt', '.mlmodel')  # filename
     94         model.save(f)
     95         print('CoreML export success, saved as %s' % f)
     96     except Exception as e:
     97         print('CoreML export failure: %s' % e)
     98 
     99     # Finish
    100     print('
    Export complete (%.2fs). Visualize with https://github.com/lutzroeder/netron.' % (time.time() - t))

    二、libtorch+GPU


    在上面的基础上做了如下修改:1、将模型塞进cuda,2、将样图塞进cuda

      1 """Exports a YOLOv5 *.pt model to ONNX and TorchScript formats
      2 
      3 Usage:
      4     $ export PYTHONPATH="$PWD" && python models/export.py --weights ./weights/yolov5s.pt --img 640 --batch 1
      5 """
      6 
      7 import argparse
      8 import sys
      9 import time
     10 
     11 sys.path.append('./')  # to run '$ python *.py' files in subdirectories
     12 
     13 import torch
     14 import torch.nn as nn
     15 
     16 import models
     17 from models.experimental import attempt_load
     18 from utils.activations import Hardswish, SiLU
     19 from utils.general import set_logging, check_img_size
     20 
     21 if __name__ == '__main__':
     22     parser = argparse.ArgumentParser()
     23     parser.add_argument('--weights', type=str, default='./yolov5s.pt', help='weights path')  # from yolov5/models/
     24     parser.add_argument('--img-size', nargs='+', type=int, default=[640, 640], help='image size')  # height, width
     25     parser.add_argument('--dynamic', action='store_true', help='dynamic ONNX axes')
     26     parser.add_argument('--batch-size', type=int, default=1, help='batch size')
     27     opt = parser.parse_args()
     28     opt.img_size *= 2 if len(opt.img_size) == 1 else 1  # expand
     29     print(opt)
     30     set_logging()
     31     t = time.time()
     32 
     33     # Load PyTorch model
     34     # gpu
     35     model = attempt_load(opt.weights, map_location=torch.device('cuda'))  # load FP32 model
     36     labels = model.names
     37 
     38     # Checks
     39     gs = int(max(model.stride))  # grid size (max stride)
     40     opt.img_size = [check_img_size(x, gs) for x in opt.img_size]  # verify img_size are gs-multiples
     41 
     42     # Input
     43     # gpu
     44     img = torch.zeros(opt.batch_size, 3, *opt.img_size).to(device='cuda')  # image size(1,3,320,192) iDetection
     45 
     46     # Update model
     47     for k, m in model.named_modules():
     48         m._non_persistent_buffers_set = set()  # pytorch 1.6.0 compatibility
     49         if isinstance(m, models.common.Conv):  # assign export-friendly activations
     50             if isinstance(m.act, nn.Hardswish):
     51                 m.act = Hardswish()
     52             elif isinstance(m.act, nn.SiLU):
     53                 m.act = SiLU()
     54         # elif isinstance(m, models.yolo.Detect):
     55         #     m.forward = m.forward_export  # assign forward (optional)
     56     model.model[-1].export = False  # set Detect() layer export=True
     57     y = model(img)  # dry run
     58 
     59     # TorchScript export
     60     try:
     61         print('
    Starting TorchScript export with torch %s...' % torch.__version__)
     62         f = opt.weights.replace('.pt', '.torchscript.pt')  # filename
     63         ts = torch.jit.trace(model, img)
     64         ts.save(f)
     65         print('TorchScript export success, saved as %s' % f)
     66     except Exception as e:
     67         print('TorchScript export failure: %s' % e)
     68 
     69     # ONNX export
     70     try:
     71         import onnx
     72 
     73         print('
    Starting ONNX export with onnx %s...' % onnx.__version__)
     74         f = opt.weights.replace('.pt', '.onnx')  # filename
     75         torch.onnx.export(model, img, f, verbose=False, opset_version=12, input_names=['images'],
     76                           output_names=['classes', 'boxes'] if y is None else ['output'],
     77                           dynamic_axes={'images': {0: 'batch', 2: 'height', 3: 'width'},  # size(1,3,640,640)
     78                                         'output': {0: 'batch', 2: 'y', 3: 'x'}} if opt.dynamic else None)
     79 
     80         # Checks
     81         onnx_model = onnx.load(f)  # load onnx model
     82         onnx.checker.check_model(onnx_model)  # check onnx model
     83         # print(onnx.helper.printable_graph(onnx_model.graph))  # print a human readable model
     84         print('ONNX export success, saved as %s' % f)
     85     except Exception as e:
     86         print('ONNX export failure: %s' % e)
     87 
     88     # CoreML export
     89     try:
     90         import coremltools as ct
     91 
     92         print('
    Starting CoreML export with coremltools %s...' % ct.__version__)
     93         # convert model from torchscript and apply pixel scaling as per detect.py
     94         model = ct.convert(ts, inputs=[ct.ImageType(name='image', shape=img.shape, scale=1 / 255.0, bias=[0, 0, 0])])
     95         f = opt.weights.replace('.pt', '.mlmodel')  # filename
     96         model.save(f)
     97         print('CoreML export success, saved as %s' % f)
     98     except Exception as e:
     99         print('CoreML export failure: %s' % e)
    100 
    101     # Finish
    102     print('
    Export complete (%.2fs). Visualize with https://github.com/lutzroeder/netron.' % (time.time() - t))

    三、源码

     在百度网盘,需要请留言

    台式机:i7-8700   p4000, 5s:5ms

    笔记本:i5-7200u MX940, 5s:5m

    我有点看不懂了。

    下图就是笔记本实测:

    CV&DL
  • 相关阅读:
    求最大子数组和
    第四周学习进度
    四则运算3
    实用工具箱app开发日记5
    实用工具箱app开发日记4
    实用工具箱app开发日记3
    实用工具箱app开发日记2
    实用工具箱app开发日记1
    《软件需求与分析》阅读笔记
    软件需求分析--阅读笔记3
  • 原文地址:https://www.cnblogs.com/winslam/p/14664162.html
Copyright © 2011-2022 走看看