[笔记]ros_deep_learning based on jetson-inference on Jetson AGX Xavier

主要参考
https://www.ncnynl.com/archives/201904/2985.html
源码
https://github.com/dusty-nv/jetson-inference
https://github.com/dusty-nv/ros_deep_learning
第〇步,首先安装jetson-inference,再catkin_make ros_deep_learning。没什么特殊的,根据README.md一步步来就行。我下载了ResNet-18,替代了默认的googlenet。

第一步,测试一下基于ros的inference好不好使。
第1步,启动roscore

roscore

[笔记]ros_deep_learning based on jetson-inference on Jetson AGX Xavier_第1张图片
第2步,往rostopic上发个要识别的图片

rosrun image_publisher image_publisher __name:=image_publisher ~/jetson-inference/data/images/orange_0.jpg

[笔记]ros_deep_learning based on jetson-inference on Jetson AGX Xavier_第2张图片
第3步,启动识别节点

rosrun ros_deep_learning imagenet /imagenet/image_in:=image_publisher/image_raw _model_name:=resnet-18

[笔记]ros_deep_learning based on jetson-inference on Jetson AGX Xavier_第3张图片
第4步,打印识别结果信息

rostopic echo /imagenet/classification

[笔记]ros_deep_learning based on jetson-inference on Jetson AGX Xavier_第4张图片
第二步,创建数据集。利用迁移学习(transfer learning)训练自己的数据集,基于PyTorch。(我涉及到的是图片分类问题) https://github.com/dusty-nv/jetson-inference/blob/master/docs/pytorch-collect.md

数据集的tree结构是这样的:

.
├── data
│   ├── labels.txt
│   ├── test
│   │   ├── class-A
│   │   ├── class-B
│   │   └── class-C
│   ├── train
│   │   ├── class-A
│   │   ├── class-B
│   │   └── class-C
│   └── val
│       ├── class-A
│       ├── class-B
│       └── class-C

我要识别7个类:
[笔记]ros_deep_learning based on jetson-inference on Jetson AGX Xavier_第5张图片

文件夹是这样的,我的数据集名字叫scene_identify:
[笔记]ros_deep_learning based on jetson-inference on Jetson AGX Xavier_第6张图片

train存放的是训练数据,val存放的是验证集数据,test存放的是测试数据,labels.txt 中按字母排序每行一个类别名:
[笔记]ros_deep_learning based on jetson-inference on Jetson AGX Xavier_第7张图片
这就是为什么labels.txt中要按字母排序的原因:
[笔记]ros_deep_learning based on jetson-inference on Jetson AGX Xavier_第8张图片

将数据集放到 ~/jetson-inference/python/training/classification/data/ 下。

第三步,训练。因为要在控制器上部署,对实时性有要求,所以选择resnet-18进行训练。
在 ~/jetson-inference/python/training/classification/ 中打开终端,训练前,先看一下都有哪些选项,执行

python3 train.py --help

[笔记]ros_deep_learning based on jetson-inference on Jetson AGX Xavier_第9张图片

训练,需要指明模型保存路径和训练数据路径

python3 train.py --model-dir=models/scene_identifier/ data/scene_identify

如果准确度不理想,想要继续训练,就执行

python3 train.py --model-dir=models/scene_identifier/ data/scene_identify --epochs 100 --resume models/scene_identifier/model_bast.pth.tar

训练之后会有这样两个文件
[笔记]ros_deep_learning based on jetson-inference on Jetson AGX Xavier_第10张图片

生成onnx,执行

python3 onnx_export.py --model-dir=models/scene_identifier/

[笔记]ros_deep_learning based on jetson-inference on Jetson AGX Xavier_第11张图片
再用TensorRT进行推理,执行

imagenet --model=models/scene_identifier/resnet18.onnx --input_blob=input_0 --output_blob=output_0 --labels=data/scene_identify/labels.txt data/scene_identify/test/road/05.jpg test_road_05.jpg

第一次比较慢,因为要生成engine文件,之后再进行推理就快了。随便拿出一张测试集中的图片推理一下,看看效果
[笔记]ros_deep_learning based on jetson-inference on Jetson AGX Xavier_第12张图片
同时在 /scene_identifier 下又会多出一个engine文件
[笔记]ros_deep_learning based on jetson-inference on Jetson AGX Xavier_第13张图片
提前创建好一个test_output_road文件夹,然后执行下面一行命令可测试某一类文件夹中的所有测试图片:

imagenet --model=models/scene_identifier/resnet18.onnx --input_blob=input_0 --output_blob=output_0 --labels=data/scene_identify/labels.txt data/scene_identify/test/road data/test_output_road

第四步,基于ROS的推理
将/jetson-inference/python/training/classification/data/scene_identify下的labels.txt 和 /jetson-inference/python/training/classification/models/scene_identifier下的resnet18.onnx 放到/home下
[笔记]ros_deep_learning based on jetson-inference on Jetson AGX Xavier_第14张图片

修改/home/nvidia/ros_workspace/src/ros_deep_learning/launch/imagenet.ros1.launch文件

<launch>


	<!-- IMAGENET -->
    <arg name="model_name" default="resnet-18"/>
    <arg name="model_path" default="/home/nvidia/resnet18.onnx"/>
	<arg name="prototxt_path" default=""/>
	<arg name="class_labels_path" default="/home/nvidia/labels.txt"/>
	<arg name="input_blob" default="input_0"/>
	<arg name="output_blob" default="output_0"/>

	<node pkg="ros_deep_learning" type="imagenet" name="imagenet" output="screen">
            <remap from="/imagenet/image_in" to="/camera/image"/>
		    <param name="model_name" value="$(arg model_name)"/>
			<param name="model_path" value="$(arg model_path)"/>
			<param name="prototxt_path" value="$(arg prototxt_path)"/>
			<param name="class_labels_path" value="$(arg class_labels_path)"/>
			<param name="input_blob" value="$(arg input_blob)"/>
			<param name="output_blob" value="$(arg output_blob)"/>
	</node>


	<!-- VIDEO OUTPUT -->
	<arg name="output" default="display://0"/>
	<arg name="output_codec" default="unknown"/>
	<arg name="output_bitrate" default="0"/>

	<include file="$(find ros_deep_learning)/launch/video_output.ros1.launch">
		<arg name="topic" value="/imagenet/overlay"/>
		<arg name="output" value="$(arg output)"/>
		<arg name="output_codec" value="$(arg output_codec)"/>
		<arg name="output_bitrate" value="$(arg output_bitrate)"/>
	</include>

</launch>

解释一下其中一些行都是什么意思:

<!-- IMAGENET -->
<arg name="model_path" default="/home/nvidia/resnet18.onnx"/>
这一行是指出onnx文件的路径,我把它复制出来,放在了根目录下
<arg name="prototxt_path" default=""/>
这一行用不到
<arg name="class_labels_path" default="/home/nvidia/labels.txt"/>
这一行必须有,是分类的labels.txt文件,也复制出来放到和onnx文件同一目录下
<arg name="input_blob" default="input_0"/>
这个input_blob是之前用imagenet可执行文件做推理时起的名字,input_0,必须是这个名字
<arg name="output_blob" default="output_0"/>
同理
<remap from="/imagenet/image_in" to="/camera/image"/>
这一行是订阅的话题名
<!-- VIDEO OUTPUT -->
<arg name="output" default="display://0"/>
作者README.md中说这是创建一个GUI界面,显示推理结果,在左上角

请忽略车道线识别结果,手头没有原始.bag了,就拿车道线识别结果实验一下

$ roslaunch ros_deep_learning imagenet.ros1.launch

你可能感兴趣的:(深度学习)