国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

YOLOV5 INT8 量化對比

這篇具有很好參考價值的文章主要介紹了YOLOV5 INT8 量化對比。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

結果

對比了兩種INT8量化, 熵校準的量化有更高的速度,但是吧…
yolov5 量化,項目,部署,算法,人工智能,計算機視覺

1. TensorRT下的INT8量化: 最小最大值校準 (Min-Max Calibration)

最大最小值校準是一種 INT8 校準算法。在最大最小值校準中,
需要使用一組代表性的校準數(shù)據(jù)來生成量化參數(shù),
首先將推理中的數(shù)據(jù)進行統(tǒng)計,計算數(shù)據(jù)的最小值和最大值,然后根據(jù)這些值來計算量化參數(shù)。具體步驟如下:

  1. 準備一組代表性的校準數(shù)據(jù)集合,大小通常在 500-1000 之間。這些數(shù)據(jù)應該是真實推理數(shù)據(jù)的一個子集,并且要包含來自所有分類或數(shù)據(jù)分布的數(shù)據(jù)點。

  2. 執(zhí)行推理操作,對于每個輸入張量中的每個元素,記錄最大值和最小值。

  • 圖像的最大最小值就是輸入圖像像素的最大最小
  1. 根據(jù)上述步驟中收集的最小值和最大值,計算范圍和比例因子,以獲得在 INT8 上的量化值。
  • 將圖像的范圍限定在最大最小區(qū)間內(nèi)(計算范圍),再將數(shù)據(jù)類型從浮點型轉(zhuǎn)換為8位整型,就可以達到模型壓縮和運算加速的目的。
  • 這個最大最小區(qū)間可以通過統(tǒng)計輸入數(shù)據(jù)的最小值和最大值得到,然后將所有的數(shù)據(jù)映射到這個區(qū)間內(nèi)。
  • 計算范圍和縮放因子是TensorRT執(zhí)行INT8量化的時候自動生成的
  1. 通過最大最小值校準方法,我們可以得到每個權重參數(shù)和激活函數(shù)所需的量化參數(shù),以實現(xiàn)INT8精度量化。

2. TensorRT下的INT8量化: 熵校準 (Entropy Calibration)

  1. 熵校準是一種動態(tài)校準算法,它使用 KL 散度(KL Divergence)來度量推理數(shù)據(jù)和校準數(shù)據(jù)之間的分布差異。KL 散度是一種測量兩個概率分布之間差異的方法,它通常被用于度量模型的質(zhì)量和精度,而在 INT8 量化中,我們使用它來比較校準數(shù)據(jù)和推理數(shù)據(jù)之間的分布。

  2. 相對于最大最小法,熵校準在量化時需要進行動態(tài)的計算,因此在計算量上會稍微慢一些。但是,熵校準可以更好地反映實際推理數(shù)據(jù)的分布,因此通??梢垣@得更好的量化效果。所以,選擇使用哪種方法主要取決于具體的應用場景和需求。

3. TensorRT下的FP16量化:

  1. 相比于INT8量化,F(xiàn)P16量化不需要進行校準,因為FP16在浮點數(shù)表示中的精度比INT8更高。因此,F(xiàn)P16量化可以在不犧牲太多精度的情況下,顯著減少存儲和計算成本。在TensorRT中,可以通過設置相應的標志來啟用FP16量化。

  2. FP16量化不需要校準的原因是它不會改變權重和偏置的數(shù)據(jù)類型,而只是減小了它們的存儲精度。在FP16量化中,權重和偏置仍然被表示為16位浮點數(shù),但是它們的范圍被縮小了,從而減少了存儲空間的使用和計算時的延遲。因此,F(xiàn)P16量化不需要執(zhí)行校準過程來確定量化參數(shù)。

4. Build.cu文件的中的校準器

4.1 構造函數(shù)

  1. 實例化對象的時候定義傳入文件路徑, 分割好的文件名列表, batchSize
  2. 通過參數(shù)列表定義成員變量mDataDir, mBatchSize, mImgSize緩存文件名字
  3. 設置網(wǎng)絡輸入尺寸{batch, channels, mImgSize}
  4. 計算全部的tensor數(shù)量(mInputCount) = batchSize x {1x3x640x640}
  5. cuda_preprocess_init() 需要足夠的內(nèi)存處理每一幀的圖像
  6. cudaMalloc(device指針, size) 開辟內(nèi)存 size = input_height * input_width * 3
  7. 加載校準數(shù)據(jù)集的文件列表, 把全部文件名存入mFileNames()
  8. mBatchCount: 每一個batch處理多少條文件
CalibrationDataReader(const std::string &dataDir, const std::string &list, int batchSize = 1)
        : mDataDir(dataDir), mCacheFileName("weights/calibration.cache"),
          mBatchSize(batchSize), mImgSize(kInputH * kInputW)
    {
        mInputDims = {1, 3, kInputH, kInputW}; // 設置網(wǎng)絡輸入尺寸
        mInputCount = mBatchSize * samplesCommon::volume(mInputDims); // 將全部維度相乘獲得tensor的總數(shù)
        cuda_preprocess_init(mImgSize); // 獲得足夠的內(nèi)存處理每一幀數(shù)據(jù)

        // 開辟內(nèi)存
        cudaMalloc(&mDeviceBatchData, kInputH * kInputW * 3 * sizeof(float));
        // 加載校準數(shù)據(jù)集的文件列表
        std::ifstream infile(list);         // 創(chuàng)建一個文件輸入流
        std::string line;                   // 用于讀取每一行文件名
        while (std::getline(infile, line))  // 用于逐行讀取文件列表中的文件名
        {   // std::getline() 每次讀完都會自動到換行符或者stream的結尾
            sample::gLogInfo << line << std::endl; // 打印讀取到的文件名
            mFileNames.push_back(line);     // mFileNames  vector<string> 
        }  

        // 計算mBatchCount 
        mBatchCount = mFileNames.size() / mBatchSize; 
        std::cout << "CalibrationDataReader: " << mFileNames.size() << " images, " << mBatchCount << " batches." << std::endl;
    }

4.2 getBatchSize()

拿到BatchSize()

int32_t getBatchSize() const noexcept override
    {
        return mBatchSize;
    }

4.3 getBatch()

getBatch() 函數(shù)用于提供一批校準數(shù)據(jù),并將數(shù)據(jù)綁定到 TensorRT 引擎的輸入張量上。在該函數(shù)中,校準器需要將當前批次的校準數(shù)據(jù)讀取到內(nèi)存中,并將其復制到設備內(nèi)存中,然后將數(shù)據(jù)指針傳遞給 TensorRT 引擎,以供后續(xù)的校準計算使用。getBatch() 函數(shù)是由 TensorRT 引擎在執(zhí)行校準時自動調(diào)用的。

bool getBatch(void *bindings[], const char *names[], int nbBindings) noexcept override
    {
        // 如果當前批次已經(jīng)大于總批次數(shù), 返回false
        if (mCurBatch + 1 > mBatchCount)
        {
            return false;
        }
        // offset 指針在Device上面的偏移量
        int offset = kInputH * kInputW * 3 * sizeof(float);
        for (int i = 0; i < mBatchSize; i++)
        {
            int idx = mCurBatch * mBatchSize + i;   // 獲取索引在List里面
            std::string fileName = mDataDir + "/" + mFileNames[idx]; // 獲取輸入樣本的文件名
            cv::Mat img = cv::imread(fileName);  // 讀取圖片
            int new_image_size = img.cols * img.rows; // size

            // 如果圖片大了要重新分配內(nèi)存的
            if (new_image_size > mImgSize)
            {
                mImgSize = new_image_size;
                cuda_preprocess_destroy();
                cuda_preprocess_init(mImgSize);
            }

            // 輸入預處理
            process_input_gpu(img, mDeviceBatchData + i * offset);
        }

        /*
        這里就是綁定bindings跟name, 一一對應
        bindings 是 TensorRT 引擎綁定數(shù)據(jù)所使用的指針數(shù)組,用于將輸入和輸出張量分配到對應的位置,同時也可以用來傳遞批量數(shù)據(jù)。
        name是bindings對應的名字
        */
        for (int i = 0; i < nbBindings; i++)
        {
           if (!strcmp(names[i], kInputTensorName))
           {
                bindings[i] = mDeviceBatchData + i * offset;
           } 
        }
        mCurBatch++;
        return true;
    }

4.4 readCalibrationCache()

讀取存儲在文件中的量化校準表,將其存儲在緩存中,并返回緩存的指針和大小。函數(shù)首先清空了存儲在成員變量 mCalibrationCache 中的量化校準表緩存,然后從文件流中讀取緩存數(shù)據(jù)并存儲到 mCalibrationCache 中,最后將緩存的指針和大小返回。如果讀取失敗或者緩存大小為0,則返回nullptr。這個函數(shù)在 CalibrationDataReader 中被實現(xiàn),并在量化推理引擎中用于加載量化校準表。 也是在engine執(zhí)行校準的時候自動調(diào)用的

const void *readCalibrationCache(std::size_t &length) noexcept override
    {
        // 清空緩存
        mCalibrationCache.clear();
        // 輸入文件流: 路徑名
        std::ifstream input(mCacheFileName, std::ios::binary);
        input >> std::noskipws; // 設置輸入流, 不忽略空白字符
        if (input.good())
        {  
           // 把輸入流的中讀取的所有字符都復制mCalibrationCache中
           std::copy(std::istream_iterator<char>(input), std::istream_iterator<char>(), std::back_inserter(mCalibrationCache));
        }

        length = mCalibrationCache.size();
        return length ? mCalibrationCache.data() : nullptr;
    }

4.5 writeCalibrationCache()

writeCalibrationCache 方法也是在 TensorRT 引擎執(zhí)行 INT8 校準過程中自動調(diào)用的,用于將校準結果寫入到緩存文件中,以便下次使用時可以直接讀取緩存,避免重新執(zhí)行校準過程,提高了性能。具體來說,writeCalibrationCache 方法會將緩存數(shù)據(jù)指針和緩存數(shù)據(jù)的大小傳遞給文件輸出流,并將其寫入到緩存文件中。

// 用于將校準緩存寫入到緩存文件中。在該方法中,需要將緩存數(shù)據(jù)指針和緩存數(shù)據(jù)的大小傳遞給文件輸出流,并將其寫入到緩存文件中。
    void writeCalibrationCache(const void *cache, std::size_t length) noexcept override
    {
        std::ofstream output(mCacheFileName, std::ios::binary);
        output.write(reinterpret_cast<const char *>(cache), length);
    }

5. build.cu

1. builder: 創(chuàng)建builder
2. builder->network; 
    - network->parsed
    - network->Input

3. builder->config;
    config<- (builder->profile(Input))
    config<- (profileStream)
    config<- (setFlag)

4. builder->engine(*network, *config)
  1. 先創(chuàng)建builder

  2. 通過builder創(chuàng)建一個空network

  • 通過onnx解析器給網(wǎng)絡添加網(wǎng)絡的輸入、輸出、層等節(jié)點,以及設置各個節(jié)點之間的連接關系
  • onnx解析器通過日志等級查看是否能被解析, 如果能的話就走下去
  • 通過添加好的網(wǎng)絡拿到第一個Input節(jié)點
  1. builder->config(配置參數(shù))
  • config設置優(yōu)化配置profile, 這里只優(yōu)化輸入尺寸
  • config設置量化精度
  • config設置profileStream
  • config設置最大workspace
  • build設置最大的batch size
  1. engine(*network, *config)

  2. 序列化保存engine

int main(int argc, char **argv)
{
    if (argc < 4)
    {
        std::cerr << "Usage: ./build [onnx_path] [calib_dir] [calib_list_file]" << std::endl;
        return -1;
    }

    // 命令行獲取: onnx path, 校準文件路徑, 校準數(shù)據(jù)列表文件
    char *onnx_file_path = argv[1];
    char *calib_dir = argv[2];
    char *calib_list_file = argv[3];

    // ============1. 創(chuàng)建Builder===============
    auto builder = std::unique_ptr<nvinfer1::IBuilder>(nvinfer1::createInferBuilder(sample::gLogger.getTRTLogger()));
    if (!builder)
    {
        std::cerr << "builder not created" << std::endl;
        return -1;
    }

    // ============2. builder->network ================
    auto network = std::unique_ptr<nvinfer1::INetworkDefinition>(builder->createNetworkV2(1));
    if (!network)
    {
        std::cerr << "network not created" << std::endl;
        return -1;
    }
    // ============3. 解析onnx, 看看能不能解析這個onxx文件 ===============
    auto parser = std::unique_ptr<nvonnxparser::IParser>(nvonnxparser::createParser(*network, sample::gLogger.getTRTLogger()));
    auto parsed = parser->parseFromFile(onnx_file_path, static_cast<int>(sample::gLogger.getReportableSeverity()));
    if (!parsed)
    {

        std::cerr << "could not parse ONNX file: " << onnx_file_path << std::endl;
        return -1;
    }

    
    // 配置網(wǎng)絡參數(shù), 告訴TensorRT可以怎么去優(yōu)化網(wǎng)絡, 
    auto input = network->getInput(0);  // 拿到第一個輸入的節(jié)點

    // profile是TensorRT中的優(yōu)化配置,這里只使用輸入大小配置
    auto profile = builder->createOptimizationProfile();
    profile->setDimensions(input->getName(), nvinfer1::OptProfileSelector::kMIN, nvinfer1::Dims4{1, 3, 640, 640});
    profile->setDimensions(input->getName(), nvinfer1::OptProfileSelector::kMAX, nvinfer1::Dims4{1, 3, 640, 640});
    profile->setDimensions(input->getName(), nvinfer1::OptProfileSelector::kOPT, nvinfer1::Dims4{1, 3, 640, 640});

    // ============4. builder->config: 配置============================
    auto config = std::unique_ptr<nvinfer1::IBuilderConfig>(builder->createBuilderConfig());
    if (!config)
    {
        std::cerr << "create config failed" << std::endl;
        return - 1;
    }

    // 把profile加進config
    config->addOptimizationProfile(profile);

    // 設置精度, 設備不支持就FP16量化
    if (!builder->platformHasFastInt8())
    {
        sample::gLogInfo << "設備不支持int 8" << std::endl;
        config->setFlag(nvinfer1::BuilderFlag::kFP16);
    }
    else // INT8量化
    {
        // 設置calibrator量化校準器
        auto calibrator = new CalibrationDataReader(calib_dir, calib_list_file);
        config->setFlag(nvinfer1::BuilderFlag::kINT8);
        config->setInt8Calibrator(calibrator);
    }

    // 設置最大的Batch Size, workspace 
    builder->setMaxBatchSize(1);
    config->setMemoryPoolLimit(nvinfer1::MemoryPoolType::kWORKSPACE, 1 << 30);

    // 創(chuàng)建profileStream, 設置profile
    auto profileStream = samplesCommon::makeCudaStream();
    if (!profileStream)
    {
        std::cerr << "No profile stream" << std::endl;
        return -1;
    }

    // profileStream 加進 config
    config->setProfileStream(*profileStream);

    // 5. builder->Engine
    auto plan = std::unique_ptr<nvinfer1::IHostMemory>(builder->buildSerializedNetwork(*network, *config));
    if (!plan)
    {
        std::cerr << "Failed to build plan" << std::endl;
        return -1;
    }

    // ==========6. 序列化保存engine====================
    std::ofstream engine_file("./weights/my_yolov5.engine", std::ios::binary);
    assert(engine_file.is_open() && "Failed to open engine file");
    engine_file.write((char *)plan->data(), plan->size());

    // 不用釋放資源
    std::cout << "Engine Build Sucess!" << std::endl;
    return 0;
}

6. runtime.cu

解析看這篇帖子,這里幾乎沒有變化(https://blog.csdn.net/bobchen1017/article/details/129900569)文章來源地址http://www.zghlxwxcb.cn/news/detail-604138.html

#include "NvInfer.h"
#include "NvOnnxParser.h"
#include "logger.h"
#include "common.h"
#include "buffers.h"
#include "utils/preprocess.h"
#include "utils/postprocess.h"
#include "utils/types.h"

// 加載模型文件
std::vector<unsigned char> load_engine_file(const std::string &file_name)
{
    std::vector<unsigned char> engine_data;
    std::ifstream engine_file(file_name, std::ios::binary);
    assert(engine_file.is_open() && "Unable to load engine file.");
    engine_file.seekg(0, engine_file.end);
    int length = engine_file.tellg();
    engine_data.resize(length);
    engine_file.seekg(0, engine_file.beg);
    engine_file.read(reinterpret_cast<char *>(engine_data.data()), length);
    return engine_data;
}

int main(int argc, char **argv)
{
    if (argc < 4)
    {
        std::cerr << "用法: " << argv[0] << " <engine_file> <input_path_path> <mode>" << std::endl;
        return -1;
    }

    auto engine_file = argv[1];      // 模型文件
    auto input_video_path = argv[2]; // 輸入視頻文件
    auto mode = std::stoi(argv[3]);  // 模式

    // ========= 1. 創(chuàng)建推理運行時runtime =========
    auto runtime = std::unique_ptr<nvinfer1::IRuntime>(nvinfer1::createInferRuntime(sample::gLogger.getTRTLogger()));
    if (!runtime)
    {
        std::cout << "runtime create failed" << std::endl;
        return -1;
    }
    // ======== 2. 反序列化生成engine ==========
    // 加載模型文件
    auto plan = load_engine_file(engine_file);
    // 反序列化生成engine
    auto mEngine = std::shared_ptr<nvinfer1::ICudaEngine>(runtime->deserializeCudaEngine(plan.data(), plan.size()));
    if (!mEngine)
    {
        return -1;
    }

    // ======== 3. 創(chuàng)建執(zhí)行上下文context =========
    auto context = std::unique_ptr<nvinfer1::IExecutionContext>(mEngine->createExecutionContext());
    if (!context)
    {
        std::cout << "context create failed" << std::endl;
        return -1;
    }

    // ========== 4. 創(chuàng)建輸入輸出緩沖區(qū) =========
    samplesCommon::BufferManager buffers(mEngine);

    auto cap = cv::VideoCapture(input_video_path);

    int width = int(cap.get(cv::CAP_PROP_FRAME_WIDTH));
    int height = int(cap.get(cv::CAP_PROP_FRAME_HEIGHT));
    int fps = int(cap.get(cv::CAP_PROP_FPS));

    // 寫入MP4文件,參數(shù)分別是:文件名,編碼格式,幀率,幀大小
    cv::VideoWriter writer("./output/record.mp4", cv::VideoWriter::fourcc('H', '2', '6', '4'), fps, cv::Size(width, height));

    cv::Mat frame;
    int frame_index{0};

    int img_size = width * height;
    cuda_preprocess_init(img_size); // 申請cuda內(nèi)存

    while (cap.isOpened())
    {
        // 統(tǒng)計運行時間
        auto start = std::chrono::high_resolution_clock::now();

        cap >> frame;
        if (frame.empty())
        {
            std::cout << "文件處理完畢" << std::endl;
            break;
        }
        frame_index++;

        // 選擇預處理方式
        if (mode == 0)
        {
            // 使用CPU做letterbox、歸一化、BGR2RGB、NHWC to NCHW
            process_input_cpu(frame, (float *)buffers.getDeviceBuffer(kInputTensorName));
        }
        else if (mode == 1)
        {
            // 使用CPU做letterbox,GPU做歸一化、BGR2RGB、NHWC to NCHW
            process_input_cv_affine(frame, (float *)buffers.getDeviceBuffer(kInputTensorName));
        }
        else if (mode == 2)
        {
            // 使用cuda預處理所有步驟
            process_input_gpu(frame, (float *)buffers.getDeviceBuffer(kInputTensorName));
        }


        // ========== 5. 執(zhí)行推理 =========
        context->executeV2(buffers.getDeviceBindings().data());
        // 拷貝回host
        buffers.copyOutputToHost();

        // 從buffer manager中獲取模型輸出
        int32_t *num_det = (int32_t *)buffers.getHostBuffer(kOutNumDet); // 檢測到的目標個數(shù)
        int32_t *cls = (int32_t *)buffers.getHostBuffer(kOutDetCls);     // 檢測到的目標類別
        float *conf = (float *)buffers.getHostBuffer(kOutDetScores);     // 檢測到的目標置信度
        float *bbox = (float *)buffers.getHostBuffer(kOutDetBBoxes);     // 檢測到的目標框
        // 執(zhí)行nms(非極大值抑制),得到最后的檢測框
        std::vector<Detection> bboxs;
        yolo_nms(bboxs, num_det, cls, conf, bbox, kConfThresh, kNmsThresh);

        // 結束時間
        auto end = std::chrono::high_resolution_clock::now();
        // microseconds 微秒,milliseconds 毫秒,seconds 秒,1微妙=0.001毫秒 = 0.000001秒
        auto elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() / 1000.f;
        auto time_str = std::to_string(elapsed) + "ms";
        auto fps = 1000.0f / elapsed;
        auto fps_str = std::to_string(fps) + "fps";

        // 遍歷檢測結果
        for (size_t j = 0; j < bboxs.size(); j++)
        {
            cv::Rect r = get_rect(frame, bboxs[j].bbox);
            cv::rectangle(frame, r, cv::Scalar(0x27, 0xC1, 0x36), 2);
            cv::putText(frame, std::to_string((int)bboxs[j].class_id), cv::Point(r.x, r.y - 10), cv::FONT_HERSHEY_PLAIN, 1.2, cv::Scalar(0x27, 0xC1, 0x36), 2);
        }
        cv::putText(frame, time_str, cv::Point(50, 50), cv::FONT_HERSHEY_PLAIN, 1.2, cv::Scalar(0xFF, 0xFF, 0xFF), 2);
        cv::putText(frame, fps_str, cv::Point(50, 100), cv::FONT_HERSHEY_PLAIN, 1.2, cv::Scalar(0xFF, 0xFF, 0xFF), 2);

        // cv::imshow("frame", frame);
        // 寫入視頻文件
        writer.write(frame);
        std::cout << "處理完第" << frame_index << "幀" << std::endl;
        if (cv::waitKey(1) == 27)
            break;
    }
    // ========== 6. 釋放資源 =========
    // 因為使用了unique_ptr,所以不需要手動釋放
    return 0;
}

到了這里,關于YOLOV5 INT8 量化對比的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 模型量化(6):Yolov5 QAT量化訓練

    2023年08月06日
    瀏覽(25)
  • YOLOV5-模型輕量化的一些常見方法

    YOLOV5-模型輕量化的一些常見方法

    歡迎關注、點贊、評論! YOLOv5是一個基于深度學習的目標檢測算法,是YOLO系列算法的最新版本。YOLO是You Only Look Once的縮寫,意味著只需要一次前向傳遞就可以完成目標檢測任務,因此具有非??斓臋z測速度和較高的精度。 相比于YOLOv4,YOLOv5在多個方面進行了改進和優(yōu)化,包

    2024年01月22日
    瀏覽(17)
  • RK3588平臺開發(fā)系列講解(項目篇)YOLOv5部署測試

    RK3588平臺開發(fā)系列講解(項目篇)YOLOv5部署測試

    平臺 內(nèi)核版本 安卓版本 RK3588 Linux 5.10 Android 12 沉淀、分享、成長,讓自己和他人都能有所收獲!??

    2024年02月06日
    瀏覽(27)
  • YOLOv5改進實戰(zhàn) | 更換主干網(wǎng)絡Backbone(一)之輕量化網(wǎng)絡Ghostnet

    YOLOv5改進實戰(zhàn) | 更換主干網(wǎng)絡Backbone(一)之輕量化網(wǎng)絡Ghostnet

    前言 輕量化網(wǎng)絡設計 是一種針對移動設備等資源受限環(huán)境的深度學習模型設計方法。下面是一些常見的輕量化網(wǎng)絡設計方法: 網(wǎng)絡剪枝 :移除神經(jīng)網(wǎng)絡中冗余的連接和參數(shù),以達到模型壓縮和加速的目的。 分組卷積 :將卷積操作分解為若干個較小的卷積操作,并將它們分

    2024年02月05日
    瀏覽(31)
  • YOLOv8+tracking與YOLOv5+tracking performance score對比

    YOLOv8+tracking與YOLOv5+tracking performance score對比

    如果你想了解YOLOv8的模型細節(jié)和里面每個流程,可以閱讀這篇博客 https://blog.csdn.net/Albert233333/article/details/130044349 如果這篇博客對你有幫助, 希望你 點贊、收藏、關注、評論 ,您的認可將是我創(chuàng)作下去最大的動力! MOT17——https://motchallenge.net/data/MOT17/ MOT15——https://motchall

    2024年02月04日
    瀏覽(20)
  • YOLOv5內(nèi)置--hyp超參配置文件對比

    YOLOv5內(nèi)置--hyp超參配置文件對比

    YOLOv5 有大約 30 個超參數(shù)用于各種訓練設置。這些是在目錄中*.yaml的文件中定義的/data。更好的初始猜測會產(chǎn)生更好的最終結果,因此在演化之前正確初始化這些值很重要。 1. yolov5/data/hyps/hyp.scratch-low.yaml(YOLOv5 COCO訓練從頭優(yōu)化,數(shù)據(jù)增強低) 2. yolov5/data/hyps/hyp.scratch-mdeia.yaml(

    2023年04月17日
    瀏覽(79)
  • YOLOv5改進實戰(zhàn) | 更換主干網(wǎng)絡Backbone(四)之輕量化模型MobileNetV3

    YOLOv5改進實戰(zhàn) | 更換主干網(wǎng)絡Backbone(四)之輕量化模型MobileNetV3

    前言 輕量化網(wǎng)絡設計 是一種針對移動設備等資源受限環(huán)境的深度學習模型設計方法。下面是一些常見的輕量化網(wǎng)絡設計方法: 網(wǎng)絡剪枝 :移除神經(jīng)網(wǎng)絡中冗余的連接和參數(shù),以達到模型壓縮和加速的目的。 分組卷積 :將卷積操作分解為若干個較小的卷積操作,并將它們分

    2024年02月07日
    瀏覽(22)
  • 【YOLOv5】LabVIEW+TensorRT的yolov5部署實戰(zhàn)(含源碼)

    【YOLOv5】LabVIEW+TensorRT的yolov5部署實戰(zhàn)(含源碼)

    ????博客主頁: virobotics的CSDN博客:LabVIEW深度學習、人工智能博主 ??所屬專欄:『LabVIEW深度學習實戰(zhàn)』 ??上期文章: 手把手教你使用LabVIEW TensorRT實現(xiàn)圖像分類實戰(zhàn)(含源碼) ??如覺得博主文章寫的不錯或?qū)δ阌兴鶐椭脑?,還望大家多多支持呀! 歡迎大家?關注、

    2024年02月14日
    瀏覽(23)
  • YOLOV5的backbone改為shuffleNet,并進行效果對比

    YOLOV5的backbone改為shuffleNet,并進行效果對比

    近期,想嘗試將YOLOV5的backbone改為ShuffleNetv2這類的輕量級網(wǎng)絡,想和yolov5s進行對比,話不多少,正文開始 拉取YOLOV5的最新代碼,代碼鏈接如下:YOLOV5 2.1數(shù)據(jù)集下載 這里我們準備VOC數(shù)據(jù)集,如果不想提現(xiàn)下載也沒關系,訓練時會自動下載,但是這里還是建議提前準備好,下載

    2024年02月06日
    瀏覽(24)
  • 【目標檢測】YOLOv5:640與1280分辨率效果對比

    【目標檢測】YOLOv5:640與1280分辨率效果對比

    YOLOv5-5.0版本的四個預訓練權重輸入的圖片尺寸固定為640x640。 但是在YOLOv5-6.1版本,多了幾個例如 yolov5l6.pt 末尾帶6的預訓練權重,這幾個權重是在更大分辨率1280x1280進行訓練的。 因此我想在自己的電腦上測試一下相同的數(shù)據(jù)集從640x640到1280x1280效果會有多少提升。 原本是想在

    2024年02月06日
    瀏覽(49)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包