PaddlePaddle / Paddle

PArallel Distributed Deep LEarning: Machine Learning Framework from Industrial Practice (『飞桨』核心框架,深度学习&机器学习高性能单机、分布式训练和跨平台部署)
http://www.paddlepaddle.org/
Apache License 2.0
21.66k stars 5.44k forks source link

求助,我在paddleseg下用自己数据集训练好的bisenetV2模型,想通过模型裁剪,来提升在jetson nx C++部署预测的速度,在,模型裁剪时遇到下面的问题。的速度, #36436

Closed huangwan-jiayi closed 2 years ago

huangwan-jiayi commented 2 years ago

问题如下,我在执行到第三步时报错。我在命令行中运行的指令是: image

image

image

paddle-bot-old[bot] commented 2 years ago

您好,我们已经收到了您的问题,会安排技术人员尽快解答您的问题,请耐心等待。请您再次检查是否提供了清晰的问题描述、复现代码、环境&版本、报错信息等。同时,您也可以通过查看官网API文档常见问题历史IssueAI社区来寻求解答。祝您生活愉快~

Hi! We've received your issue and please be patient to get responded. We will arrange technicians to answer your questions as soon as possible. Please make sure that you have posted enough message to demo your request. You may also check out the APIFAQGithub Issue and AI community to get the answer.Have a nice day!

zhiboniu commented 2 years ago

您好,麻烦打印一下这几个变量看看 image

huangwan-jiayi commented 2 years ago

咋打印呢?这样吗? image 我运行没什么显示 image

zhiboniu commented 2 years ago

在进入if判断前面打印

huangwan-jiayi commented 2 years ago

结果一样 image ![Uploading image.png…]()

huangwan-jiayi commented 2 years ago

结果一样 image ![Uploading image.png…]()

huangwan-jiayi commented 2 years ago

结果一样 image image

zhiboniu commented 2 years ago

print("logits:", logits) print("labels:", labels) 像这样加上字符串,看看是没有执行还是值为空

huangwan-jiayi commented 2 years ago

看来是没有执行 image image

zhiboniu commented 2 years ago

看起来最早的log是跑到了这里的,而且你最新的执行跟开始的log不一样啊,确认一下吧,把最早的log复现出来。

huangwan-jiayi commented 2 years ago

不好意思,不太明白你的意思。 image

zhiboniu commented 2 years ago

image 这段log里显示跑到这个位置出错了,在这个位置之前打印肯定可以运行到。 请问后面几次测试为什么没有再出现这个log啊?复现这个log就可以看到打印的值了

huangwan-jiayi commented 2 years ago

我太笨了,还是不太明白你的意思,不过我之前裁剪的时候我还没有停止训练,不知道是不是和这个有关系。我现在把之前的裁剪好的文件删除了,再重新裁剪试一试。

huangwan-jiayi commented 2 years ago

image image 说输入的标签的值不对?

zhiboniu commented 2 years ago

是的,看起来实际用的标签值超出了网络中softmax实际范围,请确认网络配置或者标签与实际预期的差别吧,把错误的改了再试试

huangwan-jiayi commented 2 years ago

看起来实际用的标签值超出了网络中softmax实际范围

我不太明白怎么修改,是配置文件里的num_classes不对吗?还是要改哪里呢?

zhiboniu commented 2 years ago

如果有num_classes配置一般是这个,对的。另外确认一下softmax前面的fc层输出数量是否跟num_classes一致。 关键是要确保实际label值的范围不能大于这个num_classes。

huangwan-jiayi commented 2 years ago

如果有num_classes配置一般是这个,对的。另外确认一下softmax前面的fc层输出数量是否跟num_classes一致。 关键是要确保实际label值的范围不能大于这个num_classes。

您好我不太明白怎么确认softmax、前面的fc层输出数量是否跟num_calsses一致,另外label值就是标签里的颜色种类数吧,也就是num_classes的值吧?.

huangwan-jiayi commented 2 years ago

如果有num_classes配置一般是这个,对的。另外确认一下softmax前面的fc层输出数量是否跟num_classes一致。 关键是要确保实际label值的范围不能大于这个num_classes。

您好我不太明白怎么确认softmax、前面的fc层输出数量是否跟num_calsses一致,另外label值就是标签里的颜色种类数吧,也就是num_classes的值吧?.

hallo?

zhiboniu commented 2 years ago

num_classes可以认为是颜色种类数,label值需要不大于这个种类数量,你先确认看看两者各是多少

huangwan-jiayi commented 2 years ago

那label值在哪个地方确认以及修改呢,是label.txt吗? image

zhiboniu commented 2 years ago

因为你是用自己的数据集训练的,所以你先确认一下你的数据集跟label之间是否正确对应,如果是label的问题为什么训练过程中没有报错,会不会训练和裁剪用的是不同的label

huangwan-jiayi commented 2 years ago

image 我在原先的命令前加了这句话 , export PYTHONPATH=‘ 就好了。。。。 这是啥原因,难道我路径有问题。。。

zhiboniu commented 2 years ago

那可能是python版本兼容性的问题,可能数据解析时不同版本解析结果有些区别。

zhiboniu commented 2 years ago

如果好了的话,issue就关闭吧

huangwan-jiayi commented 2 years ago

又出现新问题了。。我把裁剪后重新训练的模型,部署到jetson nx上想看看预测速度是否有提示时,报错了, image 部署是根据c++inference的,没有裁剪的模型可以正常部署。是不是数据的输入也要做相应的修改呢? image

zhiboniu commented 2 years ago

应该不需要修改输入吧,可能还是裁剪有点问题,可以根据原因排查,我帮你找相关同事问问这个错误的原因

huangwan-jiayi commented 2 years ago

麻烦您了

应该不需要修改输入吧,可能还是裁剪有点问题,可以根据原因排查,我帮你找相关同事问问这个错误的原因

麻烦您了

zhiboniu commented 2 years ago

你好,跟推理同事讨论了这个问题,推理程序里应该没有调用opencv,所以这部分可能是前、后处理部分的问题,你可以把输入、输出打印看看,还有dtype类型,看看有没有什么异常,也可以跟裁剪前结果做一下对比

huangwan-jiayi commented 2 years ago

include

include

include

include

include

include <gflags/gflags.h>

include <glog/logging.h>

include <opencv2/opencv.hpp>

include <opencv2/core/core.hpp>

include <opencv2/highgui/highgui.hpp>

include <opencv2/imgproc/imgproc.hpp>

include "paddle/include/paddle_inference_api.h"

include "yaml-cpp/yaml.h"

include

include

include

include

using namespace std; using namespace cv;

DEFINE_string(model_dir, "/home/nvidia/Paddle-Inference-Demo/c++/bisenetV2-debug", "Directory of the inference model. " "It constains deploy.yaml and infer models"); DEFINE_string(img_path, "/home/nvidia/Paddle-Inference-Demo/c++/bisenetV2/img251.png", "Path of the test image."); DEFINE_bool(use_cpu, false, "Wether use CPU. Default: use GPU."); DEFINE_bool(use_trt, false, "Wether enable TensorRT when use GPU. Defualt: false."); DEFINE_bool(use_mkldnn, false, "Wether enable MKLDNN when use CPU. Defualt: false."); DEFINE_string(save_dir, "", "Directory of the output image.");

typedef struct YamlConfig { std::string model_file; std::string params_file; bool is_normalize; }YamlConfig;

YamlConfig load_yaml(const std::string& yaml_path) { YAML::Node node = YAML::LoadFile(yaml_path); std::string model_file = node["Deploy"]["model"].as(); std::string params_file = node["Deploy"]["params"].as(); bool is_normalize = false; if (node["Deploy"]["transforms"] && node["Deploy"]["transforms"][0]["type"].as() == "Normalize") { is_normalize = true; }

YamlConfig yaml_config = {model_file, params_file, is_normalize}; return yaml_config; }

std::shared_ptr create_predictor(const YamlConfig& yaml_config) { std::string& model_dir = FLAGS_model_dir;

paddle_infer::Config infer_config; infer_config.SetModel(model_dir + "/" + yaml_config.model_file, model_dir + "/" + yaml_config.params_file); infer_config.EnableMemoryOptim(); infer_config.EnableProfile(); std::cout << "Profile is: " << infer_config.profile_enabled() << std::endl;

if (FLAGS_use_cpu) { LOG(INFO) << "Use CPU"; if (FLAGS_use_mkldnn) { // TODO(jc): fix the bug //infer_config.EnableMKLDNN(); infer_config.SetCpuMathLibraryNumThreads(5); } } else { LOG(INFO) << "Use GPU"; infer_config.EnableUseGpu(500, 0); if (FLAGS_use_trt) { infer_config.EnableTensorRtEngine(1 << 30, 1, 1, paddle_infer::PrecisionType::kInt8, false,true); } }

auto predictor = paddle_infer::CreatePredictor(infer_config); return predictor; }

void hwc_img_2_chw_data(const cv::Mat& hwc_img, float data) { int rows = hwc_img.rows; int cols = hwc_img.cols; int chs = hwc_img.channels(); for (int i = 0; i < chs; ++i) { cv::extractChannel(hwc_img, cv::Mat(rows, cols, CV_32FC1, data + i rows * cols), i); } }

cv::Mat read_process_image(bool is_normalize) { cv::Mat img = cv::imread(FLAGS_img_path, cv::IMREAD_COLOR); cv::cvtColor(img, img, cv::COLOR_BGR2RGB); if (is_normalize) { img.convertTo(img, CV_32F, 1.0 / 255, 0); img = (img - 0.5) / 0.5; } return img; }

Mat convertTo3Channels(const Mat& binImg) { Mat three_channel = Mat::zeros(binImg.rows,binImg.cols,CV_8UC3); vector channels; for (int i=0;i<3;i++) { channels.push_back(binImg); } merge(channels,three_channel); return three_channel; }

int main(int argc, char *argv[]) { google::ParseCommandLineFlags(&argc, &argv, true); if (FLAGS_model_dir == "") { LOG(FATAL) << "The model_dir should not be empty."; }

int cntFrame = 0; std::string outFile;

// Load yaml std::string yaml_path = FLAGS_model_dir + "/deploy.yaml"; YamlConfig yaml_config = load_yaml(yaml_path);

// Create predictor auto predictor = create_predictor(yaml_config);

// 打开视频 cv::VideoCapture capture; capture.open("/home/nvidia/Paddle-Inference-Demo/c++/bisenetV2-debug/5.mp4"); if (!capture.isOpened())
{
std::cout << "Read video Failed !" << std::endl;
return -1;
}
long totalFrameNumber = capture.get(CV_CAP_PROP_FRAME_COUNT); std::cout << totalFrameNumber << endl;

//namedWindow("input video",CV_WINDOW_AUTOSIZE); //vector result; VideoWriter writer("/home/nvidia/Paddle-Inference-Demo/c++/bisenetV2-debug/test.avi",CV_FOURCC('D','I','V','X'),30.02,Size(480,270),true); int num = 0; while(true) { cv::Mat img; capture.read(img); Mat src; img.copyTo(src); // Prepare data // cv::Mat img = read_process_image(yaml_config.is_normalize); cv::cvtColor(img, img, cv::COLOR_BGR2RGB); if (yaml_config.is_normalize) { img.convertTo(img, CV_32F, 1.0 / 255, 0); img = (img - 0.5) / 0.5; }

int rows = img.rows;
int cols = img.cols;
int chs = img.channels();
std::vector<float> input_data(1 * 3 * 270 *480, 0.0f);
hwc_img_2_chw_data(img, input_data.data());

// Set input
auto input_names = predictor->GetInputNames();
auto input_t = predictor->GetInputHandle(input_names[0]);
std::vector<int> input_shape = {1, 3, 270, 480};
input_t->Reshape(input_shape);
input_t->CopyFromCpu(input_data.data()); //+++++

// Run
 clock_t start,end;
 start=clock();
// for (int a = 10; a>=1;a=a-1)
 //{
  predictor->Run();

 //}
 end=clock();
 cout << "The run time is:" << (double)(end-start)/CLOCKS_PER_SEC << "s" << endl;
 //cout << CLOCKS_PER_SEC << endl;

// Get output
auto output_names = predictor->GetOutputNames();
auto output_t = predictor->GetOutputHandle(output_names[0]);
std::vector<int> output_shape = output_t->shape();  // n * h * w
int out_num = std::accumulate(output_shape.begin(), output_shape.end(), 1,
                              std::multiplies<int>());
std::vector<int64_t> out_data(out_num);
output_t->CopyToCpu(out_data.data());

// Get pseudo image
std::vector<uint8_t> out_data_u8(out_num);
for (int i = 0; i < out_num; i++) {
  out_data_u8[i] = static_cast<uint8_t>(out_data[i]);
}

// double fps = capture.get(CV_CAP_PROP_FPS); //printf("FPS : %f",fps);

cv::Mat out_gray_img(output_shape[1], output_shape[2], CV_8UC1, out_data_u8.data());
cv::Mat im_color;
cv::Mat out_eq_img;
cv::Mat img_add;
cv::equalizeHist(out_gray_img, out_eq_img);

Mat out = convertTo3Channels(out_eq_img);

cv::applyColorMap(out, im_color, COLORMAP_HOT); // imwrite("src.png",src); // imwrite("out.png",out); cv::addWeighted(im_color,0.4,src,0.6,0,img_add); // imwrite("img_add.png",img_add);

writer.write(img_add);
//imshow("input video",out_eq_img);
num++;
if(num==totalFrameNumber) break;
cntFrame += 1;

//writer.write(out_gray_img);
//cv::waitKey(1000);

} capture.release(); LOG(INFO) << "Finish"; return 0; } 您好,以上是我全部的推理程序,我是调用了opencv的,因为我要对推理结果进行一些可视化处理。我不知道如何把输入输出打印出来。 裁剪执行过程中: image 推理程序中: ![Uploading image.png…]()

dtype类型是int64吧

huangwan-jiayi commented 2 years ago

include

include

include

include

include

include <gflags/gflags.h>

include <glog/logging.h>

include <opencv2/opencv.hpp>

include <opencv2/core/core.hpp>

include <opencv2/highgui/highgui.hpp>

include <opencv2/imgproc/imgproc.hpp>

include "paddle/include/paddle_inference_api.h"

include "yaml-cpp/yaml.h"

include

include

include

include

using namespace std; using namespace cv;

DEFINE_string(model_dir, "/home/nvidia/Paddle-Inference-Demo/c++/bisenetV2-debug", "Directory of the inference model. " "It constains deploy.yaml and infer models"); DEFINE_string(img_path, "/home/nvidia/Paddle-Inference-Demo/c++/bisenetV2/img251.png", "Path of the test image."); DEFINE_bool(use_cpu, false, "Wether use CPU. Default: use GPU."); DEFINE_bool(use_trt, false, "Wether enable TensorRT when use GPU. Defualt: false."); DEFINE_bool(use_mkldnn, false, "Wether enable MKLDNN when use CPU. Defualt: false."); DEFINE_string(save_dir, "", "Directory of the output image.");

typedef struct YamlConfig { std::string model_file; std::string params_file; bool is_normalize; }YamlConfig;

YamlConfig load_yaml(const std::string& yaml_path) { YAML::Node node = YAML::LoadFile(yaml_path); std::string model_file = node["Deploy"]["model"].as(); std::string params_file = node["Deploy"]["params"].as(); bool is_normalize = false; if (node["Deploy"]["transforms"] && node["Deploy"]["transforms"][0]["type"].as() == "Normalize") { is_normalize = true; }

YamlConfig yaml_config = {model_file, params_file, is_normalize}; return yaml_config; }

std::shared_ptr create_predictor(const YamlConfig& yaml_config) { std::string& model_dir = FLAGS_model_dir;

paddle_infer::Config infer_config; infer_config.SetModel(model_dir + "/" + yaml_config.model_file, model_dir + "/" + yaml_config.params_file); infer_config.EnableMemoryOptim(); infer_config.EnableProfile(); std::cout << "Profile is: " << infer_config.profile_enabled() << std::endl;

if (FLAGS_use_cpu) { LOG(INFO) << "Use CPU"; if (FLAGS_use_mkldnn) { // TODO(jc): fix the bug //infer_config.EnableMKLDNN(); infer_config.SetCpuMathLibraryNumThreads(5); } } else { LOG(INFO) << "Use GPU"; infer_config.EnableUseGpu(500, 0); if (FLAGS_use_trt) { infer_config.EnableTensorRtEngine(1 << 30, 1, 1, paddle_infer::PrecisionType::kInt8, false,true); } }

auto predictor = paddle_infer::CreatePredictor(infer_config); return predictor; }

void hwc_img_2_chw_data(const cv::Mat& hwc_img, float data) { int rows = hwc_img.rows; int cols = hwc_img.cols; int chs = hwc_img.channels(); for (int i = 0; i < chs; ++i) { cv::extractChannel(hwc_img, cv::Mat(rows, cols, CV_32FC1, data + i rows * cols), i); } }

cv::Mat read_process_image(bool is_normalize) { cv::Mat img = cv::imread(FLAGS_img_path, cv::IMREAD_COLOR); cv::cvtColor(img, img, cv::COLOR_BGR2RGB); if (is_normalize) { img.convertTo(img, CV_32F, 1.0 / 255, 0); img = (img - 0.5) / 0.5; } return img; }

Mat convertTo3Channels(const Mat& binImg) { Mat three_channel = Mat::zeros(binImg.rows,binImg.cols,CV_8UC3); vector channels; for (int i=0;i<3;i++) { channels.push_back(binImg); } merge(channels,three_channel); return three_channel; }

int main(int argc, char *argv[]) { google::ParseCommandLineFlags(&argc, &argv, true); if (FLAGS_model_dir == "") { LOG(FATAL) << "The model_dir should not be empty."; }

int cntFrame = 0; std::string outFile;

// Load yaml std::string yaml_path = FLAGS_model_dir + "/deploy.yaml"; YamlConfig yaml_config = load_yaml(yaml_path);

// Create predictor auto predictor = create_predictor(yaml_config);

// 打开视频 cv::VideoCapture capture; capture.open("/home/nvidia/Paddle-Inference-Demo/c++/bisenetV2-debug/5.mp4"); if (!capture.isOpened())
{
std::cout << "Read video Failed !" << std::endl;
return -1;
}
long totalFrameNumber = capture.get(CV_CAP_PROP_FRAME_COUNT); std::cout << totalFrameNumber << endl;

//namedWindow("input video",CV_WINDOW_AUTOSIZE); //vector result; VideoWriter writer("/home/nvidia/Paddle-Inference-Demo/c++/bisenetV2-debug/test.avi",CV_FOURCC('D','I','V','X'),30.02,Size(480,270),true); int num = 0; while(true) { cv::Mat img; capture.read(img); Mat src; img.copyTo(src); // Prepare data // cv::Mat img = read_process_image(yaml_config.is_normalize); cv::cvtColor(img, img, cv::COLOR_BGR2RGB); if (yaml_config.is_normalize) { img.convertTo(img, CV_32F, 1.0 / 255, 0); img = (img - 0.5) / 0.5; }

int rows = img.rows;
int cols = img.cols;
int chs = img.channels();
std::vector<float> input_data(1 * 3 * 270 *480, 0.0f);
hwc_img_2_chw_data(img, input_data.data());

// Set input
auto input_names = predictor->GetInputNames();
auto input_t = predictor->GetInputHandle(input_names[0]);
std::vector<int> input_shape = {1, 3, 270, 480};
input_t->Reshape(input_shape);
input_t->CopyFromCpu(input_data.data()); //+++++

// Run
 clock_t start,end;
 start=clock();
// for (int a = 10; a>=1;a=a-1)
 //{
  predictor->Run();

 //}
 end=clock();
 cout << "The run time is:" << (double)(end-start)/CLOCKS_PER_SEC << "s" << endl;
 //cout << CLOCKS_PER_SEC << endl;

// Get output
auto output_names = predictor->GetOutputNames();
auto output_t = predictor->GetOutputHandle(output_names[0]);
std::vector<int> output_shape = output_t->shape();  // n * h * w
int out_num = std::accumulate(output_shape.begin(), output_shape.end(), 1,
                              std::multiplies<int>());
std::vector<int64_t> out_data(out_num);
output_t->CopyToCpu(out_data.data());

// Get pseudo image
std::vector<uint8_t> out_data_u8(out_num);
for (int i = 0; i < out_num; i++) {
  out_data_u8[i] = static_cast<uint8_t>(out_data[i]);
}

// double fps = capture.get(CV_CAP_PROP_FPS); //printf("FPS : %f",fps);

cv::Mat out_gray_img(output_shape[1], output_shape[2], CV_8UC1, out_data_u8.data());
cv::Mat im_color;
cv::Mat out_eq_img;
cv::Mat img_add;
cv::equalizeHist(out_gray_img, out_eq_img);

Mat out = convertTo3Channels(out_eq_img);

cv::applyColorMap(out, im_color, COLORMAP_HOT); // imwrite("src.png",src); // imwrite("out.png",out); cv::addWeighted(im_color,0.4,src,0.6,0,img_add); // imwrite("img_add.png",img_add);

writer.write(img_add);
//imshow("input video",out_eq_img);
num++;
if(num==totalFrameNumber) break;
cntFrame += 1;

//writer.write(out_gray_img);
//cv::waitKey(1000);

} capture.release(); LOG(INFO) << "Finish"; return 0; } 您好,以上是我全部的推理程序,我是调用了opencv的,因为我要对推理结果进行一些可视化处理。我不知道如何把输入输出打印出来。 裁剪执行过程中: image 推理程序中: ![Uploading image.png…]()

dtype类型是int64吧

zhiboniu commented 2 years ago

看你的输入是float,std::vector input_data(1 3 270 *480, 0.0f); 但是输出同时用了int64盒uint8, std::vector out_data(out_num); output_t->CopyToCpu(out_data.data());

// Get pseudo image std::vector out_data_u8(out_num); for (int i = 0; i < out_num; i++) { out_data_u8[i] = static_cast(out_data[i]); }

应该是你的数据类型用乱了,这个错误应该是错误的数据类型引起的,好好梳理一下吧

huangwan-jiayi commented 2 years ago

看你的输入是float,std::vector input_data(1 3 270 *480, 0.0f); 但是输出同时用了int64盒uint8, std::vector out_data(out_num); output_t->CopyToCpu(out_data.data());

// Get pseudo image std::vector out_data_u8(out_num); for (int i = 0; i < out_num; i++) { out_data_u8[i] = static_cast(out_data[i]); }

应该是你的数据类型用乱了,这个错误应该是错误的数据类型引起的,好好梳理一下吧

如果是数据类型的问题,那为什么我没有裁剪的模型可以正常使用呢?

zhiboniu commented 2 years ago

这样吧,你把程序注释掉再一块一块放开测试,直到出现报错。然后对这块程序再同样分块放开测试,看看具体是哪一行代码引起的,就可以明确问题了

huangwan-jiayi commented 2 years ago

我还是没有解决,我把这个issue关了,重新开一个issue,把代码和模型文件,以及环境信息都提供一下,看您们可以帮忙复现一下吗