我们已经使用 NCS2 好几个月了,最近发现了非常奇怪的行为。我已经包含了最小可重现程序的完整脚本。不过,在此之前,这是安装条件:
Raspberry Pi 4B+,运行 Raspbian GNU/Linux 11(靶心)
python3 --version
是 Python 3.9.2
openvino 构建自
2022.1.1
行为:
我们正在运行的代码获取一批 n 个图像,异步处理它们(我们通过这种方式运行找到了最佳性能),然后返回该批次。参见下面的
syn
。
我们预计会得到 16 个不同的结果,但由于某种原因,我们似乎得到了图像索引的结果与异步推断队列的作业数的模数。对于下面
jobs=1
的情况,所有图像的结果都与第一个结果相同(但注意:userdata 是唯一的,因此 asyncinferqueue 为回调提供了 userdata 的唯一值)。
_temp_infer_queue = AsyncInferQueue(compiled_model, jobs=1)
AsyncInferenceResult = namedtuple("AsyncInferenceResult", ["id", "result"])
def syn(input_imgs, sort = False):
res: List[AsyncInferenceResult] = []
def _cb(
infer_request: InferRequest, userdata: Any
) -> None:
res.append(
AsyncInferenceResult(
id=userdata, result=infer_request.output_tensors[0].data[:]
# also tried the following:
# id=userdata, result=infer_request.get_output_tensor(0).data
)
)
_temp_infer_queue.set_callback(_cb)
for i, image in enumerate(input_imgs):
tensor = np.expand_dims(image, (0, 3))
# if all tensors were the same, their sum would be the same
# easy way to verify that each image is unique
print("TENSOR SUM", tensor.sum())
_temp_infer_queue.start_async({0: tensor}, userdata=i)
_temp_infer_queue.wait_all()
for r1 in res:
print(r1)
print("---------------------------")
if sort:
return [r.result for r in sorted(res, key=op.attrgetter("id"))]
return res
data = zarr.open("../../../allan/2023-03-03-135043__nomaxnoflowcontrol2.zip")
# yield_n will give n samples from an iterator - in this case,
# it will give [0,1,2,3], then [4,5,6,7], etc
for index_batch in yield_n(range(data.initialized), 4):
images = [data[:, :, i] for i in index_batch]
syn(images, sort=True)
预期结果:结果的唯一值,因为我们正在对唯一图像进行推理
TENSOR SUM 181712885
TENSOR SUM 182752565
TENSOR SUM 182640761
TENSOR SUM 182361927
AsyncInferenceResult(id=0, result=array([[3.1972656]], dtype=float32))
AsyncInferenceResult(id=1, result=array([[2.3463234]], dtype=float32))
AsyncInferenceResult(id=2, result=array([[-1.345323]], dtype=float32))
AsyncInferenceResult(id=3, result=array([[3.0023452]], dtype=float32))
---------------------------
TENSOR SUM 182579212
TENSOR SUM 182199813
TENSOR SUM 180750311
TENSOR SUM 180896550
AsyncInferenceResult(id=0, result=array([[1.2942656]], dtype=float32))
AsyncInferenceResult(id=1, result=array([[1.3351234]], dtype=float32))
AsyncInferenceResult(id=2, result=array([[2.3451223]], dtype=float32))
AsyncInferenceResult(id=3, result=array([[0.0345552]], dtype=float32))
---------------------------
...etc
Actual Result:每一个推理结果都是一样的
TENSOR SUM 181712885
TENSOR SUM 182752565
TENSOR SUM 182640761
TENSOR SUM 182361927
AsyncInferenceResult(id=0, result=array([[3.1972656]], dtype=float32))
AsyncInferenceResult(id=1, result=array([[3.1972656]], dtype=float32))
AsyncInferenceResult(id=2, result=array([[3.1972656]], dtype=float32))
AsyncInferenceResult(id=3, result=array([[3.1972656]], dtype=float32))
---------------------------
TENSOR SUM 182579212
TENSOR SUM 182199813
TENSOR SUM 180750311
TENSOR SUM 180896550
AsyncInferenceResult(id=0, result=array([[2.6289062]], dtype=float32))
AsyncInferenceResult(id=1, result=array([[2.6289062]], dtype=float32))
AsyncInferenceResult(id=2, result=array([[2.6289062]], dtype=float32))
AsyncInferenceResult(id=3, result=array([[2.6289062]], dtype=float32))
---------------------------
...etc
当我们将 AsyncInferQueue 的作业数设置为 2 时,重复相同的值(修改作业数)
TENSOR SUM 181508284
TENSOR SUM 182244105
TENSOR SUM 181800558
TENSOR SUM 182178069
AsyncInferenceResult(id=0, result=array([[4.4921875]], dtype=float32))
AsyncInferenceResult(id=1, result=array([[3.3867188]], dtype=float32))
AsyncInferenceResult(id=2, result=array([[4.4921875]], dtype=float32))
AsyncInferenceResult(id=3, result=array([[3.3867188]], dtype=float32))
---------------------------
TENSOR SUM 181820857
TENSOR SUM 181130636
TENSOR SUM 181852573
TENSOR SUM 181331641
AsyncInferenceResult(id=0, result=array([[2.3867188]], dtype=float32))
AsyncInferenceResult(id=1, result=array([[2.9765625]], dtype=float32))
AsyncInferenceResult(id=2, result=array([[2.3867188]], dtype=float32))
AsyncInferenceResult(id=3, result=array([[2.9765625]], dtype=float32))
---------------------------
...etc
这是怎么回事?难道我做错了什么?我试着尽可能地遵循文档(虽然这甚至不容易,文档可能有点稀疏,搜索它们会给出旧版本的 openvino,等等)。如果我在这里做错了什么,这似乎很容易落入陷阱?某处不应该有一个很大的失败吗?
我们已经使用 NCS2 好几个月了,所以我们希望这是一个简单的修复。
让我知道什么需要澄清。我真的很希望能在这里得到一些帮助!
提前谢谢你! :)
问题源于您的 Python 演示脚本中的这部分代码:
def _cb(
infer_request: InferRequest, userdata: Any
) -> None:
res.append(
AsyncInferenceResult(
id=userdata, result=infer_request.output_tensors[0].data[:]
# also tried the following:
# id=userdata, result=infer_request.get_output_tensor(0).data
)
)
您的结果列表正在读取整个输出张量的最终值,而不是从每个单独的输出张量读取。
编辑:
正确的方法是使用
next(iter(infer_request.results.values()))
而不是 infer_request.output_tensors[0].data[:]
以便将结果附加到您的列表中,因为它是基于我们的 Image Classification Async Python Sample 的久经考验的方法。