当前位置: 首页 > news >正文

yolov8x-p2 实现 tensorrt 推理

简述

在最开始的yolov8提供的不同size的版本,包括n、s、m、l、x(模型规模依次增大,通过depth, width, max_channels控制大小),这些都是通过P3、P4和P5提取图片特征;
正常的yolov8对象检测模型输出层是P3、P4、P5三个输出层,为了提升对小目标的检测能力,新版本的yolov8 已经包含了P2层(P2层做的卷积次数少,特征图的尺寸(分辨率)较大,更加利于小目标识别),有四个输出层。Backbone部分的结果没有改变,但是Neck跟Head部分模型结构做了调整。

在这里插入图片描述


yolov8-p2 yaml

# Ultralytics YOLO 🚀, AGPL-3.0 license
# YOLOv8 object detection model with P2-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect# Parameters
nc: 80  # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov8n.yaml' will call yolov8.yaml with scale 'n'# [depth, width, max_channels]n: [0.33, 0.25, 1024]s: [0.33, 0.50, 1024]m: [0.67, 0.75, 768]l: [1.00, 1.00, 512]x: [1.00, 1.25, 512]# YOLOv8.0 backbone
backbone:# [from, repeats, module, args]- [-1, 1, Conv, [64, 3, 2]]  # 0-P1/2- [-1, 1, Conv, [128, 3, 2]]  # 1-P2/4- [-1, 3, C2f, [128, True]]- [-1, 1, Conv, [256, 3, 2]]  # 3-P3/8- [-1, 6, C2f, [256, True]]- [-1, 1, Conv, [512, 3, 2]]  # 5-P4/16- [-1, 6, C2f, [512, True]]- [-1, 1, Conv, [1024, 3, 2]]  # 7-P5/32- [-1, 3, C2f, [1024, True]]- [-1, 1, SPPF, [1024, 5]]  # 9# YOLOv8.0-p2 head
head:- [-1, 1, nn.Upsample, [None, 2, 'nearest']]- [[-1, 6], 1, Concat, [1]]  # cat backbone P4- [-1, 3, C2f, [512]]  # 12- [-1, 1, nn.Upsample, [None, 2, 'nearest']]- [[-1, 4], 1, Concat, [1]]  # cat backbone P3- [-1, 3, C2f, [256]]  # 15 (P3/8-small)- [-1, 1, nn.Upsample, [None, 2, 'nearest']]- [[-1, 2], 1, Concat, [1]]  # cat backbone P2- [-1, 3, C2f, [128]]  # 18 (P2/4-xsmall)- [-1, 1, Conv, [128, 3, 2]]- [[-1, 15], 1, Concat, [1]]  # cat head P3- [-1, 3, C2f, [256]]  # 21 (P3/8-small)- [-1, 1, Conv, [256, 3, 2]]- [[-1, 12], 1, Concat, [1]]  # cat head P4- [-1, 3, C2f, [512]]  # 24 (P4/16-medium)- [-1, 1, Conv, [512, 3, 2]]- [[-1, 9], 1, Concat, [1]]  # cat head P5- [-1, 3, C2f, [1024]]  # 27 (P5/32-large)- [[18, 21, 24, 27], 1, Detect, [nc]]  # Detect(P2, P3, P4, P5)

yolov8-p2 tensort 实现

参考: https://github.com/wang-xinyu/tensorrtx/tree/master/yolov8

  1. model.cpp 中增加 buildEngineYolov8x_p2 方法.

    Backbone

    • backbone 和 yolov8 一样 , 无需改动,照搬下来就行.

          /************************************************************************************************************************************************  YOLOV8 BACKBONE  ***************************************************************************************************************************************************/nvinfer1::IElementWiseLayer *conv0 = convBnSiLU(network, weightMap, *data, 80, 3, 2, 1, "model.0");nvinfer1::IElementWiseLayer *conv1 = convBnSiLU(network, weightMap, *conv0->getOutput(0), 160, 3, 2, 1, "model.1");nvinfer1::IElementWiseLayer *conv2 = C2F(network, weightMap, *conv1->getOutput(0), 160, 160, 3, true, 0.5, "model.2");nvinfer1::IElementWiseLayer *conv3 = convBnSiLU(network, weightMap, *conv2->getOutput(0), 320, 3, 2, 1, "model.3");nvinfer1::IElementWiseLayer *conv4 = C2F(network, weightMap, *conv3->getOutput(0), 320, 320, 6, true, 0.5, "model.4");nvinfer1::IElementWiseLayer *conv5 = convBnSiLU(network, weightMap, *conv4->getOutput(0), 640, 3, 2, 1, "model.5");nvinfer1::IElementWiseLayer *conv6 = C2F(network, weightMap, *conv5->getOutput(0), 640, 640, 6, true, 0.5, "model.6");nvinfer1::IElementWiseLayer *conv7 = convBnSiLU(network, weightMap, *conv6->getOutput(0), 640, 3, 2, 1, "model.7");nvinfer1::IElementWiseLayer *conv8 = C2F(network, weightMap, *conv7->getOutput(0), 640, 640, 3, true, 0.5, "model.8");nvinfer1::IElementWiseLayer *conv9 = SPPF(network, weightMap, *conv8->getOutput(0), 640, 640, 5, "model.9");
      

    Head

    • 由3个输出层 (P3、P4、P5) 变成4个输出层 (P2、P3、P4、P5)

      HEAD
        /*************************************************************************************************************************************************  YOLOV8 HEAD  ******************************************************************************************************************************************************/float scale[] = {1.0, 2.0, 2.0};nvinfer1::IResizeLayer *upsample10 = network->addResize(*conv9->getOutput(0));upsample10->setResizeMode(nvinfer1::ResizeMode::kNEAREST);upsample10->setScales(scale, 3);nvinfer1::ITensor *inputTensor11[] = {upsample10->getOutput(0), conv6->getOutput(0)};nvinfer1::IConcatenationLayer *cat11 = network->addConcatenation(inputTensor11, 2);nvinfer1::IElementWiseLayer *conv12 = C2F(network, weightMap, *cat11->getOutput(0), 640, 640, 3, false, 0.5, "model.12");nvinfer1::IResizeLayer *upsample13 = network->addResize(*conv12->getOutput(0));upsample13->setResizeMode(nvinfer1::ResizeMode::kNEAREST);upsample13->setScales(scale, 3);nvinfer1::ITensor *inputTensor14[] = {upsample13->getOutput(0), conv4->getOutput(0)};nvinfer1::IConcatenationLayer *cat14 = network->addConcatenation(inputTensor14, 2);nvinfer1::IElementWiseLayer *conv15 = C2F(network, weightMap, *cat14->getOutput(0), 320, 320, 3, false, 0.5, "model.15");nvinfer1::IResizeLayer *upsample16 = network->addResize(*conv15->getOutput(0));upsample16->setResizeMode(nvinfer1::ResizeMode::kNEAREST);upsample16->setScales(scale, 3);nvinfer1::ITensor *inputTensor17[] = {upsample16->getOutput(0), conv2->getOutput(0)};nvinfer1::IConcatenationLayer *cat17 = network->addConcatenation(inputTensor17, 2);nvinfer1::IElementWiseLayer *conv18 = C2F(network, weightMap, *cat17->getOutput(0), 160, 160, 3, false, 0.5, "model.18");nvinfer1::IElementWiseLayer *conv19 = convBnSiLU(network, weightMap, *conv18->getOutput(0), 160, 3, 2, 1, "model.19");nvinfer1::ITensor *inputTensor20[] = {conv19->getOutput(0), conv15->getOutput(0)};nvinfer1::IConcatenationLayer *cat20 = network->addConcatenation(inputTensor20, 2);nvinfer1::IElementWiseLayer *conv21 = C2F(network, weightMap, *cat20->getOutput(0), 320, 320, 3, false, 0.5, "model.21");nvinfer1::IElementWiseLayer *conv22 = convBnSiLU(network, weightMap, *conv21->getOutput(0), 320, 3, 2, 1, "model.22");nvinfer1::ITensor *inputTensor23[] = {conv22->getOutput(0), conv12->getOutput(0)};nvinfer1::IConcatenationLayer *cat23 = network->addConcatenation(inputTensor23, 2);nvinfer1::IElementWiseLayer *conv24 = C2F(network, weightMap, *cat23->getOutput(0), 640, 640, 3, false, 0.5, "model.24");nvinfer1::IElementWiseLayer *conv25 = convBnSiLU(network, weightMap, *conv24->getOutput(0), 640, 3, 2, 1, "model.25");nvinfer1::ITensor *inputTensor26[] = {conv25->getOutput(0), conv9->getOutput(0)};nvinfer1::IConcatenationLayer *cat26 = network->addConcatenation(inputTensor26, 2);nvinfer1::IElementWiseLayer *conv27 = C2F(network, weightMap, *cat26->getOutput(0), 640, 640, 3, false, 0.5, "model.27");
      
      OUTPUT
      /****************************************************************************************************************************************************  YOLOV8 OUTPUT  *************************************************************************************************************************************************/// output0nvinfer1::IElementWiseLayer *conv28_cv2_0_0 = convBnSiLU(network, weightMap, *conv18->getOutput(0), 64, 3, 1, 1, "model.28.cv2.0.0");nvinfer1::IElementWiseLayer *conv28_cv2_0_1 = convBnSiLU(network, weightMap, *conv28_cv2_0_0->getOutput(0), 64, 3, 1, 1, "model.28.cv2.0.1");nvinfer1::IConvolutionLayer *conv28_cv2_0_2 = network->addConvolutionNd(*conv28_cv2_0_1->getOutput(0), 64, nvinfer1::DimsHW{1, 1}, weightMap["model.28.cv2.0.2.weight"], weightMap["model.28.cv2.0.2.bias"]);conv28_cv2_0_2->setStrideNd(nvinfer1::DimsHW{1, 1});conv28_cv2_0_2->setPaddingNd(nvinfer1::DimsHW{0, 0});nvinfer1::IElementWiseLayer *conv28_cv3_0_0 = convBnSiLU(network, weightMap, *conv18->getOutput(0), 160, 3, 1, 1, "model.28.cv3.0.0");nvinfer1::IElementWiseLayer *conv28_cv3_0_1 = convBnSiLU(network, weightMap, *conv28_cv3_0_0->getOutput(0), 160, 3, 1, 1, "model.28.cv3.0.1");nvinfer1::IConvolutionLayer *conv28_cv3_0_2 = network->addConvolutionNd(*conv28_cv3_0_1->getOutput(0), kNumClass, nvinfer1::DimsHW{1, 1}, weightMap["model.28.cv3.0.2.weight"], weightMap["model.28.cv3.0.2.bias"]);conv28_cv3_0_2->setStride(nvinfer1::DimsHW{1, 1});conv28_cv3_0_2->setPadding(nvinfer1::DimsHW{0, 0});nvinfer1::ITensor *inputTensor28_0[] = {conv28_cv2_0_2->getOutput(0), conv28_cv3_0_2->getOutput(0)};nvinfer1::IConcatenationLayer *cat28_0 = network->addConcatenation(inputTensor28_0, 2); // P2// output1nvinfer1::IElementWiseLayer *conv28_cv2_1_0 = convBnSiLU(network, weightMap, *conv21->getOutput(0), 64, 3, 1, 1, "model.28.cv2.1.0");nvinfer1::IElementWiseLayer *conv28_cv2_1_1 = convBnSiLU(network, weightMap, *conv28_cv2_1_0->getOutput(0), 64, 3, 1, 1, "model.28.cv2.1.1");nvinfer1::IConvolutionLayer *conv28_cv2_1_2 = network->addConvolutionNd(*conv28_cv2_1_1->getOutput(0), 64, nvinfer1::DimsHW{1, 1}, weightMap["model.28.cv2.1.2.weight"], weightMap["model.28.cv2.1.2.bias"]);conv28_cv2_1_2->setStrideNd(nvinfer1::DimsHW{1, 1});conv28_cv2_1_2->setPaddingNd(nvinfer1::DimsHW{0, 0});nvinfer1::IElementWiseLayer *conv28_cv3_1_0 = convBnSiLU(network, weightMap, *conv21->getOutput(0), 160, 3, 1, 1, "model.28.cv3.1.0");nvinfer1::IElementWiseLayer *conv28_cv3_1_1 = convBnSiLU(network, weightMap, *conv28_cv3_1_0->getOutput(0), 160, 3, 1, 1, "model.28.cv3.1.1");nvinfer1::IConvolutionLayer *conv28_cv3_1_2 = network->addConvolutionNd(*conv28_cv3_1_1->getOutput(0), kNumClass, nvinfer1::DimsHW{1, 1}, weightMap["model.28.cv3.1.2.weight"], weightMap["model.28.cv3.1.2.bias"]);conv28_cv3_1_2->setStrideNd(nvinfer1::DimsHW{1, 1});conv28_cv3_1_2->setPaddingNd(nvinfer1::DimsHW{0, 0});nvinfer1::ITensor *inputTensor28_1[] = {conv28_cv2_1_2->getOutput(0), conv28_cv3_1_2->getOutput(0)};nvinfer1::IConcatenationLayer *cat28_1 = network->addConcatenation(inputTensor28_1, 2);// output2nvinfer1::IElementWiseLayer *conv28_cv2_2_0 = convBnSiLU(network, weightMap, *conv24->getOutput(0), 64, 3, 1, 1, "model.28.cv2.2.0");nvinfer1::IElementWiseLayer *conv28_cv2_2_1 = convBnSiLU(network, weightMap, *conv28_cv2_2_0->getOutput(0), 64, 3, 1, 1, "model.28.cv2.2.1");nvinfer1::IConvolutionLayer *conv28_cv2_2_2 = network->addConvolution(*conv28_cv2_2_1->getOutput(0), 64, nvinfer1::DimsHW{1, 1}, weightMap["model.28.cv2.2.2.weight"], weightMap["model.28.cv2.2.2.bias"]);nvinfer1::IElementWiseLayer *conv28_cv3_2_0 = convBnSiLU(network, weightMap, *conv24->getOutput(0), 160, 3, 1, 1, "model.28.cv3.2.0");nvinfer1::IElementWiseLayer *conv28_cv3_2_1 = convBnSiLU(network, weightMap, *conv28_cv3_2_0->getOutput(0), 160, 3, 1, 1, "model.28.cv3.2.1");nvinfer1::IConvolutionLayer *conv28_cv3_2_2 = network->addConvolution(*conv28_cv3_2_1->getOutput(0), kNumClass, nvinfer1::DimsHW{1, 1}, weightMap["model.28.cv3.2.2.weight"], weightMap["model.28.cv3.2.2.bias"]);nvinfer1::ITensor *inputTensor28_2[] = {conv28_cv2_2_2->getOutput(0), conv28_cv3_2_2->getOutput(0)};nvinfer1::IConcatenationLayer *cat28_2 = network->addConcatenation(inputTensor28_2, 2);// output3nvinfer1::IElementWiseLayer *conv28_cv2_3_0 = convBnSiLU(network, weightMap, *conv27->getOutput(0), 64, 3, 1, 1, "model.28.cv2.3.0");nvinfer1::IElementWiseLayer *conv28_cv2_3_1 = convBnSiLU(network, weightMap, *conv28_cv2_3_0->getOutput(0), 64, 3, 1, 1, "model.28.cv2.3.1");nvinfer1::IConvolutionLayer *conv28_cv2_3_2 = network->addConvolution(*conv28_cv2_3_1->getOutput(0), 64, nvinfer1::DimsHW{1, 1}, weightMap["model.28.cv2.3.2.weight"], weightMap["model.28.cv2.3.2.bias"]);nvinfer1::IElementWiseLayer *conv28_cv3_3_0 = convBnSiLU(network, weightMap, *conv27->getOutput(0), 160, 3, 1, 1, "model.28.cv3.3.0");nvinfer1::IElementWiseLayer *conv28_cv3_3_1 = convBnSiLU(network, weightMap, *conv28_cv3_3_0->getOutput(0), 160, 3, 1, 1, "model.28.cv3.3.1");nvinfer1::IConvolutionLayer *conv28_cv3_3_2 = network->addConvolution(*conv28_cv3_3_1->getOutput(0), kNumClass, nvinfer1::DimsHW{1, 1}, weightMap["model.28.cv3.3.2.weight"], weightMap["model.28.cv3.3.2.bias"]);nvinfer1::ITensor *inputTensor28_3[] = {conv28_cv2_3_2->getOutput(0), conv28_cv3_3_2->getOutput(0)};nvinfer1::IConcatenationLayer *cat28_3 = network->addConcatenation(inputTensor28_3, 2);
      
      DETECT
      /****************************************************************************************************************************************************  YOLOV8 DETECT  *************************************************************************************************************************************************/// P2nvinfer1::IShuffleLayer *shuffle28_0 = network->addShuffle(*cat28_0->getOutput(0));shuffle28_0->setReshapeDimensions(nvinfer1::Dims2{64 + kNumClass, (kInputH / 4) * (kInputW / 4)});nvinfer1::ISliceLayer *split28_0_0 = network->addSlice(*shuffle28_0->getOutput(0), nvinfer1::Dims2{0, 0}, nvinfer1::Dims2{64, (kInputH / 4) * (kInputW / 4)}, nvinfer1::Dims2{1, 1});nvinfer1::ISliceLayer *split28_0_1 = network->addSlice(*shuffle28_0->getOutput(0), nvinfer1::Dims2{64, 0}, nvinfer1::Dims2{kNumClass, (kInputH / 4) * (kInputW / 4)}, nvinfer1::Dims2{1, 1});nvinfer1::IShuffleLayer *dfl28_0 = DFL(network, weightMap, *split28_0_0->getOutput(0), 4, (kInputH / 4) * (kInputW / 4), 1, 1, 0, "model.28.dfl.conv.weight");nvinfer1::ITensor *inputTensor28_dfl_0[] = {dfl28_0->getOutput(0), split28_0_1->getOutput(0)};nvinfer1::IConcatenationLayer *cat28_dfl_0 = network->addConcatenation(inputTensor28_dfl_0, 2);// P3nvinfer1::IShuffleLayer *shuffle28_1 = network->addShuffle(*cat28_1->getOutput(0));shuffle28_1->setReshapeDimensions(nvinfer1::Dims2{64 + kNumClass, (kInputH / 8) * (kInputW / 8)});nvinfer1::ISliceLayer *split28_1_0 = network->addSlice(*shuffle28_1->getOutput(0), nvinfer1::Dims2{0, 0}, nvinfer1::Dims2{64, (kInputH / 8) * (kInputW / 8)}, nvinfer1::Dims2{1, 1});nvinfer1::ISliceLayer *split28_1_1 = network->addSlice(*shuffle28_1->getOutput(0), nvinfer1::Dims2{64, 0}, nvinfer1::Dims2{kNumClass, (kInputH / 8) * (kInputW / 8)}, nvinfer1::Dims2{1, 1});nvinfer1::IShuffleLayer *dfl28_1 = DFL(network, weightMap, *split28_1_0->getOutput(0), 4, (kInputH / 8) * (kInputW / 8), 1, 1, 0, "model.28.dfl.conv.weight");nvinfer1::ITensor *inputTensor28_dfl_1[] = {dfl28_1->getOutput(0), split28_1_1->getOutput(0)};nvinfer1::IConcatenationLayer *cat28_dfl_1 = network->addConcatenation(inputTensor28_dfl_1, 2);// P4nvinfer1::IShuffleLayer *shuffle28_2 = network->addShuffle(*cat28_2->getOutput(0));shuffle28_2->setReshapeDimensions(nvinfer1::Dims2{64 + kNumClass, (kInputH / 16) * (kInputW / 16)});nvinfer1::ISliceLayer *split28_2_0 = network->addSlice(*shuffle28_2->getOutput(0), nvinfer1::Dims2{0, 0}, nvinfer1::Dims2{64, (kInputH / 16) * (kInputW / 16)}, nvinfer1::Dims2{1, 1});nvinfer1::ISliceLayer *split28_2_1 = network->addSlice(*shuffle28_2->getOutput(0), nvinfer1::Dims2{64, 0}, nvinfer1::Dims2{kNumClass, (kInputH / 16) * (kInputW / 16)}, nvinfer1::Dims2{1, 1});nvinfer1::IShuffleLayer *dfl28_2 = DFL(network, weightMap, *split28_2_0->getOutput(0), 4, (kInputH / 16) * (kInputW / 16), 1, 1, 0, "model.28.dfl.conv.weight");nvinfer1::ITensor *inputTensor28_dfl_2[] = {dfl28_2->getOutput(0), split28_2_1->getOutput(0)};nvinfer1::IConcatenationLayer *cat28_dfl_2 = network->addConcatenation(inputTensor28_dfl_2, 2);// P5nvinfer1::IShuffleLayer *shuffle28_3 = network->addShuffle(*cat28_3->getOutput(0));shuffle28_3->setReshapeDimensions(nvinfer1::Dims2{64 + kNumClass, (kInputH / 32) * (kInputW / 32)});nvinfer1::ISliceLayer *split28_3_0 = network->addSlice(*shuffle28_3->getOutput(0), nvinfer1::Dims2{0, 0}, nvinfer1::Dims2{64, (kInputH / 32) * (kInputW / 32)}, nvinfer1::Dims2{1, 1});nvinfer1::ISliceLayer *split28_3_1 = network->addSlice(*shuffle28_3->getOutput(0), nvinfer1::Dims2{64, 0}, nvinfer1::Dims2{kNumClass, (kInputH / 32) * (kInputW / 32)}, nvinfer1::Dims2{1, 1});nvinfer1::IShuffleLayer *dfl28_3 = DFL(network, weightMap, *split28_3_0->getOutput(0), 4, (kInputH / 32) * (kInputW / 32), 1, 1, 0, "model.28.dfl.conv.weight");nvinfer1::ITensor *inputTensor28_dfl_3[] = {dfl28_3->getOutput(0), split28_3_1->getOutput(0)};nvinfer1::IConcatenationLayer *cat28_dfl_3 = network->addConcatenation(inputTensor28_dfl_3, 2);nvinfer1::IPluginV2Layer *yolo = addYoLoLayer(network, std::vector<nvinfer1::IConcatenationLayer *>{cat28_dfl_0, cat28_dfl_1, cat28_dfl_2, cat28_dfl_3});yolo->getOutput(0)->setName(kOutputTensorName);network->markOutput(*yolo->getOutput(0));
      
  2. 修改 yololayer.cuforwardGpu 方法

     void YoloLayerPlugin::forwardGpu(const float *const *inputs, float *output, cudaStream_t stream, int mYoloV8netHeight, int mYoloV8NetWidth, int batchSize)
    {int outputElem = 1 + mMaxOutObject * sizeof(Detection) / sizeof(float);cudaMemsetAsync(output, 0, sizeof(float), stream);for (int idx = 0; idx < batchSize; ++idx){CUDA_CHECK(cudaMemsetAsync(output + idx * outputElem, 0, sizeof(float), stream));}int numElem = 0;   // int grids[3][2] = {{mYoloV8netHeight / 8, mYoloV8NetWidth / 8}, {mYoloV8netHeight / 16, mYoloV8NetWidth / 16}, {mYoloV8netHeight / 32, mYoloV8NetWidth / 32}};// todo int grids[4][2] = {{mYoloV8netHeight / 4, mYoloV8NetWidth / 4}, {mYoloV8netHeight / 8, mYoloV8NetWidth / 8}, {mYoloV8netHeight / 16, mYoloV8NetWidth / 16}, {mYoloV8netHeight / 32, mYoloV8NetWidth / 32}};// int strides[] = { 8, 16, 32 };// todo int strides[] = {4, 8, 16, 32};// for (unsigned int i = 0; i < 3; i++)// todo for (unsigned int i = 0; i < 4; i++){int grid_h = grids[i][0];int grid_w = grids[i][1];int stride = strides[i];numElem = grid_h * grid_w * batchSize;if (numElem < mThreadCount)mThreadCount = numElem;CalDetection<<<(numElem + mThreadCount - 1) / mThreadCount, mThreadCount, 0, stream>>>(inputs[i], output, numElem, mMaxOutObject, grid_h, grid_w, stride, mClassCount, outputElem);}
    }
    
  3. 修改 main.cpp -> serialize_engine ,增加一个 sub_type

      ...else if (sub_type == "x-p2"){serialized_engine = buildEngineYolov8x_p2(builder, config, DataType::kFLOAT, wts_name);}...
    
  4. 参考作者 (https://github.com/wang-xinyu/tensorrtx/tree/master/yolov8) , 获取wts , 然后生成模型.
    ./yolov8 -s ./weights/xxx.wts ./weights/xxx.engine x-p2

  5. 推理模型测试
    ./yolov8 -d xxx.engine ../images g

    在这里插入图片描述


END

  • 官网中没有找到p2的预训练模型,所以需要根据自己数据集训练模型
  • 自己训练模型需要更改 config.h 中对应的参数.
  • 以上纯手工输出,若有不对,欢迎大佬指正.

参考:

  • https://github.com/ultralytics/ultralytics/tree/main
  • https://github.com/wang-xinyu/tensorrtx/tree/master/yolov8

在这里插入图片描述

相关文章:

yolov8x-p2 实现 tensorrt 推理

简述 在最开始的yolov8提供的不同size的版本&#xff0c;包括n、s、m、l、x&#xff08;模型规模依次增大&#xff0c;通过depth, width, max_channels控制大小&#xff09;&#xff0c;这些都是通过P3、P4和P5提取图片特征&#xff1b; 正常的yolov8对象检测模型输出层是P3、…...

Type Script的变量类型

Typescript 的重要特性之一就是数据有类型了。 常见的类型如&#xff1a;字符串、数值、布尔等都有了明确的定义。 变量声明的格式 let 变量名:类型 初始值&#xff1b;字符型 let str:string "abc";数值型 数值型也支持不同的进制&#xff0c;用前缀区分 支持 整…...

系统架构师备考倒计时13天(每日知识点)

1. 数据仓库四大特点 面向主题的。操作型数据库的数据组织面向事务处理任务&#xff0c;各个业务系统之间各自分离&#xff0c;而数据仓库中的数据是按照一定的主题域进行组织的。集成的。数据仓库中的数据是在对原有分散的数据库数据抽取、清理的基础上经过系统加工、汇总和整…...

20 | Spring Data JPA 中文文档

Spring Data JPA 中文文档 1. 前言 Spring Data JPA 为 Jakarta Persistence API&#xff08;JPA&#xff09;提供 repository 支持。它简化了需要访问JPA数据源的应用程序的开发。 1.1. 项目元数据 版本控制: https://github.com/spring-projects/spring-data-jpaBug跟踪:…...

【AOA-VMD-LSTM分类故障诊断】基于阿基米德算法AOA优化变分模态分解VMD的长短期记忆网络LSTM分类算法(Matlab代码)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

K8s:Pod 中 command、args 与 Dockerfile 中 CMD、 ENTRYPOINT 的对应关系

写在前面 前几天被问到&#xff0c;这里整理笔记之前也没怎么注意这个问题理解不足小伙伴帮忙指正 曾以为老去是很遥远的事&#xff0c;突然发现年轻是很久以前的事了。时光好不经用&#xff0c;抬眼已是半生&#xff0c;所谓的中年危机&#xff0c;真正让人焦虑的不是孤单、不…...

Visual Studio Code (VS Code)安装教程

Visual Studio Code&#xff08;简称“VS Code”&#xff09;。 1.下载安装包 VS Code的官网&#xff1a; Visual Studio Code - Code Editing. Redefined 首先提及一下&#xff0c;vscode是不需要破解操作的&#xff1b; 第一步&#xff0c;看好版本&#xff0c;由于我的系…...

技巧 | 如何解决 zsh: permission denied 问题 | Mac

技巧 | 如何解决 zsh: permission denied 问题 | Mac 问题描述 在 macOS 系统终端执行 sh 程序脚本时&#xff0c;抛出异常 zsh: permission denied 原因分析 用户没有权限&#xff0c;所以才出现了这个错误&#xff0c;所以只需要用 chmod 修改一下权限就可以了 解决方法…...

【JavaEE】线程安全的集合类 -- 多线程篇(9)

线程安全的集合类 多线程环境使用 ArrayList多线程环境使用队列多线程环境使用哈希表 多线程环境使用 ArrayList 自己使用同步机制 (synchronized 或者 ReentrantLock)Collections.synchronizedList(new ArrayList); synchronizedList 是标准库提供的一个基于 synchronized 进…...

【MySQL架构篇】MySQL字符集、大小写规范及默认数据库

文章目录 1. 字符集与字符集比较规则2. 大小写规范3. 默认数据库4. 与文件系统相关 1. 字符集与字符集比较规则 MySQL有4个级别的字符集和比较规则&#xff0c;分别是 服务器级别数据库级别表级别列级别 当创建对应表或列未指定字符集时&#xff0c;默认会取其上一级别的字符…...

【Linux系统编程】命令模式2

目录 一&#xff0c;Linux下的初阶认识 1&#xff0c;管道 2&#xff0c;时间戳 二&#xff0c;Liunx系统命令操作 1&#xff0c;date时间指令 2&#xff0c;cal日历指令 3&#xff0c;which和find查找指令 3-1&#xff0c;which指令&#xff1a; 3-2&#xff0c;find…...

【Leetcode】【中等】1726.同积元组

力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能&#xff0c;轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/tuple-with-same-product/ 给你…...

Git教程

文章目录 Git 介绍GIt历史Git 安装环境配置工作区、缓存区和仓库区&#xff08;版本库&#xff09;工作区(工作目录)暂存区仓库区git工作目录下文件的装填 Git 生成公钥及添加到gitlab或Gerrit上Git常用命令git stautsgit statu -sgit addgit commitgit reset1. git reset --ha…...

使用序列化技术保存数据 改进 IO流完成项目实战水果库存系统

上一节内容是 使用IO流完成项目实战水果库存系统https://blog.csdn.net/m0_65152767/article/details/133999972?spm1001.2014.3001.5501 package com.csdn.fruit.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java…...

0基础学习PyFlink——使用PyFlink的Sink将结果输出到外部系统

在《0基础学习PyFlink——使用PyFlink的SQL进行字数统计》一文中&#xff0c;我们直接执行了Select查询操作&#xff0c;在终端中直接看到了查询结果。 select word, count(1) as count from source group by word; ------------------------------------------------------ |…...

会声会影2024旗舰版详细功能介绍

随着网络视频的蓬勃发展&#xff0c;越来越多的人开始涉足视频剪辑领域&#xff0c;毕竟技多不压身嘛。在众多剪辑软件中&#xff0c;剪映和会声会影是备受新手青睐的两种。那么&#xff0c;会声会影和剪映哪个好呢&#xff1f;在它们之间&#xff0c;哪一个更适合初学者呢接&a…...

QtCreator 查看类帮助文档,快捷键操作:按两次F1 全屏帮助,Esc取消全屏

如何查看类帮助文档 选择类&#xff0c;按F1查看类帮助文档。 示例&#xff1a; #include <QLabel> // 将光标放在QLabel上&#xff0c;按F1右侧弹出的类帮助手册可视宽度很小&#xff0c;如果按两次 F1 键&#xff0c;帮助文档将会以全屏模式显示&#xff0c;以便更清…...

C语言文件操作(1)

C语言文件操作&#xff08;1&#xff09; 文章目录 C语言文件操作&#xff08;1&#xff09;一、理解文件1.概述2.分类①.正常角度②.文本文件和二进制文件 二、文件的打开和关闭1.流和标准流2.文件类型指针3.文件的打开和关闭以及使用类型 三、文件缓冲区 一、理解文件 1.概述…...

adb 操作命令(adb调试QT项目使用到的命令)

1.adb连接串口 获取root权限 adb root && adb remount && adb shell2.测试串口命令 stty -F /dev/ttyS4 cs8 -parenb -cstopb -echoecho "12345\n" > /dev/ttyS8cat /dev/ttyS4 &3.软件在安卓系统上的名字已经活动名称&#xff08;下面是示…...

mysql下载和安装,使用

先下载安装 官方下载 已下载备份软件 安装&#xff0c;一路下一步设置环境变量 4. 打开一个cmd&#xff0c;输入mysql -u root -p...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

小木的算法日记-多叉树的递归/层序遍历

&#x1f332; 从二叉树到森林&#xff1a;一文彻底搞懂多叉树遍历的艺术 &#x1f680; 引言 你好&#xff0c;未来的算法大神&#xff01; 在数据结构的世界里&#xff0c;“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的&#xff0c;它…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道

文/法律实务观察组 在债务重组领域&#xff0c;专业机构的核心价值不仅在于减轻债务数字&#xff0c;更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明&#xff0c;合法债务优化需同步实现三重平衡&#xff1a; 法律刚性&#xff08;债…...

【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?

FTP&#xff08;File Transfer Protocol&#xff09;本身是一个基于 TCP 的协议&#xff0c;理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况&#xff0c;主要原因包括&#xff1a; ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...