zl程序教程

您现在的位置是:首页 >  其它

当前栏目

TNN MatConvertParam参数scale和bias设置

设置 参数 scale
2023-09-11 14:19:30 时间

Pytorch的Normalize的计算过程是:TNN MatConvertParam参数设置

使用TNN进行模型推理前,需要进行必要的预处理,如下需要设置TNN_NS::MatConvertParam inputCvtParam的scale和bias两个参数值

    /*** Read image ***/
    cv::Mat orig_image = cv::imread(IMAGE_NAME);
    int imageWidth = orig_image.size[1];
    int imageHeight = orig_image.size[0];
    printf("image size: width = %d, height = %d\n", imageWidth, imageHeight);

    /*** Pre process ***/
    /* resize, colorconversion */
    cv::Mat inputImage;
    cv::resize(orig_image, inputImage, cv::Size(MODEL_WIDTH, MODEL_HEIGHT));
    cv::cvtColor(inputImage, inputImage, cv::COLOR_BGR2RGB);
    /*** normalize ***/
    auto inputMat = std::make_shared<TNN_NS::Mat>(DEVICE_TYPE, TNN_NS::N8UC3, nchw, (uint8_t*)inputImage.data);
    CHECK(inputMat != NULL);
    TNN_NS::MatConvertParam inputCvtParam;
    inputCvtParam.scale = {1 / 0.5 / 255.f, 1 / 0.5 / 255.f, 1 / 0.5 / 255.f, 1 / 0.5 / 255.;
    inputCvtParam.bias  = {-0.5 / 0.5, -0.5 / 0.5, -0.5 / 0.5, -0.5 / 0.5};
    status = instance->SetInputMat(inputMat, inputCvtParam);

TNN_NS::MatConvertParam inputCvtParam的scale和bias的计算规则是:

y = scale*x+bias

如果你的模型是Pytorch训练的模型,一般会使用:

rgb_mean=(0.5, 0.5, 0.5)
rgb_std=(0.5, 0.5, 0.5)

normalize = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize(rgb_mean, rgb_std)
])

 Pytorch的Normalize的计算过程是减均值除方差,即:

input[channel] = (input[channel] - mean[channel]) / std[channel]
即:y = (x-m)/std (其中输入x是将0~255归一化到0~1的图像数据)

将Pytorch的Normalize和TNN的MatConvertParam进行变换,即可对齐了:

y = (x-m)/std  --->  y = scale*x+bias

恒等变换如下:

y = (x-m)/std

# 由于Pytorch的Normalize对输入x是将0~255归一化到0~1的图像数据,因此需要逆归一化为0~255

y = (x-m*255)/(std*255)

#  拆分每项

y=x/(std*255)-m/std

# 比较y = scale*x+bias得:

scale=1/(std*255)=1/std/255

bias=-m/std

因此Pytorch的

transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
对应TNN_NS::MatConvertParam的参数为:
    TNN_NS::MatConvertParam inputCvtParam;
    inputCvtParam.scale = {1 / 0.5 / 255.f, 1 / 0.5 / 255.f, 1 / 0.5 / 255.f, 1 / 0.5 / 255.;
    inputCvtParam.bias  = {-0.5 / 0.5, -0.5 / 0.5, -0.5 / 0.5, -0.5 / 0.5};

在NCNN的Normalize:

【NCNN源码解读】Mat(二)Normalize - 知乎

ncnn::Mat input = ncnn::Mat::from_pixels(resized.data, ncnn::Mat::PIXEL_BGR2RGB, WIDTH, HEIGHT);
const float mean[3] = { 0.5f * 255.f, 0.5f * 255.f, 0.5f * 255.f };
const float norm[3] = { 1 / 0.5f / 255.f, 1 / 0.5f / 255.f, 1 /0.5f / 255.f };
input.substract_mean_normalize(mean, norm);