Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

@Jaewoo, please try the following experiment:

  1. Import the model in Torch, generate input, make forward pass and save reference output:

    require 'nn'

    torch.setdefaulttensortype('torch.FloatTensor')

    net = torch.load('Picasso.t7'):float()

    net:evaluate()

    input = torch.rand(1, 3, 100, 100) output = net:forward(input)

    torch.save('input.t7', input, 'binary') torch.save('output.t7', output, 'binary')

  2. Load the same model using OpenCV, set input blob and get output one. Compare it with reference blob:

    import cv2 as cv import numpy as np

    net = cv.dnn.readNet('Picasso.t7') net.setPreferableBackend(cv.dnn.DNN_BACKEND_OPENCV)

    inp = cv.dnn.readTorchBlob('input.t7') ref = cv.dnn.readTorchBlob('output.t7')

    net.setInput(inp) out = net.forward()

    print np.max(np.abs(out - ref))

I received 2.08616e-06 maximal absolute difference that means very similar output.

@Jaewoo, please try the following experiment:

  1. 1. Import the model in Torch, generate input, make forward pass and save reference output:

    require 'nn'

    'nn' torch.setdefaulttensortype('torch.FloatTensor')

    torch.setdefaulttensortype('torch.FloatTensor')

    net = torch.load('Picasso.t7'):float()

    torch.load('Picasso.t7'):float() net:evaluate()

    net:evaluate()

    input = torch.rand(1, 3, 100, 100) output = net:forward(input)

    net:forward(input)

    torch.save('input.t7', input, 'binary') torch.save('output.t7', output, 'binary')

  2. 'binary')
  3. 2. Load the same model using OpenCV, set input blob and get output one. Compare it with reference blob:

    import cv2 as cv
    import numpy as np

    np

    net = cv.dnn.readNet('Picasso.t7') net.setPreferableBackend(cv.dnn.DNN_BACKEND_OPENCV)

    net.setPreferableBackend(cv.dnn.DNN_BACKEND_OPENCV)

    inp = cv.dnn.readTorchBlob('input.t7') ref = cv.dnn.readTorchBlob('output.t7')

    cv.dnn.readTorchBlob('output.t7')

    net.setInput(inp) out = net.forward()

    net.forward()

    print np.max(np.abs(out - ref))

ref))

I received 2.08616e-06 maximal absolute difference that means very similar output.

@Jaewoo, please try the following experiment:

1. Import the model in Torch, generate input, make forward pass and save reference output:

require 'nn'

torch.setdefaulttensortype('torch.FloatTensor')

net = torch.load('Picasso.t7'):float()

net:evaluate()

input = torch.rand(1, 3, 100, 100)
output = net:forward(input)

torch.save('input.t7', input, 'binary')
torch.save('output.t7', output, 'binary')

2. Load the same model using OpenCV, set input blob and get output one. Compare it with reference blob:

import cv2 as cv
import numpy as np

net = cv.dnn.readNet('Picasso.t7')
net.setPreferableBackend(cv.dnn.DNN_BACKEND_OPENCV)

inp = cv.dnn.readTorchBlob('input.t7')
ref = cv.dnn.readTorchBlob('output.t7')

net.setInput(inp)
out = net.forward()

print np.max(np.abs(out - ref))

I received 2.08616e-06 maximal absolute difference that means very similar output.


UPDATE

@Jaewoo, Oh thank you, I got it! Yes, you're definitely right. Usually style transfer models are based on batch normalization layers which work in train mode that means they normalize input data using it's mean and div. In example, https://github.com/jcjohnson/fast-neural-style introduces InstanceNormalization. If you able to recompile OpenCV, you may enable your model modifying https://github.com/opencv/opencv/blob/master/modules/dnn/src/torch/torch_importer.cpp:

replace

if (nnName == "InstanceNormalization")

to

if (nnName == "InstanceNormalization" || (scalarParams.has("train") && scalarParams.get<bool>("train")))

I got about 2.63751e-05 difference between Torch and OpenCV outputs using scripts above without adding net:evaluate().