Tensorrt简明教程第二期(在jetson上进行部署)

@TOC

首先执行

pip install networkx

首先转onnx和openvino

系统会自动调用/project/ev_sdk/model/convert_openvino.sh
内容写为

#!/bin/bash

# Root directory of the script
#!/bin/bash

# Root directory of the script


python /project/LYXXX/export.py  --weights '/project/train/models/exp9/weights/best.pt' --img-size 640 --opset-version 10         
# .onnx ==> openvino
chmod 777 /project/LYXXX/yolov5_openvino/run_convert.sh
/project/LYXXX/yolov5_openvino/run_convert.sh            # need to change path and img_size here!

其中weights为在线训练产生的权重位置
run_convert.sh内容为

python /opt/intel/openvino/deployment_tools/model_optimizer/mo_onnx.py \
--input_model /project/train/models/exp9/best.onnx \
--output_dir /project/train/models/exp9/weights/ \
--input_shape="[1,3,640,640]" \
--log_level DEBUG --data_type FP16

# --mean_values="[128, 128, 128]" \
# --scale_values="[255, 255, 255]" \

# cd /opt/intel/openvino/deployment_tools/model_optimizer/

修改ji.py里面的内容


需要修改

```python
input_h, input_w, input_c, input_n = (640, 640, 3, 1)           # TODO: image size
label_id_map = {            # TODO: labels
    0: "person_no_clothes",
    1: "person_clothes",
}
 model_xml = "/project/train/models/exp9/weights/best.xml"          # TODO: model xml path

    data=non_max_suppression(data, 0.5, 0.5)                # conf_thres, iou_thres,


 image_dir = '/home/data/130'

                detect_objs.append(
                    {
                                                     # TODO: need to change
                    'xmin': int(xmin),
                    'ymin': int(ymin),
                    'xmax': int(xmax),
                    'ymax': int(ymax),
                    'name': label_id_map[0],   
                    'confidence': float(confidence)
                    }python /project/LYXXX/train.py --img 800 --batch 36 --epoch 50 --data /project/LYXXX/data/myvoc.yaml --cfg /project/LYXXX/models/yolov5s.yaml --weights /project/LYXXX/weights/yolov5s.pt --workers 1

                )

测试结果

from __future__ import print_function

import logging as log
import os
import pathlib
import json
import cv2
import numpy as np
from openvino.inference_engine import IENetwork, IECore
import torch
import torchvision
import time



def xywh2xyxy(x):
    # Convert nx4 boxes from [x, y, w, h] to [x1, y1, x2, y2] where xy1=top-left, xy2=bottom-right
    y = torch.zeros_like(x) if isinstance(x, torch.Tensor) else np.zeros_like(x)
    y[:, 0] = x[:, 0] - x[:, 2] / 2  # top left x
    y[:, 1] = x[:, 1] - x[:, 3] / 2  # top left y
    y[:, 2] = x[:, 0] + x[:, 2] / 2  # bottom right x
    y[:, 3] = x[:, 1] + x[:, 3] / 2  # bottom right y
    return y


def non_max_suppression(prediction, conf_thres=0.1, iou_thres=0.6, merge=False, classes=None, agnostic=False):
    """Performs Non-Maximum Suppression (NMS) on inference results
    Returns:
         detections with shape: nx6 (x1, y1, x2, y2, conf, cls)
    """
    prediction=torch.from_numpy(prediction)
    if prediction.dtype is torch.float16:
        prediction = prediction.float()  # to FP32

    nc = prediction[0].shape[1] - 5  # number of classes
    xc = prediction[..., 4] > conf_thres  # candidates

    # Settings
    min_wh, max_wh = 2, 4096  # (pixels) minimum and maximum box width and height
    max_det = 300  # maximum number of detections per image
    time_limit = 10.0  # seconds to quit after
    redundant = True  # require redundant detections
    multi_label = nc > 1  # multiple labels per box (adds 0.5ms/img)

    t = time.time()
    output = [None] * prediction.shape[0]
    for xi, x in enumerate(prediction):  # image index, image inference
        # Apply constraints
        # x[((x[..., 2:4] < min_wh) | (x[..., 2:4] > max_wh)).any(1), 4] = 0  # width-height
        x = x[xc[xi]]  # confidence

        # If none remain process next image
        if not x.shape[0]:
            continue

        # Compute conf
        x[:, 5:] *= x[:, 4:5]  # conf = obj_conf * cls_conf

        # Box (center x, center y, width, height) to (x1, y1, x2, y2)
        box = xywh2xyxy(x[:, :4])

        # Detections matrix nx6 (xyxy, conf, cls)
        if multi_label:
            i, j = (x[:, 5:] > conf_thres).nonzero(as_tuple=False).T
            x = torch.cat((box[i], x[i, j + 5, None], j[:, None].float()), 1)
        else:  # best class only
            conf, j = x[:, 5:].max(1, keepdim=True)
            x = torch.cat((box, conf, j.float()), 1)[conf.view(-1) > conf_thres]

        # Filter by class
        if classes:
            x = x[(x[:, 5:6] == torch.tensor(classes, device=x.device)).any(1)]

        # Apply finite constraint
        # if not torch.isfinite(x).all():
        #     x = x[torch.isfinite(x).all(1)]

        # If none remain process next image
        n = x.shape[0]  # number of boxes
        if not n:
            continue

        # Sort by confidence
        # x = x[x[:, 4].argsort(descending=True)]

        # Batched NMS
        c = x[:, 5:6] * (0 if agnostic else max_wh)  # classes
        boxes, scores = x[:, :4] + c, x[:, 4]  # boxes (offset by class), scores
        i = torchvision.ops.boxes.nms(boxes, scores, iou_thres)
        if i.shape[0] > max_det:  # limit detections
            i = i[:max_det]
        if merge and (1 < n < 3E3):  # Merge NMS (boxes merged using weighted mean)
            try:  # update boxes as boxes(i,4) = weights(i,n) * boxes(n,4)
                iou = box_iou(boxes[i], boxes) > iou_thres  # iou matrix
                weights = iou * scores[None]  # box weights
                x[i, :4] = torch.mm(weights, x[:, :4]).float() / weights.sum(1, keepdim=True)  # merged boxes
                if redundant:
                    i = i[iou.sum(1) > 1]  # require redundancy
            except:  # possible CUDA error https://github.com/ultralytics/yolov3/issues/1139
                print(x, i, x.shape, i.shape)
                pass

        output[xi] = x[i]
        if (time.time() - t) > time_limit:
            break  # time limit exceeded

    return output



device = 'CPU'
input_h, input_w, input_c, input_n = (640, 640, 3, 1)           # TODO: image size
log.basicConfig(level=log.DEBUG)

# For objection detection task, replace your target labels here.
label_id_map = {            # TODO: labels
    0: "person_no_clothes",
    1: "person_clothes",
}
exec_net = None


def init():
    """Initialize model
    Returns: model
    """
    model_xml = "/project/train/models/exp2/weights/best.xml"          # TODO: model xml path
    #model_xml="/project/LYXXXold/__pycache__/exp2/weights/best.xml"
    if not os.path.isfile(model_xml):
        log.error(f'{model_xml} does not exist')
        return None
    model_bin = pathlib.Path(model_xml).with_suffix('.bin').as_posix()
    log.info("Loading network files:\n\t{}\n\t{}".format(model_xml, model_bin))
    net = IENetwork(model=model_xml, weights=model_bin)

    # Load Inference Engine
    log.info('Loading Inference Engine')
    ie = IECore()
    global exec_net
    exec_net = ie.load_network(network=net, device_name=device)
    log.info('Device info:')
    versions = ie.get_versions(device)
    print("{}".format(device))
    print("MKLDNNPlugin version ......... {}.{}".format(versions[device].major, versions[device].minor))
    print("Build ........... {}".format(versions[device].build_number))

    input_blob = next(iter(net.inputs))
    n, c, h, w = net.inputs[input_blob].shape
    global input_h, input_w, input_c, input_n
    input_h, input_w, input_c, input_n = h, w, c, n

    return net


def process_image(net, input_image,args=None, **kwargs):
    """Do inference to analysis input_image and get output
    Attributes:
        net: model handle
        input_image (numpy.ndarray): image to be process, format: (h, w, c), BGR
        thresh: thresh value
    Returns: process result
    """
    if not net or input_image is None:
        #log.error('Invalid input args')
        return None
    #log.info(f'process_image, ({input_image.shape}')
    ih, iw, _ = input_image.shape

    # --------------------------- Prepare input blobs -----------------------------------------------------
    if ih != input_h or iw != input_w:
        # input_image = cv2.resize(input_image, (360, 640))
        # input_image=input_image.append(np.zeros_like(280,640))
        input_image = cv2.resize(input_image, (input_w, input_h))
    input_image = cv2.cvtColor(input_image, cv2.COLOR_BGR2RGB)
    input_image = input_image/255
    input_image = input_image.transpose((2, 0, 1))
    images = np.ndarray(shape=(input_n, input_c, input_h, input_w))
    images[0] = input_image

    input_blob = next(iter(net.inputs))
    out_blob = next(iter(net.outputs))

    # --------------------------- Performing inference ----------------------------------------------------
    #log.info("Creating infer request and starting inference")
    res = exec_net.infer(inputs={input_blob: images})

    data = res['output']            # 'output'

    data=non_max_suppression(data, 0.3, 0.3)                # conf_thres, iou_thres,
    detect_objs = []
    if data[0]==None:
        return json.dumps({"objects": detect_objs})
    else:
        data=data[0].numpy()
        for proposal in data:19.5274	0.4469
            #print('proposals (hgx):', proposal)         # [-0.06005549 -0.18499237  1.6241994   0.14814436  8.453168    1.        ]
            #print(proposal[5])
            if proposal[4] > 0.3 :
                confidence = proposal[4]
                xmin = np.int(iw * (proposal[0]/640))           # TODO: 640
                ymin = np.int(ih * (proposal[1]/640))           # TODO: 640
                xmax = np.int(iw * (proposal[2]/640))           # TODO: 640
                ymax = np.int(ih * (proposal[3]/640))           # TODO: 640

                detect_objs.append(
                    {
                                                     # TODO: need to change
                    'xmin': int(xmin),
                    'ymin': int(ymin),
                    'xmax': int(xmax),
                    'ymax': int(ymax),
                    'name': label_id_map[int(proposal[5])],   
                    'confidence': float(confidence)
                    }
                )

        return json.dumps({"objects": detect_objs})


if __name__ == '__main__':
    # Test API
    print("22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222")
    image_dir = '/home/data/130'
    image_names = os.listdir(image_dir)
    #image_names="/home/data/130/CARTclothes20200821_10.jpg"
    predictor = init()
    for image_name in image_names:
        #print('image_path:', os.path.join(image_dir, image_name))
        img = cv2.imread(os.path.join(image_dir, image_name))
        result = process_image(predictor, img)
        #log.info(result)
    

数值为20.2503的fps和0.4604的fscore
0.4,0.3时为19.5473和0.4683
0.5,0.3时为19.683和0.4737
0.5,0.2时为19.8365和0.4703
0.55,0.4时为19.5082和0.4764
0.65,0.4时为19.3546 0.4703
0.65,0.4时修改尺寸为384,640 35.3492 0.5395

测试尺寸修改教程

尺寸设置应为32的倍数
ji.py

input_h, input_w, input_c, input_n = (2*384, 2*640, 3, 1)           # TODO: image size

export.py

parser.add_argument('--img-size', nargs='+', type=int, default=[2*384, 2*640], help='image (height, width)')

run_convert.sh

--input_shape="[1,3,2*384,2*640]" \

多尺度测试

在/project/LYXXX/models/yolo.py中将augment修改为True即可。

 def forward(self, x, augment=True, profile=False, visualize=False):
        if augment:
            return self.forward_augment(x)  # augmented inference, None
        return self.forward_once(x, profile, visualize)  # single-scale inference, train

    def forward_augment(self, x):
        img_size = x.shape[-2:]  # height, width
        s = [1, 0.83, 0.67]  # scales
        f = [None, 3, None]  # flips (2-ud, 3-lr)
        y = []  # outputs
        for si, fi in zip(s, f):
            xi = scale_img(x.flip(fi) if fi else x, si, gs=int(self.stride.max()))
            yi = self.forward_once(xi)[0]  # forward
            # cv2.imwrite(f'img_{si}.jpg', 255 * xi[0].cpu().numpy().transpose((1, 2, 0))[:, :, ::-1])  # save
            yi = self._descale_pred(yi, fi, si, img_size)
            y.append(yi)
        return torch.cat(y, 1), None  # augmented inference, train

拼接部分(阻止变形)


image_pre=x=np.ones((1,3,384,640))
image_pre=114*image_pre


def process_image(net, input_image,args=None, **kwargs):
    """Do inference to analysis input_image and get output
    Attributes:
        net: model handle
        input_image (numpy.ndarray): image to be process, format: (h, w, c), BGR
        thresh: thresh value
    Returns: process result
    """
    if not net or input_image is None:
        #log.error('Invalid input args')
        return None
    #log.info(f'process_image, ({input_image.shape}')
    ih, iw, _ = input_image.shape

    # --------------------------- Prepare input blobs -----------------------------------------------------
    if ih != input_h or iw != input_w:
        # input_image = cv2.resize(input_image, (360, 640))
        input_image = cv2.resize(input_image, (input_w, input_h))

    input_image = cv2.cvtColor(input_image, cv2.COLOR_BGR2RGB)
    #input_image = input_image/255
    input_image = input_image.transpose((2, 0, 1))
    images = np.ndarray(shape=(input_n, input_c, input_h, input_w))
    images[0] = input_image
    image_pre[:,:,:input_h,:input_w] = images
    

    input_blob = next(iter(net.inputs))
    out_blob = next(iter(net.outputs))

    # --------------------------- Performing inference ----------------------------------------------------
    #log.info("Creating infer request and starting inference")
    res = exec_net.infer(inputs={input_blob: image_pre})

    data = res['output']            # 'output'

    data=non_max_suppression(data, 0.65, 0.4)                # conf_thres, iou_thres,
    detect_objs = []
    if data[0]==None:
        return json.dumps({"objects": detect_objs})
    else:
        data=data[0].numpy()
        for proposal in data:
            #print('proposals (hgx):', proposal)         # [-0.06005549 -0.18499237  1.6241994   0.14814436  8.453168    1.        ]
            #print(proposal[5])
            if proposal[4] > 0.65 :
                confidence = proposal[4]
                xmin = np.int(iw * (proposal[0]/640))           # TODO: 640
                ymin = np.int(ih * (proposal[1]/384))           # TODO: 640
                xmax = np.int(iw * (proposal[2]/640))           # TODO: 640
                ymax = np.int(ih * (proposal[3]/384))           # TODO: 640

                detect_objs.append(
                    {
                                                     # TODO: need to change
                    'xmin': int(xmin),
                    'ymin': int(ymin),
                    'xmax': int(xmax),
                    'ymax': int(ymax),
                    'name': label_id_map[int(proposal[5])],   
                    'confidence': float(confidence)
                    }
                )

        return json.dumps({"objects": detect_objs})

训练记录

yty img800 50轮 有马赛克增强

python /project/LYXXX/train.py --img 800 --batch 36 --epoch 50 --data /project/LYXXX/data/myvoc.yaml --cfg /project/LYXXX/models/yolov5s.yaml --weights /project/LYXXX/weights/yolov5s.pt --workers 1

/project/LYXXX/data/hyps/hyp.scratch.yaml

# Hyperparameters for COCO training from scratch
# python train.py --batch 40 --cfg yolov5m.yaml --weights '' --data coco.yaml --img 640 --epochs 300
# See tutorials for hyperparameter evolution https://github.com/ultralytics/yolov5#tutorials


lr0: 0.01  # initial learning rate (SGD=1E-2, Adam=1E-3)
lrf: 0.2  # final OneCycleLR learning rate (lr0 * lrf)
momentum: 0.937  # SGD momentum/Adam beta1
weight_decay: 0.0005  # optimizer weight decay 5e-4
warmup_epochs: 3.0  # warmup epochs (fractions ok)
warmup_momentum: 0.8  # warmup initial momentum
warmup_bias_lr: 0.1  # warmup initial bias lr
box: 0.05  # box loss gain
cls: 0.5  # cls loss gain
cls_pw: 1.0  # cls BCELoss positive_weight
obj: 1.0  # obj loss gain (scale with pixels)
obj_pw: 1.0  # obj BCELoss positive_weight
iou_t: 0.20  # IoU training threshold
anchor_t: 4.0  # anchor-multiple threshold
# anchors: 3  # anchors per output layer (0 to ignore)
fl_gamma: 0.0  # focal loss gamma (efficientDet default gamma=1.5)
hsv_h: 0.015  # image HSV-Hue augmentation (fraction)
hsv_s: 0.7  # image HSV-Saturation augmentation (fraction)
hsv_v: 0.4  # image HSV-Value augmentation (fraction)
degrees: 0.0  # image rotation (+/- deg)
translate: 0.1  # image translation (+/- fraction)
scale: 0.5  # image scale (+/- gain)
shear: 0.0  # image shear (+/- deg)
perspective: 0.0  # image perspective (+/- fraction), range 0-0.001
flipud: 0.0  # image flip up-down (probability)
fliplr: 0.5  # image flip left-right (probability)
mosaic: 1.0  # image mosaic (probability)
mixup: 0.0  # image mixup (probability)
copy_paste: 0.0  # segment copy-paste (probability)

训练结果

                 all      16434      44977      0.959      0.944      0.984      0.828
   person_no_clothes      16434       8554      0.959      0.942      0.981      0.838
      person_clothes      16434      36423       0.96      0.947      0.988      0.817

测试结果:
800 800 0.3 0.3 6.8955 0.4586

512 800 0.3 0.3 17.2369 0.5318
512 800 0.5 0.3 17.0393 0.5444
多尺度测试 s = [1, 0.83, 0.67] # scales 512 800 0.5 0.3 5.2076 0.5544
512 800 0.7 0.5 11.5858 0.5446
512 800 0.7 0.3 10.4661 0.5423
512 800 0.9 0.3 17.5817 0.3813
512 800 0.6 0.5 19.0995 0 .5548
512 800 0.65 0.5 19.3433 0.5511
512 800 0.6 0.5 尺度为1.5 6.954 0.5631
512 800 0.6 0.5 尺度为0.5 34.5691 0.4943
448 800 0.6 0.5 尺度为1.0 21.2744 0.5498
896 1600 0.6 0.5 尺度为1.0 3.8012 0.5608
544 960 0.6 0.5 尺度为1.0 12.2599 0.5611
544 960 0.55 0.5 尺度为1.25 6.6271 0.5655
544 960 0.55 0.5 尺度为1.5 4.9359 0.57
512 800 0.55 0.5 尺度为1.5 6.9263 0.5639
512 800 0.55 0.5 尺度为1 FLOAT 18.7135 0.5567
512 800 0.55 0.5 尺度为1.5 FLOAT 6.3225 0.5639

zyf img 640 50轮 无马赛克增强

训练id 3948

python /project/LYXXX/train.py --img 640 --batch 16 --epoch 50 --data /project/LYXXX/data/myvoc.yaml --cfg /project/LYXXX/models/yolov5s.yaml --weights /project/LYXXX/weights/yolov5s.pt --workers 1

mosaic: 0.0  # image mosaic (probability)

结果

                 all      16434      44977      0.897      0.822      0.911      0.713
   person_no_clothes      16434       8554      0.883      0.771      0.876      0.708
      person_clothes      16434      36423      0.911      0.873      0.945      0.719

测试结果:
0.3,0.3 尺寸640640 19.5274 0.4469
0.3,0.3尺寸480
480 29.3796 0.4261
0.3, 0.3 384 640 29.2589 0.5225

zyf img 640 50轮 马赛克增强+mixup

训练id 4032

python /project/LYXXX/train.py --img 640 --batch 16 --epoch 50 --data /project/LYXXX/data/myvoc.yaml --cfg /project/LYXXX/models/yolov5s.yaml --weights /project/LYXXX/weights/yolov5s.pt --workers 1

mosaic: 1.0  # image mosaic (probability)
mixup: 0.5  # image mixup (probability)

结果


测试结果:

miaomiaomiao

python /project/LYXXX/train.py --img 960 --batch 32 --epoch 45 --data /project/LYXXX/data/myvoc.yaml --cfg /project/LYXXX/models/yolov5s.yaml --weights /project/LYXXX/weights/yolov5s.pt --workers 1

mosaic: 1.0  # image mosaic (probability)
mixup: 0.0  # image mixup (probability)

电动车

训练

python /project/LYXXX/train.py --img 240 --batch 128 --epoch 50 --data /project/LYXXX/data/myvoc.yaml --cfg /project/LYXXX/models/yolov5s.yaml --weights /project/LYXXX/weights/yolov5s.pt --workers 1

             all      12873      33867      0.963      0.959      0.972      0.821
          person      12873      20570      0.973      0.973      0.989      0.823
         bicycle      12873       1300      0.935      0.925      0.937      0.777
       e_vehicle      12873      11997      0.982      0.978       0.99      0.86

测试

转onnx

def export_onnx(model, img, file, opset_version, train, dynamic, simplify):
    # ONNX model export
    prefix = colorstr('ONNX:')
    try:
        check_requirements(('onnx', 'onnx-simplifier'))
        import onnx

        print(f'\n{prefix} starting export with onnx {onnx.__version__}...')
        f = file.with_suffix('.onnx')
        torch.onnx.export(model, img, f, verbose=False, opset_version=opset_version,
                          training=torch.onnx.TrainingMode.TRAINING if train else torch.onnx.TrainingMode.EVAL,
                          do_constant_folding=not train,
                          input_names=['images'],
                          output_names=['output'],
                        #   dynamic_axes={'images': {0: 'batch', 2: 'height', 3: 'width'},  # shape(1,3,640,640)
                        #                 'output': {0: 'batch', 1: 'anchors'}  # shape(1,25200,85)
                          dynamic_axes={'images': {0: '1', 2: 'height', 3: 'width'},  # shape(1,3,640,640)
                                        'output': {0: 'batch', 1: 'anchors'}  # shape(1,25200,85)
                                        } if dynamic else None)

        # Checks
        model_onnx = onnx.load(f)  # load onnx model
        onnx.checker.check_model(model_onnx)  # check onnx model
        # print(onnx.helper.printable_graph(model_onnx.graph))  # print

big submit

训了一半测试
16.8405 0.5248 800 512 0.6 0.5

             all      16434      44977      0.931      0.911      0.967       0.79

person_no_clothes 16434 8554 0.921 0.899 0.955 0.793
person_clothes 16434 36423 0.941 0.922 0.978 0.787

emmmmmmmmmmmm

0.5 0.5 640 352 19.7877 0.8259
0.55 0.5 640 352 21.2569 0.8262
0.6 0.5 640 352 20.8601 0.8229

你可能感兴趣的:(python,tornado,flask,django)