3.5.1 TensorFlow名词与语法
李里:TensorFlow作为开源产品整体源代码放在了网上供大家下载,下载地址是https://github.com/TensorFlow/TensorFlow,下载源码编译然后配置环境变量等,但并不建议采用这样的安装方式,容易出现各种异常状况,而且安装逻辑比较复杂,这里推荐采用Pip的方式进行安装。这里列出一些常用的Tensorflow名词和基础语法,有助于你们阅读后继的培训材料。
TensorFlow版本:TensorFlow的版本号可以通过API去查看,这里注意一点不要看到新版本就去升级,TensorFlow的API是不往下兼容的,如你升级到1.7版本很大可能1.4版本上的程序就无法使用了,而且变动不只是参数的多少和函数名称,而是可能整个调用的模块都变更或取消了。
TensorFlow-GPU:TensorFlow提供一个专门的支持CUDA的GPU版本,CUDA(Compute Unified Device Architecture),是显卡厂商NVIDIA推出的运算平台。可以登陆网址,https://developer.nvidia.com/cuda-gpus,选择对应的显卡系列,即可查看你的GPU显卡是否支持CUDA。
TensorFlow-playground:Google提供的一个图形化用于教学目的的简单神经网络在线演示、实验的平台,非常强大地可视化了神经网络的训练过程。
TensorBoard: Google开发的用于可视化TensorFlow的程序的工具,可以便于理解模型的各种指标以及方便调试。
Bazel: Bazel是一个编译构建工具,即一个可以运行编译和测试来组装软件的工具,跟Make、Ant、Gradle、Buck、Pants和Maven一样。TensorFlow的编译工具,很多自带的Model都需要Bazel来编译。
Tensor:从TensorFlow的名称可以看出Tensor的重要性,这里中文翻译为张量,Tensor是一种基本数据类型,用法与n维数组类似,在编写TensorFlow程序时,要先建立基于Tensor的数据集,然后构建基于Tensor的计算流程并得到一个结果。Tensor同时包含数据类型与Shape两种属性。
变量:与Tensor不同之处在于不需要计算图的运行该值就会保存在定义的对象中。
计算图:大多数 TensorFlow 程序都以数据计算图构建阶段开始。这里的数据计算图是指根据模型构建一个在各个指令之间可以流动数据的桥梁,从TensorFlow的名称可以看到,这里指的是Tensor在构建的图中的流动。
会话:启动计算图时,第一步是创建一个会话对象,会话的作用负责让这个计算图运算起来,并且负责分配GPU和CPU。
占位符:在TensorFlow中用于保存数据,占位符的用处在于你先预定义好类型与shape,在运行时才会实际进行数据填充。在TensorFlow中用Placeholder表示。
TensorFlow数据类型定义:
数据类型 |
Python 类型 |
描述 |
DT_FLOAT |
tf.float32 |
32 位浮点数 |
DT_DOUBLE |
tf.float64 |
64 位浮点数 |
DT_INT64 |
tf.int64 |
64 位有符号整型 |
DT_INT32 |
tf.int32 |
32 位有符号整型 |
DT_INT16 |
tf.int16 |
16 位有符号整型 |
DT_INT8 |
tf.int8 |
8 位有符号整型 |
DT_UINT8 |
tf.uint8 |
8 位无符号整型. |
DT_STRING |
tf.string |
可变长度的字节数组.每一个张量元素都是一个字节数组 |
DT_BOOL |
tf.bool |
布尔型 |
DT_COMPLEX64 |
tf.complex64 |
由两个32位浮点数组成的复数:实数和虚数 |
DT_QINT32 |
tf.qint32 |
用于量化Ops的32位有符号整型 |
DT_QINT8 |
tf.qint8 |
用于量化Ops的8位有符号整型 |
DT_QUINT8 |
tf.quint8 |
用于量化Ops的8位无符号整型 |
以下代码均以使用 import tensorflow as tf导入tensorflow库。
变量初始化:这里数据初始化,一种是声明为常量这种类型在后继不能再被改变,无论值还是类型,另一种是变量,后期还可以被改变。
#变量初始化 #声明X为常量 X = tf.constant(10) #Tensor("Const:0", shape=(), dtype=int32) print (X) #声明Y为变量 Y = tf.Variable(10) #打印输出<tf.Variable 'Variable:0' shape=() dtype=int32_ref> print (Y) |
类型转换:Python属于自适应数据类型的语言,但在不同数据类型进行转换时也需要类型转换函数来实现,TensorFlow里面提供了tf.string_to_number,tf.to_float等等函数来强制进行类型转换,使用时只需将数据直接传入即可:
#类型转换 #将整数型数据转换为float型 X = tf.Variable(10,name="toint") # 这里打印X可以看到初始化时为int类型 # <tf.Variable 'toint:0' shape=() dtype=int32_ref> print (X) float_data = tf.to_float(X,name="tofloat") #经过类型转化后,可以看到已经转化为float类型 #Tensor("tofloat:0", shape=(), dtype=float32) print (float_data) |
数据赋值:是指对于一些初始化为变量的值进行重新赋值。
#数据赋值 X = tf.Variable(10, dtype=tf.int32) sess = tf.InteractiveSession() sess.run(tf.assign(X,20,name="toint")) #X值被赋值为20 print (X.eval()) |
数据形状:这里的形状指的是Tensor的shape,可以理解为矩阵的维数,而Tensor类型确实也可以转化为数组类型。
#数据形状 #查看TensorShape X = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) print(X) #将Tensor转为数组 sess = tf.InteractiveSession() #将Tensor转为数组 print(X.eval()) |
变量作用域:这里有两种作用域表达方式:命名空间的tf.name_scope和变量共享的tf.variable_scope。tf.name_scope相当于在变量名称前加入命名空间的前缀来区分变量。
#变量作用域 #命名空间作用域 with tf.name_scope('conv1') as scope: weights1 = tf.Variable([1.0, 2.0], name='weights') bias1 = tf.Variable([0.3], name='bias')
with tf.name_scope('conv2') as scope: weights2 = tf.Variable([4.0, 2.0], name='weights') bias2 = tf.Variable([0.33], name='bias')
#conv1/weights:0,增加了前缀conv1 print (weights1.name) #conv2/weights:0,增加了前缀conv2 print (weights2.name) |
tf.varibale_scope与tf.get_variable一起实现在指定作用域范围内是否重用变量。
#共享与重用变量 with tf.variable_scope('v_scope') as scope1: Weights1 = tf.get_variable('Weights', shape=[3,2]) bias1 = tf.get_variable('bias', shape=[2])
#使用之前已经定义好的变量,在scope 才能设置 reuse=True,否则会报错 with tf.variable_scope('v_scope', reuse=True) as scope2: Weights2 = tf.get_variable('Weights') #v_scope/Weights:0 print (Weights1.name) #v_scope/Weights:0 ,可以看到使用了reuse=True后,Weights2变量与Weights1是完全#一致的 print (Weights2.name)
#设置 reuse=False时由于v_scope已经有了Weights变量,故报错 with tf.variable_scope('v_scope', reuse=False) as scope3: Weights3 = tf.get_variable('Weights') print (Weights3.name) |
Tensor运算:Tensor的运算也包括四则运算,大小比较等。
#Tensor运算 X = tf.constant(10) Y = tf.constant(20) #比大小,打印False,X比Y小 print (tf.greater(X,Y).eval()) #加法,返回30 print (tf.add(X,Y).eval()) |
条件依赖触发:只有当依赖的条件都完成时才去执行作用域内的内容。
#条件依赖触发 X = tf.constant(20) Y = tf.constant(10) #先计算assert断言值,只有执行完才开始后面的计算 with tf.control_dependencies([tf.assert_greater(X.eval(), Y.eval())]): output = tf.add(X,Y) #输出30 print (output.eval())
Z = tf.add(X,Y) H = tf.add(Z,X) #保证Z与H先执行结束 with tf.control_dependencies([Z,H]): #输出50 print (H.eval()) |
条件语句:与if语句作用一致,是一种更简便的写法。
#条件语句 #case语法 X = tf.constant(20) Y = tf.constant(10) f1 = lambda: tf.constant(17) f2 = lambda: tf.constant(23) r = tf.case([(tf.less(X, Y), f1)], default=f2) #打印23,X < Y 为假,返回f2条件 print (r.eval()) |
循环语句:与while语句作用一致,是一种更简便的写法。
#循环语句 #while语法 i = tf.constant(0) c = lambda i: tf.less(i, 10) b = lambda i: tf.add(i, 1) r = tf.while_loop(c, b, [i]) #屏幕输出10 print(r.eval()) |