TensorFlow笔记(1) 基础概念


1. TensorFlow简介

TensorFlow笔记(1) 基础概念
TensorFlow™是一个基于数据流编程(dataflow programming)的符号数学系统

借助其灵活的架构,用户可以轻松地将计算工作部署到多种平台(CPU、 GPU、 TPU)和设备(桌面设备、服务器集群、移动设备、边缘设备等),被广泛应用于各类机器学习算法的编程实现

TensorFlow由谷歌人工智能团队谷歌大脑(Google Brain)开发和维护


2. TensorFlow概念

TensorFlow = Tensor + Flow

  • Tensor 张量 :数据结构(多维数组)
  • Flow 流计算模型:张量之间通过计算而转换的过程

TensorFlow是一个通过计算图的形式表述计算的编程系统

  • 每一个计算都是计算图上的一个节点
  • 节点之间的边描述了计算之间的关系

3. 计算图

TensorFlow笔记(1) 基础概念
计算图是一个有向图,由以下内容构成:
• 一组节点,每个节点都代表一个操作,是一种运算
• 一组有向边,每条边代表节点之间的关系(数据传递和控制依赖)

TensorFlow有两种边:
• 常规边(实线) :代表数据依赖关系。
一个节点的运算输出成为另一个节点的输入,两个节点之间有tensor流动(值传递)

• 特殊边(虚线) :不携带值,表示两个节点之间的控制相关性。
比如, happens-before关系,源节点必须在目的节点执行前完成执行

例如一个计算图的实例:node3 = node1+node2

node1 = tf.constant(1.0, tf.float32, name="node1")
node2 = tf.constant(2.0, tf.float32, name="node2")
node3 = tf.add(node1, node2, name="node3")

TensorFlow笔记(1) 基础概念
显示节点node3

print(node3)

结果:不是一个具体的数字,而是一个张量的结构

Tensor("node3:0", shape=(), dtype=float32)

创建计算图只是建立静态计算模型,执行会话才能提供数据并获得结果

sess = tf.Session()  # 建立会话
print("运行sess.run(node1)的结果:", sess.run(node1))
print("运行sess.run(node3)的结果:", sess.run(node3))
sess.close()  # 关闭会话
运行sess.run(node1)的结果: 1.0
运行sess.run(node3)的结果: 3.0

4. Tensor 张量

在TensorFlow中,所有的数据都通过张量的形式来表示
并且张量并没有真正保存数字,它保存的是计算过程

Tensor("Add:0", shape=(), dtype=float32)

名字(name) : node 节点名称, src_output 来自节点的第几个输出
形状(shape):张量的维度信息, shape=() ,表示是标量
类型(dtype) :每一个张量会有一个唯一的类型,类型不匹配时会报错

从功能的角度, 张量可以简单理解为多维数组
零阶张量表示标量(scalar),也就是一个数;
一阶张量表示向量(vector),也就是一维数组;
n 阶张量可以理解为一个n维数组;

三个术语描述张量的维度: 阶(rank)、 形状(shape) 、 维数(dimension number)

形状 维数 例子
0 () 0-D 1
1 (D0) 1-D [2,3,4]
2 (D0,D1) 2-D [[5,6],[7,8]]
3 (D0,D1,D2) 3-D [[[9],[0]],[[1],[2]]]
N (D0,D1,…,Dn-1) n-D 形为(D0,D1,…,Dn-1)的张量
import tensorflow as tf

scalar = tf.constant(1)
vector = tf.constant([2, 3, 4])
matrix = tf.constant([[5, 6], [7, 8]])
cube_matrix = tf.constant([[[9], [0]], [[1], [2]]])

print(scalar.get_shape())
print(vector.get_shape())
print(matrix.get_shape())
print(cube_matrix.get_shape())

sess = tf.Session()  # 建立会话
# 获取张量的元素
print("运行sess.run(cube_matrix)[0, 1, 0]的结果:", sess.run(cube_matrix)[0, 1, 0])
sess.close()  # 关闭会话
()
(3,)
(2, 2)
(2, 2, 1)
运行sess.run(cube_matrix)[0, 1, 0]的结果: 0

TensorFlow支持14种不同的类型

  • 实数 tf.float32, tf.float64
  • 整数 tf.int8, tf.int16, tf.int32, tf.int64, tf.uint8
  • 布尔 tf.bool
  • 复数 tf.complex64, tf.complex128

默认类型:

  • 不带小数点的数会被默认为 tf.int32
  • 带小数点的会被默认为 tf.float32

5. Operation 操作

计算图中的节点就是操作(Operation)
一次加法是一个操作;一次乘法也是一个操作;构建一些变量的初始值也是一个操作。

每个运算操作都有属性,它在构建图的时候需要确定下来
操作可以和计算设备绑定,指定操作在某个设备上执行
操作之间存在顺序关系,这些操作之间的依赖就是“边”
如果操作A的输入是操作B执行的结果,那么这个操作A就依赖于操作B


6. Session 会话

会话拥有并管理TensorFlow程序运行时的所有资源
当所有计算完成之后需要关闭会话帮助系统回收资源

指定默认的会话:
TensorFlow不会自动生成默认的会话,需要手动指定
当默认的会话被指定之后可以直接通过 tf.Tensor.eval 函数来计算一个张量的取值

import tensorflow as tf

tens1 = tf.constant([0, 1, 2])  # 定义计算图
sess = tf.Session()  # 建立会话
with sess.as_default():  # 创建一个默认会话
    # 两个语句同样功能
    print(sess.run(tens1))
    print(tens1.eval())

交互式环境下设置默认会话:
在交互式环境下,通过设置默认会话来获取张量的取值更加方便
使用函数 tf.InteractiveSession 自动将生成的会话注册为默认会话

import tensorflow as tf

tens1 = tf.constant([0, 1, 2])  # 定义计算图
sess = tf.InteractiveSession() 	# 建立默认会话
print(tens1.eval())	# 显示得到的运行结果
sess.close()  # 关闭会话

关闭会话有多种方法:

  1. 直接调用 Session.close() 函数来关闭会话并释放资源
    但当异常退出时,关闭会话函数可能就不会被执行从而导致资源泄漏
    import tensorflow as tf
    
    tens1 = tf.constant([0, 1, 2])  # 定义计算图
    sess = tf.Session()  # 建立会话
    print(sess.run(tens1))  # 显示得到的运行结果
    sess.close()  # 关闭会话
    
  2. 所以可以采用 try … except … finally 确保异常退出时关闭会话函数依然执行
    import tensorflow as tf
    
    tens1 = tf.constant([0, 1, 2])  # 定义计算图
    sess = tf.Session()  # 建立会话
    
    try:
    	print(sess.run(tens1))  # 显示得到的运行结果
    except:
    	print("error")  # 提示异常出错
    finally:
    	sess.close()  # 关闭会话
    
  3. 一般采用关键字 with 简洁的确保异常退出时关闭会话
    import tensorflow as tf
    
    tens1 = tf.constant([0, 1, 2])  # 定义计算图
    
    with tf.Session() as sess:  # 建立会话,并通过上下文管理器来管理会话
    	print(sess.run(tens1))  # 显示得到的运行结果码片
    

谢谢!