Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No attribute axes in reduce onnx layer with opset13 #25118

Open
4 tasks done
LaurentBerger opened this issue Feb 28, 2024 · 7 comments
Open
4 tasks done

No attribute axes in reduce onnx layer with opset13 #25118

LaurentBerger opened this issue Feb 28, 2024 · 7 comments
Assignees
Labels
bug category: dnn (onnx) ONNX suport issues in DNN module
Milestone

Comments

@LaurentBerger
Copy link
Contributor

LaurentBerger commented Feb 28, 2024

System Information

opencv 4.9

Detailed description

There is no attribute axes in all reduce layers since onnx version 13

reduce axes is given using an input

In current opencv version if there is no attribute axes all axes are reduce

// get axes if it is existed, otherwise reduce all
if (params.has("axes")) {
auto param_axes = params.get("axes");
int num_axes = param_axes.size();
axes.resize(num_axes);
for (int i = 0; i < num_axes; ++i)
axes[i] = param_axes.get<int>(i);
}

Steps to reproduce

import numpy as np
import onnx
import onnxsim
import onnx.reference
import cv2 as cv

shape_ini = (4, 5)
sim_net = True
N = 2
data = np.arange(0, 1 * N * 3 *shape_ini[0]* shape_ini[1]).reshape((1, N, 3, shape_ini[0], shape_ini[1])).astype(dtype=np.float32)    
shape_ini = data.shape 
select_axes = np.array([2], dtype=np.int64)
keepdims = 0
print("input DATA ")
print(data)
onnx_name = "reduceMean2inp"
out1 = onnx.helper.make_tensor_value_info('out1', onnx.TensorProto.FLOAT, [None, None, None, None])
inp0 = onnx.helper.make_tensor_value_info('inp0', onnx.TensorProto.FLOAT, [1, 2, 3 ,4 , 5])
axis = onnx.helper.make_tensor_value_info('axis', onnx.TensorProto.INT64, [1])
node1 = onnx.helper.make_node( "ReduceMean", inputs=["inp0", "axis"], outputs=["out1"], keepdims=keepdims )
graph = onnx.helper.make_graph([node1], onnx_name,  [inp0, axis], [out1])
onnx_model = onnx.helper.make_model(graph)

feeds = {'inp0': data, 'axis': select_axes}
sess = onnx.reference.ReferenceEvaluator(onnx_model)
res_onnx = sess.run(["out1"], feeds)
print("ONNX result")
print(res_onnx[0])
print("Writting model")
with open(onnx_name + ".onnx", "wb") as f:
    f.write(onnx_model.SerializeToString())
if sim_net:
    print("Reading model")
    onnx_model = onnx.load(onnx_name+'.onnx')
    simplified_model, _ = onnxsim.simplify(onnx_model)
    onnx.save(simplified_model, onnx_name+'_sim.onnx')

net = cv.dnn.readNet(onnx_name+'.onnx')
net.enableWinograd(False)
print("Set opencv input DATA ")

net.setInput(data, "inp0")
net.setInput(data, "axis")
res_ocv = net.forward()
print("Opencv result. Shape = ", res_ocv.shape)
print(res_ocv)
print("Quadratic error for node  : ", np.mean((res_ocv -  res_onnx[0])**2))
print("Max error for  node : ", np.max((res_ocv -  res_onnx[0])**2))


input DATA
[[[[[ 0. 1. 2. 3. 4.]
[ 5. 6. 7. 8. 9.]
[ 10. 11. 12. 13. 14.]
[ 15. 16. 17. 18. 19.]]

[[ 20. 21. 22. 23. 24.]
[ 25. 26. 27. 28. 29.]
[ 30. 31. 32. 33. 34.]
[ 35. 36. 37. 38. 39.]]

[[ 40. 41. 42. 43. 44.]
[ 45. 46. 47. 48. 49.]
[ 50. 51. 52. 53. 54.]
[ 55. 56. 57. 58. 59.]]]

[[[ 60. 61. 62. 63. 64.]
[ 65. 66. 67. 68. 69.]
[ 70. 71. 72. 73. 74.]
[ 75. 76. 77. 78. 79.]]

[[ 80. 81. 82. 83. 84.]
[ 85. 86. 87. 88. 89.]
[ 90. 91. 92. 93. 94.]
[ 95. 96. 97. 98. 99.]]

[[100. 101. 102. 103. 104.]
[105. 106. 107. 108. 109.]
[110. 111. 112. 113. 114.]
[115. 116. 117. 118. 119.]]]]]
ONNX result
[[[[20. 21. 22. 23. 24.]
[25. 26. 27. 28. 29.]
[30. 31. 32. 33. 34.]
[35. 36. 37. 38. 39.]]

[[80. 81. 82. 83. 84.]
[85. 86. 87. 88. 89.]
[90. 91. 92. 93. 94.]
[95. 96. 97. 98. 99.]]]]
Writting model
Reading model
Set opencv input DATA
Opencv result. Shape = (1, 1)
[[59.5]]
Quadratic error for node : 933.25
Max error for node : 1560.25

Issue submission checklist

  • I report the issue, it's not a question
  • I checked the problem with documentation, FAQ, open issues, forum.opencv.org, Stack Overflow, etc and have not found any solution
  • I updated to the latest OpenCV version and the issue is still there
  • There is reproducer code and related data files (videos, images, onnx, etc)
@LaurentBerger LaurentBerger changed the title No attribute axes in reduce onnx layer with opset>13 No attribute axes in reduce onnx layer with opset>=13 Feb 28, 2024
@LaurentBerger LaurentBerger changed the title No attribute axes in reduce onnx layer with opset>=13 No attribute axes in reduce onnx layer with opset13 Feb 28, 2024
@asmorkalov asmorkalov added the category: dnn (onnx) ONNX suport issues in DNN module label Feb 28, 2024
@asmorkalov asmorkalov added this to the 4.10.0 milestone Feb 28, 2024
@fengyuentau
Copy link
Member

It has been taken care of in onnx importer:

if (!layerParams.has("axes") && num_inputs == 2 && constBlobs.find(node_proto.input(1)) != constBlobs.end()) {
Mat mat_axes = getBlob(node_proto, 1);
int num_axes = mat_axes.total();
std::vector<int> axes(num_axes);
for (int i = 0; i < num_axes; ++i)
axes[i] = mat_axes.at<int>(i);
layerParams.set("axes", DictValue::arrayInt(&axes[0], num_axes));
}

@LaurentBerger
Copy link
Contributor Author

LaurentBerger commented Mar 1, 2024

It has been taken care of in onnx importer:

Yes but it's not a constBlob.
node1 = onnx.helper.make_node( "ReduceMean", inputs=["inp0", "axis"], outputs=["out1"], keepdims=keepdims )

axis is a layer : again output shape is known only at inference time

@fengyuentau
Copy link
Member

axis is a layer : again output shape is known only at inference time

In this case, dnn does not support for now. Output shape needs to be determined before forward.

@LaurentBerger
Copy link
Contributor Author

LaurentBerger commented May 5, 2024

@fengyuentau
I have process dynamic input shape. I replace litteral dim by shape values given by user : cv::dnn::Net importOnnxWithFixedShape(const char* onnxFile, std::map<std::string, int>& valSubstitute)
Now Have you got any idea to process this bug about dynamic input for a node? split graph?
@dkurt Have you got same bug in tfimporter?

@fengyuentau
Copy link
Member

importOnnxWithFixedShape

What is this? I do not recommand manual changes on dimensions since you do not have tools to check whether you do it in a correct way.

@LaurentBerger
Copy link
Contributor Author

@Abdurrahheem
Copy link
Contributor

@LaurentBerger, is the reproducer illustrative case of some real word model issue when the axis is given at inference time as input? I understand that currently, OpenCV only supports axis as an attribute.

@asmorkalov asmorkalov modified the milestones: 4.11.0, 5.0-release Dec 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug category: dnn (onnx) ONNX suport issues in DNN module
Projects
None yet
Development

No branches or pull requests

5 participants