TensorFlow 2.0简单介绍及使用
TensorFlow 2.0简介
TensorFlow起源于谷歌内部的DisBelief平台,2015年11月9日谷歌依据Apache 2.0协议将其开源。
TensorFlow 1.x经过三年多的迭代,在2018年的Google Cloud Next上TensorFlow团队宣布开启TensorFlow 2.0的迭代,2019年3月TensorFlow团队发布了TensorFlow 2.0-Alpha版本,同年6月发布了TensorFlow 2.0-Beta版本。
TensorFlow 2.0在TensorFlow 1.x版本上进行了大幅度改进,主要的变化如下:
- 将Eager模式作为TensorFlow 2.0默认的运行模式。Eager模式是一种命令行交互式的运行环境,不用构建Session就可以完成控制流的计算和输出。
- 删除tf.contrib库,将tf.contrib库中的高阶API和应用整合到tf.keras库下
- 合并精简API,将TensorFlow 1.x中大量重复、重叠的API进行合并精简
- 删除全局变量,在TensorFlow 2.0中不再有变量自动追踪机制,需要开发者自己实现对变量的追踪。一旦丢失对变量的追踪,变量就会被垃圾回收机制回收,不过开发者可以使用Keras对象来减轻自己的负担。
- 确立Keras的高阶API的唯一地位,在TensorFlow 2.0中所有的高阶API全部集中到tf.keras库下。
TensorFlow2.0环境搭建
TensorFlow支持CPU和GPU作为计算资源,而且不管使用Windows系统还是Linux系统都可以安装TensorFlow。
Linux CPU环境
直接使用python3-pip安装TensorFlow 2.0
sudo apt-get install python3-pip #安装TensorFlow 2.0 pip3 install tensorflow==2.0.0 #测试是否安装成功 python3 #导入tensorflow并打印其版本 import tensorflow as tf print(tf.__version__)
Windows CPU环境
在Windows环境下可以使用Anaconda安装TensorFlow 2.0
- 打开Anaconda官网下载适应自己系统的安装版本
- 打开Anaconda Prompt,就可以直接使用pip命令进行安装
#安装TensorFlow 2.0 pip3 install tensorflow==2.0.0
- 验证是否成功安装
#导入tensorflow并打印其版本 import tensorflow as tf print(tf.__version__)
基于Docker 的GPU环境搭建
TensorFlow官方提供了基于NVIDIA GPU显卡的Docker镜像,只需要在操作系统中安装GPU的显卡驱动即可,不需要安装cuDNN和CUDA就可以直接构建起一个TensorFLow-GPU开发环境。
在NVIDIA官网查看并下载显卡的驱动程序,下载地址为https://www.nvidia.cn/Download/index.aspx?lang=cn
TensorFlow 2.0 基础知识
基础知识,包括运行模式和基本的语法操作等。
TensorFlow 2.0 Eager模式简介
TensorFlow 2.0把Eager模式作为默认的模式,以此来提高TensorFlow的易用性和交互的友好性。
TensorFlow 2.0的Eager模式是一种命令式编程环境,无须构建计算图,所有的操作会立即返回结果。Eager模式不但使开发者可以轻松地使用TensorFlow进行编程和调试模型,而且还使编程代码变得更加简洁。
在TensorFlow官网总结的Eager模式的优势:
- 直观的代码结构:使代码更加符合Python的代码结构,整个代码逻辑一目了然
- 更轻松的调试功能:直接调用操作以检查正在运行的模型并测试更改
- 自然控制流程:使用Python控制流程而不是图控制流程,降低了动态图模型的规模
TensorFlow 2.0 AutoGraph简介
AutoGraph是tf.function装饰器带来的一个功能,可以将Python控制流转换为计算图,就是我们可以直接使用Python实现对计算图进行另一种意义的编辑。AutoGraph将控制流转换为计算图的方式可以带来更快的模型运行效率,以及模型导出上的便利,使用tf.function装饰器具有如下优势:
- 虽然一个函数被tf.function装饰后会被编译成图,但是依然可以按照函数的方式进行调用
- 如果在装饰的函数中有被调用的函数,那么被调用的函数也将以图的模式运行
- tf.function支持Python所有的控制流语句,比如if、for、while等
TensorFlow 2.0低阶API基础编程
在TensorFlow 2.0中定义了很多低阶API,一些常用的重要的低阶API。
- tf.constant
tf.constant提供了常量的声明功能
import tensorflow as tf a = tf.constant(7) print(a) print(a.numpy()) ########## tf.Tensor(7, shape=(), dtype=int32) 7
- tf.Variable
tf.Variable提供了变量的声明功能
import tensorflow as tf #声明一个Python变量 a1=7 #声明一个0阶Tensor变量 a2=tf.Variable(7) #声明一个1阶Tensor变量,即数组 a3=tf.Variable([0,1,2]) print(a1) print(a2) print(a3) ########### 7 <tf.Variable 'Variable:0' shape=() dtype=int32, numpy=7> <tf.Variable 'Variable:0' shape=(3,) dtype=int32, numpy=array([0, 1, 2])>
- tf.reshape
tf.reshape提供了多阶Tensor的形状变换功能
import tensorflow as tf a=tf.Variable([[0,1,2], [3,4,5]]) print(a.shape) #对a的形状进行变换,变换为(3,2) a1=tf.reshape(a, [3,2]) print(a1.shape) ########### (2, 3) (3, 2)
- tf.math.reduce_meantf.math.reduce_mean提供了对Tensor求平均值的功能,输出数据类型会根据输入数据类型来确定。使用该API时可以配置的参数如下:
- input_tensor:配置输入的Tensor
- axis:配置按行求平均值或按列求平均值,默认是全行全列求平均值
- keepdims:配置输出结果是否保持二维矩阵特性
- name:配置操作的名称
import tensorflow as tf a=tf.constant([1,2.,3,4,5,6,7.]) #输入数据类型是float32,输出数据类型也是float32 print(a.dtype) print(tf.math.reduce_mean(a)) b=tf.constant([[1,2,1], [5,2,10]]) #输入数据类型是int32,输出数据类型也是int32 print(b.dtype) #其实平均值应为(1+2+1+5+2+10)/6=3.5,但是由于输出类型为整型,因此强制赋值为3 print(tf.math.reduce_mean(b)) ########### <dtype: 'float32'> tf.Tensor(4.0, shape=(), dtype=float32) <dtype: 'int32'> tf.Tensor(3, shape=(), dtype=int32)
- tf.random.normaltf.random.normal可以随机生成一个Tensor,其值符合正态分布。使用该API时有如下参数需要配置:
- shape:配置生成Tensor的维度
- mean:配置正态分布的中心值
- stddev:配置正态分布的标准差( 不是方差 )
- seed:配置正态分布的随机生成种子
- dtype:配置生成Tensor的数据类型
import tensorflow as tf a=tf.random.normal(shape=[2,3], mean=2) print(a.numpy()) ######## [[1.9367738 2.375896 2.2572062] [2.2311876 2.0414147 2.7178261]]
- tf.random.uniformtf.random.uniform可以随机生成一个Tensor,其值符合均匀分布。使用该API时有如下参数需要配置:
- shape:配置生成Tensor的维度
- minval:配置随机生成数值的最小值
- maxval:配置随机生成数值的最大值
- seed:配置正态分布的随机生成种子
- dtype:配置生成Tensor的数据类型
import tensorflow as tf a=tf.random.uniform(shape=[2,3], minval=1, maxval=10, seed=8, dtype=tf.int32) print(a.numpy()) ######## [[4 9 9] [6 4 9]]
- tf.transposetf.transpose提供了矩阵的转置功能。使用该API时配置的参数如下:
- a:输入需要转置的矩阵
- perm:配置转置后矩阵的形状,
[0,2,1]表示 转置后的第0维是原本的第0维,转置后的1维是原本的第2维,转置后的第2维是原本的第1维
如果原本的形状为: [2,2,3] , 则转置后为 [ 2,3, 2] - conjugate:当输入矩阵是复数时,需要配置为True
- name:配置本次操作的名称
import tensorflow as tf x = tf.constant([[ [ 1, 2, 3], [ 4, 5, 6]], [ [ 7, 8, 9], [10, 11, 12]]]) a=tf.transpose(x, perm=[0,2,1]) print(a.numpy()) ######### [[[ 1 4] [ 2 5] [ 3 6]] [[ 7 10] [ 8 11] [ 9 12]]]
- tf.math.argmaxtf.math.argmax提供了返回一个数组内最大值对应索引的功能。使用该API时有如下参数可以配置:
- input:配置输入的数组
- axis:配置计算的维度
- output_type:配置输出的格式
- name:配置操作的名称
import tensorflow as tf a=tf.constant([1,2,3,4,5]) x=tf.math.argmax(a) print(x.numpy()) ######## 4
- tf.expand_dimstf.expand_dims的作用是在输入的Tensor中增加一个维度,比如t是一个维度为[2]的Tensor,那么tf.expand_dims(t,0)的维度就会变成[1,2]。使用这个API时需要配置如下参数:
- input:配置输入的Tensor
- axis:配置需要添加维度的下标,比如[2,1]需要在2和1之间添加,则配置值为1。
- name:配置输出Tensor的名称。
import tensorflow as tf #初始化一个维度为(3,1)的Tensor a=tf.constant([[1], [2], [3]]) print(a.shape) #为a增加一个维度,使其维度变成(1,3,1) b=tf.expand_dims(a,0) print(b.shape) print(b) ########### (3, 1) (1, 3, 1) tf.Tensor( [[[1] [2] [3]]], shape=(1, 3, 1), dtype=int32)
- tf.concattf.concat的作用是将多个Tensor在同一个维度上进行连接使用该API时需要进行如下参数配置
- values:配置Tensor的列表或者是一个单独的Tensor
- axis:配置按行或按列连接,axis=0表示按行连接,axis=1表示按列连接。
- name:配置运算操作的名称
import tensorflow as tf a1=tf.constant([[2,3,4], [4,5,6], [2,3,4]]) a2=tf.constant([[1,2,2], [6,7,9], [2,3,2]]) #按行进行连接 b=tf.concat([a1, a2], axis=0) print(b.numpy()) ######## [[2 3 4] [4 5 6] [2 3 4] [1 2 2] [6 7 9] [2 3 2]]
- tf.bitcasttf.bitcast提供了数据类型转换功能使用该API时需要进行如下参数配置
- input:配置需要进行类型转换的Tensor, Tensor的类型可以为bfloat16, half, float32, float64, int64, int32, uint8, uint16, uint32, uint64, int8, int16, complex64, complex128, qint8, quint8, qint16, quint16, qint32。
- type:配置转换后的数据类型,可以选择的类型包括tf.bfloat16, tf.half, tf.float32, tf.float64, tf.int64, tf.int32, tf.uint8, tf.uint16, tf.uint32, tf.uint64, tf.int8, tf.int16, tf.complex64, tf.complex128, tf.qint8, tf.quint8, tf.qint16, tf.quint16, tf.qint32。
- name:配置运算操作的名称。
import tensorflow as tf a=tf.constant(32.0) b=tf.bitcast(a, type=tf.int32) print(a.dtype) print(b.dtype) ######### <dtype: 'float32'> <dtype: 'int32'>
TensorFlow 2.0高阶API(tf.keras)
在TensorFlow 2.0中对大量的高阶API库进行了删减与合并,根据官方的解释,这一切的变化都是为了使TensorFlow 2.0更加易用和简洁
- tf.keras高阶API概览在TensorFlow 2.0版本中完全移除了tf.contrib这个高阶API库,官方推荐的高阶API只有tf.keras。Keras是一个意在降低机器学习编程入门门槛的项目,其在业界拥有众多的拥护者和使用者。经过Keras社区的多年发展,Keras集成了很多符合工业和研究需求的高阶API,使用这些API只需要几行代码就可以构建和运行一个非常复杂的神经网络。TensorFlow官方社区首次宣布发布TensorFlow 2.0版本计划时就明确了Keras会深度融合到TensorFlow中,并且作为官方支持的高阶API。官方文档中提到的tf.keras下的接口模块:
- activations:tf.keras.actibations中包含了当前主流的激活函数,可以直接通过该API进行激活函数的调用。
- applications:tf.keras.applications中包含的是已经进行预训练的神经网络模型,可以直接进行预测或者迁移学习。目前该模块中包含了主流的神经网络结构。
- backend:tf.keras.backend中包含了Keras后台的一些基础API接口,用于实现高阶API或者自己构建神经网络。
- datasets:tf.keras.datasets中包含了常用的公开数据训练集,可以直接进行使用(需要翻墙),数据集有CIFAR-100、Boston Housing等。
- layers:tf.keras.layers中包含了已经定义好的常用的神经网络层。
- losses:tf.keras.losses中包含了常用的损失函数,可以根据实际需求直接进行调用。\
- optimizers:tf.keras.optimizers中包含了主流的优化器,可以直接调用API使用。比如Adm等优化器可以直接调用,然后配置所需要的参数即可。
- preprocessing:tf.keras.preprocessing中包含了数据处理的一些方法,分为图片数据处理、语言序列处理、文本数据处理等,比如NLP常用的pad_sequences等,在神经网络模型训练前的数据处理上提供了非常强大的功能。
- regularizers:tf.keras.regularizers中提供了常用的正则化方法,包括L1、L2等正则化方法。
- wrappers:tf.keras.wrappers是一个Keras模型的包装器,当需要进行跨框架迁移时,可以使用该API接口提供与其他框架的兼容性。
- Sequential类:tf.keras.Sequential可以将神经网络层进行线性组合形成神经网络结构。
- tf.keras高阶API**例子:**构建一个线性回归模型
- 使用tf.keras高阶API构建神经网络模型
在TensorFlow 2.0中可以使用高阶API tf.keras.Sequential进行神经网络模型的构建。
#导入所需要的依赖包 import tensorflow as tf import numpy as np #实例化一个tf.keras.Sequential model=tf.keras.Sequential() #使用Sequential的add方法添加一层全连接神经网络 model.add(tf.keras.layers.Dense(input_dim=1, units=1)) #使用Sequential的compile方法对神经网络模型进行编译,loss函数使用MSE, optimizer使用SGD(随机梯度下降) model.compile(loss='mse', optimizer='sgd')
- 使用tf.keras高阶API训练神经网络模型
在完成神经网络模型的构建和编译之后,需要准备训练数据,然后对神经网络模型进行训练。
可以使用tf.keras.Sequential的fit方法进行训练
#随机生成一些训练数据,在-10到10的范围内生成700个等差数列作为训练输入 X = np.linspace(-10, 10, 700) #通过一个简单的算法生成Y数据,模拟训练数据的标签 Y=2*X+100+np.random.normal(0, 0.1, (700, )) #开始训练,“verbose=1”表示以进度条的形式显示训练信息,“epochs=200”表示训练的epochs为200, “validation_split=0.2”表示分离20%的数据作为验证数据 model.fit(X, Y, verbose=1, epochs=200, validation_split=0.2)
- 使用tf.keras高阶API保存神经网络模型
在完成神经网络模型的训练之后,可以使用Sequential的save方法将训练的神经网络模型保存为H5格式的模型文件。
filename='line_model.h5' model.save(filename) print("保存模型为line_model.h5")
- 使用tf.keras高阶API加载模型进行预测
加载神经网络模型需要使用tf.keras.models.load_model这个API,在完成模型的加载后可以使用Sequential的predict方法进行预测。
import tensorflow as tf filename='line_model.h5' x=tf.constant([0.5]) model=tf.keras.models.load_model(filename) y=model.predict(x) print(y)