Closed LaurentBerger closed 1 year ago
@berak @sturkmen72 @crackwitz
Please Can you run this code? My conclusion is : disable multithreading make opencv model adabins works
simplified model can be loaded here image is here
import onnx
import onnxruntime as rt
import numpy as np
import cv2 as cv
onnx_name = "AdaBins_kitti_sim.onnx"
image = cv.imread(cv.samples.findFile("classroom__rgb_00283.jpg"))
# DATA for ONNX and OPENCV
blob = np.transpose(image.astype(np.float32), [2, 0, 1])/255
blob = blob.reshape((1,3, 480, 640))
# ONNX inference
sess = rt.InferenceSession(onnx_name)
input_name = sess.get_inputs()[0].name
output_name = sess.get_outputs()[0].name
predonnx = sess.run([sess.get_outputs()[0].name,
sess.get_outputs()[1].name,
],
{input_name: blob})
print("ONNX RESULT")
disparity_onnx = predonnx[1][0, 0, : ,:]
bins_onnx = predonnx[0]
print(disparity_onnx[100:105,25:43:3])
# OPENCV inference
net = cv.dnn.readNet(onnx_name)
net.setInput(blob)
pred_opencv = net.forward([sess.get_outputs()[0].name,
sess.get_outputs()[1].name,
])
print("OPENCV")
disparity_opencv = pred_opencv[1][0, 0, : ,:]
bins_opencv = pred_opencv[0]
print(disparity_opencv[100:105,25:43:3])
print("Quadratic error ", np.mean((disparity_onnx-disparity_opencv)**2))
print("Max error ", np.max((disparity_onnx-disparity_opencv)**2))
cv.setNumThreads(0)
print("DISABLE THREAD")
pred_opencv = net.forward([sess.get_outputs()[0].name,
sess.get_outputs()[1].name,
])
print("OPENCV")
disparity_opencv = pred_opencv[1][0, 0, : ,:]
bins_opencv = pred_opencv[0]
print(disparity_opencv[100:105,25:43:3])
print("Quadratic error ", np.mean((disparity_onnx-disparity_opencv)**2))
print("Max error ", np.max((disparity_onnx-disparity_opencv)**2))
Please Can you run this code?
No thanks. I am not involved.
Hi @LaurentBerger, can you try to disable the winograd optimized before forward the net?
net = cv.dnn.readNet(onnx_name)
net.enableWinograd(false)
net.setInput(blob)
pred_opencv = net.forward([sess.get_outputs()[0].name,
sess.get_outputs()[1].name,
])
Ref : https://docs.opencv.org/4.x/db/d30/classcv_1_1dnn_1_1Net.html#a14a87a7604c03ef4ff366672ee9bfcf2
Hi @zihaomu
new code:
onnx_name = "AdaBins_kitti_sim.onnx"
image = cv.imread(cv.samples.findFile("classroom__rgb_00283.jpg"))
# DATA for ONNX and OPENCV
blob = np.transpose(image.astype(np.float32), [2, 0, 1])/255
blob = blob.reshape((1,3, 480, 640))
# ONNX inference
sess = rt.InferenceSession(onnx_name)
input_name = sess.get_inputs()[0].name
output_name = sess.get_outputs()[0].name
predonnx = sess.run([sess.get_outputs()[0].name,
sess.get_outputs()[1].name,
],
{input_name: blob})
disparity_onnx = predonnx[1][0, 0, : ,:]
bins_onnx = predonnx[0]
# OPENCV inference
cv.setNumThreads(32)
print("Multithreads for opencv")
net = cv.dnn.readNet(onnx_name)
net.setInput(blob)
pred_opencv = net.forward([sess.get_outputs()[0].name,
sess.get_outputs()[1].name,
])
disparity_opencv = pred_opencv[1][0, 0, : ,:]
bins_opencv = pred_opencv[0]
# print(disparity_opencv[100:105,25:43:3])
print("Quadratic error ", np.mean((disparity_onnx-disparity_opencv)**2))
print("Max error ", np.max((disparity_onnx-disparity_opencv)**2))
cv.setNumThreads(1)
print("DISABLE THREAD or 1 thread")
pred_opencv = net.forward([sess.get_outputs()[0].name,
sess.get_outputs()[1].name,
])
disparity_opencv = pred_opencv[1][0, 0, : ,:]
bins_opencv = pred_opencv[0]
# print(disparity_opencv[100:105,25:43:3])
print("Quadratic error ", np.mean((disparity_onnx-disparity_opencv)**2))
print("Max error ", np.max((disparity_onnx-disparity_opencv)**2))
# OPENCV inference
cv.setNumThreads(32)
net.enableWinograd(False)
print("Multithreads for opencv and no winograd")
net = cv.dnn.readNet(onnx_name)
net.setInput(blob)
pred_opencv = net.forward([sess.get_outputs()[0].name,
sess.get_outputs()[1].name,
])
disparity_opencv = pred_opencv[1][0, 0, : ,:]
bins_opencv = pred_opencv[0]
print("Quadratic error ", np.mean((disparity_onnx-disparity_opencv)**2))
print("Max error ", np.max((disparity_onnx-disparity_opencv)**2))
and results
Multithreads for opencv
Quadratic error 0.84839463
Max error 7.712089
DISABLE THREAD or 1 thread
Quadratic error 2.48915e-10
Max error 2.5547706e-09
Multithreads for opencv and no winograd
Quadratic error 0.84839463
Max error 7.712089
May be something is wrong in my opencv version. A basic model with one node reduceSum (last node AdaBins_kitti_sim) and one input
import numpy as np
import onnx
import onnxsim
import onnx.reference
import cv2 as cv
data = np.array(
[[[1, 2], [3, 4]], [[5, 6], [7, 8]], [[9, 10], [11, 12]]], dtype=np.float32
)
shape_ini = data.shape
select_axes = np.array([0], dtype=np.int64)
keepdims = 1
print("input DATA ")
print(data)
#https://github.com/onnx/onnx/blob/main/docs/PythonAPIOverview.md
#https://onnx.ai/onnx/expect_onnxruntime.html
#https://onnx.ai/onnx/intro/python.html#initializer-default-value
axes = np.array([1], dtype=np.int64)
out1 = onnx.helper.make_tensor_value_info('out1', onnx.TensorProto.FLOAT, [None, None, None])
inp0 = onnx.helper.make_tensor_value_info('inp0', onnx.TensorProto.FLOAT, shape_ini)
axes = onnx.numpy_helper.from_array(select_axes[0], "axes")
node1 = onnx.helper.make_node( "ReduceSum", inputs=["inp0", "axes"], outputs=["out1"], keepdims=keepdims)
graph = onnx.helper.make_graph([node1], 'test_reducesum', [inp0], [out1], [axes])
onnx_model = onnx.helper.make_model(graph)
feeds = {'inp0': data}
sess = onnx.reference.ReferenceEvaluator(onnx_model)
res_onnx = sess.run(None, feeds)
print("ONNX result")
print(res_onnx[0])
onnx_name = "testReduceSum"
print("Writting model")
with open(onnx_name + ".onnx", "wb") as f:
f.write(onnx_model.SerializeToString())
# print("Reading model")
# onnx_model = onnx.load(onnx_name+'.onnx')
# simplified_model, _ = onnxsim.simplify(onnx_model)
# onnx.save(simplified_model, onnx_name+'_sim.onnx')
cv.setNumThreads(0)
net = cv.dnn.readNet(onnx_name+'.onnx')
net.enableWinograd(False)
print("Set opencv input DATA ")
print(data)
net.setInput(data)
res_ocv = net.forward()
print("OPENCV result")
print(res_ocv)
results input DATA [[[ 1. 2.] [ 3. 4.]]
[[ 5. 6.] [ 7. 8.]]
[[ 9. 10.] [11. 12.]]] ONNX result [[[15. 18.] [21. 24.]]] Writting model Set opencv input DATA [[[ 1. 2.] [ 3. 4.]]
[[ 5. 6.] [ 7. 8.]]
[[ 9. 10.] [11. 12.]]] OPENCV result [[0. 0.]]
Finally I can reproduce on macOS
Hi @LaurentBerger, looks like the model link can not be reached. Can you attach the onnx file to this issue. I will try to reproduce this issue on my site.
Hi, I do not know why I can not reach this link:(http://www.traimaocv.fr/CoursTF/AdaBins_kitti_sim.onnx) Can you download the onnx model and attach it to this issue, that would be useful for me.
Model is too big. Hope this one is good https://drive.google.com/file/d/1O5yTir83UfYiNpDl0l9LZK8r_1H8DeGc/view?usp=sharing
@zihaomu I think something is weird in pallalel implementation of reduce node (Mean ,Sum, ...):
In this code I get result of node mul and reducemean and I compare output result for 1 thread and 32 threads :
import numpy as np
import cv2 as cv
onnx_name = "AdaBins_kitti_sim.onnx"
image = cv.imread(cv.samples.findFile("classroom__rgb_00283.jpg"))
# DATA OPENCV
blob = np.transpose(image.astype(np.float32), [2, 0, 1])/255
blob = blob.reshape((1,3, 480, 640))
# OPENCV inference
cv.setNumThreads(32)
print("Multithreads for opencv")
net = cv.dnn.readNet(onnx_name)
net.setInput(blob)
l_name_ouput =[sess.get_outputs()[0].name,
sess.get_outputs()[1].name,
'onnx_node!/encoder/blocks.0/blocks.0.0/act1/Mul',
'onnx_node!/encoder/blocks.0/blocks.0.0/se/ReduceMean'
]
pred_opencv32 = net.forward(l_name_ouput)
cv.setNumThreads(1)
print("DISABLE THREAD or 1 thread")
pred_opencv1 = net.forward(l_name_ouput)
idx = 2
print("Quadratic error for node ", l_name_ouput[idx], " : ", np.mean((pred_opencv32[idx] - pred_opencv1[idx])**2))
print("Max error for node ", l_name_ouput[idx], " : ", np.max((pred_opencv32[idx] - pred_opencv1[idx])**2))
idx = 3
print("Quadratic error for node ", l_name_ouput[idx], " : ", np.mean((pred_opencv32[idx] - pred_opencv1[idx])**2))
print("Max error for node ", l_name_ouput[idx], " : ", np.max((pred_opencv32[idx] - pred_opencv1[idx])**2))
Result is
Multithreads for opencv
DISABLE THREAD or 1 thread
Quadratic error for node onnx_node!/encoder/blocks.0/blocks.0.0/act1/Mul : 0.0
Max error for node onnx_node!/encoder/blocks.0/blocks.0.0/act1/Mul : 0.0
Quadratic error for node onnx_node!/encoder/blocks.0/blocks.0.0/se/ReduceMean : 3.4234838
Max error for node onnx_node!/encoder/blocks.0/blocks.0.0/se/ReduceMean : 13.81892
System Information
Detailed description
pytorch and onnx gives same results opencv does not give good results
Results
ONNX RESULT [[4.446731 4.4490666 4.46463 4.4546375 4.4510665 4.456948 ] [4.4421244 4.4491835 4.4703193 4.460532 4.4576974 4.462741 ] [4.440228 4.4505563 4.4774194 4.4691973 4.4677935 4.470848 ] [4.435331 4.4522853 4.484742 4.480783 4.480365 4.4803877] [4.4323177 4.4522853 4.4912124 4.4923916 4.4934096 4.4903293]] OPENCV [[5.1145616 5.1145616 5.1145616 5.1145616 5.1145616 5.1145616] [5.115294 5.115294 5.115294 5.115294 5.115294 5.115294 ] [5.116197 5.116197 5.116197 5.116197 5.116197 5.116197 ] [5.1162567 5.1162567 5.1162567 5.1162567 5.1162567 5.1162567] [5.115356 5.115356 5.115356 5.115356 5.115356 5.115356 ]] 0.84839463 7.712089
Steps to reproduce
simplified model can be loaded here image is here
Issue submission checklist