1 | initial version |
@Jaewoo, please try the following experiment:
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')
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.
2 | No.2 Revision |
@Jaewoo, please try the following experiment:
1. Import the model in Torch, generate input, make forward pass and save reference output:
require torch.setdefaulttensortype('torch.FloatTensor')
net:evaluate()
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 I received 2.08616e-06
maximal absolute difference that means very similar output.
3 | No.3 Revision |
@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()
.