0.TensorFlow的基础模型:

    |- 计算模型:计算图

    |- 数据模型:张量

    |- 运行模型:会话

1.计算模型——计算图:

 1.1 计算图的概念

计算图,又称为“张量流图”(TensorFlow的字面意思就是“张量流”)。用来描述张量(在TensorFlow中作为一种基本数据结构,可以简单的理解为多维数组)之间通过计算相互转化的过程。所以TensorFlow是一个通过计算图的形式来表述计算的编程系统。TensorFlow中的每一个计算都是计算图上的一个节点。节点之间的边描述的是计算之间的依赖关系。TensorBoard是TensorFlow的可视化工具,可以用来绘制计算图。

tensorflow什么版本最好用_TensorFlow

1.2 一次计算

1.2.1 完整代码:

>>> import tensorflow as tf
>>> a = tf.constant([1.0,2.0], name="a")
>>> b = tf.constant([2.0,3.0], name="b")    
>>> result = a + b
>>> sess = tf.Session()
2018-11-08 07:24:51.866562: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
>>> sess.run(result)
array([3., 5.], dtype=float32)

1.2.2 一次计算

    |- 定义计算

    |- 执行计算

1.2.3 定义计算:此过程会将定义的计算转化成计算图上的节点。

>>> import tensorflow as tf # 为了简洁,导入模块时,指定其简称。类似于标准SQL语句中的“as”
>>> a = tf.constant([1.0,2.0], name="a")
>>> b = tf.constant([2.0,3.0], name="b")    
>>> result = a + b

1.2.4 执行计算:

>>> sess = tf.Session()
>>> sess.run(result)

1.2.5 默认计算图:

系统会自动维护一个默认的计算图,通过tf.get_default_graph函数可以获取当前默认的计算图。

1.2.6 获取张量x所属计算图:x.graph

 

>>> print(a.graph is tf.get_default_graph())
True
# 通过a.graph 可以查看张量所属的计算图。因为我们没有指定,所以这个计算图应该等于当前默认的计算图。所以上面操作返回值为“True”。

1.3 生成计算图

可以使用tf.Graph函数来生成新的计算图。不同计算图上的张量和运算都不会共享。

import tensorflow as tf

# 定义g1,v的初值设置为“0”
g1 = tf.Graph()
with g1.as_default():
	v = tf.get_variable("v", shape=[1], initializer=tf.zeros_initializer)

# 定义g2,v的初值设置为“1”
g2 = tf.Graph()
with g2.as_default():
	v = tf.get_variable("v", shape=[1], initializer=tf.ones_initializer)

# 在计算图g1中读取变量“v”的取值
with tf.Session(graph=g1) as sess:
	tf.global_variables_initializer().run()
		with tf.variable_scope("", reuse=True):
			print(sess.run(tf.get_variable("v")))

# 在计算图g2中读取变量“v”的取值
with tf.Session(graph=g2) as sess:
	tf.global_variables_initializer().run()
		with tf.variable_scope("", reuse=True):
			print(sess.run(tf.get_variable("v")))

运行:

>>> import tensorflow as tf
>>> g1 = tf.Graph()
>>> with g1.as_default():
...     v = tf.get_variable("v", shape=[1], initializer=tf.zeros_initializer)
... 
>>> 
>>> 
>>> with tf.Session(graph=g1) as sess:
...     tf.global_variables_initializer().run()
...     with tf.variable_scope("", reuse=True):
...             print(sess.run(tf.get_variable("v")))
... 
[ 0.]


>>> g2 = tf.Graph()
>>> with g2.as_default():
...     v = tf.get_variable("v", shape=[1], initializer=tf.ones_initializer)
... 
>>> 
>>> with tf.Session(graph=g2) as sess:
...     tf.global_variables_initializer().run()
...     with tf.variable_scope("", reuse=True):
...             print(sess.run(tf.get_variable("v")))
... 
[ 1.]

1.4 计算图的基本功能:

    |- 1.隔离张量和计算

    |- 2.管理张量和计算

    |- 3.指定运行计算的设备:计算图可以通过tf.Graph.device 函数指定运行计算的设备。

        例如:

g = tf.Graph()
# 指定计算运行的设备
with g.device('/gpu:0'):
    result = a + b

    |-4.计算图的资源管理:计算图可以通过集合(collection)来管理不同类型的资源。

        |- 将资源加入一个或多个集合:tf.add_to_collection

        |- 获取一个集合中的所有资源:tf.get_collection

        |- 这里的资源包括:张量、变量、运行TensorFlow程序所需的队列资源等

        |- 为了方便使用,TensorFlow自动管理了一些常用集合:

            |- tf.GraphKeys.VARIABLES;所有变量;用于持久化TensorFlow模型。

            |- tf.GraphKeys.TRAINABLE.VARIABLES;可学习的变量(一般指神经网络中的参数);用于模型训练、生成模型可视化内容。

            |- tf.GraphKeys.SUMMARIES;日志生成相关的张量;用于TensorFlow计算可视化。

            |- tf.GraphKeys.QUEUE_RUNNERS;处理输入的QueueRunner;用于输入处理

            |- tf.GraphKeys.MOVING_AVERAGE_VARIABLES;所有计算了滑动平均值的变量;用于计算变量的滑动平均值

2.数据模型——张量

2.1 张量的概念

在TensorFlow中,所有的数据都通过张量的形式来表示。

功能角度:可以理解为多维数组。

    |- 零阶张量表示标量(scalar),也就是一个数;

    |- 一阶张量表示向量(vector),也就是一个一维数组;

    |- 第n阶张量可以理解为一个n维数组。

2.2 张量中存储内容的实质

张量中存储的内容并不是数组,它只是对TensorFlow中运算结果的引用。在张量中并没有真正保存数字,它保存的是如何得到这些数字的计算过程。例如:

import tensorflow as tf
# tf.constant 是一个计算,这个计算的结果为一个张量,保存在变量a中
a = tf.constant([1.0,2.0], name="a")
b = tf.constant([2.0,3.0], name="b")    
result = tf.add(a, b, name="add")
print result
输出:
Tensor("add:0", shape=(2,), dtype=float32)

2.3 张量的结构

从上面的输出内容“Tensor("add:0", shape=(2,), dtype=float32)”看出,张量中保存了名字(name),维度(shape)和类型(type)。

    |- 名字(name):

        |- 一个张量的唯一标识符

        |- 该张量是如何计算出来的

        |- 张量的名字的组成:node:src_output_number。(add:0,表示该“result”张量是计算节点“add”输出的第一个结果)

    |- 维度(shape)

        |- 描述该张量的维度信息。(shape=(2,)表示该张量是一个一维数组,这个数组的长度为2)

    |- 类型(type)

        |- 每个张量都会有一个唯一的类型

        |- 指张量所表示的数组的数据类型

        |- 不同类型的张量之间运算会报错:类型不匹配

2.4 张量的创建

创建张量:

# 1.定义一个浮点型张量
a = tf.constant([1.0, 2.0], name="a", dtype=tf.float32)

# 2.定义一个浮点型张量
a = tf.constant([1, 2], name="a", dtype=tf.float32)

# 3.定义一个浮点型张量
a = tf.constant([1.0, 2.0], name="a")

# 4.定义一个整型张量
a = tf.constant([1, 2], name="a", dtype=tf.int32)

# 5.定义一个整型张量
a = tf.constant([1, 2], name="a")

不指定类型,系统会根据输入的数组数据类型来推断数据类型。不带小数点,被推断为int32;带有小数点,被推断为float32。

2.5 张量的数据类型

TensorFlow支持14种数据类型:

    |- 字符串

        |- tf.string

    |- 布尔型

        |- tf.bool

    |- 整型

        |- tf.int8

        |- tf.int16

        |- tf.int32

        |- tf.int64

        |- tf.uint8

        |- tf.uint16

    |- 浮点型

        |- tf.float16

        |- tf.float32

        |- tf.float64

        |- tf.double

    |- 复数

        |- tf.complex64

        |- tf.complex128

2.6 张量的创建

创建张量的用途:

    |- 1.表示中间结果,用以提高代码的可读性;

    |- 2.表示最终结果,用来获取程序的最终结果:tf.Session().run(result).

 

3.运行模型——会话

3.1 会话的功能:

    |- 执行定义好的运算

    |- 拥有并管理TensorFlow程序运行时的所有资源

    |- 计算结束之后,需要关闭会话来帮助系统回收资源,否则会造成资源泄露

3.2 会话的模式

模式一:

# 创建一个会话
sess = tf.Session()
# 使用这个创建好的会话来得到关心的运算的结果。如前面的:sess.run(result)
sess.run(...)
# 关闭会话,释放资源
sess.close()

模式二:

# 创建一个会话,并通过Python中的上下文管理器来管理这个会话。将所有计算放在with内即可。
with tf.Session() as sess:
    # 使用创建好的会话来计算关心的结果
    sess.run(...)
# 不需要再调用“Session.close”函数来关闭会话,当上下文退出时 自动关闭会话并释放资源。

对比:

    |- 模式一:当程序因异常退出时,后面关闭会话的函数(sess.close())可能就不会被执行,那么可能造成资源泄露。

    |- 模式二:不存在忘记关闭会话的问题,不存在异常退出导致的资源泄露问题。

(推荐模式二,注意缩进即可。)

3.3 默认会话

通过设定默认会话并计算张量的取值

# 方法一
sess = tf.Session()        # 获取一个会话
with sess.as_default():    # 将获取的会话设置为默认会话
    print(result.eval())   # 用默认会话计算出result张量并输出

# 方法二
sess = tf.Session()        # 获取一个会话
print(sess.run(result))    # 以指定的会话计算出result张量并输出

# 方法三
sess = tf.Session()              # 获取一个会话
print(result.eval(session=sess)) # 以指定的会话计算出result张量并输出

3.4 直接构建默认会话

sess = tf.InteractiveSession() # 生成交互式会话,并将其注册为默认会话(在交互式环境中可用)
print(result.eval())
sess.close()

功能上:tf.Session().as_default() = tf.InteractiveSession()

3.5 配置会话

通过ConfigProto配置会话:

# 配置会话的属性
config = tf.ConfigProto(allow_soft_placement=True,log_device_placement=True)

# 用上面配置好的配置来创建一个交互式会话
sess1 = tf.InteractiveSession(config=config)

# 用上面配置好的配置来创建一个会话
sess2 = tf.Session(config=config)

参数包含并行的线程数、GPU分配策略、运算超时时间等。

最常用的是allow_soft_placement和log_device_placement。

    |- 允许软放置allow_soft_placement:Boolean,默认为False。

        |- 意义:当此参数取“True”时,以下情况中GPU上的运算可以放在CPU上进行计算。提高代码的可移植性。

            |- 1. 运算无法在GPU上执行;

            |- 2.GPU资源不足;

            |- 3.运算输入包含对CPU结果的引用。

    |- 允许将计算在设备中的分布记录至日志log_device_placement:Boolean,默认为False。

        |- 意义:当此参数取“True”时,日志中将会记录每个节点(计算)被安排到哪个设备上以方便调试。在生产环境将此参数设置为“False”以减少日志量。