Jetson Nano系列教程9:TensorFlow入门介绍 总结篇

摘要: JetsonNano+TensorFlow入坑介绍4,总结篇
一、前言
前面结合神经网络简要介绍TensorFlow相关概念,并给出了MNIST手写数字识别的简单示例,可以得出结论是,构建的神经网络目的就是利用已有的样本数据训练网络的权重和偏置,使神经网络最终能拟合或逼近现实世界中事物或现象的数学模型,故样本数据大,可以覆盖事物或现象所有特征时,可以越准确的识别事物,这也是大数据时代,数据是燃料的观点。
TensorFlow是一个神经网络软件框架,通过构建计算图,执行计算图方法来运行神经网络,前文示例中也是先构建计算图即构建神经网络隐藏层和输出层,再启动会话执行计算图。TensorFlow上线至今发行了几个API版本,每更新一次版本时,API要重新学一次,对比FaceBook的动态的pytorch框架,TensorFlow这点确实让人诟病,当然TensorFlow在训练网络阶段的速度相对更快。目前,Google于2019.03发行了TensorFlow2.0Beta版本,同pytorch一样支持动态执行(TensorFlow2.0默认eager模式,无需启动会话执行计算图),同时删除了杂乱低阶API,使用高阶API简单地构建复杂神经网络模型,本文主要分享用高阶API构建模型和数据集使用。
二、CNN、RNN、DNN
CNN、RNN、DNN都是神经网络,应用的场景不同,构建网络的结构不一样,命名也各不相同,例如前一篇文章提到的GoogleNet是CNN其中一种,还有著名的AlphGo也是基于CNN。随着对神经网络的的研究推进,出现了许多结构不同的神经网络,如在时间序列上建模的RNN(Recurrent Neural Network,递归神经网络)能对语义进行识别;残差网络的提出解决了神经网络在深度上训练难等问题,使神经网络隐藏层可以达到上百层而且能进行有效的训练,形成真正意义上的深度神经网络(Depth Neural Network,DNN)。当然还有许多其它知名的神经网络,感兴趣用户可以点击我阅读更多相关信息。
①、CNN(Convolution Neural Network,卷积神经网络),CNN模拟了视觉神经识别原理,应用在图像分类领域,使用CNN一个原因是CNN减少权重和偏置的训练,动辄千万级的参数造成训练难凸显的问题,CNN很好解决了此问题。CNN中出现的卷积核,通道,感受野,池化等概念可用CNN人脸识别过程的例子解释。CNN人脸识别过程是,先提取像素信息,往下一层是提取边界信息,然后往下一层是提取脸上部件信息如鼻子、眼睛、嘴等,最后是将识别到各部件进行分类进行人脸识别。其中提取边界信息可看下图1,图1中间矩阵为卷积核,将卷积核与图片进行卷积,得到图1右边的边界图片信息,卷积后的输出可称为feature map,图2给出了卷积核在图像上卷积(滑动)过程,滑动结束后得到右边像素信息,滑动过程中stride=(1,1)表示3*3卷积核每次从左向右滑动1个像素点,移动到行方向最右后移回到最左再往下移动一个像素,直至卷积完所有像素点。通道是输入神经网络图片的RGB三个通道;感受野是卷积神经网络每一层输出的特征图上的像素点在原始图像上映射的区域大小,如下图2右边特征图中每个像素点的感受野是来自原图片的3*3个像素点。顺便提一下,卷积的意义是加权求和,关于卷积的详细内容可点击参考相关内容

图1 (图片来源于网络/侵删)

图2 (图片来源于网络/侵删)

池化层是CNN中一个隐藏层,池化层的作用是缩减模型的大小,提高计算速度,同时减小噪声提高所提取特征的稳健性。池化理解为抽象化特征,提取特征,还有补偿卷积过程中消失的特征信息作用。池化有最大池化和平均池化。直观理解看下图3。图3为最大池化,将卷积后的图像进行缩小,提取或抽象化特征,没有足够的证据证明这种直观解释的正确性,而最大池化被使用的主要原因是它在很多实验中的效果都很好。一次卷积运算难以提取出全局的特征,因此需要在一层卷积基础上继续做卷积计算,提取脸上鼻子、嘴等特征信息,这就是多层卷积。通过卷积池化这样构建网络,每层输出会相应减少权重偏置的参数,简化训练难度,有些CNN模型并没池化层也能对图像分类有很好的效果,所以池化层(Pool)是可选项。


图3 (图片来源于网络/侵删)

下图4进行CNN图片分类任务中,CONV表示进行卷积,RELU表示卷积层的激活函数,POOL表示池化层,FC(Fully Connect)表示全连接层用于将识别到特征进行分类后输出,CNN网络是在隐藏层进行合理堆叠卷积池化层(不断提取特征)、全连接层进行分类实现图像识别的。


图4(图片来源于网络/侵删)

CNN更多内容请点击相关链接:吴恩达《深度学习》系列课程笔记

②、循环卷积网络(RNN,Recurrent Neural Network),RNN主要是对有序列模型进行处理,如输入法输入关联词时,能预测后续输出,此前较热门应用有使用RNN写实时新闻稿,写论文等,其中可让程序猿高效办公的Deep TabNine插件自动预测代码输出更是让RNN大放异彩。

RNN更多内容请点击相关链接:吴恩达《深度学习》系列课程笔记

三、使用Keras构建网络模型
TensorFlow2.0 Beta版本已经整合Keras库,使构建神经网络变得简单快速。目前JetPack4.2.1支持TensorFlow 1.14.1,下一个更新版本为2.0,当前版本也可用tf.kera.layer简单地构建复杂神经网络。
利用models模块API快速构建网络,Sequential是系列意思,按照神经网络从左往右经典结构堆叠神经层。由下面例子发现,使用keras构建一个神经网络不用10行代码,输入层使用Flatten函数将28*28数据平铺成784输入,隐藏层使用512个神经元的全连接层,激活函数为RELU,由于是全连接相当于无脑的隐藏层,参数训练量大,使用dropout训练网络过程每次回传随机忽略其中20%的权重和偏置参数调整,输出层有10个神经元,激活函数为softmax。
01from __future__ import absolute_import, division, print_function, unicode_literals
02import tensorflow as tf
03from PIL import Image
04import numpy as np
05 
06model = tf.keras.models.Sequential([
07         tf.keras.layers.Flatten(input_shape=(28, 28)),
08         tf.keras.layers.Dense(512, activation=tf.nn.relu),
09         tf.keras.layers.Dropout(0.2),
10         tf.keras.layers.Dense(10, activation=tf.nn.softmax) ])
列举一个CNN经典模型Lenet模型的例子,Lenet由两个卷积池化层,两个全连接层组成, 卷积核是5*5矩阵,stride=(1,1),使用最大池化。Lenet神经网络结构如下图所示。图5中,卷积池化层深度增加(32*32*1变成28*28*6),而宽度和高度(32*32变成28*28)减小,输入层使用6个卷积核生成深度为6的feature map,C1卷积层是用16个卷积核输出C2卷积层,池化层C5卷积层为120表示深度,形成了高度抽象特征信息。最后使用84个神经元全连接层连接10个神经元输出层。

图5(图片来源于网络/侵删)

Lenet参考python代码如下所示,tf.keras.layers..Conv2D()函数代表创建卷积层,tf.keras.layers.MaxPool2D()函数代表创建池化层,tf.keras.layers.Dense()函数创建全连接层,各函数具体参数请参考上面Lenet模型分析,还可点击我查看TensorFlow API了解更多内容。这样通过合理堆叠卷积池化层(一般当作一个层)、全连接层来构建CNN神经网络使得TensorFlow更加易用。
1model = tf.keras.models.Sequential([
2         tf.keras.layers..Conv2D(6, kernel_size=(5, 5), strides=(1, 1), activation='tanh', input_shape=(28,28,1), padding="same")
3         tf.keras.layers.MaxPool2D(pool_size=(2, 2), strides=(1, 1), padding='valid'),
4         tf.keras.layers.Conv2D(16, kernel_size=(5, 5), strides=(1, 1), activation='tanh', padding='valid')
5         tf.keras.layers.MaxPool2D(pool_size=(2, 2), strides=(2, 2), padding='valid')
6         tf.keras.layers.Conv2D(120, kernel_size=(5, 5), strides=(1, 1), activation='tanh', padding='valid'),
7         tf.keras.layers.Flatten(),
8         tf.keras.layers.Dense(84, activation='tanh'),
9         tf.keras.layers.Dense(10, activation='softmax') ])