admin管理员组文章数量:1399823
I use a pre-trained model facenet512
from the python project DeepFace. I exported the model and converted it to onnx format in order to run it with gocv.
Then I wrote a comparison script to make sure than both formats are equals, such as:
# Load models
tf_model = tf.saved_model.load('./exports/facenet512')
ort_session = ort.InferenceSession('./facenet512.onnx')
def embed_img(imgpath):
img, _ = image_utils.load_image(imgpath)
img = image.img_to_array(img)
img = np.expand_dims(img, axis=0)
test_input = img
print(f"Shape of test_input: {test_input.shape}")
test_input_reshaped = np.transpose(test_input, (0, 3, 1, 2)) # Convert to NCHW (PyTorch/ONNX)
print(f"Shape of test_input_reshaped: {test_input_reshaped.shape}")
# TensorFlow
infer = tf_model.signatures['serving_default']
tf_output = infer(tf.convert_to_tensor(test_input))
output_key = list(tf_output.keys())[0]
tf_output = tf_output[output_key].numpy()
# ONNX
input_name = ort_session.get_inputs()[0].name
output_name = ort_session.get_outputs()[0].name
onnx_output = ort_session.run([output_name], {input_name: test_input_reshaped})[0]
# Compare
difference = np.abs(tf_output - onnx_output).mean()
print(f"Average difference: {difference}")
image_utils.debug_feature_vector(f"tf_{imgpath}", tf_output)
image_utils.debug_feature_vector(f"onnx_{imgpath}", onnx_output)
return tf_output, onnx_output
img1_tf, img1_onnx = embed_img("someimage.jpg")
The result is good, running saved model against ONNX model there are no differences:
Average difference: 1.4876641216687858e-06
The result of the inference:
Shape and Type - Name: someimage.jpg, Rows: 1, Cols: 512, Type: float32
Memory address - Name: someimage.jpg, Address: 0x318d5bf90
Sample values:
Sample value - Index: 0, Value: 3.632195234298706
Sample value - Index: 1, Value: -1.988647699356079
Sample value - Index: 2, Value: 3.5143983364105225
Sample value - Index: 3, Value: 0.8864414691925049
Sample value - Index: 4, Value: 5.087140083312988
Statistics - Min: -10.288069725036621, Max: 10.912190437316895, Mean: -0.31338077783584595, Std: 3.7746989727020264
Please note I also ran the net through cv2 to check if the runtime was in cause, but the output is the same:
onnx_cv2_net = cv2.dnn.readNetFromONNX('./facenet512.onnx')
onnx_cv2_net.setInput(test_input_reshaped, "input")
onnx_output = onnx_cv2_net.forward("Bottleneck_BatchNorm")
But when running through gocv, the inference result is vastly different:
msg="Tensor details" Name=embed1 Size="[1 512]" Channels=1 Type=CV32F TotalElements=512
msg="Shape and Type" Name=embed1 Rows=1 Cols=512 Type=CV32F
msg="Memory address" Name=embed1 Address="&{p:0x139068920 d:[]}"
msg="Sample values"
msg="Sample value" Index=0 Value=0.9129840135574341
msg="Sample value" Index=1 Value=-0.298820436000824
msg="Sample value" Index=2 Value=-0.06013426184654236
msg="Sample value" Index=3 Value=-0.2546067535877228
msg="Sample value" Index=4 Value=1.2503312826156616
msg=Statistics Min=-2.7190661430358887 Max=2.411057949066162 Mean=0.052061960360333615 Std=0.9108246561958873
the Go code is:
// package the model weights into the binary for static use
//
//go:embed facenet512.onnx
var facenet512weights []byte
net, err := gocv.ReadNetFromONNXBytes(facenet512weights)
embed1, err := e.Embed(img1path)
img := gocv.IMRead(imgPath, gocv.IMReadColor)// Create NCHW tensor
tensor = gocv.NewMatWithSizes([]int{1, channels, height, width}, gocv.MatTypeCV32F)
// Extract channels
channelMats := gocv.Split(preprocessed)
for i := range channelMats {
defer channelMats[i].Close()
}
// Copy data
for c := 0; c < channels && c < len(channelMats); c++ {
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
// Calculer l'indice linéaire dans le tensor 4D
// L'indice pour NCHW: batch_idx * C*H*W + c * H*W + y * W + x
idx := c*height*width + y*width + x
val := channelMats[c].GetFloatAt(y, x)
tensor.SetFloatAt(0, idx, val) // Dans la première ligne (batch 0), à l'indice calculé
}
}
}
e.Net.SetInput(tensor, "input")
embed = e.Net.Forward("Bottleneck_BatchNorm")
The actual tensor values are:
# python
channel MIN MAX AVERAGE
0 0 0,73725492 0,4409493168
1 0 0,78039223 0,4888215594
2 0,01176471 0,87843144 0,5979496282
# go
channel MIN MAX AVERAGE
0 0,0120490575 0,9137533 0,5996299743
1 0 0,79382753 0,4950213559
2 0 0,7389256 0,4466549111
There is a RGB inversion but swapping the channels had a minor difference on the result, the MIN/MAX of the inference still have a factor 5 difference.
Any ideas, tips, tricks?
本文标签: machine learningDifferent inference results between gocv and python opencvStack Overflow
版权声明:本文标题:machine learning - Different inference results between gocv and python opencv - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744202550a2595035.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论