NVIDIA Jetson使用指导

本文将以NVIDIA Jetson为硬件基础,为你展现NVIDIA的力量,可以将其作为Jetson Nano的入门参考手册(教程)。

1. 入门篇

入门篇的有两章内容,来自NVIDIA JETSON包装盒自带的内容。

1.1. 准备环境

Ref.1: https://developer.nvidia.com/embedded/learn/get-started-jetson-nano-devkit

Ref.2: https://developer.nvidia.com/embedded/downloads

这里我使用的是一个Jetson Nano开发板,起初我以为随便一个USB数据线就能把它跑起来,但是我想多了。18W的快充头插上后可以正常启动,但是一旦运行比如WebGL测试的页面直接就关机了,因而我把小米音箱的电源适配器(5V2A)给它用了,还真能跑的动。

但是为了接下来的内容,我特意买了一个5V4A的5.5mm OD的电源适配器,要不然以我现在的环境很难保证能过了接下来的准备环境阶段。

要使用这个板子,你需要提前下载SDK的SD卡镜像,以及Host OS(PC,Ubuntu 18.04)所需的SDK Manager

下载完成之后,从Ref.1的链接中下载所需的镜像烧录软件或者别的烧录软件也行,将SD卡镜像烧录至TF卡中(这里我使用的是64G TF卡,A2)。烧录完毕将其插入核心板下面的卡槽中(有些不好找),见下图。

然后通过HDMI/DP线将之与显示器连接(启动阶段的分辨率需要修改,要不然小点的屏幕没法显示启动logo,这个不是重点以后再说),插上蓝牙USB键鼠,接入USB电源,你就可以看到信仰之NVIDIA logo。

这里你需要等它初始化完成,初始化工作包括扩展跟文件系统、解压乱七八糟的包之类的,总之等看到Ubuntu Desktop的安装配置界面后可以开始操作了。

进入桌面后的第一件事儿,可以先打开Chromium,访问WebGL的示例网站,随便开个demo试试会不会关机,如果关机那么恭喜你可以找个正经的USB电源了(Ref.1里有Adafruit的USB和DC电源适配器购买链接)。

当你的DC电源到了以后,先不要直接插上,因为需要设置一下跳线,如图所示。

看到Power Jack/USB Jumper没,由于我手里没有跳线帽,所以我直接短接了它们,如图所示(看我意念焊接术)。

然后再插上刚入手的DC 5V4A,即可空出你的USB并将之与Host PC相连了。

1.2. 准备SDK

这一节你可以先跳过去,等跑完下面的小节后再看,因为这部分并不影响接下来的操作。

准备SDK的内容主要包括:下载安装Host PC、开发板所需CUDA、OpenCV之类的,需要开发板的USB连接到Host PC上作数据连接用(我没有尝试过那个USB口既作电源又作数据传输)。

这里我并不打算过多介绍,只要按照引导进行操作即可。

1.3. Hello AI World

这个示例为你充分避开了各种依赖库的复杂安装步骤以及非常多的专业术语,对新手较为友好,但是我会仍会将其以链接形式展现,在最后章节的连接中。

第一步,从Hello World开始,你仍然需要最基础的工具。

$ sudo apt install git make cmake
$ git clone https://github.com/dusty-nv/jetson-inference
$ cd jetson-inference
$ git submodule update --init
$ mkdir build
$ cd build
$ cmake ../
$ make -j4
$ sudo make install
$ cd aarch64/bin

这一顿操作后,你会拥有个Hello AI World的全部成果。但是,what the hell an I doing?

来,对于一些Linux不熟悉的同学来说只要知道这里的cmake与make是编译源码的指令就行,cmake用来生成Makefile,make会根据Makefile里定义的动作调用gcc开始编译。

然后让我们看第一个例子,使用ImageNet的图片素材来训练我们的“机器人”让它能够识别各种物体,其中你会看到当前目录下有两个imagenet开头的文件,让我们从imagenet-console开始。

在图形界面上打开终端后,执行如下命令。

$ ./imagenet-console orange_0.jpg output_0.jpg
$ nautilus .

然后经过机器人的推理以后,你会得到一张橘子、另一张还是橘子的图片,并且新橘子图片的左上角标识了机器人认为它有多大概率是橘子。

是不是有感觉了?OK,我们继续。

既然它可以看图片,那么它当然也可以看视频或者摄像头中的内容,那么接下来我们让它看到摄像头中的橘子试试。

这里我需要给Jetson Nano接一个USB摄像头,接入以后可以在终端键入cheese打开拍照应用程序看它是否工作。

然后终端中运行如下命令。

./imagenet-camera

Oops,segmentation fault了,如文档所说,默认的摄像头是板载CSI摄像头,所以这里需要修改代码让它使用后来插入的USB摄像头。

$ vi ../../../imagenet-camera/imagenet-camera.cpp

...
#include "imageNet.h"
#define DEFAULT_CAMERA 0 // -1 for onboard camera, or change to index of /dev/video V4L2 camera (>=0)
bool signal_recieved = false;
...

将DEFAULT_CAMERA修改为0以后,便会启用/dev/video0路径上的摄像头,然后重新编译。

$ cd ../../ # build
$ cmake ../
$ make -j4

然后进到bin目录下再运行一次imagenet-camera即可。

PS:不是所有的摄像头都叫罗技C920,由于摄像头原生编码的问题,可能会导致上述程序黑屏,那么我们需要是适当修改一些内容。笔者暂时跳过这里,等改好以后再看。关于兼容列表可以参考eLinux的链接

1.4. 写一个小程序

如果你跟着github的教程,那么应该到你自己写一段代码的时间了,直接粘贴吧。

// include imageNet header for image recognition
#include <jetson-inference/imageNet.h>
// // include loadImage header for loading images
#include <jetson-utils/loadImage.h>

int main( int argc, char** argv )
{
                // a command line argument containing the image filename is expected,
                //      // so make sure we have at least 2 args (the first arg is the program)
  if( argc < 2 )
  {
    printf("my-recognition:  expected image filename as argument\n");
    printf("example usage:   ./my-recognition my_image.jpg\n");
    return 0;
  }

// retrieve the image filename from the array of command line args
  const char* imgFilename = argv[1];
  float* imgCPU    = NULL;    // CPU pointer to floating-point RGBA image data
  float* imgCUDA   = NULL;    // GPU pointer to floating-point RGBA image data
  int    imgWidth  = 0;       // width of the image (in pixels)
  int    imgHeight = 0;       // height of the image (in pixels)

// load the image from disk as float4 RGBA (32 bits per channel, 128 bits per pixel)
  if( !loadImageRGBA(imgFilename, (float4**)&imgCPU, (float4**)&imgCUDA, &imgWidth, &imgHeight) )
  {
    printf("failed to load image '%s'\n", imgFilename);
    return 0;
  }
  imageNet* net = imageNet::Create(imageNet::GOOGLENET);

  if( !net )
  {
    printf("failed to load image recognition network\n");
    return 0;
  }
  float confidence = 0.0;
  const int classIndex = net->Classify(imgCUDA, imgWidth, imgHeight, &confidence);
  if( classIndex >= 0 )
  {
    // retrieve the name/description of the object class index
    const char* classDescription = net->GetClassDesc(classIndex);
    // print out the classification results
    printf("image is recognized as '%s' (class #%i) with %f%% confidence\n",
    classDescription, classIndex, confidence * 100.0f);
  }
  else
  {
    // if Classify() returned < 0, an error occurred
    printf("failed to classify image\n");
  }
  delete net;
  // this is the end of the example!
  return 0;
}
# require CMake 2.8 or greater
cmake_minimum_required(VERSION 2.8)

# declare my-recognition project
project(my-recognition)

# import jetson-inference and jetson-utils packages.
# note that if you didn't do "sudo make install"
# while building jetson-inference, this will error.
find_package(jetson-utils)
find_package(jetson-inference)

# CUDA and Qt4 are required
find_package(CUDA)
find_package(Qt4)

# setup Qt4 for build
include(${QT_USE_FILE})
add_definitions(${QT_DEFINITIONS})

# compile the my-recognition program
cuda_add_executable(my-recognition my-recognition.cpp)

# link my-recognition to jetson-inference library
target_link_libraries(my-recognition jetson-inference)

然后编译并运行。

$ cmake .
$ make
$ ./my.cpp polarbear.jpg

输出结果如下。

[cuda]  cudaAllocMapped 5089520 bytes, CPU 0x100c30000 GPU 0x100c30000

imageNet -- loading classification network model from:
         -- prototxt     networks/googlenet.prototxt
         -- model        networks/bvlc_googlenet.caffemodel
         -- class_labels networks/ilsvrc12_synset_words.txt
         -- input_blob   'data'
         -- output_blob  'prob'
         -- batch_size   2

[TRT]  TensorRT version 5.0.6
[TRT]  detected model format - caffe  (extension '.caffemodel')
[TRT]  desired precision specified for GPU: FASTEST
[TRT]  requested fasted precision for device GPU without providing valid calibrator, disabling INT8
[TRT]  native precisions detected for GPU:  FP32, FP16
[TRT]  selecting fastest native precision for GPU:  FP16
[TRT]  attempting to open engine cache file /usr/local/bin/networks/bvlc_googlenet.caffemodel.2.1.GPU.FP16.engine
[TRT]  loading network profile from engine cache... /usr/local/bin/networks/bvlc_googlenet.caffemodel.2.1.GPU.FP16.engine
[TRT]  device GPU, /usr/local/bin/networks/bvlc_googlenet.caffemodel loaded
[TRT]  device GPU, CUDA engine context initialized with 2 bindings
[TRT]  binding -- index   0
               -- name    'data'
               -- type    FP32
               -- in/out  INPUT
               -- # dims  3
               -- dim #0  3 (CHANNEL)
               -- dim #1  224 (SPATIAL)
               -- dim #2  224 (SPATIAL)
[TRT]  binding -- index   1
               -- name    'prob'
               -- type    FP32
               -- in/out  OUTPUT
               -- # dims  3
               -- dim #0  1000 (CHANNEL)
               -- dim #1  1 (SPATIAL)
               -- dim #2  1 (SPATIAL)
[TRT]  binding to input 0 data  binding index:  0
[TRT]  binding to input 0 data  dims (b=2 c=3 h=224 w=224) size=1204224
[cuda]  cudaAllocMapped 1204224 bytes, CPU 0x101310000 GPU 0x101310000
[TRT]  binding to output 0 prob  binding index:  1
[TRT]  binding to output 0 prob  dims (b=2 c=1000 h=1 w=1) size=8000
[cuda]  cudaAllocMapped 8000 bytes, CPU 0x101440000 GPU 0x101440000
device GPU, /usr/local/bin/networks/bvlc_googlenet.caffemodel initialized.
[TRT]  networks/bvlc_googlenet.caffemodel loaded
imageNet -- loaded 1000 class info entries
networks/bvlc_googlenet.caffemodel initialized.
class 0296 - 1.000000  (ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus)
image is recognized as 'ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus' (class #296) with 100.000000% confidence

简言之,程序使用ImageNet的图片配上GoogleNet的模型对你的图片进行推理,然后得出它认为这是北极熊的可能性。

因为这篇文章的目的是入门,也就是带进来以后看哪个方向就自己看,所以相关数学知识在这里已经忽略了,如果你能写出厉害的理论paper又做出很厉害的工程实现,那么大牛就请继续往下过,顺便留个言交个朋友让我膜拜一下。你也可以查看文末的链接进一步扩展阅读什么是GoogleNet,什么是CNN,然后撸一遍机器学习、深度学习、强化学习啥的,也可能一路懵懂复习到信号与系统、高等数学,你要书的话我这还卖,另外我的学习笔记可以参阅DataNote

2. 进阶篇

2.1. 重新训练模型

2.2. 作为推理节点

2.3. 深度学习实验

2.4. TensorFlow实验

安装TensorFlow

$ sudo apt-get install libhdf5-serial-dev hdf5-tools libhdf5-dev zlib1g-dev zip libjpeg8-dev
$ sudo apt-get install python3-pip
$ sudo pip3 install -U pip
$ sudo pip3 install -U numpy grpcio absl-py py-cpuinfo psutil portpicker six mock requests gast h5py astor termcolor protobuf keras-applications keras-preprocessing wrapt google-pasta
$ sudo pip3 install --pre --extra-index-url https://developer.download.nvidia.com/compute/redist/jp/v42 tensorflow-gpu==1.14.0+nv19.9

 

https://devtalk.nvidia.com/default/topic/1048776/official-tensorflow-for-jetson-nano-/

https://www.tensorflow.org/tutorials

with jupyter

2.5. TensorRT实验

3. 行业方案篇

太阳底下没有新东西,我发现把之前的笔记稍微整理点可以新开一个目录出一个系列,那么,这里我就直接写关键字吧,以后说不定又冒出什么新东西了呢。

在继续之前,我们需要抓住一样内容,即凡是人类自己通过观察、模仿、学习可以获得的重复能力,机器/深度/强化等内容理论来说都可以帮你实现,即使是创造力。

然后我们再讲方案,即在这个小小的盒子,它有多少能力,能干啥。

3.1. 边缘计算

工业现场

计算转移

CDN

军用头戴

3.2. 云游戏

4K/8K/HDR/60FPS家用主机、服务端

无主机头戴

3.3. 教学设备

甭管便宜的贵的只要带卡都能当教学设备,不信你看研究生论文有多少CUDA相关。

3.4. 残障辅助

手语翻译(https://github.com/EvilPort2/Sign-Language),可按照中国残联手语进行训练(http://www.cdpf.org.cn/special/zgsy/node_305701.htm)。

apt install python3-keras

辅助视觉(物体/人脸识别后转语音)

参考:

文献

[1] NVIDIA AI Two Days Demo: https://developer.nvidia.com/embedded/twodaystoademo

[2] CNN Architecture: https://medium.com/@sidereal/cnns-architectures-lenet-alexnet-vgg-googlenet-resnet-and-more-666091488df5

[3] eLinux: https://www.elinux.org/Jetson

术语

[1] ImageNet: http://image-net.org/download

[2] TensorRT: https://developer.nvidia.com/tensorrt

[3] DeepStream: https://developer.nvidia.com/deepstream-sdk

[4] cuDNN

[5] PyTorch

[6] NVDLA

 

基于ARM(NVIDIA-JETSON-NANO)编译NetLogo

本文主要目的为测试这块板子的性能,看看其是否有作为边缘节点的能力。

Env

Ubuntu 18.04(jetson-nano-sd-r32.1-2019-03-18)

Prepare

$ sudo set -i 's/ports.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
$ sudo apt install -y curl x11vnc openjdk openjfx libopenjfx-jni libopenjfx-java

Build

$ git clone https://github.com/NetLogo/NetLogo
$ cd NetLogo
$ git submodule update --init
$ ./sbt netlogo/compile

Run and Package

$ ./sbt netlogo/run
$ ./sbt dist/buildNetLogo

Addon: Add VNC server to your board

$ sudo apt install -y x11nvc
$ x11vnc # to generate ~/.vnc files
$ echo 'x11vnc --loop &' >> ~/.xsessionrc

Ref

https://github.com/NetLogo/NetLogo/wiki/Building

https://github.com/NetLogo/NetLogo/wiki/Releasing

Agent based modeling Strategy in forex trading market

PREFACE

Since I’ve tested S1, S2, and S3 from the DATANOTE. However, it was not so good or in other words, identical with expectation. It’s time to make a change.

BASIC MODEL AND ARCHITECTURE

As you can see from my last articles, the architecture’s infrastructure is about to go and the agent’s protocol is well defined. Now what we should do is to combine them together.

In the first phase, the simulation will JUST be a Netlogo program. If the performance is just like S1-3, then it goes to phase 2 —- treating the agents as the real from the data gained and strategy trained from the real world. And if NOT, less probable, the program must be corrected.

PRACTICAL GUIDE

1. FAKE WORLD, FAKE AGENT

2. REAL WORLD, FAKE AGENT

3. REAL WORLD, REAL AGENT

World3 Model is a choice.(System Dynamics)

https://insightmaker.com/insight/1954/The-World3-Model-A-Detailed-World-Forecaster

Build a robot assistant with nowadays cloud apis

好多年前就想做个Jarvis,当时技术所限,构建出一个比较初级的机器人后觉得它还不如一条狗。

现在随着AI以及计算技术的成熟,尤其Google Assistant已经可以跟人自然语音对话了,所以觉得可以再尝试一下,加之工作需要,所以便又再开启。

现在随着AI以及计算技术的成熟,尤其Google Assistant已经可以跟人自然语音对话了,所以觉得可以再尝试一下,加之工作需要,所以便又再开启。

当然,这里我们首先选取交互平台为微信(Web API),交互形式为语音、文字等不限形式。然后再来看看哪些平台提供的最好用且最像人。

1. Google Assistant

2. 小爱同学(小米)/天猫精灵

3. 图灵/XiaoI

4. 自建

结论(对,有结论了):

1没中文,2最难用,3比较傻,4需要各种训练。直接用3+pyweixin自定义回复就OK了。

docker using linux bridge

A. Change docker bridge
dockerd -H unix:// -b br_eth0 –fixed-cidr=172.20.230.1/24 –default-gateway 172.20.0.1

B. Create manually, but flexibly
Recreate veth pair if your docker instance was restarted or exited.

[root@172-20-17-247 ~]# docker run –network none -it tianon/network-toolbox /bin/bash
[root@172-20-17-247 ~]# docker inspect –format ‘{{.State.Pid}}’ 3
74406
[root@172-20-17-247 ~]# ip link add centos3-cont type veth peer name centos3-host
[root@172-20-17-247 ~]# brctl addif br_eth0 centos3-host
[root@172-20-17-247 ~]# ifconfig centos3-host up
[root@172-20-17-247 ~]# ip link set netns 74406 dev centos3-cont
[root@172-20-17-247 ~]# nsenter -t 74406 -n ip link set centos3-cont up
[root@172-20-17-247 ~]# nsenter -t 74406 -n ip addr add 172.20.77.141/16 dev centos3-cont
[root@172-20-17-247 ~]# nsenter -t 74406 -n ip route add default via 172.20.0.1

[root@172-20-17-247 ~]# docker exec -it 3 bash
root@39eb1da6e842:/# ping google.com
PING google.com (172.217.25.206): 56 data bytes
64 bytes from 172.217.25.206: icmp_seq=0 ttl=55 time=87.434 ms
^C— google.com ping statistics —
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 87.434/87.434/87.434/0.000 ms

C. With pipework script
https://github.com/jpetazzo/pipework
[root@172-20-17-247 ~]# pipework br_eth0 -i eth2 CONTAINERID 172.20.100.22/16
[root@172-20-17-247 ~]# pipework route CONTAINERID replace default via 172.20.0.1

Ref:
[1] https://clcnetwork.wordpress.com/2017/05/31/docker-container-and-vm-networking/

这是一篇表达

距离上一次写已经很久了,而且似乎有个趋势就是对生活越熟悉就越麻木,也同样伴随体重的增加。

写了一句话,我已经忘了落笔时的念想。

要偶尔转移压力,但不是通过思考,方法或许成熟,但是经不得劳累。

要放弃linode的集群了,因为vultr ipv6内部通信更便宜。

transfer IPv6 to IPv4 via socat

Suppose that you have an ipv6-only server A with ip [ipv6-A], and ipv4-ipv6 server B with ip (ipv4-B, [ipv6-B]).

If you wanna visit http://[ipv6-A]:80, but your ISV does not provide some ipv6 addresses. Now then, you’ll make B be your “ipv6-ipv4 relay server” with following guide.

If TCP:

root@B:~# socat tcp4-listen:2222,fork tcp6:[2001:19f0:7001:5a34:5400:01ff:feb5:5bcd]:80

If UDP:

root@B:~# socat udp4-listen:2222,fork udp6:[2001:19f0:7001:5a34:5400:01ff:feb5:5bcd]:80

Now you can visit http://ipv4-B:2222 to access http://[ipv6-A]:80