Is it expected to see deviated values after converting the input to Tensor in C++ and Python?

I am trying to run inference on a jit traced model in c++ and currently the output I get in Python is different than the output I get in C++.
At first it seems like there is something wrong with the jit in the C++, while this still could be the case, I’m not sure any more as I spotted some small deviations in the input tensor in C++ as well. I believe I did everything as instructed by the documentation so that might as well show an issue in torch::from_blob.
Therefore in order to make sure which is the case, Here are the snippets both in Python and C++ plus the sample input and sample model to test it yourself.
I also attached the weights and input comparisions in addition to the output I get from each of them so you can better see the difference and hopefully tell me what is wrong here :

  • download the jit models : models_jit.zip and extract them somewhere.
  • get the sample image as well :

for Pytorch run the following snippet of code :

import cv2
import torch
from PIL import Image 
import math

pnet_jit = torch.jit.load('D:/Codes/MTCNN/pnet.jit')
img = Image.open('D:/Codes/imgs/profile6.jpg')
width, height = img.size
scale = 0.6
sw, sh = math.ceil(width * scale), math.ceil(height * scale)
img = img.resize((sw, sh), Image.BILINEAR)
img = np.asarray(img, 'float32')

# preprocess it 
img = img.transpose((2, 0, 1))
img = np.expand_dims(img, 0)
img = (img - 127.5) * 0.0078125
img = torch.from_numpy(img)
pnet_jit.eval()

with torch.no_grad():
    output = pnet_jit(img)
    offsets = output[0].data.cpu().numpy()
    probs = output[1].data.cpu().numpy()[0, 1, :, :]
    np.set_printoptions(precision=6, suppress=True)

    print(f'offsets.shape: {offsets.shape}')
    print(f'offsets[:, :, :3, :3]: {offsets[:,:,:3,:3]}')
    print(f'probs.shape: {probs.shape}')
    print(f'probs[:3,:3]: {probs[:3,:3]}')

# output: 
"""
offsets.shape: (1, 4, 46, 85)
offsets[:, :, :3, :3]: [[
  [[-0.046459 -0.044137 -0.042813]
   [-0.018772 -0.012278  0.003612]
   [-0.00507  -0.001392  0.008206]]

  [[-0.020479 -0.023341 -0.01451 ]
   [ 0.009624  0.010831  0.011209]
   [-0.029733 -0.035114 -0.043128]]

  [[-0.018409 -0.002512  0.006032]
   [ 0.007651  0.017719  0.030373]
   [ 0.032841  0.039231  0.046088]]

  [[ 0.212606  0.226369  0.236699]
   [ 0.239645  0.243053  0.239074]
   [ 0.215258  0.212819  0.203118]]]]
probs.shape: (46, 85)
probs[:3,:3]: [
 [0.0002   0.000134 0.000091]
 [0.000558 0.000553 0.000529]
 [0.001526 0.001293 0.001365]]
"""

for C++:

#include <iostream>
#include <torch/torch.h>
#include <torch/script.h>
using namespace torch::indexing;

#include <opencv2/core.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>

void test15()
{
    std::string pnet_path = "D:/Codes//MTCNN/pnet.jit"; 
    cv::Mat img = cv::imread("D:/Codes/imgs/profile6.jpg");
    auto pnet = torch::jit::load(pnet_path);
    pnet.to(c10::DeviceType::CPU);
    pnet.eval();

    torch::NoGradGuard nograd;

    int width = img.cols;
    int height = img.rows;
    float scale = 0.6f;
    int sw = int(std::ceil(width * scale));
    int sh = int(std::ceil(height * scale));

    //cv::Mat img;
    cv::resize(img, img, cv::Size(sw, sh), 0, 0, 1);

    auto tensor_image = torch::from_blob(img.data, { img.rows, img.cols, img.channels() }, at::kByte);
    tensor_image = tensor_image.permute({ 2,0,1 });
    tensor_image.unsqueeze_(0);
    tensor_image = tensor_image.toType(c10::kFloat).sub(127.5).mul(0.0078125);
    tensor_image.to(c10::DeviceType::CPU);

    auto outputs = pnet.forward({ tensor_image }).toTuple();
    auto output0 = outputs->elements()[0].toTensor();
    auto output1 = outputs->elements()[1].toTensor();

    auto probs = output1.data().cpu().index({ 0, 1, Slice(), Slice() });
    auto offsets = output0.data().cpu();

    std::cout << "offsets.shape: " << offsets.sizes() << std::endl;
    std::cout << "offsets: " << offsets.index({ Slice(), Slice(), Slice(None,5), Slice(None,5) }) << std::endl;
    std::cout << "probs.shape: " << probs.sizes() << std::endl;
    std::cout << "probs: " << probs.index({ Slice(None,5), Slice(None,5) })<< std::endl;

}

/*output:
offsets.shape: [1, 4, 46, 85]
offsets: (1,1,.,.) =
 0.01 *
  0.1006  1.2322  1.4785  0.8394 -0.9099
  -2.9587 -2.2280  0.9300 -0.2308 -1.8565
  -3.9297 -2.1750 -0.1311 -0.4570 -1.6974
  -3.7373 -2.4041 -1.1337 -1.4220 -1.6173
  -2.1611 -1.3214 -1.1488 -1.6253 -1.8294

(1,2,.,.) =
 0.01 *
  1.3772  1.3971  1.0763  0.8742 -0.0868
  -1.2813 -0.8563 -0.8726 -1.3861 -3.3406
  -7.3669 -7.6641 -7.8015 -9.1806 -9.6936
  -12.2440 -13.5946 -14.4936 -14.9172 -14.9992
  -15.9835 -17.3126 -18.1479 -18.4232 -20.1504

(1,3,.,.) =
  0.0624  0.0926  0.1035  0.0817  0.0505
  0.0357  0.0547  0.0693  0.0535  0.0191
  0.0079  0.0276  0.0339  0.0251  0.0062
 -0.0169 -0.0048  0.0072  0.0056  0.0053
  0.0048  0.0221  0.0233  0.0170  0.0237

(1,4,.,.) =
  0.2901  0.2963  0.2959  0.2804  0.2496
  0.2618  0.2771  0.2569  0.2516  0.2052
  0.1862  0.1827  0.1650  0.1467  0.1389
  0.1131  0.0967  0.0869  0.0875  0.0919
  0.1016  0.0981  0.0872  0.0815  0.0741
[ CPUFloatType{1,4,5,5} ]
probs.shape: [46, 85]
probs: 0.001 *
 0.1459  0.1035  0.1115  0.1166  0.1958
  0.6678  0.4910  0.8298  0.9519  2.0390
  1.5165  1.6454  2.4029  3.1594  3.8440
  1.4742  2.1590  2.5001  3.3515  3.9793
  0.3751  0.3293  0.3784  0.4359  0.4375
[ CPUFloatType{5,5} ]

*/

And Here are the information regarding Weights and Their input (to make sure they are identical):

Weight comparison:

for key, module in pnet_jit.named_modules():
    print(f'module name: {key}: ')   
    if 'features.conv1' in key:
        for name, param in module.named_parameters():
            print(f'{name}: {param}')
Pytorch output
weight: tensor([[[[-0.0816,  0.8359,  1.2465],
          [-0.0150,  0.2380, -1.3453],
          [ 0.1246, -0.4108, -0.5808]],

         [[-0.2663,  0.8522,  0.5174],
          [ 0.2975,  0.3202, -1.0906],
          [ 0.1030, -0.3321, -0.4963]],

         [[-0.1369,  0.0164,  0.0337],
          [ 0.1016,  0.4359, -0.2164],
          [-0.1793, -0.1034,  0.0597]]],


        [[[ 0.4879, -0.8749, -2.4024],
          [ 0.3251, -0.7900, -0.7244],
          [ 0.7851,  0.2713,  0.2545]],

         [[-0.4946,  0.2710,  1.1370],
          [-0.1313, -0.3163,  0.5235],
          [-0.2501, -0.1840,  0.6914]],

         [[-0.2958,  1.1880,  1.2591],
          [ 0.2304,  0.4256,  0.6742],
          [-0.6014, -0.2309, -0.9644]]],


        [[[-0.7042,  0.1816, -0.3616],
          [-0.0549,  0.1669,  0.2031],
          [-0.5338, -0.0997, -0.2377]],

         [[ 0.6441,  0.2686,  0.3320],
          [ 0.5240,  0.1196,  0.3597],
          [ 0.5634,  0.0950,  0.3147]],

         [[ 0.3934, -0.2291,  0.3150],
          [-0.1116, -0.4287, -0.3120],
          [ 0.7103, -0.1339,  0.1115]]],


        [[[-2.0421, -0.5308,  0.1612],
          [-1.3518,  0.9715,  0.6593],
          [ 0.2722,  1.1669,  0.4001]],

         [[-0.0620, -0.1261,  0.5850],
          [-0.3468,  0.0133,  0.5690],
          [-0.5115,  0.1502, -0.2370]],

         [[ 0.1861, -0.4167, -0.2363],
          [-0.3585, -0.3084,  0.3250],
          [-0.0993,  0.1994,  0.8541]]],


        [[[-1.4441,  3.1158, -1.2826],
          [-0.8900,  0.8446, -0.7795],
          [ 0.2078,  0.2566, -0.0483]],

         [[-1.1270,  2.3380, -1.1374],
          [-0.0492,  0.3376, -0.4688],
          [ 0.0759,  0.0539, -0.0208]],

         [[-0.5917,  0.9548, -0.5569],
          [ 0.4371, -0.5969,  0.3891],
          [-0.0968, -0.1839,  0.2156]]],


        [[[-0.3098,  1.1087,  0.2215],
          [-1.2481,  0.5376,  0.7132],
          [-0.6857, -0.4005,  0.4775]],

         [[-0.3679,  0.5855,  0.1316],
          [-1.0780,  0.2779,  0.6630],
          [-0.6459, -0.7225,  0.3408]],

         [[-0.1987,  0.2181,  0.4195],
          [-0.5669,  0.0587,  0.2915],
          [ 0.3173, -0.4066,  0.2406]]],


        [[[-0.5409, -0.6875, -1.7550],
          [ 0.1231,  0.3844, -0.8736],
          [ 0.7980,  1.7604,  1.1732]],

         [[ 0.2150, -0.1214,  0.0584],
          [ 0.4521,  0.3732,  0.2367],
          [-0.9273, -0.4391, -0.2047]],

         [[-0.2877, -0.3038, -0.0793],
          [-0.0045,  0.1454, -0.2187],
          [ 0.4220,  0.4764, -0.2135]]],


        [[[ 1.0726,  0.6265, -1.7609],
          [ 0.9449,  1.0202, -1.6218],
          [ 0.8421,  0.5825, -1.6865]],

         [[-0.2256,  0.4871, -0.2873],
          [-0.1027,  0.5822, -0.3538],
          [-0.3428,  0.2516,  0.0826]],

         [[ 0.4017, -0.1654, -0.4704],
          [ 0.2889,  0.3179, -0.6670],
          [ 0.2409,  0.1736, -0.2978]]],


        [[[-0.9578, -1.2807, -0.7732],
          [ 1.9559,  2.3139,  1.2954],
          [-0.9624, -1.0256, -0.5687]],

         [[-0.1683, -0.8830, -0.1274],
          [ 0.7475,  1.3671,  0.5782],
          [-0.5269, -0.6681, -0.3480]],

         [[-0.3523, -0.3842, -0.2158],
          [ 0.5751,  0.6146,  0.2712],
          [-0.1618, -0.2791, -0.0442]]],


        [[[-0.5648, -1.5434,  0.6763],
          [-0.2447, -0.5838,  0.2134],
          [ 0.0059, -0.2488,  0.3020]],

         [[ 2.3330,  0.8325,  0.5582],
          [ 0.9319,  0.9614, -0.1041],
          [ 0.1203, -0.2600, -0.6534]],

         [[-1.3353,  0.2698, -1.0193],
          [-0.9542,  0.3225, -0.4546],
          [-0.0500,  0.3450,  0.5087]]]], requires_grad=True)
bias: tensor([-0.0828,  0.9198,  1.1887,  0.0868, -0.0194, -0.0315,  0.1324, -0.0522,
         0.0077,  0.6673], requires_grad=True)
module name: features.prelu1: 
module name: features.pool1: 
module name: features.conv2: 
module name: features.prelu2: 
module name: features.conv3: 
module name: features.prelu3: 
module name: conv4_1: 
module name: conv4_2: 
cpp:
for (auto m: pnet.named_modules()) {
    std::cout << m.name << std::endl;
    if (m.name == "features.conv1") {
        for (auto p : m.value.named_parameters()) {
            std::cout << p.name << ": " << p.value << std::endl;
        }}}
libtorch output
features.conv1
weight: (1,1,.,.) =
 -0.0816  0.8359  1.2465
 -0.0150  0.2380 -1.3453
  0.1246 -0.4108 -0.5808

(2,1,.,.) =
  0.4879 -0.8749 -2.4024
  0.3251 -0.7900 -0.7244
  0.7851  0.2713  0.2545

(3,1,.,.) =
 -0.7042  0.1816 -0.3616
 -0.0549  0.1669  0.2031
 -0.5338 -0.0997 -0.2377

(4,1,.,.) =
 -2.0421 -0.5308  0.1612
 -1.3518  0.9715  0.6593
  0.2722  1.1669  0.4001

(5,1,.,.) =
 -1.4441  3.1158 -1.2826
 -0.8900  0.8446 -0.7795
  0.2078  0.2566 -0.0483

(6,1,.,.) =
 -0.3098  1.1087  0.2215
 -1.2481  0.5376  0.7132
 -0.6857 -0.4005  0.4775

(7,1,.,.) =
 -0.5409 -0.6875 -1.7550
  0.1231  0.3844 -0.8736
  0.7980  1.7604  1.1732

(8,1,.,.) =
  1.0726  0.6265 -1.7609
  0.9449  1.0202 -1.6218
  0.8421  0.5825 -1.6865

(9,1,.,.) =
 -0.9578 -1.2807 -0.7732
  1.9559  2.3139  1.2954
 -0.9624 -1.0256 -0.5687

(10,1,.,.) =
 -0.5648 -1.5434  0.6763
 -0.2447 -0.5838  0.2134
  0.0059 -0.2488  0.3020

(1,2,.,.) =
 -0.2663  0.8522  0.5174
  0.2975  0.3202 -1.0906
  0.1030 -0.3321 -0.4963

(2,2,.,.) =
 -0.4946  0.2710  1.1370
 -0.1313 -0.3163  0.5235
 -0.2501 -0.1840  0.6914

(3,2,.,.) =
  0.6441  0.2686  0.3320
  0.5240  0.1196  0.3597
  0.5634  0.0950  0.3147

(4,2,.,.) =
 -0.0620 -0.1261  0.5850
 -0.3468  0.0133  0.5690
 -0.5115  0.1502 -0.2370

(5,2,.,.) =
 -1.1270  2.3380 -1.1374
 -0.0492  0.3376 -0.4688
  0.0759  0.0539 -0.0208

(6,2,.,.) =
 -0.3679  0.5855  0.1316
 -1.0780  0.2779  0.6630
 -0.6459 -0.7225  0.3408

(7,2,.,.) =
  0.2150 -0.1214  0.0584
  0.4521  0.3732  0.2367
 -0.9273 -0.4391 -0.2047

(8,2,.,.) =
 -0.2256  0.4871 -0.2873
 -0.1027  0.5822 -0.3538
 -0.3428  0.2516  0.0826

(9,2,.,.) =
 -0.1683 -0.8830 -0.1274
  0.7475  1.3671  0.5782
 -0.5269 -0.6681 -0.3480

(10,2,.,.) =
  2.3330  0.8325  0.5582
  0.9319  0.9614 -0.1041
  0.1203 -0.2600 -0.6534

(1,3,.,.) =
 -0.1369  0.0164  0.0337
  0.1016  0.4359 -0.2164
 -0.1793 -0.1034  0.0597

(2,3,.,.) =
 -0.2958  1.1880  1.2591
  0.2304  0.4256  0.6742
 -0.6014 -0.2309 -0.9644

(3,3,.,.) =
  0.3934 -0.2291  0.3150
 -0.1116 -0.4287 -0.3120
  0.7103 -0.1339  0.1115

(4,3,.,.) =
  0.1861 -0.4167 -0.2363
 -0.3585 -0.3084  0.3250
 -0.0993  0.1994  0.8541

(5,3,.,.) =
 -0.5917  0.9548 -0.5569
  0.4371 -0.5969  0.3891
 -0.0968 -0.1839  0.2156

(6,3,.,.) =
 -0.1987  0.2181  0.4195
 -0.5669  0.0587  0.2915
  0.3173 -0.4066  0.2406

(7,3,.,.) =
 -0.2877 -0.3038 -0.0793
 -0.0045  0.1454 -0.2187
  0.4220  0.4764 -0.2135

(8,3,.,.) =
  0.4017 -0.1654 -0.4704
  0.2889  0.3179 -0.6670
  0.2409  0.1736 -0.2978

(9,3,.,.) =
 -0.3523 -0.3842 -0.2158
  0.5751  0.6146  0.2712
 -0.1618 -0.2791 -0.0442

(10,3,.,.) =
 -1.3353  0.2698 -1.0193
 -0.9542  0.3225 -0.4546
 -0.0500  0.3450  0.5087
[ CPUFloatType{10,3,3,3} ]
bias: -0.0828
 0.9198
 1.1887
 0.0868
-0.0194
-0.0315
 0.1324
-0.0522
 0.0077
 0.6673
[ CPUFloatType{10} ]
features.prelu1
features.pool1
features.conv2
features.prelu2
features.conv3
features.prelu3
conv4_1
conv4_2

Input comparison :

and here are the tensor values both in Python and C++
Pytorch input (img[:, :, :10, :10]):

img: tensor([[
    [[0.3555,  0.3555,  0.3477,  0.3555,  0.3711,  0.3945,  0.3945,  0.3867,  0.3789,  0.3789],
    [ 0.3477,  0.3555,  0.3555,  0.3555,  0.3555,  0.3555,  0.3555,  0.3477,  0.3398,  0.3398],
    [ 0.3320,  0.3242,  0.3320,  0.3242,  0.3320,  0.3398,  0.3398,  0.3242,  0.3164,  0.3242],
    [ 0.2852,  0.2930,  0.2852,  0.2852,  0.2930,  0.2930,  0.2930,  0.2852,  0.2773,  0.2773],
    [ 0.2539,  0.2617,  0.2539,  0.2617,  0.2539,  0.2148,  0.2148,  0.2148,  0.2070,  0.2070],
    [ 0.1914,  0.1914,  0.1836,  0.1836,  0.1758,  0.1523,  0.1367,  0.1211,  0.0977,  0.0898],
    [ 0.1367,  0.1211,  0.0977,  0.0820,  0.0742,  0.0586,  0.0273,  -0.0195, -0.0742, -0.0820],
    [-0.0039, -0.0273, -0.0508, -0.0664, -0.0898, -0.1211, -0.1367, -0.1523, -0.1758, -0.1758],
    [-0.2070, -0.2070, -0.2148, -0.2227, -0.2148, -0.1992, -0.1992, -0.1836, -0.1680, -0.1680],
    [-0.2539, -0.2461, -0.2383, -0.2305, -0.2227, -0.1914, -0.1836, -0.1758, -0.1680, -0.1602]],

    [[0.8398,  0.8398,  0.8320,  0.8242,  0.8320,  0.8477,  0.8398, 0.8320,  0.8164,  0.8164],
    [ 0.8320,  0.8242,  0.8164,  0.8164,  0.8086,  0.8008,  0.7930, 0.7852,  0.7695,  0.7695],
    [ 0.7852,  0.7852,  0.7773,  0.7695,  0.7695,  0.7617,  0.7539, 0.7383,  0.7305,  0.7148],
    [ 0.7227,  0.7070,  0.7070,  0.6992,  0.6914,  0.6836,  0.6836, 0.6680,  0.6523,  0.6367],
    [ 0.6289,  0.6211,  0.6211,  0.6211,  0.6055,  0.5586,  0.5508, 0.5352,  0.5273,  0.5039],
    [ 0.4805,  0.4727,  0.4648,  0.4648,  0.4570,  0.4180,  0.3945, 0.3633,  0.3477,  0.3164],
    [ 0.3555,  0.3398,  0.3086,  0.2930,  0.2695,  0.2461,  0.2070, 0.1523,  0.1055,  0.0820],
    [ 0.1367,  0.1133,  0.0820,  0.0508,  0.0273, -0.0117, -0.0352, -0.0508, -0.0820, -0.0898],
    [-0.1211, -0.1289, -0.1445, -0.1602, -0.1602, -0.1523, -0.1523, -0.1367, -0.1367, -0.1289],
    [-0.2070, -0.1992, -0.1992, -0.1992, -0.1992, -0.1680, -0.1680, -0.1602, -0.1523, -0.1445]],

    [[0.9492,  0.9414,  0.9336,  0.9180,  0.9180,  0.9336,  0.9258, 0.9023,  0.8867,  0.9023],
    [ 0.9258,  0.9258,  0.9102,  0.9023,  0.8945,  0.8789,  0.8633, 0.8477,  0.8320,  0.8398],
    [ 0.8711,  0.8633,  0.8555,  0.8477,  0.8320,  0.8242,  0.8086, 0.7930,  0.7852,  0.7773],
    [ 0.7852,  0.7773,  0.7617,  0.7539,  0.7461,  0.7305,  0.7148, 0.6992,  0.6914,  0.6836],
    [ 0.6758,  0.6680,  0.6602,  0.6602,  0.6367,  0.5820,  0.5742, 0.5508,  0.5430,  0.5273],
    [ 0.5117,  0.5117,  0.4961,  0.4883,  0.4727,  0.4336,  0.4102, 0.3711,  0.3477,  0.3242],
    [ 0.3867,  0.3711,  0.3398,  0.3164,  0.2930,  0.2539,  0.2148, 0.1523,  0.1055,  0.0820],
    [ 0.1680,  0.1445,  0.1055,  0.0742,  0.0352, -0.0039, -0.0273, -0.0586, -0.0820, -0.0898],
    [-0.0898, -0.0977, -0.1211, -0.1367, -0.1445, -0.1445, -0.1445, -0.1445, -0.1445, -0.1445],
    [-0.1758, -0.1680, -0.1680, -0.1680, -0.1680, -0.1523, -0.1523, -0.1602, -0.1602, -0.1523]]]])

C++/Libtorch tensor values (img.index({Slice(), Slice(), Slice(None, 10), Slice(None, 10)});):

img: (1,1,.,.) =
  0.3555  0.3555  0.3555  0.3555  0.3555  0.4023  0.3945  0.3867  0.3789  0.3789
  0.3633  0.3633  0.3555  0.3555  0.3555  0.3555  0.3477  0.3555  0.3398  0.3398
  0.3398  0.3320  0.3320  0.3242  0.3398  0.3320  0.3398  0.3242  0.3242  0.3242
  0.2930  0.2930  0.2852  0.2773  0.2852  0.2930  0.2852  0.2852  0.2773  0.2852
  0.2695  0.2695  0.2617  0.2773  0.2695  0.2227  0.2227  0.2227  0.2148  0.2148
  0.1914  0.1914  0.1914  0.1914  0.1914  0.1602  0.1445  0.1289  0.1055  0.0977
  0.1289  0.1133  0.0820  0.0742  0.0586  0.0586  0.0195 -0.0273 -0.0820 -0.0898
  0.0039 -0.0195 -0.0508 -0.0664 -0.0820 -0.1289 -0.1445 -0.1602 -0.1836 -0.1836
 -0.2070 -0.2148 -0.2227 -0.2383 -0.2305 -0.2070 -0.2070 -0.1914 -0.1836 -0.1758
 -0.2539 -0.2461 -0.2461 -0.2383 -0.2305 -0.1914 -0.1914 -0.1758 -0.1680 -0.1602

(1,2,.,.) =
  0.8398  0.8398  0.8242  0.8164  0.8242  0.8555  0.8398  0.8320  0.8242  0.8242
  0.8320  0.8320  0.8242  0.8242  0.8086  0.8008  0.7930  0.7773  0.7695  0.7617
  0.7930  0.7852  0.7773  0.7695  0.7695  0.7695  0.7539  0.7461  0.7305  0.7227
  0.7070  0.7070  0.6992  0.6992  0.6914  0.6836  0.6758  0.6602  0.6523  0.6367
  0.6367  0.6367  0.6289  0.6289  0.6211  0.5664  0.5586  0.5430  0.5352  0.5117
  0.4805  0.4805  0.4805  0.4648  0.4727  0.4258  0.4023  0.3711  0.3555  0.3320
  0.3398  0.3320  0.3008  0.2773  0.2617  0.2461  0.1992  0.1445  0.0898  0.0586
  0.1367  0.1211  0.0898  0.0508  0.0273 -0.0195 -0.0352 -0.0664 -0.0898 -0.1055
 -0.1211 -0.1289 -0.1367 -0.1602 -0.1602 -0.1523 -0.1523 -0.1445 -0.1445 -0.1367
 -0.2148 -0.2070 -0.2070 -0.2070 -0.1992 -0.1680 -0.1680 -0.1602 -0.1523 -0.1445

(1,3,.,.) =
  0.9414  0.9414  0.9336  0.9180  0.9102  0.9336  0.9258  0.9023  0.8945  0.9023
  0.9180  0.9180  0.9102  0.9102  0.8945  0.8711  0.8633  0.8555  0.8242  0.8477
  0.8711  0.8711  0.8633  0.8477  0.8320  0.8164  0.8164  0.7930  0.7852  0.7852
  0.7773  0.7773  0.7539  0.7461  0.7305  0.7148  0.7070  0.6992  0.6836  0.6758
  0.6836  0.6836  0.6758  0.6680  0.6445  0.5898  0.5820  0.5586  0.5508  0.5352
  0.5273  0.5195  0.5117  0.4883  0.4883  0.4414  0.4102  0.3789  0.3633  0.3398
  0.3867  0.3633  0.3320  0.3008  0.2695  0.2539  0.2070  0.1445  0.0898  0.0664
  0.1836  0.1523  0.1133  0.0742  0.0352 -0.0117 -0.0352 -0.0664 -0.0898 -0.1055
 -0.0820 -0.0977 -0.1211 -0.1367 -0.1445 -0.1445 -0.1445 -0.1367 -0.1445 -0.1445
 -0.1758 -0.1758 -0.1758 -0.1758 -0.1758 -0.1602 -0.1523 -0.1680 -0.1602 -0.1602

[ CPUFloatType{1,3,10,10} ]

I’m sure there is something wrong with the input but I cant figure out whats the other way that yeilds the same value as pythons!

Update:
OK I found out this is indeed an input issue and more specifically this is becasue the image is first read by PIL.Image.Open in python and later changed into a numpy array.
If the image is read with Opencv, then , everything input wise, is the same in python and C++.
However, in my specific case, using the opencv image results in a minor change in the final result.
The only way this change/difference is minized, is when I make the opencv image grayscale and feed it to the network in which case, both the PIL input and opencv input have nearly identical output
Here are the two example, the pil image is bgr and the opencv is in grayscale mode: you need to save them on disk and see that the are nearly identical.
(left is cv_image, right is pil_image):
img62_cv img62_pil

However, if I simply dont convert the opencv image into grayscale mode (and back to bgr to get 3 channels), this is how it looks :
(left is cv_image and right is pil_image):
img62_cv img62_pil

I wonder what is causing this weird phenomena to happen!
any suggestion/help in this regard is greatly appreciated

Hi, I suspect it might be the issue with the image format.
Is your image .jpg ?
Or have you tested with a .png image ?

Even with the identical input still the network outputs different results. here are the input samples from python and c++ with their respective outputs :
python
input :

img.shape: torch.Size([1, 3, 101, 180])
img_tensored: tensor([[
        [[0.3555, 0.3555, 0.3555],
          [0.3633, 0.3633, 0.3555],
          [0.3398, 0.3320, 0.3320]],

         [[0.8398, 0.8398, 0.8242],
          [0.8320, 0.8320, 0.8242],
          [0.7930, 0.7852, 0.7773]],

         [[0.9414, 0.9414, 0.9336],
          [0.9180, 0.9180, 0.9102],
          [0.8711, 0.8711, 0.8633]]]])

output :


offsets.shape: (1, 4, 46, 85)
offsets: [[[[-0.03554668 -0.03690651]
   [-0.01305734 -0.00945055]]

  [[-0.01119633 -0.01438548]
   [ 0.01255823  0.01120286]]

  [[-0.01207605  0.00594437]
   [ 0.01896726  0.02646127]]

  [[ 0.21539722  0.2312614 ]
   [ 0.24871898  0.24893966]]]]
probs.shape: (46, 85)
probs: [[0.00016916 0.00012743]
 [0.00051409 0.00051995]]

cpp:
input :

img.shape: [1, 3, 101, 180]
img: (1,1,.,.) =
  0.9414  0.9414  0.9336
  0.9180  0.9180  0.9102
  0.8711  0.8711  0.8633

(1,2,.,.) =
  0.8398  0.8398  0.8242
  0.8320  0.8320  0.8242
  0.7930  0.7852  0.7773

(1,3,.,.) =
  0.3555  0.3555  0.3555
  0.3633  0.3633  0.3555
  0.3398  0.3320  0.3320
[ CPUFloatType{1,3,3,3} ]

output :

offsets.shape: [1, 4, 46, 85]
probs.shape: [46, 85]
offsets: (1,1,.,.) =
 0.01 *
  0.1006  1.2322
  -2.9587 -2.2280

(1,2,.,.) =
 0.01 *
  1.3772  1.3971
  -1.2813 -0.8563

(1,3,.,.) =
 0.01 *
  6.2367  9.2561
   3.5719  5.4744

(1,4,.,.) =
  0.2901  0.2963
  0.2618  0.2771
[ CPUFloatType{1,4,2,2} ]
probs: 0.0001 *
 1.4593  1.0351
  6.6782  4.9104
[ CPUFloatType{2,2} ]

Note that the cv_image channels seem to be locked when converted into tensor, that is no matter what I do , i.e. use
cv::cvtColor(image, image, cv::COLOR_BGR2RGB); or not, the channel order that you see displayed in the output wont change!

Hi, Thanks for your response, the image is jpg
but I’ll recheck now as well.
I resaved the image as jpeg regardless and used that instead, still no change, the outputs are different

The problem might be that a .jpg file is read differently by different image readers.
For example, scipy.io.imread() reads a jpg image with a different decoder level than cv2.imread(). Mayble PIL might also read a jpg image with a different decoder level.
That’s why I asked you to try with a png image.
A PNG image is not compressed and it will be read the same way whether it is from PIL or opencv.
The only possibility might be that the channels could be read in reverse mode.

1 Like

Thanks a lot. but I switched both sides to use opencv. thats why in my latest update, I stated that using the very same input, the network output is different.
meanwhile I’d test this using png as well. its not any different when using the png instead of jpg.
still the outputs are different

From the output of your last comment, I see that input is somewhat seemed to be reversed.
Can you notice it ?

Yes, the c++ side is like this, no matter what I do, it stays the same ( at least in the output)
update:
it turns out after the very same input was used (i.e. used cv both in python and c++ to read the image)
the channels had to be the same as well. the stupid me had placed the cv::cvtColor(image, image, cv::COLOR_BGR2RGB); after I have resized the image into a new object and thus it took me 14 hours to spot this stupid mistake of mine! after the channels order were fixed, everything became identical both in Python and C++.
So the gist of this post is, use the very same library for reading/dealing with images in Python and C++. using PIL and converting it to numpy is not the same as using cv from scratch! (specially if you have done some random operations such as resize, etc in PIL, etc. they yeild slightly different results, which is more than enough in some cases to send your outputs haywire! and waste your time until you realize this simple mistake!!!
Hope this prevents others from doing the very same mistake !
God bless you all!