MXNet Forum

C++ predict that the results would be abnormal


#1

Hi,I used the C++ load model to predict that the results would be abnormal.
code:

int main(int argc, char *argv)
{

// 模型路径
std::string json_file = "model/save-symbol.json";
std::string param_file = "model/save-0016.params";

// 读取模型文件
BufferFile json_data(json_file);
BufferFile param_data(param_file);

// 参数
int dev_type = 1;  // 1: cpu, 2: gpu
int dev_id = 0;  // 设备号 多个GPU CPU使用
mx_uint num_input_nodes = 1;  // 1 个输入节点
const char* input_key[1] = { "data" };
const char** input_keys = input_key;

//输入网络的图像尺寸以及通道
int width = 273;
int height = 273;
int channels = 3;

//输入数据的指针 从0开始到4结束
const mx_uint input_shape_indptr[2] = { 0, 4 };
//输入网络数据的形状
const mx_uint input_shape_data[4] = { 1,
									  static_cast<mx_uint>(channels),
									  static_cast<mx_uint>(height),
									  static_cast<mx_uint>(width) };

if (json_data.GetLength() == 0 || param_data.GetLength() == 0)
{
	return NET_RET_CODE_READ_PARAMS_FAILD;
}

//预测器句柄
PredictorHandle pred_hnd = nullptr;

//创建预测器
if (MXPredCreate(static_cast<const char*>(json_data.GetBuffer()),
	static_cast<const char*>(param_data.GetBuffer()),
	static_cast<int>(param_data.GetLength()),
	dev_type,
	dev_id,
	num_input_nodes,
	input_keys,
	input_shape_indptr,
	input_shape_data,
	&pred_hnd) != 0)
{
	return NET_RET_CODE_CREATE_PREDICTOR_FAILD;
}

if (!pred_hnd)
{
	std::cerr << "Failed to create predict handler" << std::endl;
	return NET_RET_CODE_CREATE_PREDICTOR_FAILD;
}
//读取一张图像
Mat p_mSrcImage = imread("img1.png", IMREAD_COLOR);
//判断图像是否为空
if (p_mSrcImage.empty())
	return NET_RET_CODE_CV_READ_EMPTY;
Mat p_mChangeSizeImage;
//调整图像大小
resize(p_mSrcImage, p_mChangeSizeImage, cv::Size(width, height));
//获取一共的size
int p_iSize = p_mChangeSizeImage.rows*p_mChangeSizeImage.cols;
// Read Image Data
auto image_size = static_cast<std::size_t>(width * height * channels);
std::vector<mx_float> image_data(image_size);
std::vector<uchar> image_data2(image_size);

//分离三个通道 获取mxnet输入数据
//GetImageFile2("img1.png", image_data2.data(),3);
GetImageFile("img1.png", image_data.data(), 3);

//将图像导入到MXNET中
if (MXPredSetInput(pred_hnd, "data", image_data.data(), image_data.size()) != 0)
{
	return NET_RET_CODE_MXNET_IMPORT_DATA_FAILD;
}

//网络向前传播
if (MXPredForward(pred_hnd) != 0)
{
	return NET_RET_CODE_NET_FORWARD_FAILD;
}

mx_uint output_index = 0;
mx_uint* shape = nullptr;
mx_uint shape_len;

//获取网络输出节点的形状
if (MXPredGetOutputShape(pred_hnd, output_index, &shape, &shape_len) != 0)
{
	return NET_RET_CODE_NET_OUT_RESULT_FAILD;
}
//获取输出数据的长度
std::size_t size = 1;
for (mx_uint i = 0; i < shape_len; ++i)
{
	size *= shape[i];
}
//根据尺寸重构输出 2*273*273
std::vector<float> output_data(size);
if (MXPredGetOutput(pred_hnd, output_index, &(output_data[0]), static_cast<mx_uint>(size)) != 0)
{
	return NET_RET_CODE_NET_PRED_OUT_FAILD;//网络预测结果失败
}
//获取神经网络输出的数据 沿0轴的数据 记住神经网络输出是输入一样的格式
//获取一整段数据长度
int iLen = size / 2;
//背景通道数据
float* pfData0 = output_data.data();
//第一类通道数据 在这里是目标类
float* pfData1 = output_data.data() + iLen;
//创建一273*273的数组
std::vector<uchar> vectfTarget(iLen);
uchar* puTarget = vectfTarget.data();
//for循环比较两个值的大小 取最大值的下标 相当于argmax(axis=0)
for (int i = 0; i < iLen; i++)
{
	if (*pfData0++ <= *pfData1++)
		*puTarget++ = 1;
	else
		*puTarget++ = 0;
}
Mat mPredImage, mTempImage(273, 273, CV_8UC1, vectfTarget.data());
mTempImage.convertTo(mPredImage, CV_8UC1, 255);
//Mat mCorpImage=mPredImage*p_mSrcImage;
imshow("预测图像", mPredImage);
waitKey(0);
std::cout << "Out Net Data: " << output_data.size() << std::endl;
//释放预测器资源
if (MXPredFree(pred_hnd) != 0)
{
	return NET_RET_CODE_NET_PRED_REALSE;//是否预测器失败
}

}

Use opencv to display the projected image, which is shown in black.But there is no problem with using the python load model to predict .I would like to ask if I am wrong about the way mxnet predicted the output is stored?Or what causes the problem?


#2

This is source code link:https://pan.baidu.com/s/1bVzvyArZ86wMP3gGEx2WsQ


#3

This problem has been solved. I did not divide the data by 255


#4

Thanks for following up @DarkWings ! Glad you fixed it


#5

But now I have a problem,C++ predicts much more slowly than python predicts,C++ :0.6s,python:0.008s.Do you know what happened?


#6

I think you are mistaken on your python timings. Python code is eagerly executed. add a mx.nd.waitall() before your second clock timing to make sure the prediction is actually finished processing.


#7

You are right. add a mx.nd.waitall() after,it shows 1.0s,Thanks.