TensorFlow 2.0 概述

简介: 在本文中将介绍与我的毕设论文演示案例相关的TensorFlow的一些基础知识,包括张量、计算图、操作、数据类型和维度以及模型的保存,接着在第二部分,本文将介绍演示案例代码中用到的一些TensorFlow 2.0中的高阶API,代码中不会涉及像TensorFlow 1.x版本中的Session等一些较为复杂的东西,所有的代码都是基于高阶API中的tf.keras.models来构建的(具体模型构建使用Sequential按层顺序构建),可以大大的方便读者更好的理解代码。

前言


在本文中将介绍与我的毕设论文演示案例相关的TensorFlow的一些基础知识,包括张量计算图操作数据类型和维度以及模型的保存,接着在第二部分,本文将介绍演示案例代码中用到的一些TensorFlow 2.0中的高阶API,代码中不会涉及像TensorFlow 1.x版本中的Session等一些较为复杂的东西,所有的代码都是基于高阶API中的tf.keras.models来构建的(具体模型构建使用Sequential按层顺序构建),可以大大的方便读者更好的理解代码。


需要注意的一点,本论文中所实现的两个案例均在本机CPU上进行运算,对于更大数量级的数据训练建议采用添加GPU的方法或者托管在Google cloud、AWS云平台上进行数据的处理。



1.1 基础知识概述


1.1.1 张量


第一次看到TensorFlow这个名词,第一反应是去翻译一下这代表什么意思,通过查阅相关字典可以知道,Tensor被翻译为张量,Flow被翻译为流或者流动,组合起来TensorFlow可以被翻译为张量流。那什么是张量,什么又是流呢?


一般来将,把任意维度的数据称为张量,比如说一维数组(任意一门编程语言里都会学到一维数组的概念)、二维矩阵(我们在线性代数中学过关于矩阵的概念,这里不做赘述)以及N维数据。而是指让数据在不同的计算设备上进行传输并计算(因为只有Tensor形式的数据可以实现在不同的设备之间进行传递)。


总结起来,我们可以认为TensorFlow的意思就是:让Tensor类型的数据在各个计算设备之间进行流动并完成计算。那为什么要让数据流动起来呢?Tensor类型又具体包括什么呢?接下来先来看一段演示代码:


# 将通过清华镜像下载的tensorflow包导入
import tensorflow as tf
a = tf.constant([[1.0,-2],[-3,4]])
print(a)

控制台输出结果如下:


tf.Tensor(
[[ 1.-2.]
 [-3.4.]], shape=(2, 2), dtype=float32)```


在上述代码中规定了一个2*2的矩阵,并将其打印在控制台。通过结果可以发现控制台输出的Tensor里面有三个参数:


  1. 第一个参数是一个2*2的矩阵,且矩阵中的元素全部为浮点类型。
  2. 第二个参数是shape,也就是输出矩阵的类型,很明显shape(2,2)表示输出矩阵为一个2*2的矩阵;举个例子,一个二阶张量a=[[1,1,1],[2,2,2]]的形状是两行三列,即shape=(2,3)。
  3. dtype=float32表示输出矩阵中元素的数据类型为浮点型(32为浮点数)


【注】:在上述对于代码部分的解释中提到一个名词二阶张量,接下来将通过表格的形式来区分一下标量、向量、矩阵的阶数的细微差异:


1-1 标量向量和矩阵的阶数

rank(阶) 实例 例子
0
标量(只有大小) a=1
1 向量(有大小和方向) b=[1,1,1,1]
2
矩阵(数据表) c=[[1,1],[1,1]]
3
3阶张量(数据立体) d=[[[1],[1]],[[1],[1]]]
n
n n层括号


简单解释一下,阶指的就是维度,它与矩阵的阶不同。


举个例子,对于a=[[1,1,1],[2,2,2],[3,3,3]]从矩阵的角度看,这是一个3*3的方阵,也就是说它的阶数为3,而从张量的角度看,它的阶数为2,即维度为2,因为它只有两层中括号。



1.1.2 计算图


首先来看看TensorFlow官网中的这幅图,一方面是帮助我们理解的概念,另一方面是为我们理解的概念做下铺垫。


【注】TensorFlow官网中的动图演示请参考如下网址:


http://www.shipudong.com/2020/03/24/bi-ye-she-ji-nei-rong-bu-chong/



微信图片_20220611003032.gif

1.1 TensorFlow官网流图演示



将图一般分为两种,包括动态计算图静态计算图。我以中铁某局修建地铁为例来讲解这两种图的区别:


修建一条地铁需要设计图纸和施工队:


第一种情况,当设计师在设计图纸的时候(包括隧道走向、站点设置等,具体细节不予赘述)施工队什么也不干,必须等到设计工作完成之后,施工队才开始工作,(我们可以把这种情况理解为计算机中的同步方式,把设计工作和施工操作看作两个任务,当前任务未完成之前,不能进行其他操作)也就是说设计工作和具体施工完全分开,这就是所谓的静态计算图,我们称能够支持静态计算图的为静态框架,主要包括TensorFlow、Theano等;


第二种情况,设计工作和施工操作一起进行,设计方要求开凿隧道,施工队立即完成任务,如此下去,一经设计方下达任务,施工队必须立即完成操作,如此良性循环直到项目完成(我们把这种情况理解为计算机中的异步方式),这就是所谓的动态计算图,我们称能够支持动态计算图的为动态框架,主要包括Torch等。


在了解了动态计算图和静态计算图的例子之后,我们很明显的可以看出两种图的差异:静态计算图在未执行之前就必须定义好执行顺序和内存分配,简单来说,在程序未执行之前就知道了所有操作,有助于较快地执行计算操作;相比动态计算图,每次的执行顺序规划和内存分配都是局部的,并非全局最优,虽然灵活性较静态计算图有很大提升,但是代价太高,所以在现在流行的框架中,还是以静态框架为主,比如本论文中的由谷歌公司开源的TensorFlow。



1.1.3 操作


从图1.1可以观察到,数据一经输入(Input),会被进行不同的操作,首先会将数据进行预处理(比如图中的reshape操作),接着给处理好的数据中加入非线性操作(ReLU操作)等,使数据更符合自然界中的普遍关系,然后我们根据输入数据的类型进而采取比较合适的交叉熵函数(Crossentropy),用来衡量真实值与预测值的偏差,最后我们我们将根据项目真实情况选取合适的优化器(图中选用的为sgd,即随机梯度下降法)。图中的一个节点就代表一个操作,我们从计算图中了解到,TensorFlow属于静态计算图,也就是说在未执行前就已经定义好了执行的顺序,简单来讲,图中的各个操作之间是存在执行顺序的,而这些操作之间的依赖就是图中的。我们以一个非常简单的图示来讲解这个关系,首先来看一段代码:


# 定义变量a
a = tf.Variable(1.0,name="a")
# 定义操作b为a+1
b = tf.add(a,1,name="b")
# 定义操作c为b+1
c = tf.add(b,1,name="c")
# 定义操作d为b+10
d = tf.add(b,10,name="d")


上述代码认为a、b、c和d均为需要进行的操作,下图中的x表示一个常数,值为1。


微信图片_20220611003042.png

1.2 操作之间的依赖关系


首先定义a=1.0,b=a+1,即b=2.0,以此类推,c=3.0,d=11.0,可以这样理解,操作b的进行需要依赖操作a,操作c的进行需要依赖操作b的完成,操作d的进行需要依赖操作b,且操作c和d之间没有依赖关系。


1.1.4 数据类型和维度


对于任意一门编程语言都会有数据类型,区别就在于每一门编程语言定义不同数据类型的方式不一样,在本章开始的时候了解过,在TensorFlow中,用张量(Tensor)来表示数据结构,接下来我们就将TensorFlow中的的数据类型与Python中的数据类型作以简单的对比,并通过表格的形式清晰的展现出来:


1-2 TensorFlowPython中数据类型的对应关系

TensorFlow数据类型

Python中的表示 说明
DT_FLOAT tf.float32 32位浮点数
DT_DOUBLE tf.float64 64位浮点数
DT_INT8 tf.int8 8位有符号整数
DT_INT16 tf.int16 16位有符号整数
DT_INT32 tf.int32 32位有符号整数
DT_INT64 tf.int64 64位有符号整数
DT_UINT8 tf.uint8 8位无符号整数
DT_UINT16 tf.uint16 16位无符号整数
DT_STRING tf.string byte类型数组
DT_BOOL tf.bool 布尔型
DT_COMPLEX64 tf.complex64 复数类型,由32位浮点数的实部和虚部组成
DT_COMPLEX128 tf.complex128 复数类型,由64位浮点数的实部和虚部组成
DT_QINT8 tf.qint8 量化操作的8位有符号整数
DT_QINT32 tf.quint32 量化操作的32位有符号整数
DT_QUINT8 tf.quint8 量化操作的8位无符号整数


维度的相关概念,在上述文章中的张量部分已经详细讲过,此处不再赘述。一般来说张量的阶数(维度)就是看有几层中括号,接下来看一段代码:


import tensorflow as tf
value_shape_0 = tf.Variable(1002)
value_shape_1 = tf.Variable([1,2,3])
value_shape_2 = tf.Variable([[1,2,3],[3,4,5],[5,6,7]])
print(value_shape_0.get_shape())
print(value_shape_1.get_shape())
print(value_shape_2.get_shape())

控制台输出结果如下:


()
(3,)
(3, 3)
(2, 3, 2)


代码解释:


  • value_shape_0:定义了一个标量(只有大小),其维度为0;
  • value_shape_1:定义了一个一维向量(有大小和方向),其维度为3;
  • value_shape_2:定义了一个二维的矩阵,矩阵大小为3*2;
  • value_shape_3:定义了一个三维张量,第一维的维度是2,第二维的维度是3,第三维的维度是2,可以简单理解为:这是一个大小为2*3且深度为2的矩阵。



1.1.5 模型保存


当我们完成一个案例之后,我们想要把当前训练好的模型保存下来(保存模型是指把训练的参数保存下来),方便我们之后重新使用。当我们重新使用的时候,我们只需要重新载入模型即可。


首先我们来看一下保存模型的代码:

# 保存模型
model.save("my_model.h5")

在关于MNIST手写字的例子中将我们训练好的模型保存下来,并命名为my_model.h5,接下来我们看一段载入模型的代码:


# 加载模型文件
model = tf.keras.models.load_model("my_model.h5")


同样是在MNIST手写字的例子中,我们将保存好的模型导入,并通过matplotlib函数画出模型图,具体模型图我会在本毕设系列推文的案例讲解部分中进行展示。



2. 相关API介绍


一般来讲,TensorFlow共有5个不同的层次结构,从低到高分别是硬件层内核层低阶API中阶API高阶API,我们对每一层作以简单的介绍:


  1. 硬件层:我们知道TensorFlow可以支持CPU、GPU、TPU(受限于硬件条件,我们本文中的项目是在本机CPU上运行的)加入计算资源池,作为一种计算设备参与运算;
  2. 内核层:该层是由C++语言实现的内核,可以支持跨平台的分布运行;
  3. 低阶API:该层主要提供了由Python实现的一些操作符,并对由内核层实现的一些低阶API进行封装,包括各种Tensor(张量)操作算子、计算图、自动微分等;
  4. 中阶API:该层是由Python实现的模型组件,并对低阶API进行了函数封装,主要包括各种模型层(tf.keras.layers)、损失函数(tf.keras.losses)、优化器(tf.keras.optimizers)、数据管道(tf.data.Dataset)等;
  5. 高阶API:该层为由Python实现的模型成品,主要为tf.keras.models提供的模型的类接口,在第四章中实现MNIST手写字识别的例子我们主要使用它。



微信图片_20220611003047.png

2.1  API详解


上述内容是我们对TensorFlow中的API做了宏观的描述,接下来我将着重介绍5个代码案例中较为重要的API:


  • tf.keras.models.Sequential:我们可以通过Sequential按层顺序来构建模型,也可以通过add方法一层一层添加模型(不建议使用),以下为代码演示:


model = tf.keras.models.Sequential([
#  里面是添加的模型层,比如说卷积层、池化层等
])
  • tf.keras.layers:我们可以通过此API添加我们需要的不同的模型层(卷积层、池化层等),通过查阅TensorFlow官网关于此API的介绍可以知道,读者可以通过此API添加如下模型层:



微信图片_20220611003053.png

2.2 TensorFlow官网tf.keras.layers部分API


以下是代码演示:


tf.keras.layers.Conv2D(input_shape = (28,28,1),filters = 32,kernel_size = 5,strides = 1,padding = "same",activation = "relu"),  # 28*28
  • tf.keras.datasets:用如下代码来加载MNIST收据集


mnist = tf.keras.datasets.mnist
(x_train, y_train),(x_test, y_test) = mnist.load_data()


  • model.compile:可以通过此API来编译经Sequential构建好的模型,同时也可以定义优化器、损失函数、如何对网络参数进行优化以及在训练过程中是否要计算准确率等,我们来看看官网中对此API的解释:


微信图片_20220611003057.png

2.3 compile函数官网介绍


具体代码如下:


tf.keras.layers.Conv2D(input_shape = (28,28,1),filters = 32,kernel_size = 5,strides = 1,padding = "same",activation = "relu"),  # 28*28# 编译模型   优化器--adam  (sgd--随机梯度下降法)损失函数---均方误差   metrics---训练过程中计算准确率accuracy
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy',metrics=['accuracy'])


  • model.fit:通过此API来训练模型,同时可以定义训练的迭代周期以及每次训练获取样本集的数量(一般默认batch_size=32),我们来看看官网对此API的解释:


微信图片_20220611003101.png

2.4 fit函数官网介绍



具体代码如下:


# 训练模型      epochs --- 迭代周期   batch_size默认为32
model.fit(x_train, y_train, batch_size=32,epochs=5)
相关文章
|
3月前
|
机器学习/深度学习 PyTorch TensorFlow
【TensorFlow】深度学习框架概述&TensorFlow环境配置
【1月更文挑战第26天】【TensorFlow】深度学习框架概述&TensorFlow环境配置
|
机器学习/深度学习 人工智能 自然语言处理
人工智能实践Tensorflow笔记:人工智能概述-1
人工智能实践Tensorflow笔记:人工智能概述-1
人工智能实践Tensorflow笔记:人工智能概述-1
|
机器学习/深度学习 数据可视化 数据挖掘
斯坦福tensorflow教程(一) tensorflow概述
斯坦福tensorflow教程(一) tensorflow概述
177 0
斯坦福tensorflow教程(一) tensorflow概述
|
3月前
|
机器学习/深度学习 人工智能 API
TensorFlow Lite,ML Kit 和 Flutter 移动深度学习:1~5
TensorFlow Lite,ML Kit 和 Flutter 移动深度学习:1~5
|
3月前
|
机器学习/深度学习 存储 人工智能
TensorFlow Lite,ML Kit 和 Flutter 移动深度学习:6~11(3)
TensorFlow Lite,ML Kit 和 Flutter 移动深度学习:6~11(3)
|
3月前
|
机器学习/深度学习 Dart TensorFlow
TensorFlow Lite,ML Kit 和 Flutter 移动深度学习:6~11(5)
TensorFlow Lite,ML Kit 和 Flutter 移动深度学习:6~11(5)
|
1天前
|
机器学习/深度学习 运维 监控
TensorFlow分布式训练:加速深度学习模型训练
【4月更文挑战第17天】TensorFlow分布式训练加速深度学习模型训练,通过数据并行和模型并行利用多机器资源,减少训练时间。优化策略包括配置计算资源、优化数据划分和减少通信开销。实际应用需关注调试监控、系统稳定性和容错性,以应对分布式训练挑战。
|
2月前
|
机器学习/深度学习 PyTorch TensorFlow
Python中的深度学习:TensorFlow与PyTorch的选择与使用
Python中的深度学习:TensorFlow与PyTorch的选择与使用
|
2月前
|
机器学习/深度学习 数据可视化 TensorFlow
基于tensorflow深度学习的猫狗分类识别
基于tensorflow深度学习的猫狗分类识别
61 1

热门文章

最新文章