Jetson Nano系列教程6:TensorFlow入门介绍(一)


摘要: JetsonNano+TensorFlow入坑介绍1
一、前言
时下火热的AI浪潮,似乎商品都需挂钩AI这名词,作为边缘计算类产品的JetsonNano是货真价宜人工智能产品,JetsonNano具备Maxwell128核心的GPU和4核心 ARM A57的CPU,可运行Ubuntu(Linux for Tegra,L4T),浮点运算能力为472GFLOPS(FP16),官方给出的功率为10W,如此功率和算力已经相当可观,对比其它厂商的板卡可谓一枝独秀。GPU、TPU、CPU等计算类产品相关介绍请点击我了解
JetsonNano可以用来干嘛?若仅仅用来跑控制程序未免过于浪费,所以,本文开始将通过JetsonNano+TensorFlow介绍机器学习相关内容(神经网络(Neural Network)简要发展可点击我了解),帮助用户理清入门TensorFlow的思路。
注意:
1. JetsonNano平台只支持Python3.6的TensorFlow。
2. JetsonNano镜像版本:JetPack4.4(目前最新镜像为JetPack4.4)
3. TensroFlow API版本:r2.1.0(Nvidia于201904更新了tensorflow-2.1.0)
二、环境搭建
①、登陆Jetson Nano,安装相关函数库,点击我参阅登录Jetson Nano相关教程,输入下面命令:
注意:在输入第二个指令相关函数库的时候可能会由于网络延迟问题出现报错,如果有这种现象,建议你将指令拆开,手动一个个安装
1sudo apt-get update
2sudo apt-get install pip3 libhdf5-serial-dev hdf5-tools libhdf5-dev zlib1g-dev zip libjpeg8-dev liblapack-dev libblas-dev gfortran
②、更新一下pip3
1sudo apt-get install python3-pip
2sudo pip3 install -U pip testresources setuptools
③、安装TensorFlow依赖库, 对应需求的版本注意对应TensorFlow版本查看对应需求的依赖库版本(点这里查询),如果由于网络延迟问题有中断的话,建议拆分指令一个一个安装
1sudo pip3 install -U numpy==1.16.1 future==0.17.1 mock==3.0.5 h5py==2.9.0 keras_preprocessing==1.0.5 keras_applications==1.0.8 gast==0.2.2 futures protobuf pybind11
下载安装tensorflow. 截止到200515, 目前针对最新的JetPack4.4, TensorFlow版本更新到2.1.0版本,并且由原来的TensorFlow-gpu更改为tensorflow. 这里我们直接下载最新版本. 下载完成之后,可以import tensorflow测试一下
1sudo pip3 install --pre --no-cache-dir --extra-index-url https://developer.download.nvidia.com/compute/redist/jp/v44 tensorflow

此时可以按下Ctrl+Z退出python3交互界面
⑤、另外安装其它支持包,分别输入下面命令:
1sudo apt-get install python3-matplotlib
2sudo apt-get install python3-dev python3-setuptools libtiff5-dev zlib1g-dev libfreetype6-dev liblcms2-dev libwebp-dev libharfbuzz-dev libfribidi-dev  tcl8.6-dev tk8.6-dev python3-tk
3sudo pip3 install pillow

三、TensorFlow初探
1 简介
①神经网络(Neural Network,简称NN)
人工神经网络英语:Artificial Neural Network,ANN),简称神经网络(Neural Network,NN)或类神经网络,在机器学习认知科学领域,是一种模仿生物神经网络(动物的中枢神经系统,特别是大脑)的结构和功能的数学模型计算模型,用于对函数进行估计或近似。神经网络由大量的人工神经元联结进行计算。大多数情况下人工神经网络能在外界信息的基础上改变内部结构,是一种自适应系统,通俗的讲就是具备学习功能。现代神经网络是一种非线性统计性数据建模工具,神经网络通常是通过一个基于数学统计学类型的学习方法(Learning Method)得以优化,所以也是数学统计学方法的一种实际应用,通过统计学的标准数学方法我们能够得到大量的可以用函数来表达的局部结构空间,另一方面在人工智能学的人工感知领域,我们通过数学统计学的应用可以来做人工感知方面的决定问题(也就是说通过统计学的方法,人工神经网络能够类似人一样具有简单的决定能力和简单的判断能力),这种方法比起正式的逻辑学推理演算更具有优势。和其他机器学习方法一样,神经网络已经被用于解决各种各样的问题,例如机器视觉语音识别。这些问题都是很难被传统基于规则的编程所解决的。(来自Wiki)
了解高中生物学的用户知道,人类大脑中神经元达到上千亿个,形成神经网络让人类有强大的学习能力,以至出现麦克斯韦,普朗克等许多科学家(他们神经网络参数调的好),为什么神经网络会有如此强大的能力呢?答案是,神经网络逼近或拟合任意连续函数能力,使神经网络能提取事物的特征。
假设有一简单函数y=x+1,我们知道,当x=1时,y=2;x=2,y=3;x如此增加下去我们就掌握一个规律,每输入1个数,输出为这个数加1的值,我们就形成一种思维能力或者说大脑中已经有了这个事物的特征,可能你小学学习这一函数时有画坐标轴描点画线,学了半天终于知道有这么一回事,但是学会之后,你看到这一函数,你就知道这函数的特征甚至想在脑海中画了一张图,我们可将学习过程称之为训练,将后来发生的事称之为部署。一旦学会,脑袋不断电不出bug就不会忘记这一特征。上述也是机器学习的类似过程,模拟大脑建立一个多层神经网络,不断输入不同数据,经过神经元计算输出然后传递到下一层网络,最终到达输出层输出预测数据,然后跟输入的样本目标结果(训练用的样本数据包含目标结果)比较进行神经元参数调整,并将参数回传到上一层网络,如此往复不断调整网络参数,若最终训练结果符合预期即可在其它端设备上进行部署。关于神经网络更多讲解请点击我阅读

②TensorFlow
TensorFlow是一个软件库,封装了建构神经网络的API,类似于MatLab的神经网络工具箱,是Google于2015年推出的深度学习框架(目前最流行的深度学习框架),JetsonNano支持TensorFlow r1.14.0版本(Google于2019年3月推出了TensorFlow 2.0 Beta版)。
从输入输出角度理解TensorFlow是,在一张计算图中,Tensor(输入)像流体(Flow)流过节点,节点定义运算方法,整个过程执行是建立会话启动计算图得到运算结果(输出),下图可以更好理解TensorFlow工作流程:

图片引用自TensorFlow官网

从上图可以引出相关概念进行简要表述:

①计算图(Graph),如上图,表述了一个计算任务(也可以说是训练任务)。

②张量(Tensor),是对矢量和矩阵向潜在的更高维度的泛化。TensorFlow在内部将张量表示为基本数据类型的 n 维数组。

例:线性代数中用秩来表示矩阵的维度,同样在TensorFlow中也可以用秩来表示张量的维度

0阶张量(标量Scalar) 5

1阶张量(向量Vector) [1,2]

2阶张量(矩阵Matrix)[[1,2],[2,3]]

3阶张量 [[ [1,2,3],[4,5,6],[7,8,9]] [[1,3,5],[2,4,6],[5,7,9]] [[7,8,9],[2,4,6],[1,3,5]]]

③节点(Operation),是定义数据操作方法,上图中,流过节点的张量会被进行加减乘除取模运算。
④会话(Session),将计算图的节点(Op)分发到诸如CPU或GPU之类的设备上, 同时提供执行Op的方法。会话就是与后端连接高效C++库来进行计算,通俗理解是前期构建好计算图,启动会话就是按下开始按键,让数据流向每个节点。

2.张量的使用
张量形式有变量(tf.Variable),常量(tf.constant),占位符(tf.placeholder),稀疏张量(tf.SparseTensor),除了变量(tf.Variable),其它张量的值是不能改变的。变量是用在神经网络(NN)的权重和偏值的修正上,上图中每训练一次都可能需要更改网络权重W和偏值b。本小节从张量使用出发,逐步过渡到网络训练。
①.常量与固定张量
01python3
02import tensorflow as tf#导入tensorflow
03a=tf.constant('Hello World!')#常数张量
04b=tf.zeros([1,3,3])#生成3阶0张量
05c=tf.ones([1,3,3])#生成3阶单位1张量
06d=tf.fill([1,3,3],2.0)#生成3阶张量,并用2.0填充
07print(a)
08print(b)
09print(c)
10print(d)

可以从上图得到,使用print函数打印张量时,返回了张量的类型和形状,并未给出具体的数据,这是为什么呢?还记得上面提到的启动会话使Tensor流过节点,才会有输出。这里使用默认的计算图(默认存在一张计算图),使用Session.run函数启动会话,得到输出结果,我们这边并没有让Tensor作计算,只是让Tensor流过节点。
1sess=tf.Session()
2print(sess.run(a))
3print(sess.run(b))
4print(sess.run(c))
5print(sess.run(d))

②变量和占位符
上面提到变量是张量值可变的量,主要用来调整这些变量的值来生成网络模型。例如设置某神经网络中的参数(权重和偏值),另外需要初始化变量才能使用变量:
1w=tf.Variable(tf.zeros([784,10])
2b=tf.Variable(tf.zeros[10])
3init_op=tf.global_variables_initializer()
占位符通常作为输入输出的声明,提前占位,例如某神经网络中输入数据,每训练完一组数据,需读取磁盘其它批次数据到占位符这个坑等待数据流向节点计算,更新操作用feed_dict传入数据