1、训练代码
# 训练我家小喵咪nora的照片
# 用的是yolov5 v6.1版本的ghost网络-->/models/hub/yolov5s-ghost.yaml
# 训练请自己百度哈哈
2、导出onnx
#在yolov5修改export.py,导出onnx模型,修改要添加模型为训练模式 即model.train()
3、onnx转换为onnx-sim
# 安装onnx-simplifer
pip install onnx-simplifer
python -m onnxsim yolov5s.onnx nora.onnx
4、onnx-sim转换为ncnn模型
#打开vs2019中 x64 Native Tools Command Promopt for VS 2019
>cd protobuf-3.4.0 # 进入protobuf目录 下载链接为:https://github.com/google/protobuf/archive/v3.4.0.zip
>mkdir buildd
>cd buildd
>cmake -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%cd%/install -Dprotobuf_BUILD_TESTS=OFF -Dprotobuf_MSVC_STATIC_RUNTIME=OFF ../cmake
>nmake
>nmake install
>cd ncnn-master # 进入ncnn-master目录 下载链接:https://codeload.github.com/Tencent/ncnn/zip/refs/heads/master
>mkdir build
>cd build
>cmake -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%cd%/install -DProtobuf_INCLUDE_DIR=E:/PythonProject/202205/protobuf-3.4.0/buildd/install/include -DProtobuf_LIBRARIES=E:/PythonProject/202205/protobuf-3.4.0/buildd/install/lib/libprotobuf.lib -DProtobuf_PROTOC_EXECUTABLE=E:/PythonProject/202205/protobuf-3.4.0/buildd/install/bin/protoc.exe -DNCNN_VULKAN=OFF ..
>nmake
>nmake install
>cd tools #进入编译好的ncnn-master/build/tools
>onnx2ncnn.exe E:/PythonProject/202204/yolov5-master/runs/train/exp18/weights/nara.onnx E:/PythonProject/202204/yolov5-master/runs/train/exp18/weights/nora.param E:/PythonProject/202204/yolov5-master/runs/train/exp18/weights/nora.bin
转换成功,如图
>
5、修改输出grid数的限制,修改为-1
6、用netron查看onnx模型结构,找出输出的3个output,分别对应8-16-32stride的输出。在官方提供的代码中修改对应的
#include "layer.h"
#include "net.h"
#include
#include
#include
#include
#include
#include
class YoloV5Focus : public ncnn::Layer
{
public:
YoloV5Focus()
{
one_blob_only = true;
}
virtual int forward(const ncnn::Mat& bottom_blob, ncnn::Mat& top_blob, const ncnn::Option& opt) const
{
int w = bottom_blob.w;
int h = bottom_blob.h;
int channels = bottom_blob.c;
int outw = w / 2;
int outh = h / 2;
int outc = channels * 4;
top_blob.create(outw, outh, outc, 4u, 1, opt.blob_allocator);
if (top_blob.empty())
return -100;
#pragma omp parallel for num_threads(opt.num_threads)
for (int p = 0; p < outc; p++)
{
const float* ptr = bottom_blob.channel(p % channels).row((p / channels) % 2) + ((p / channels) / 2);
float* outptr = top_blob.channel(p);
for (int i = 0; i < outh; i++)
{
for (int j = 0; j < outw; j++)
{
*outptr = *ptr;
outptr += 1;
ptr += 2;
}
ptr += w;
}
}
return 0;
}
};
DEFINE_LAYER_CREATOR(YoloV5Focus)
struct Object
{
cv::Rect_ rect;
int label;
float prob;
};
static inline float intersection_area(const Object& a, const Object& b)
{
cv::Rect_ inter = a.rect & b.rect;
return inter.area();
}
static void qsort_descent_inplace(std::vector
7、vs2019运行结果