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

username: Shisho_Sama
cooked: <p>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++.<br>
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 <code>torch::from_blob</code>.<br>
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.<br>
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 :</p>
<ul>
<li>download the jit models : <a href="https://github.com/pytorch/pytorch/files/5113669/models_jit.zip" rel="nofollow noopener">models_jit.zip</a> and extract them somewhere.</li>
<li>get the sample image as well :<br>
<img src="https://user-images.githubusercontent.com/5382892/90974936-f50c9200-e544-11ea-8c69-136e61705c33.jpg" alt="" width="300" height="168">
</li>
</ul>
<p>for Pytorch run the following snippet of code :</p>
<pre><code class="lang-python">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]]
"""
</code></pre>
<p>for C++:</p>
<pre><code class="lang-cpp">#include &lt;iostream&gt;
#include &lt;torch/torch.h&gt;
#include &lt;torch/script.h&gt;
using namespace torch::indexing;

#include &lt;opencv2/core.hpp&gt;
#include&lt;opencv2/imgproc/imgproc.hpp&gt;
#include&lt;opencv2/highgui/highgui.hpp&gt;

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-&gt;elements()[0].toTensor();
    auto output1 = outputs-&gt;elements()[1].toTensor();

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

    std::cout &lt;&lt; "offsets.shape: " &lt;&lt; offsets.sizes() &lt;&lt; std::endl;
    std::cout &lt;&lt; "offsets: " &lt;&lt; offsets.index({ Slice(), Slice(), Slice(None,5), Slice(None,5) }) &lt;&lt; std::endl;
    std::cout &lt;&lt; "probs.shape: " &lt;&lt; probs.sizes() &lt;&lt; std::endl;
    std::cout &lt;&lt; "probs: " &lt;&lt; probs.index({ Slice(None,5), Slice(None,5) })&lt;&lt; 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} ]

*/
</code></pre>
<p>And Here are the information regarding Weights and Their input (to make sure they are identical):</p>
<h3>Weight comparison:</h3>
<pre><code class="lang-python">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}')
</code></pre>
<details>
<summary>Pytorch output</summary>
<pre><code class="lang-python">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: 
</code></pre>
</details>
cpp:
<pre><code class="lang-cpp">for (auto m: pnet.named_modules()) {
    std::cout &lt;&lt; m.name &lt;&lt; std::endl;
    if (m.name == "features.conv1") {
        for (auto p : m.value.named_parameters()) {
            std::cout &lt;&lt; p.name &lt;&lt; ": " &lt;&lt; p.value &lt;&lt; std::endl;
        }}}
</code></pre>
<details>
<summary> libtorch output</summary>
<pre><code class="lang-cpp">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
</code></pre>
</details>
<h3>Input comparison :</h3>
<p>and here are the tensor values both in Python and C++<br>
Pytorch input (<code>img[:, :, :10, :10]</code>):</p>
<details>
<pre><code class="lang-python">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]]]])
</code></pre>
</details>
<p>C++/Libtorch tensor values (<code>img.index({Slice(), Slice(), Slice(None, 10), Slice(None, 10)});</code>):</p>
<details>
<pre><code class="lang-cpp">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} ]
</code></pre>
</details>

username: Shisho_Sama
cooked: <p>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!</p>
<p>Update:<br>
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.<br>
If the image is read with Opencv, then , everything input wise, is the same in python and C++.<br>
However, in my specific case, using the opencv image results in a minor change in the final result.<br>
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<br>
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.<br>
(left is cv_image, right is pil_image):<br>
<img src="https://discuss.pytorch.org/uploads/default/original/3X/9/3/93cd84bd8f1fc2280c3289df3a9a5d3cd063e4bf.jpeg" alt="img62_cv" data-base62-sha1="l5wvAHLBqinMgJEqEye4ljGDiBV" width="112" height="112"> <img src="https://discuss.pytorch.org/uploads/default/original/3X/5/9/592df49254669f56d3497a31e82365414fd5a935.jpeg" alt="img62_pil" data-base62-sha1="cIUX8i5U1VWWwqXM13lnFo29y4t" width="112" height="112"></p>
<p>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 :<br>
(left is cv_image and right is pil_image):<br>
<img src="https://discuss.pytorch.org/uploads/default/original/3X/0/6/06ac08dafa4f0763895d88cdfc55a1d20fbe591b.jpeg" alt="img62_cv" data-base62-sha1="X1rJayTi5tTpl43zlaU5xEPRGj" width="112" height="112"> <img src="https://discuss.pytorch.org/uploads/default/original/3X/5/9/592df49254669f56d3497a31e82365414fd5a935.jpeg" alt="img62_pil" data-base62-sha1="cIUX8i5U1VWWwqXM13lnFo29y4t" width="112" height="112"></p>
<p>I wonder what is causing this weird phenomena to happen!<br>
any suggestion/help in this regard is greatly appreciated</p>

username: chetan_patil
cooked: <p>Hi, I suspect it might be the issue with the image format.<br>
Is your image <code>.jpg</code> ?<br>
Or have you tested with a <code>.png</code> image ?</p>

username: Shisho_Sama
cooked: <p>Even with the identical input still the network outputs different results. here are the input samples from python and c++ with their respective outputs :<br>
python<br>
input :</p>
<pre><code class="lang-auto">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]]]])
</code></pre>
<p>output :</p>
<pre><code class="lang-auto">
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]]
</code></pre>
<p>cpp:<br>
input :</p>
<pre><code class="lang-auto">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} ]
</code></pre>
<p>output :</p>
<pre><code class="lang-auto">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} ]
</code></pre>
<p>Note that the cv_image channels seem to be locked when converted into tensor, that is no matter what I do , i.e. use<br>
<code>cv::cvtColor(image, image, cv::COLOR_BGR2RGB);</code> or not, the channel order that you see displayed in the output wont change!</p>

username: Shisho_Sama
cooked: <p>Hi, Thanks for your response, the image is jpg<br>
but I’ll recheck now as well.<br>
I resaved  the image as jpeg regardless and used that instead, still no change, the outputs are different</p>

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

username: Shisho_Sama
cooked: <p>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.<br>
meanwhile I’d test this using png as well. its not any different when using the png instead of jpg.<br>
still the outputs are different</p>

username: chetan_patil
cooked: <p>From the output of your last comment, I see that input is somewhat seemed to be reversed.<br>
Can you notice it ?</p>

username: Shisho_Sama
cooked: <p>Yes, the c++ side is like this, no matter what I do, it stays the same ( at least in the output)<br>
update:<br>
it turns out after the very same input was used (i.e. used cv both in python and c++ to read the image)<br>
the channels had to be the same as well. the stupid me had placed the <code>cv::cvtColor(image, image, cv::COLOR_BGR2RGB);</code> 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++.<br>
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!!!<br>
Hope this prevents others from doing the very same mistake !<br>
God bless you all!</p>