wutianze / pynq_car

Start an exciting tour of building your autonomous car with Xilinx Pynq-Z2 and DPU.
MIT License
14 stars 5 forks source link

记录一些踩过的坑(持续更新) #2

Closed B1D1ng closed 4 years ago

B1D1ng commented 4 years ago

已解决:

  1. 安装DNNDK的时候一定要把CUDA和cudnn的版本换成install.sh里支持的版本,我用的cuda9.0+cudnn7.0.5

  2. 将训练好的模型权重文件转换城.pb文件(注意这里有一个坑,如果用的框架不是keras或者tensorflow,比如我的模型是Darknet-yolov4,转换成.pb文件所使用的tensorflow版本一定要和conda创建的decent虚拟环境中的tf版本(1.9.0)一致,不然后续操作会报错)

  3. 跟着教程按步骤走到了用DNNDK量化裁剪模型阶段,修改了quant.sh文件的参数后,报了shape错误,解决办法是喂的数据图片的尺寸要和输出节点的尺寸相同

未解决:

  1. 在执行quant.sh的时候,报了: return (img[40:,:])/255.0-0.5 TypeError: 'NoneType' object is not subscriptable 的错误,想知道作者在这一步之前有没有一些操作在教程里没有提到?比如garph_input_fn.py这个文件中,cali_batch_size=50是指要创建image文件夹并要放50张图片吗,我reshape50张图片放进去后,再执行时就报了上面这个NoneType错误,另外我看到Host-Part目录下有process_img.py这个文件,在喂数据前需要执行这个吗?

  2. 接下来执行compile.sh文件的时候,报了dnnc找不到的错误,我按之前的教程安装DNNDK的时候,替换install.sh后./install.sh PynqZ2是成功的,dnnc也是安装成功的,但是这里却报了找不到文件或路径。我怀疑可能是我安装dnndk的路径问题?我的电脑是A卡,安装不了cuda和cudnn,是用服务器操作的,没有root权限,所以就把cuda,cudnn,dnndk都安装在了/home/路径下,安装是提示成功了,但用的时候报了找不到 ##################################### COMPILE WITH DNNC ##################################### ./compile.sh: line 24: dnnc: command not found ##################################### COMPILATION COMPLETED #####################################

折腾了好几天,望作者可以答疑一下!谢谢

wutianze commented 4 years ago

NoneType这个问题应该是没有读到图片,你可以print一下看看有没有读到,没有的话改一下读取路径试试。 第二个问题,DNNDK安装是可以不需要cuda的,你安装完以后试试运行dnnc这类的指令,不行的话你把安装路径里的可执行文件(一般是安装目录里的bin文件下)拷贝到linux默认的命令执行目录下或者建立软连接试试。

B1D1ng commented 4 years ago

NoneType这个问题应该是没有读到图片,你可以print一下看看有没有读到,没有的话改一下读取路径试试。 第二个问题,DNNDK安装是可以不需要cuda的,你安装完以后试试运行dnnc这类的指令,不行的话你把安装路径里的可执行文件(一般是安装目录里的bin文件下)拷贝到linux默认的命令执行目录下或者建立软连接试试。

感谢您的回复,我把图片文件夹放到执行文件的同目录下后修改路径就解决这个error了,但随之出现了新的几个报错: if files[itercalib_batch_size+index] == "train.csv" or (not os.path.exists(path+files[itercalib_batch_size + index]) or os.path.getsize(path + files[iter*calib_batch_size + index])<1000):# it will ignore the images which are too small IndexError: list index out of range

我没有进行前一个环节的图片预处理以及训练过程,因为我的模型是训练好了的并且已经有了.pb文件,所以我没有train.csv文件。 这个报错应该是files的下标越界了,files读取的是图片文件夹名称列表,我只放了50个图片,您原来设置的calib_iter=100,calib_batch_size=50,再加index好像就是越界了,但我不太清楚您这个公式的含义,不知道该如何去修改它们的参数。

wutianze commented 4 years ago

你可以把这些数值设小一些,本质上这个过程只需要用一些输入来去给dnndk做量化用就行,如果你的图片本身数量比较小那就把值改小一点

B1D1ng commented 4 years ago

你可以把这些数值设小一些,本质上这个过程只需要用一些输入来去给dnndk做量化用就行,如果你的图片本身数量比较小那就把值改小一点

我尝试着把数组下标调小到0-49范围内,上面的下标越界错误就消失了,但出现了: File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1111, in _run str(subfeed_t.get_shape()))) ValueError: Cannot feed value of shape (0,) for Tensor 'yolov4-tiny-obj/net1:0', which has shape '(?, 608, 608, 3)' google了一下问题应该是图片尺寸的问题,但我用的50张图片已经提前reshape成符合网络输入尺寸的608*608了。

wutianze commented 4 years ago

shape(0,)这个应该就是图片没读到或是读到了空的图片,你检查一下出错的时候图片是否完整,是否是某个图片名出现了错误。 另外你可以把读到的图片的尺寸都输出一下看看是不是有问题

B1D1ng commented 4 years ago

shape(0,)这个应该就是图片没读到或是读到了空的图片,你检查一下出错的时候图片是否完整,是否是某个图片名出现了错误。 另外你可以把读到的图片的尺寸都输出一下看看是不是有问题

graph_input_fn.py的代码中,image_handle这个函数返回了img[40:,:],我将图片resize后执行quant.sh的时候,会报尺寸不匹配的错误,将其修改为img[:,:]后这个错误便消失了,但报了下面这个错误:

Traceback (most recent call last):
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1322, in _do_call
return fn(*args)
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1307, in _run_fn
options, feed_dict, fetch_list, target_list, run_metadata)
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1409, in _call_tf_sessionrun
run_metadata)
tensorflow.python.framework.errors_impl.FailedPreconditionError: Attempting to use uninitialized value conv2d_14/kernel
[[Node: conv2d_14/kernel/read = Identity[T=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:GPU:0"](conv2d_14/kernel)]]
[[Node: conv2d_20/BiasAdd/_3 = _Recv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/device:CPU:0", send_device="/job:localhost/replica:0/task:0/device:GPU:0", send_device_incarnation=1, tensor_name="edge_507_conv2d_20/BiasAdd", tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]]

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/opt/conda/envs/decent/bin/decent_q", line 8, in <module>
sys.exit(run_main())
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/contrib/decent_q/python/decent_q.py", line 565, in run_main
app.run(main=my_main, argv=[sys.argv[0]] + unparsed)
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/python/platform/app.py", line 125, in run
_sys.exit(main(argv))
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/contrib/decent_q/python/decent_q.py", line 564, in <lambda>
my_main = lambda unused_args: main(unused_args, FLAGS)
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/contrib/decent_q/python/decent_q.py", line 357, in main
s_config)
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/contrib/decent_q/python/decent_q.py", line 328, in quantize
check_float_graph(input_graph_def, q_config, i_config, s_config)
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/contrib/decent_q/python/decent_q.py", line 189, in check_float_graph
sess.run(output_tensors, feed_dict)
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 899, in run
run_metadata_ptr)
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1135, in _run
feed_dict_tensor, options, run_metadata)
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1316, in _do_run
run_metadata)
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1335, in _do_call
raise type(e)(node_def, op, message)
tensorflow.python.framework.errors_impl.FailedPreconditionError: Attempting to use uninitialized value conv2d_14/kernel
[[Node: conv2d_14/kernel/read = Identity[T=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:GPU:0"](conv2d_14/kernel)]]
[[Node: conv2d_20/BiasAdd/_3 = _Recv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/device:CPU:0", send_device="/job:localhost/replica:0/task:0/device:GPU:0", send_device_incarnation=1, tensor_name="edge_507_conv2d_20/BiasAdd", tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]]

Caused by op 'conv2d_14/kernel/read', defined at:
File "/opt/conda/envs/decent/bin/decent_q", line 8, in <module>
sys.exit(run_main())
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/contrib/decent_q/python/decent_q.py", line 565, in run_main
app.run(main=my_main, argv=[sys.argv[0]] + unparsed)
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/python/platform/app.py", line 125, in run
_sys.exit(main(argv))
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/contrib/decent_q/python/decent_q.py", line 564, in <lambda>
my_main = lambda unused_args: main(unused_args, FLAGS)
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/contrib/decent_q/python/decent_q.py", line 357, in main
s_config)
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/contrib/decent_q/python/decent_q.py", line 328, in quantize
check_float_graph(input_graph_def, q_config, i_config, s_config)
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/contrib/decent_q/python/decent_q.py", line 179, in check_float_graph
tf.import_graph_def(input_graph_def, name='')
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/python/util/deprecation.py", line 432, in new_func
return func(*args, **kwargs)
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/python/framework/importer.py", line 442, in import_graph_def
_ProcessNewOps(graph)
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/python/framework/importer.py", line 234, in _ProcessNewOps
for new_op in graph._add_new_tf_operations(compute_devices=False): # pylint: disable=protected-access
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 3563, in _add_new_tf_operations
for c_op in c_api_util.new_tf_operations(self)
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 3563, in <listcomp>
for c_op in c_api_util.new_tf_operations(self)
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 3450, in _create_op_from_tf_operation
ret = Operation(c_op, self)
File "/opt/conda/envs/decent/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 1740, in __init__
self._traceback = self._graph._extract_stack() # pylint: disable=protected-access

我查了很多博客资料,FailedPreconditionError (see above for traceback): Attempting to use uninitialized value conv2d_14/kernel这个错误是变量没有初始化,他们的解释几乎都是在代码中加入:

tf.global_variables_initializer()

我看了报错的日志还没弄清楚这个未初始化的节点是在哪里定义的,目前在decent_q.py和生成.pb文件里都加了这条代码,均未解决这个问题。

wutianze commented 4 years ago

img[40:,:]这个你直接改掉就可以了,因为它本身是一个图片裁剪的过程。你遇到的问题看起来像是keras tensorflow版本不匹配或是一些兼容性问题,可能是dnndk不支持你的模型里的一些层。最好你的模型是用xilinx官方给的那个tensorflow的库,里面应该是有一些修改的,再另外用别的tensorflow的库可能会出问题。另外分享给你一个中文文档,里面的流程可以参考一下https://blog.csdn.net/qq_25762163/article/details/103591878

B1D1ng commented 4 years ago

img[40:,:]这个你直接改掉就可以了,因为它本身是一个图片裁剪的过程。你遇到的问题看起来像是keras tensorflow版本不匹配或是一些兼容性问题,可能是dnndk不支持你的模型里的一些层。最好你的模型是用xilinx官方给的那个tensorflow的库,里面应该是有一些修改的,再另外用别的tensorflow的库可能会出问题。另外分享给你一个中文文档,里面的流程可以参考一下https://blog.csdn.net/qq_25762163/article/details/103591878

最好是用Xilinx的AI Model Zoo里支持的模型吗,比如我看到了dk_yolov3_voc_416_416_65.42G_1.1

wutianze commented 4 years ago

这个倒是无所谓,主要是你制作pb所用的tensorflow是否是xilinx给dnndk提供的,如果直接用的tensorflow官方的库可能会有问题。

B1D1ng commented 4 years ago

这个倒是无所谓,主要是你制作pb所用的tensorflow是否是xilinx给dnndk提供的,如果直接用的tensorflow官方的库可能会有问题。

请问Xilinx给dnndk提供的tensorflow版本如何查看?我用的生成.pb的代码应该是用的tensorflow官方的库 或许我可以尝试先将我的模型生成.h5文件,再用您的教程里的生成.pb的方式来转换?

wutianze commented 4 years ago

https://github.com/wutianze/dnndk-pynqz2/blob/master/mnist_tf/mnist_handwriting_guide.md这个里有安装dnndk tensorflow的步骤。生成h5再转是比较好的方式,可以规避很多环境问题。

B1D1ng commented 4 years ago

https://github.com/wutianze/dnndk-pynqz2/blob/master/mnist_tf/mnist_handwriting_guide.md这个里有安装dnndk tensorflow的步骤。生成h5再转是比较好的方式,可以规避很多环境问题。

看了一下,那我的环境应该是没问题的,环境是直接装的虚拟环境decent,tf版本是1.9.0 keras版本是2.2.0,应该是没问题的。 我暂时放下了我手中的Yolov4-tiny模型,选择用darknet-yolov3,我看您的教程也是用darknet-yolov3训练的,训练后我得到了yolov3-tiny.weights,根据教程freeze和quant,但是这里出现一个问题,不论是我自己的训练的yolov3-tiny.weights还是官方提供的预训练的yolov3-tiny.weights,我在按照步骤的时候输出的是这个:

Found 1 possible inputs: (name=input_1, type=float(1), shape=[?,?,?,3]) 
Found 2 possible outputs: (name=conv2d_10/BiasAdd, op=BiasAdd) (name=conv2d_13/BiasAdd, op=BiasAdd) 

尺寸shape这里不对吧,我把这几个参数在quant.sh里设置好并执行后,它提示:

ValueError: input_shapes should be 4-dimension int shape list (support unknown batch_size), e.g. ?,224,224,3 or 1,299,299,3

说明是要设置尺寸的,但我用的是官方的模型,这就非常奇怪了,我自己的yolov3-tiny.weights是测试过图片检测的,没有问题。

weights和cfg文件我可以提供给您,您方便在您那边试一试吗?我这边一直不成功,心态炸裂。。

wutianze commented 4 years ago
  1. 首先确保你的tensorflow是按照这里的步骤安装的;2.检查你的模型输入是否没有指定,因为?,?,?,3这表明你的输入shape没有被找到;3.你可以先用几个简单模型比如教程里的mnist来检查流程是否正确;4.目前我手头没有配置好的环境,所以没法帮你测试了,不好意思。
B1D1ng commented 4 years ago

环境安装就是按照您给的这个链接安装的,这个没有问题。另外我的模型没有指定输入节点,这一步该如何操作?我之前是用的其他方式直接从weights转化成pb,那种方式是会给输入节点进行定义,但是会报昨天给您说的那个变量没有初始化的错误,也无法解决,所以选择您的教程的方式先转化成h5,再转pb。 请问输入节点的定义是对darknet的weights文件操作吗?

发自我的iPhone

------------------ 原始邮件 ------------------ 发件人: sauron <notifications@github.com> 发送时间: 2020年8月22日 19:06 收件人: wutianze/pynq_car <pynq_car@noreply.github.com> 抄送: Huaxun Wu <316186434@qq.com>, Author <author@noreply.github.com> 主题: 回复:[wutianze/pynq_car] 记录一些踩过的坑(持续更新) (#2)

首先确保你的tensorflow是按照这里的步骤安装的;2.检查你的模型输入是否没有指定,因为?,?,?,3这表明你的输入shape没有被找到;3.你可以先用几个简单模型比如教程里的mnist来检查流程是否正确;4.目前我手头没有配置好的环境,所以没法帮你测试了,不好意思。

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

wutianze commented 4 years ago

这个你得改darknet的源码或是keras版本yolo的源码。但实际上它们都会对图片做预处理然后转成统一的尺寸,具体看代码吧

B1D1ng commented 4 years ago

这个你得改darknet的源码或是keras版本yolo的源码。但实际上它们都会对图片做预处理然后转成统一的尺寸,具体看代码吧

最新更新! 虽然输入节点的shape[?,?,?,3],但是我在参数设置的时候还是按照输出的参数进行设置,并且shape设置成我训练模型时的尺寸,关键一部来了!!我之前由于下标越界,把calib_iter设置成了0,之后我尝试将其设为1后,执行quant.sh好像成功了,输出如下:

INFO: Start Float Graph Check
INFO: Done Float Graph Check
INFO: Start Calibration for 1 iterations:
100% (1 of 1) |#########################################################################################################################| Elapsed Time: 0:00:08 Time:  0:00:08
INFO: Done Calibration
INFO: Start Generate Deploy Model
INFO: End Generate Deploy Model
********************* Quantization Summary *********************
INFO: Output:
  quantize_eval_model: ./quantize_results/quantize_eval_model.pb
  deploy_model: ./quantize_results/deploy_model.pb
- |#                                                                                                                                                 | 0 Elapsed Time: 0:00:00
#####################################
QUANTIZATION COMPLETED
#####################################

您看看这是不是代表着quant这一步成功了,我看了以下好像和教程上的截图无异

wutianze commented 4 years ago

嗯,这个应该是成功了。

B1D1ng commented 4 years ago

嗯,这个应该是成功了。

作者你好,目前进展是这样的: 已经成功执行./quant.sh和./compile.sh 输出是这样的:

#####################################
COMPILE WITH DNNC
#####################################
[DNNC][Warning] Fail to convert gv file to jpg because 'dot' is not installed in current system. Try to install it using 'sudo apt-get install graphviz'. The original gv file is saved in 'compile/testTinyModel_kernel_graph.gv'.

DNNC Kernel Information

1. Overview
kernel numbers  : 1
kernel topology : testTinyModel_kernel_graph.jpg

2. Kernel Description in Detail
kernel id       : 0
kernel name     : testTinyModel
type            : DPUKernel
nodes           : NA
input node(s)   : conv2d_1_convolution(0) 
output node(s)  : conv2d_13_convolution(0) 

#####################################
COMPILATION COMPLETED
#####################################

请问这是成功了吗?开头那个DNNC的警告需要解决吗? 到这一步后,最后就是需要上板测试了,但是作者您这个环节的教程是否适用其他模型的测试呀?

还有一个问题就是,我的images文件夹放了20k张图片,但是在设置Cali_Iter的时候,只能设置: --calib_iter 10 再大的话,在跑的时候会出现这样的错误: File "./graph_input_fn.py", line 15, in image_handle return (img[:,:])/255.0-0.5 TypeError: 'NoneType' object is not subscriptable 请问这是什么原因呢?img[:,:]这行必须得这么写,不然到时候量化的时候shape的值会不匹配,之前提到过。

wutianze commented 4 years ago

按提示装一下吧。板上测试的程序逻辑其实都是通用的,就是加载kernel然后用这个kernel来跑结果,不同的模型改一改输入输出就行了。NoneType应该就是没读到图片导致的,可以看看graph_input_fn.py里具体是怎么循环取图的,按自己需求保证不会越界就行。

B1D1ng commented 4 years ago

按提示装一下吧。板上测试的程序逻辑其实都是通用的,就是加载kernel然后用这个kernel来跑结果,不同的模型改一改输入输出就行了。NoneType应该就是没读到图片导致的,可以看看graph_input_fn.py里具体是怎么循环取图的,按自己需求保证不会越界就行。

好的 那我继续按照教程继续剩下的内容。

还有一个问题就是,循环取图喂数据这一环节的目的是什么呢?模型不是已经预先用数据集训练好了吗?

wutianze commented 4 years ago

dnndk在量化模型的时候需要输入数据来做优化,具体的就得看深鉴当时的论文了。

B1D1ng commented 4 years ago

dnndk在量化模型的时候需要输入数据来做优化,具体的就得看深鉴当时的论文了。

我烧录了您封装好DPU的镜像文件到SD卡并成功启动了,按照这个教程执行时,dnndk显示安装成功,run yolo的时候报

[DNNDK] fail to open DPU device and exit ...
wutianze commented 4 years ago

你是直接下的镜像还是按照那个教程运行的?那个教程是做这个镜像的,有一些不一样。你试试运行insmod /home/xilinx/dpu.ko加载这个模块

B1D1ng commented 4 years ago

对,我是直接下载制作好的镜像,然后烧录到sd卡里,跳过教程的前面步骤,直接执行最后几个跑模型的步骤,我以为烧录好镜像后就可以直接调用dpu了,查看了一下确实目录中有dpu.ko这个文件,但我没有对它进行任何操作

B1D1ng commented 4 years ago

你是直接下的镜像还是按照那个教程运行的?那个教程是做这个镜像的,有一些不一样。你试试运行insmod /home/xilinx/dpu.ko加载这个模块

目前已经加载好了dpu.ko这个文件,并且执行镜像中原本就存在的yolo_prune这个工程是可以进行检测的,然后我把我的elf文件按照教程放到了Car文件夹下,移到了板子上。但是看了一下您的教程是针对小车的,我修改了Makefile和run.cc、runYolo.cc里面的那些输入输出节点,kernel名称等参数,编译后没问题,但是卡在最后的执行指令这里。。我看了您的代码,make run是编译run.cc这个文件,make fpt是编译run_fpt、runYolo这几个文件,因此我在编译时执行了make fpt,但是最后的测试指令不知道是什么。。。。 另外,我还尝试在yolo_prune这个工程内,修改了一下里面的这些参数,但是编译时报错:无法生成main.o这个文件

如果想要用Car这个工程来执行我自己的目标检测模型的话,按照步骤修改了那些参数,然后编译,最后想要用模型来检测图片是输入什么指令呢?

按照教程的指令的话应该是针对小车的,输出如下:

xilinx@pynq:~/Car$ ./build/run n 0.5
Run Model
Run Steer
Segmentation fault
wutianze commented 4 years ago

如果你只是想用yolo的话应该是看https://github.com/wutianze/dnndk-pynqz2/blob/master/yolo_keras/yolo_pynqz2_guide.md,小车的程序里有一些小车控制的内容,你没有相关硬件比如没接摄像头可能会出错,而且程序里也有很多无关代码。

B1D1ng commented 4 years ago

如果你只是想用yolo的话应该是看https://github.com/wutianze/dnndk-pynqz2/blob/master/yolo_keras/yolo_pynqz2_guide.md,小车的程序里有一些小车控制的内容,你没有相关硬件比如没接摄像头可能会出错,而且程序里也有很多无关代码。

好的,按照您发的这个guide,我把自己的模型的elf文件导入后成功编译了,但是再测试的时候发现检测不出训练好的目标。。即使是非常明显的目标 我在runYolo.cpp文件中修改了YOLOKERNEL、INPUTNODE、outputs_node、classification这几个参数

B1D1ng commented 4 years ago

如果你只是想用yolo的话应该是看https://github.com/wutianze/dnndk-pynqz2/blob/master/yolo_keras/yolo_pynqz2_guide.md,小车的程序里有一些小车控制的内容,你没有相关硬件比如没接摄像头可能会出错,而且程序里也有很多无关代码。

我从头到尾将教程又走了一遍,从最开始的用darknet-tiny-yolov3的weights文件做预测确保模型没出错,到按照教程一步一步将weights->h5->pb后,./quant.sh、./compile.sh生成elf文件以及相关信息

1. Overview
   kernel numbers  : 1
   kernel topology : testTinyModel_kernel_graph.jpg

2. Kernel Description in Detail
   kernel id       : 0
   kernel name     : testTinyModel
   type            : DPUKernel
   nodes           : NA
   input node(s)   : conv2d_1_convolution(0) 
   output node(s)  : conv2d_13_convolution(0) 

再上板修改这个工程下的Makefile和runYolo.cpp 分别是: Makefile

YOLO = yolo

CXX       :=   g++
CC        :=   gcc 
YOLOOBJ :=   runYolo.o

# linking libraries of OpenCV
LDFLAGS  =  $(shell pkg-config --libs opencv) -lpthread -lhineon -ln2cube -ldputils

CUR_DIR =   $(shell pwd)
MODEL   =   $(CUR_DIR)/dpu_testTinyModel.elf
ARCH    =     $(shell uname -m | sed -e s/arm.*/armv71/ \
    -e s/aarch64.*/aarch64/ )

CFLAGS  :=  -O2 -Wall -Wpointer-arith -std=c++11 -ffast-math

ifeq ($(ARCH),armv71)
    CFLAGS +=  -mcpu=cortex-a9 -mfloat-abi=hard -mfpu=neon
endif
ifeq ($(ARCH),aarch64)
    CFLAGS += -mcpu=cortex-a53
endif

.PHONY: clean
%.o : %.cpp
    $(CXX) -c $(CFLAGS) $< -o $(CUR_DIR)/$@

$(YOLO) : $(YOLOOBJ)
    $(CXX) $(CFLAGS) $(addprefix $(CUR_DIR)/, $^) $(MODEL) -o $(CUR_DIR)/$@ $(LDFLAGS)

runYolo.cpp:

#include <algorithm>
#include <vector>
#include <atomic>
#include <queue>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <chrono>
#include <mutex>
#include <zconf.h>
#include <thread>
#include <sys/stat.h>
#include <dirent.h>
#include <iomanip>
#include <iosfwd>
#include <memory>
#include <string>
#include <utility>
#include <math.h>
#include <arm_neon.h>
#include <opencv2/opencv.hpp>
#include <dnndk/n2cube.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
using namespace std::chrono;
//confidence and threshold
#define CONF 0.5
#define NMS_THRE  0.1
//dpu kernel info
#define YOLOKERNEL "testTinyModel"
#define INPUTNODE "conv2d_1_convolution"
vector<string>outputs_node= {"conv2d_13_convolution"};
//yolo parameters
const int classification = 2;
const int anchor = 3;
vector<float> biases { 116,90,  156,198,  373,326, 30,61,  62,45,  59,119, 10,13,  16,30,  33,23};

class image {
    public:
    int w;
    int h;
    int c;
    float *data;
    image(int ww, int hh, int cc, float fill):w(ww),h(hh),c(cc){
        data = new float[h*w*c];
        for(int i = 0; i < h*w*c; ++i) data[i] = fill;
    };
   void free(){delete[] data;};
};

void detect(vector<vector<float>> &boxes, vector<float> result, int channel, int height, int weight, int num, int sh, int sw);
image load_image_cv(const cv::Mat& img);
image letterbox_image(image im, int w, int h);

void get_output(int8_t* dpuOut, int sizeOut, float scale, int oc, int oh, int ow, vector<float>& result) {
    vector<int8_t> nums(sizeOut);
    memcpy(nums.data(), dpuOut, sizeOut);
    for(int a = 0; a < oc; ++a){
        for(int b = 0; b < oh; ++b){
            for(int c = 0; c < ow; ++c) {
                int offset = b * oc * ow + c * oc + a;
                result[a * oh * ow + b * ow + c] = nums[offset] * scale;
            }
        }
    }
}

void set_input_image(DPUTask* task, const Mat& img, const char* nodename) {
    Mat img_copy;
    int height = dpuGetInputTensorHeight(task, nodename);
    int width = dpuGetInputTensorWidth(task, nodename);
    int size = dpuGetInputTensorSize(task, nodename);
    int8_t* data = dpuGetInputTensorAddress(task, nodename);
    //cout<<"set_input_image height:"<<height<<" width:"<<width<<" size"<<size<<endl;

    image img_new = load_image_cv(img);
    image img_yolo = letterbox_image(img_new, width, height);
    vector<float> bb(size);
    for(int b = 0; b < height; ++b)
        for(int c = 0; c < width; ++c)
            for(int a = 0; a < 3; ++a)
                bb[b*width*3 + c*3 + a] = img_yolo.data[a*height*width + b*width + c];

    float scale = dpuGetInputTensorScale(task, nodename);
    //cout<<"scale: "<<scale<<endl;
    for(int i = 0; i < size; ++i) {
        data[i] = int(bb.data()[i]*scale);
        if(data[i] < 0) data[i] = 127;
    }
    img_new.free();
    img_yolo.free();
}

inline float sigmoid(float p) {
    return 1.0 / (1 + exp(-p * 1.0));
}

inline float overlap(float x1, float w1, float x2, float w2) {
    float left = max(x1 - w1 / 2.0, x2 - w2 / 2.0);
    float right = min(x1 + w1 / 2.0, x2 + w2 / 2.0);
    return right - left;
}

inline float cal_iou(vector<float> box, vector<float>truth) {
    float w = overlap(box[0], box[2], truth[0], truth[2]);
    float h = overlap(box[1], box[3], truth[1], truth[3]);
    if(w < 0 || h < 0) return 0;
    float inter_area = w * h;
    float union_area = box[2] * box[3] + truth[2] * truth[3] - inter_area;
    return inter_area * 1.0 / union_area;
}

vector<vector<float>> apply_nms(vector<vector<float>>& boxes,int classes, const float thres) {
    vector<pair<int, float>> order(boxes.size());
    vector<vector<float>> result;
    for(int k = 0; k < classes; k++) {
        for (size_t i = 0; i < boxes.size(); ++i) {
            order[i].first = i;
            boxes[i][4] = k;
            order[i].second = boxes[i][6 + k];
        }
        sort(order.begin(), order.end(),
             [](const pair<int, float> &ls, const pair<int, float> &rs) { return ls.second > rs.second; });
        vector<bool> exist_box(boxes.size(), true);
        for (size_t _i = 0; _i < boxes.size(); ++_i) {
            size_t i = order[_i].first;
            if (!exist_box[i]) continue;
            if (boxes[i][6 + k] < CONF) {
                exist_box[i] = false;
                continue;
            }
            //add a box as result
            result.push_back(boxes[i]);
            //cout << "i = " << i<<" _i : "<< _i << endl;
            for (size_t _j = _i + 1; _j < boxes.size(); ++_j) {
                size_t j = order[_j].first;
                if (!exist_box[j]) continue;
                float ovr = cal_iou(boxes[j], boxes[i]);
                if (ovr >= thres) exist_box[j] = false;
            }
        }
    }
    return result;
}

static float get_pixel(image m, int x, int y, int c)
{
    assert(x < m.w && y < m.h && c < m.c);
    return m.data[c*m.h*m.w + y*m.w + x];
}

static void set_pixel(image m, int x, int y, int c, float val)
{
    if (x < 0 || y < 0 || c < 0 || x >= m.w || y >= m.h || c >= m.c) return;
    assert(x < m.w && y < m.h && c < m.c);
    m.data[c*m.h*m.w + y*m.w + x] = val;
}

static void add_pixel(image m, int x, int y, int c, float val)
{
    assert(x < m.w && y < m.h && c < m.c);
    m.data[c*m.h*m.w + y*m.w + x] += val;
}

image resize_image(image im, int w, int h)
{
    image resized(w, h, im.c,0);   
    image part(w, im.h, im.c,0);
    int r, c, k;
    float w_scale = (float)(im.w - 1) / (w - 1);
    float h_scale = (float)(im.h - 1) / (h - 1);
    for(k = 0; k < im.c; ++k){
        for(r = 0; r < im.h; ++r){
            for(c = 0; c < w; ++c){
                float val = 0;
                if(c == w-1 || im.w == 1){
                    val = get_pixel(im, im.w-1, r, k);
                } else {
                    float sx = c*w_scale;
                    int ix = (int) sx;
                    float dx = sx - ix;
                    val = (1 - dx) * get_pixel(im, ix, r, k) + dx * get_pixel(im, ix+1, r, k);
                }
                set_pixel(part, c, r, k, val);
            }
        }
    }
    for(k = 0; k < im.c; ++k){
        for(r = 0; r < h; ++r){
            float sy = r*h_scale;
            int iy = (int) sy;
            float dy = sy - iy;
            for(c = 0; c < w; ++c){
                float val = (1-dy) * get_pixel(part, c, iy, k);
                set_pixel(resized, c, r, k, val);
            }
            if(r == h-1 || im.h == 1) continue;
            for(c = 0; c < w; ++c){
                float val = dy * get_pixel(part, c, iy+1, k);
                add_pixel(resized, c, r, k, val);
            }
        }
    }
    part.free();
    return resized;
}

image load_image_cv(const cv::Mat& img) {
    int h = img.rows;
    int w = img.cols;
    int c = img.channels();
    image im(w, h, c,0);

    unsigned char *data = img.data;

    for(int i = 0; i < h; ++i){
        for(int k= 0; k < c; ++k){
            for(int j = 0; j < w; ++j){
                im.data[k*w*h + i*w + j] = data[i*w*c + j*c + k]/255.;
            }
        }
    }

    //bgr to rgb
    for(int i = 0; i < im.w*im.h; ++i){
        float swap = im.data[i];
        im.data[i] = im.data[i+im.w*im.h*2];
        im.data[i+im.w*im.h*2] = swap;
    }
    return im;
}

image letterbox_image(image im, int w, int h)
{
    int new_w = im.w;
    int new_h = im.h;
    if (((float)w/im.w) < ((float)h/im.h)) {
        new_w = w;
        new_h = (im.h * w)/im.w;
    } else {
        new_h = h;
        new_w = (im.w * h)/im.h;
    }
    image resized = resize_image(im, new_w, new_h);
    image boxed(w, h, im.c, .5);

    int dx = (w-new_w)/2;
    int dy = (h-new_h)/2;
    for(int k = 0; k < resized.c; ++k){
        for(int y = 0; y < new_h; ++y){
            for(int x = 0; x < new_w; ++x){
                float val = get_pixel(resized, x,y,k);
                set_pixel(boxed, dx+x, dy+y, k, val);
            }
        }
    }
    resized.free();
    return boxed;
}

//------------------------------------------------------------------

void correct_region_boxes(vector<vector<float>>& boxes, int n, int w, int h, int netw, int neth, int relative = 0) {
    int new_w=0;
    int new_h=0;
    if (((float)netw/w) < ((float)neth/h)) {
        new_w = netw;
        new_h = (h * netw)/w;
    } else {
        new_h = neth;
        new_w = (w * neth)/h;
    }
    for (int i = 0; i < n; ++i){
        boxes[i][0] =  (boxes[i][0] - (netw - new_w)/2./netw) / ((float)new_w/(float)netw);
        boxes[i][1] =  (boxes[i][1] - (neth - new_h)/2./neth) / ((float)new_h/(float)neth);
        boxes[i][2] *= (float)netw/new_w;
        boxes[i][3] *= (float)neth/new_h;
    }
}

void deal(DPUTask* task, Mat& img, int sw, int sh)
{
    vector<vector<float>> boxes;
    for(int i = 0; i < outputs_node.size(); i++) //because tiny has two layers for output, so 2
    {
        string output_node = outputs_node[i];
        int channel = dpuGetOutputTensorChannel(task, output_node.c_str());
        int width = dpuGetOutputTensorWidth(task, output_node.c_str());
        int height = dpuGetOutputTensorHeight(task, output_node.c_str());

        int sizeOut = dpuGetOutputTensorSize(task, output_node.c_str());
        int8_t* dpuOut = dpuGetOutputTensorAddress(task, output_node.c_str());
        float scale = dpuGetOutputTensorScale(task, output_node.c_str());
        vector<float> result(sizeOut);
        boxes.reserve(sizeOut);
        get_output(dpuOut, sizeOut, scale, channel, height, width, result);
        detect(boxes, result, channel, height, width, i, sh, sw);
    }
    correct_region_boxes(boxes, boxes.size(), img.cols, img.rows, sw, sh);
    vector<vector<float>> res = apply_nms(boxes, classification, NMS_THRE);

    float h = img.rows;
    float w = img.cols;
    for(size_t i = 0; i < res.size(); ++i)
    {
        float xmin = (res[i][0] - res[i][2]/2.0) * w + 1.0;
        float ymin = (res[i][1] - res[i][3]/2.0) * h + 1.0;
        float xmax = (res[i][0] + res[i][2]/2.0) * w + 1.0;
        float ymax = (res[i][1] + res[i][3]/2.0) * h + 1.0;
    cout<<"class: "<<res[i][4]<<endl; 
    rectangle(img, cvPoint(xmin, ymin), cvPoint(xmax, ymax), Scalar(0, 255, 255), 1, 1, 0);
    }
}

void detect(vector<vector<float>> &boxes, vector<float> result, int channel, int height, int width, int num, int sh, int sw) 
{
    {
    int conf_box = 5 + classification;
        float swap[height * width][anchor][conf_box];
        for (int h = 0; h < height; ++h) {
            for (int w = 0; w < width; ++w) {
                for (int c = 0; c < channel; ++c) {
                    int temp = c * height * width + h * width + w;
                    swap[h * width + w][c / conf_box][c % conf_box] = result[temp];
                }
            }
        }

        for (int h = 0; h < height; ++h) {
            for (int w = 0; w < width; ++w) {
                for (int c = 0; c < anchor; ++c) {
                    float obj_score = sigmoid(swap[h * width + w][c][4]);
                    if (obj_score < CONF)
                        continue;
                    vector<float> box;
                    box.push_back((w + sigmoid(swap[h * width + w][c][0])) / width);
                    box.push_back((h + sigmoid(swap[h * width + w][c][1])) / height);
                    box.push_back(exp(swap[h * width + w][c][2]) * biases[2 * c + anchor * 2 * num] / float(sw));
                    box.push_back(exp(swap[h * width + w][c][3]) * biases[2 * c + anchor * 2 * num + 1] / float(sh));
                    box.push_back(-1);                   // class
                    box.push_back(obj_score);                   // this class's conf
                    for (int p = 0; p < classification; p++) {
                        box.push_back(obj_score * sigmoid(swap[h * width + w][c][5 + p]));
                    }
                    boxes.push_back(box);
                }
            }
        }
    }

}
int main(const int argc, const char** argv) {
        dpuOpen();
        DPUKernel *kernel = dpuLoadKernel(YOLOKERNEL);
        DPUTask *task = dpuCreateTask(kernel, 0);
        int sh = dpuGetInputTensorHeight(task, INPUTNODE);
        int sw = dpuGetInputTensorWidth(task, INPUTNODE);
    if(argc < 2){
            cout<<"You should use like: ./yolo dog.jpg";
            return -1;
        }
        string name(argv[1]);
    Mat img = imread(name);
    set_input_image(task,  img,INPUTNODE);
        dpuRunTask(task);
    deal(task, img, sw, sh);
        cv::imshow("yolo-v3", img);
        cv::waitKey(0);

        dpuDestroyTask(task);
        dpuDestroyKernel(kernel);
        dpuClose();
        return 0;
}

最后测试图片的时候,无法检测到目标,即使是换了很明显的目标图片。 去网上搜了一下相关的内容,好像看到一个回答是说有可能是模型再量化编译的时候,预处理出错了。但我这次严格按照流程来,应该不会有问题的呀,在量化的时候,也喂了很多数据,设置了200个iter,也没有出错。 有一个比较疑惑的地方就是,代码里面的input nodes 和output nodes填的应该是量化编译后显示的输入输出节点还是生成pb模型时,显示的网络输入输出节点名称?

期待您的回复,谢谢!

wutianze commented 4 years ago

就是你compile之后显示的那些名字,然后我看你的输出结果里只有一层,不太清楚是不是你换了模型。yolo印象里是有3层输出,tiny的也有两层。如果你全部跑通了那应该是模型本身和最终的结果处理的问题,建议你先复习一下yolo

B1D1ng commented 4 years ago

对,在生成pb文件的时候,确实有显示两个输出节点的名字,但是在quant.sh里我只写了一个输出节点,是要把全部输出节点都写上吗

发自我的iPhone

------------------ 原始邮件 ------------------ 发件人: sauron <notifications@github.com> 发送时间: 2020年8月29日 11:46 收件人: wutianze/pynq_car <pynq_car@noreply.github.com> 抄送: Huaxun Wu <316186434@qq.com>, Author <author@noreply.github.com> 主题: 回复:[wutianze/pynq_car] 记录一些踩过的坑(持续更新) (#2)

就是你compile之后显示的那些名字,然后我看你的输出结果里只有一层,不太清楚是不是你换了模型。yolo印象里是有3层输出,tiny的也有两层。如果你全部跑通了那应该是模型本身和最终的结果处理的问题,建议你先复习一下yolo

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

wutianze commented 4 years ago

肯定的,得到结果以后也要做后续处理,具体就好好理解一下yolo的原理吧

B1D1ng commented 4 years ago

肯定的,得到结果以后也要做后续处理,具体就好好理解一下yolo的原理吧

感谢作者大大 ,我把输出节点全部写上后,现在成功在板子上实现部署了! 只不过预测效果相比原来差了很多。。。。我原来的mAP达到了86%,量化后的模型检测效果比较差,,有没有可能是预处理出问题了呢

wutianze commented 4 years ago

有可能,图片预处理的过程train和Inference要保持一致

B1D1ng commented 4 years ago

是执行quant.sh文件时的graph_input_fn这部分吗,教程中好像没找到相关的预处理环节的内容,我搜了一下网上的资料,类似问题的一般都是预处理出了问题,我看了一下您的教程中好像没有提到这部分相关内容

B1D1ng commented 4 years ago

有可能,图片预处理的过程train和Inference要保持一致

作者你好,请问如果是转成Caffe方式生成elf文件的话,上板检测的代码是不是就不适用了?之前tf的方式压缩模型后,上板检测精度很低,怀疑是量化时图片预处理环节出了问题,但是不知道如何修改。遂尝试用官方Caffe的方式生成了elf文件,但是上板编译的时候编译不成功。。。

wutianze commented 4 years ago

graph_input_fn只是量化的时候的预处理,这一部分要和你训练模型时喂的数据做的预处理保持一致。预处理这个话题非常大,而且得根据你自己的数据集来调试,这部分需要你自己去找一些预处理的技巧。你要用caffe也是可以的,只不过你得看清楚dnndk的版本等环境

B1D1ng commented 4 years ago

但还是比较疑惑为什么原模型训练效果非常好,量化压缩后的检测效果很差...预处理的图片是用来校准压缩后的模型的吧?作者您的教程是用的完整网络darknet yolov3,我用的是tiny版本,难道预处理方面和完整网络差别很大.. 您的教程的graph_input_fn应该是和darknet yolov3完整版的预处理对应的吧?当时大概选了多少张正样本图片进行量化阶段的预处理呢?我目前正在训练一版完整网络的darknet yolov3打算再部署试试,但是追求在z2这块板子上实时性的话,还是tiny更合适,精度低的问题还是得面对

发自我的iPhone

------------------ 原始邮件 ------------------ 发件人: sauron <notifications@github.com> 发送时间: 2020年8月31日 20:40 收件人: wutianze/pynq_car <pynq_car@noreply.github.com> 抄送: Huaxun Wu <316186434@qq.com>, Author <author@noreply.github.com> 主题: 回复:[wutianze/pynq_car] 记录一些踩过的坑(持续更新) (#2)

graph_input_fn只是量化的时候的预处理,这一部分要和你训练模型时喂的数据做的预处理保持一致。预处理这个话题非常大,而且得根据你自己的数据集来调试,这部分需要你自己去找一些预处理的技巧。你要用caffe也是可以的,只不过你得看清楚dnndk的版本等环境

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

wutianze commented 4 years ago

我的预处理只是做了一下归一化再移动中位值到0,tiny的和原版的最终结果的处理上会有不同,不知道你是否已经修改了最后的处理过程。我自己试验的yolo模型效果很不错,不会出现量化后就不对的情况。

B1D1ng commented 4 years ago

我还没有修改过,那我先训练一版完整yolov3网络再按照教程部署一遍看看,完整网络的话应该可以直接使用您的预处理,不过我训练的分辨率是608608,如果直接使用您的代码,特别是return img[40:,:]这一步会出错,得把40去掉才能匹配我喂的608608尺寸的数据,这一步修改会影响预处理吗

发自我的iPhone

------------------ 原始邮件 ------------------ 发件人: sauron <notifications@github.com> 发送时间: 2020年8月31日 22:01 收件人: wutianze/pynq_car <pynq_car@noreply.github.com> 抄送: Huaxun Wu <316186434@qq.com>, Author <author@noreply.github.com> 主题: 回复:[wutianze/pynq_car] 记录一些踩过的坑(持续更新) (#2)

我的预处理只是做了一下归一化再移动中位值到0,tiny的和原版的最终结果的处理上会有不同,不知道你是否已经修改了最后的处理过程。我自己试验的yolo模型效果很不错,不会出现量化后就不对的情况。

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

wutianze commented 4 years ago

不会影响,你只要保证预处理的过程和你的模型处理图片是一致的就可以

wutianze commented 4 years ago

当然,最后inference的时候也要是同样的预处理过程

B1D1ng commented 4 years ago

请问inference是在哪一步?我好像没注意到这个环节

发自我的iPhone

------------------ 原始邮件 ------------------ 发件人: sauron <notifications@github.com> 发送时间: 2020年8月31日 22:44 收件人: wutianze/pynq_car <pynq_car@noreply.github.com> 抄送: Huaxun Wu <316186434@qq.com>, Author <author@noreply.github.com> 主题: 回复:[wutianze/pynq_car] 记录一些踩过的坑(持续更新) (#2)

当然,最后inference的时候也要是同样的预处理过程

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

wutianze commented 4 years ago

这个就是最后在板子上运行的内容,板子上的c++程序。另外也很奇怪你如果只是要做yolo为什么不直接看这个链接,之前也已经给你推荐了。而且pynq_car的项目首页也说了该项目已经不再维护,新的项目是HydraMini,里面的更新。

B1D1ng commented 4 years ago

这个链接我看了,之前第一次成功部署就是按照yolo_pynqz2_guide完成的,只不过出现了tiny版精度的问题,转tf的部署流程基本上没问题了,明天我准备试试用完整版的yolov3再部署一遍看看效果,目前主要是想把自己训练好的模型部署到板子上跑起来,并且精度不要下降太多即可。很多细节方面的还没有去学习,所以遇见问题不知道怎么处理,希望不会打扰到您哈哈

发自我的iPhone

------------------ 原始邮件 ------------------ 发件人: sauron <notifications@github.com> 发送时间: 2020年8月31日 22:51 收件人: wutianze/pynq_car <pynq_car@noreply.github.com> 抄送: Huaxun Wu <316186434@qq.com>, Author <author@noreply.github.com> 主题: 回复:[wutianze/pynq_car] 记录一些踩过的坑(持续更新) (#2)

这个就是最后在板子上运行的内容,板子上的c++程序。另外也很奇怪你如果只是要做yolo为什么不直接看这个链接,之前也已经给你推荐了。而且pynq_car的项目首页也说了该项目已经不再维护,新的项目是HydraMini,里面的更新。

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

B1D1ng commented 4 years ago

另外我发现您这个repo里上传的镜像里有一个yolo_prune工程,可以直接编译,也可以用来测试图片,但是如果换成自己的elf的话,好像只修改您提到的那些参数编译会报错,我就直接使用yolo_pynqz2这个工程了,期待明天部署完整版的yolov3可以达到理想的效果

发自我的iPhone

------------------ 原始邮件 ------------------ 发件人: sauron <notifications@github.com> 发送时间: 2020年8月31日 22:51 收件人: wutianze/pynq_car <pynq_car@noreply.github.com> 抄送: Huaxun Wu <316186434@qq.com>, Author <author@noreply.github.com> 主题: 回复:[wutianze/pynq_car] 记录一些踩过的坑(持续更新) (#2)

这个就是最后在板子上运行的内容,板子上的c++程序。另外也很奇怪你如果只是要做yolo为什么不直接看这个链接,之前也已经给你推荐了。而且pynq_car的项目首页也说了该项目已经不再维护,新的项目是HydraMini,里面的更新。

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

wutianze commented 4 years ago

嗯,yolo_prune是最早版本的,那个和现在的有比较大的差别。要想自己定制还是得把yolo的概念和程序细节看一下,不然光改几个参数很容易碰到问题。祝好

B1D1ng commented 4 years ago

嗯,yolo_prune是最早版本的,那个和现在的有比较大的差别。要想自己定制还是得把yolo的概念和程序细节看一下,不然光改几个参数很容易碰到问题。祝好

您好,我尝试用Caffe的方式成功部署了模型,谢谢您之前为我解答各种各样的问题,真的非常感谢您!

wutianze commented 4 years ago

好的。

B1D1ng commented 4 years ago

博主您好,想请问下您的模型部署到Z2上后是否测试过视频呢?帧率大概多少?我部署了Tiny后,测试视频的帧率只有大概3FPS/s

------------------ 原始邮件 ------------------ 发件人: "wutianze/pynq_car" <notifications@github.com>; 发送时间: 2020年9月2日(星期三) 下午4:03 收件人: "wutianze/pynq_car"<pynq_car@noreply.github.com>; 抄送: "吴华勋"<316186434@qq.com>;"Author"<author@noreply.github.com>; 主题: Re: [wutianze/pynq_car] 记录一些踩过的坑(持续更新) (#2)

好的。

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

B1D1ng commented 4 years ago

您好!不好意思再次打扰到您! 想请问一下您:

  1. 您的的Z2板子用您提供的那个镜像是否能在linux终端用opencv实时调用摄像头?我看了您的项目是智能小车相关,那应该要调用摄像头实时读取图片吧?我在linux终端执行了最简单的调用摄像头代码,显示框出现黑屏,想了解一下您那边是否可以实时调用摄像头
  2. 您是否试过用PYNQ-Z2这块板子通过Opencv打开并播放本地视频呢?不对图片做任何算法处理,仅仅是打开并播放本地视频,如果尝试过的话,请问您的视频的帧率如何?我打开一个568*320,30帧的视频时,视频实时显示只有大概5帧左右,还没有做任何算法处理,非常卡顿,这个帧率如果再加上模型处理图片的话,那实时性估计非常差根本不能用了。我感觉未做任何处理打开一个视频,帧率不应该这么低才对呀。。

期待您的回复,谢谢!

------------------ 原始邮件 ------------------ 发件人: "wutianze/pynq_car" <notifications@github.com>; 发送时间: 2020年9月2日(星期三) 下午4:03 收件人: "wutianze/pynq_car"<pynq_car@noreply.github.com>; 抄送: "吴华勋"<316186434@qq.com>;"Author"<author@noreply.github.com>; 主题: Re: [wutianze/pynq_car] 记录一些踩过的坑(持续更新) (#2)

Closed #2.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.