TensorFlow资源管理

Resources

tf.placeholder

placeholder:占位符,执行时通过feed_dict参数设置值

1
2
3
4
5
tf.placeholder(
dtype,
shape=None,
name=None
)
  • shape:并不必须,但最好设置参数方便debug
  • 需要导入数据给placeholder,可能影响程序速度
  • 方便用户替换图中值

tf.data.DataSet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class tf.data.DataSet:
def __init__(self)

# 从tensor slice创建`Dataset`
def from_tensor_slices(self,
?data=(?features, ?labels)
):
pass

# 从生成器创建`Dataset`
def from_generator(self,
gen,
output_types,
output_shapes
):
pass

# 迭代数据集一次,无需初始化
def make_one_shot_iterator(self):
pass

# 迭代数据集任意次,每轮迭代需要初始化
def make_initializable_iterator(self):
pass

# shuffle数据集
def shuffle(self, ?seed:int):
pass

# 重复复制数据集
def repeat(self, ?times:int):
pass

# 将数据集划分为batch
def batch(self, batch_size:int):
pass

def map(self, func:callable):
pass
  • 创建只能迭代一轮的迭代器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    iterator = dataset.make_one_shot_iterator()
    # 这里`X`、`Y`也是OPs,在执行时候才返回Tensor
    X, Y = iterator.get_next()

    with tf.Session() as sess:
    print(sess.run([X, Y]))
    print(sess.run([X, Y]))
    print(sess.run([X, Y]))
    # 每次不同的值
  • 创建可以多次初始化的迭代器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    iterator = data.make_initializable_iterator()
    with tf.Session() as sess:
    for _ in range(100):
    # 每轮重新初始化迭代器,重新使用
    sess.run(iterator.initializer)
    total_loss = 0
    try:
    while True:
    sess.run([optimizer])
    # 手动处理迭代器消耗完毕
    except tf.error.OutOfRangeError:
    pass
  • tf.datatf.placeholder适合场景对比

    • tf.data速度更快、适合处理多数据源
    • tf.placeholder更pythonic、原型开发迭代速度快

读取文件数据

可以从多个文件中读取数据

1
2
3
4
5
6
 # 文件每行为一个entry
class tf.data.TextLineDataset(filenames):
# 文件中entry定长
class tf.data.FixedLengthRecordDataset(filenames):
# 文件为tfrecord格式
class tf.data.TFRecordDataset(filenames):

tf.data.Iterator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class tf.data.Iterator:
# 获取下组迭代数据
def get_next():
pass

# 根据dtype、shape创建迭代器
@classmethod
def from_structure(self,
?dtype: type,
?shape: [int]/(int)
):
pass

# 从数据中初始化迭代器
def make_initializer(self,
?dataset: tf.data.Dataset
):
pass

TensorFlow Python IO接口

TFRecord

TFRecord格式:序列化的tf.train.Example protbuf对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class tf.python_io.TFRecordWriter:
def __init__(self,
?fileanme: str,
options: tf.python_io.TFRecordOptions,
name=None
):
pass

class tf.python_io.TFRecordReader:
def __init__(self,
options: tf.python_io.TFRecordOptions,
name=None
):
pass

def read(self):
pass

### Feature/Features

```python
class tf.train.Features:
def __init__(self,
feature: {str: tf.train.Feature}
):
pass

class tf.train.Feature:
def __init__(self,
int64_list: tf.train.Int64List,
float64_list: tf.train.Float64List,
)

示例

  • 转换、写入TFRecord

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # 创建写入文件
    writer = tf.python_io.TFRecord(out_file)
    shape, binary_image = get_image_binary(image_file)
    # 创建Features对象
    featurs = tf.train.Features(
    feature = {
    "label": tf.train.Feature(int64_list=tf.train.Int64List(label)),
    "shape": tf.train.Feature(bytes_list=tf.train.BytesList(shape)),
    "image": tf.train.Feature(bytes_list=tf.train.BytesList(binary_image))
    }
    )
    # 创建包含以上特征的示例对象
    sample = tf.train.Example(features=Features)
    # 写入文件
    writer.write(sample.SerializeToString())
    writer.close()
  • 读取TFRecord

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    dataset = tf.data.TFRecordDataset(tfrecord_files)
    dataset = dataset.map(_parse_function)
    def _parse_function(tf_record_serialized):
    features = {
    "labels": tf.FixedLenFeature([], tf.int64),
    "shape": tf.FixedLenFeature([], tf.string),
    "image": tf.FixedLenFeature([], tf.string)
    }
    parsed_features = tf.parse_single_example(tfrecord_serialized, features)
    return parsed_features["label"], parsed_features["shape"],
    parsed_features["image"]

其他函数

TensorFlow控制算符

控制OPs

Neural Network Building Blocks

tf.softmax

tf.Sigmod

tf.ReLU

tf.Convolution2D

tf.MaxPool

Checkpointing

tf.Save

tf.Restore

Queue and Synchronization

tf.Enqueue

tf.Dequeue

tf.MutexAcquire

tf.MutexRelease

Control Flow

tf.count_up_to

tf.cond

predTrue,执行true_fn,否则执行false_fn

1
2
3
4
5
tf.cond(
pred,
true_fn=None,
false_fn =None,
)

tf.case

tf.while_loop

tf.group

tf.Merge

tf.Switch

tf.Enter

tf.Leave

tf.NextIteration

TensorFlow操作符

Tensor

张量:n-dimensional array,类型化的多维数组

  • TF使用Tensor表示所有的数据
  • Tensor包含一个静态类型rank、一个shape
  • TF会将python原生类型转换为相应的Tensor
    • 0-d tensor:scalar
    • 1-d tensor:vector,1d-array
    • 2-d tensor:matrix,2d-array

Data Type

  • TF被设计为和numpy可以无缝结合

    • TF的变量类型基于numpy变量类型:tf.int32==np.int32
    • bool、numeric等大部分类型可以不加转换的使用TF、np 变量类型
    • TF、np中string类型不完全一样,但TF仍然可以从numpy 中导入string数组,但是不能在numpy中指定类型
  • 但尽量使用TF变量类型

    • python原生类型:没有细分类型,TF需要推断类型
    • numpy类型:numpy不兼容GPU,也不能自动计算衍生类型
数据类型 说明
tf.float16 16-bit half-precision floating-point
tf.float32 32-bit single-presicion floating-point
tf.float64 64-bit double-presicion floating-point
tf.bfloat16 16-bit truncated floating-point
tf.complex64 64-bit single-presicion complex
tf.complex128 128-bit double-presicion complex
tf.int8 8-bit signed integer
tf.uint8 8-bit unsigned integer
tf.int16
tf.uint16
tf.int32
tf.int64
tf.bool
tf.string
tf.qint8 quantized 8-bit signed integer
tf.quint8
tf.qint16
tf.quint16
tf.qint32
tf.resource handle to a mutable resource

Constant OPs

tf.constant

1
2
3
4
5
6
7
def constant(
value,
dtype=none,
shape=none,
name="Const",
verify_shape=False
)

同值常量OPs

  • zeros:类似np中相应函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # `np.zeros`
    def tf.zeros(
    shape,
    dtype=tf.float32,
    name=None
    )

    # `np.zores_like`
    def tf.zeros_like(
    input_tensor,
    dtype=None,
    name=None,
    optimizeTrue
    )
    • 若没有指明dtype,根据input_tensor确定其中值
      • 对数值型为0.0
      • 对bool型为False
      • 对字符串为b''
  • ones:类似np中相应函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# `np.ones`
def tf.ones(
shape,
dtype=tf.float32,
name=None
)

# `np.ones_like`
def tf.ones_like(
input_tensor,
dtype=None,
name=None,
optimize=True
)
- 若没有指明`dtype`,根据`input_tensor`确定 - 对数值型为`0.0` - 对bool型为`True` - 对字符串报错
  • fill:以value填充dims给定形状

    1
    2
    3
    4
    5
    6
    # `np.fill`
    def tf.fill(
    dims,
    value,
    name=None
    )

列表常量OPs

  • tensor列表不能直接for语句等迭代
  • tf.lin_spacestartstop直接均分为num部分

    1
    2
    3
    4
    5
    6
    7
    # `np.linspace`
    def lin_space(
    start,
    stop,
    num,
    name=None
    )
  • tf.rangestartstop间等间隔delta取值

    1
    2
    3
    4
    5
    6
    7
    8
    # `np.arange`
    def tf.range(
    start,
    limit=None,
    delta=1,
    dtype=None,
    name="range"
    )

随机常量OPs

  • seed:设置随机数种子

    1
    2
    3
    # np.random.seed
    def tf.set_random_seed(seed):
    pass
  • random:随机生成函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    def tf.random_normal()
    def tf.truncated_normal(
    ?avg=0/int/(int),
    stddev=1.0/float,
    seed=None/int,
    name=None
    ):
    pass

    def tf.random_uniform(
    shape(1d-arr),
    minval=0,
    maxval=None,
    dtype=tf.float32,
    seed=None/int,
    name=None/str
    ):
    pass

    def tf.random_crop()

    def tf.multinomial()

    def tf.random_gamma()
  • shuffle

    1
    def tf.random_shuffle()

运算OPs

元素OPs

四则运算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

def add(x, y, name=None)
def subtract(x, y, name=None)
def sub(x, y, name=None)
def multiply(x, y, name=None)
def mul(x, y, name=None)
# 加、减、乘

def floordiv(x, y, name=None)
def floor_div(x, y, name=None)
def div(x, y, name=None)
def truncatediv(x, y, name=None)
# 地板除

def divide(x, y, name=None)
def truediv(x, y, name=None)
# 浮点除

def realdiv(x, y, name=None)
# 实数除法,只能用于实数?

def add_n(input, name=None)
# `input`:list-like,元素shapetype相同
# 累加`input`中元素的值

逻辑运算

1
2
3
def greater()
def less()
def equal()

数学函数

1
2
3
4
5
6
7
8
9
10
11
def exp()
def log()
def square()
def round()
def sqrt()
def rsqrt()
def pow()
def abs()
def negative()
def sign()
def reciprocal() # 倒数

列表运算OPs

1
2
3
4
5
6
def tf.Concat()
def tf.Slice()
def tf.Split()
def tf.Rank()
def tf.Shape()
def tf.Shuffle()

矩阵OPs

1
2
3
4
def tf.MatMul()
def tf.MatrixInverse()
def tf.MatrixDeterminant()
def tf.tensordot() # 矩阵点乘

梯度OPs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def tf.gradients(				# 求`y`对`[xs]`个元素偏导
ys: tf.OPs,
xs: tf.OPs/[tf.OPs],
grad_ys=None,
name=None
)
def tf.stop_gradient(
input,
name=None
)
def clip_by_value(
t,
clip_value_min,
clip_value_max,
name=None
)
def tf.clip_by_norm(
t,
clip_norm,
axes=None,
name=None
)

Variable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class Variable:
def __init__(self,
init_value=None,
trainable=True,
collections=None,
validata_shape=True,
caching_device=None,
name=None,
variable_def=None,
dtype=None,
expected_shape=None,
import_scope=None,
constraint=None
)

# 初始化变量
# `sess.run`其即初始化变量
def intializer(self):
pass

# 读取变量值
def value(self):
pass

# 获取变量初始化值,其他变量调用、声明依赖该变量
def initilized_value(self):
pass

# 计算、获取变量值,类似`sess.run(OP)`
def eval(self):
pass

# 给变量赋值
# `assgin`内部有初始化Variable,所以有时可以不用初始化
def assign(self):
pass
#`assgin_add`等依赖于原始值,不会初始化变量
def assign_add(self, ?dec)
def assign_divide(self, ?dec)
  • Variable是包含很多方法的类

    • 其中方法OPs和一般的OP一样,也需要在Session中执行 才能生效
    • Variable必须在会话中初始化后,才能使用
    • 会话维护自身独立Variable副本,不相互影响
  • Variable和图分开存储,甚至是存储在独立参数服务器上

    • 存储大量数据也不会拖慢图载入速度
    • 通常用于存储训练过程中weight、bias、维护图执行过程 中状态信息
  • constants是常数OPs

    • 存储在图中:每次载入图会同时被载入,过大的constants 会使得载入图非常慢
    • 所以最好只对原生类型使用constants

Variable创建

tf.get_variable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def get_variable(
name,
shape=None,
dtype=None,
initializer=None,
regularizer=None,
trainable=True,
collections=None,
caching_device=None,
partitioner=None,
validate_shape=True,
use_resource=None,
custom_getter=None,
constraint=None
)
  • 此封装工厂方法相较于直接通过tf.Variable更好
    • 若变量已设置,可通过变量名获取变量,方便变量共享
    • 可以提供更多的参数定制变量值
1
2
3
4
5
6
7
8
9
10
11
	# `tf.Variable`创建变量
s = tf.Variable(2, name="scalar")
m = tf.Variable([[0,1], [2,3]], name="matrix")
w = tf.Variable(tf.zeros([784, 10]))
# `tf.get_variable`创建、获取变量
s = tf.get_variable("scalar", initializer=tf.constant(2))
m = tf.get_variable("matrix", initializer=tf.constant([[0,1], [2,3]])
W = tf.get_variable("big_matrix",
shape=(784, 10),
initializer=tf.zeros_initializer()
)

Variable初始化

1
2
3
4
5
6
7
with tf.Session() as sess:
# 初始化所有Variables
sess.run(tf.global_variable_initialier())
# 初始化变量子集
sess.run(tf.variable_initializer([s, m])
# 初始化指定单个变量
sess.run(s.initializer)
  • 若某Variable依赖其他Variable,需要使用 initialized_value指明依赖,确保依赖线性初始化

    1
    2
    3
    W = tr.Variable(tf.truncated_normal([700, 100])
    # 指明依赖,保证依赖线性初始化
    U = tf.Variable(W.initialized_value() * 2)

TensorFlow 持久化

Session Checkpoint

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class tf.train.Saver:
def __init__(self,
var_list=None/list/dict,
reshape=False,
sharded=False,
max_to_keep=5,
keep_checkpoint_every_n_hours=10000.0,
name=None,
restore_sequentially=False,
saver_def=None,
builder=None,
defer_build=False,
allow_empty=False,
write_version=tf.train.SaverDef.V2,
pad_step_number=False,
save_relative_paths=False,
filename=None
):
self.last_checkpoints
  • 用途:保存Session中变量(张量值),将变量名映射至张量值

  • 参数

    • var_list:待保存、恢复变量,缺省所有
      • 变量需在tf.train.Saver实例化前创建
    • reshape:允许恢复并重新设定张量形状
    • sharded:碎片化保存至多个设备
    • max_to_keep:最多保存checkpoint数目
    • keep_checkpoint_every_n_hours:checkpoint有效时间
    • restore_sequentially:各设备中顺序恢复变量,可以 减少内存消耗
  • 成员

    • last_checkpoints:最近保存checkpoints

保存Session

1
2
3
4
5
6
7
8
9
10
def Saver.save(self,
sess,
save_path,
global_step=None/str,
latest_filename=None("checkpoint")/str,
meta_graph_suffix="meta",
write_meta_graph=True,
write_state=True
) -> str(path):
pass
  • 用途:保存Session,要求变量已初始化

  • 参数

    • global_step:添加至save_path以区别不同步骤
    • latest_filename:checkpoint文件名
    • meta_graph_suffix:MetaGraphDef文件名后缀

恢复Session

1
2
def Saver.restore(sess, save_path(str)):
pass
  • 用途:从save_path指明的路径中恢复模型
  • 模型路径可以通过Saver.last_checkpoints属性、 tf.train.get_checkpoint_state()函数获得

tf.train.get_checkpoint_state

1
2
3
4
5
def tf.train.get_checkpoint_state(
checkpoint_dir(str),
latest_filename=None
):
pass
  • 用途:获取指定checkpoint目录下checkpoint状态
    • 需要图结构已经建好、Session开启
    • 恢复模型得到的变量无需初始化
1
2
3
ckpt = tf.train.get_checkpoint_state(checkpoint_dir)
saver.restore(ckpt.model_checkpoint_path)
saver.restore(ckpt.all_model_checkpoint_paths[-1])

Graph Saver

tf.train.write_graph

1
2
3
4
5
6
def tf.train.write_graph(
graph_or_graph_def: tf.Graph,
logdir: str,
name: str,
as_text=True
)
  • 用途:存储图至文件中

  • 参数

    • as_text:以ASCII方式写入文件

Summary Saver

tf.summary.FileWriter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class tf.summary.FileWriter:
def __init__(self,
?path=str,
graph=tf.Graph
)

# 添加summary记录
def add_summary(self,
summary: OP,
global_step
):
pass

# 关闭`log`记录
def close(self):
pass
  • 用途:创建FileWriter对象用于记录log

    • 存储图到文件夹中,文件名由TF自行生成
    • 可通过TensorBoard组件查看生成的event log文件
  • 说明

    • 一般在图定义完成后、Session执行前创建FileWriter 对象,Session结束后关闭

实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 # 创建自定义summary
with tf.name_scope("summaries"):
tf.summary.scalar("loss", self.loss)
tf.summary.scalar("accuracy", self.accuracy)
tf.summary.histogram("histogram loss", self.loss)
summary_op = tf.summary.merge_all()

saver = tf.train.Saver()

with tf.Session() as sess:
sess.run(tf.global_variables_initializer())

# 从checkpoint中恢复Session
ckpt = tf.train.get_check_state(os.path.dirname("checkpoint_dir"))
if ckpt and ckpt.model_check_path:
saver.restore(sess, ckpt.mode_checkpoint_path)

# summary存储图
writer = tf.summary.FileWriter("./graphs", sess.graph)
for index in range(10000):
loas_batch, _, summary = session.run([loss, optimizer, summary_op])
writer.add_summary(summary, global_step=index)

if (index + 1) % 1000 = 0:
saver.save(sess, "checkpoint_dir", index)

# 关闭`FileWriter`,生成event log文件
write.close()

TensorFlow训练

Optimizer

1
2
3
4
5
6
7
8
9
10
11
class tf.train.GradientDescentOptimizer:

class tf.train.AdagradOptimizer:

class tf.train.MomentumOptimizer:

class tf.train.AdamOptimizer:

class tf.train.FtrlOptimizer:

class tf.train.RMSPropOptmizer:

TensorFlow执行

Session

Session:TF中OPs对象执行、Tensor对象计算的封装环境

  • Session管理图、OPs

    • 所有图必须Session中执行
    • 将图中OPs、其执行方法分发到CPU、GPU、TPU等设备上
    • 为当前变量值分配内存
  • Session只执行Data/Tensor Flow中OPs,忽略不相关节点

    • 即通往fetches的flow中的OPs构成子图才会被计算
  • 各Session中各值独立维护,不会相互影响

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Session:
def __init__(self,
target=str,
graph=None/tf.Graph,
config=None/tf.ConfigProto)

# 获取Session中载入图
self.graph

# 关闭会话,释放资源
def close(self):
pass

# 支持上下文语法
def __enter__(self):
pass
def __exit__(self):
pass

# 执行TensorFlow中节点,获取`fetches`中节点值
# 返回值若为Tensor
# python中:以`np.ndarray`返回
# C++/C中:以`tensorflow:Tensor`返回
# 可直接调用`.eval()`获得单个OP值
def run(self,
fetches=tf.OPs/[tf.OPs],
feed_dict=None/dict,
options=None,
run_metadata=None)

tf.InteractiveSession

tf.InteractiveSession:开启交互式会话

1
2
3
4
5
6
7
8
9
10
11
 # 开启交互式Session
sess = tf.InteractiveSession()
a = tf.constant(5.0)
b = tf.constant(6.0)
c = a * b
x = tf.Variable([1.0, 2.0])
# 无需显式在`sess.run`中执行
# 直接调用`OPs.eval/run()`方法得到结果
x.initializer.run()
print(c.eval())
sess.close()

Session执行

  • Fetch机制:sess.run()执行图时,传入需取回的结果, 取回操作输出内容

  • Feed机制:通过feed_dict参数,使用自定义tensor值替代图 中任意feeable OPs的输出

    • tf.placeholder()表示创建占位符,执行Graph时必须 使用tensor替代
    • feed_dict只是函数参数,只在调用它的方法内有效, 方法执行完毕则消失
  • 可以通过feed_dict feed所有feedable tensor,placeholder 只是指明必须给某些提供值

    1
    2
    3
    4
    a = tf.add(2, 5)
    b = tf.multiply(a, 3)
    with tf.Session() as sess:
    sess.run(b, feed_dict={a: 15}) # 45

config参数选项

  • log_device_placement:打印每个操作所用设备
  • allow_soft_placement:允许不在GPU上执行操作自动迁移到 CPU上执行
  • gpu_options
    • allow_growth:按需分配显存
    • per_process_gpu_memory_fraction:指定每个GPU进程 使用显存比例(无法对单个GPU分别设置)
  • 具体配置参见tf.ConfigProto

Graph

Graph:表示TF中计算任务,

  • operation/node:Graph中节点,包括:operatorvariableconstant

    • 获取一个、多个Tensor执行计算、产生、返回tensor
    • 不能无法对其值直接进行访问、比较、操作
    • 图中节点可以命名,TF会自动给未命名节点命名
  • tensor:Graph中边,n维数组

    • TF中所有对象都是Operators
    • tensor是OPs执行结果,在图中传递/流动
  • 图计算模型优势

    • 优化能力强、节省计算资源
      • 缓冲自动重用
      • 常量折叠,只计算取得目标值过程中必须计算的值
      • 方便并行化
      • 自动权衡计算、存储效率
    • 易于部署
      • 可被割成子图(即极大连通分量),便于自动区分
      • 子图可以分发到不同的设备上分布式执行,即模型并行
      • 许多通用ML模型是通过有向图教学、可视化的
  • 图计算模型劣势

    • 难以debug
      • 图定义之后执行才会报错
      • 无法通过pdb、打印状态debug
    • 语法繁复

构建图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Graph:
def __init__(self):
pass

# 将当前图作为默认图
# 支持上下文语法
def as_default(self):
pass

# 强制OPs依赖关系(图中未反映),即优先执行指定OPs
# 支持上下文语法
def as_default(self):
def control_dependencies(self,
?ops=[tf.OPs])
pass

# 以ProtoBuf格式展示Graph
def as_graph_def(self):
pass

# 判断图中节点是否可以被feed
def is_feedable(self,
?op=tf.OPs):
pass
  • 可以通过tf.Graph创建新图,但最好在是在一张图中使用多个 不相连的子图,而不是多张图

    • 充分性:Session执行图时忽略不必要的OPs
    • 必要性
      • 多张图需要多个会话,每张图执行时默认尝试使用所有 可能资源
      • 不能通过python/numpy在图间传递数据(分布式系统)
  • 初始化即包含默认图,OP构造器默认为其增加节点

    • 通过tf.get_default_graph()获取

图相关方法

  • 获取TF初始化的默认图

    1
    2
    def tf.get_default_graph():
    pass

命名空间

1
2
3
4
5
6
7
8
 # 均支持、利用上下文语法,将OPs定义于其下
def tf.name_scope(name(str)):
pass
def tf.variable_scope(
name(str),
reuse=tf.AUTO_REUSE
):
pass
  • tf.name_scope:将变量分组
    • 只是将变量打包,不影响变量的重用、可见性等
    • 方便管理、查看graph
  • tf.variable_scope
    • 对变量有控制能力
      • 可设置变量重用性
      • 变量可见性局限于该variable scope内,即不同 variable scope间可以有完全同名变量 (未被TF添加顺序后缀)
    • 会隐式创建name scope
    • 大部分情况是用于实现变量共享
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def fully_connected(x, output_dim, scope):
# 设置variable scope中变量自动重用
# 或者调用`scope.reuse_variables()`声明变量可重用
with tf.variable_scope(scope, reuse=tf.AUTO_REUSE) as scope:
# 在当前variable scope中获取、创建变量
w = tf.get_variable("weights", [x.shape[1]], output_dim,
initializer=tf.random_normal_initializer())
b = tf.get_variable("biases", [output_dim],
initializer=tf.constant_initizer(0.0))
return tf.matmul(x, w) + b

def two_hidden_layers(x):
h1 = fully_connected(x, 50, "h1")
h2 =-fully_connected(h1, 10, "h2")

with tf.variable_scope("two_layers") as scope:
logits1 = two_hidden_layers(x1)
logits2 = two_hidden_layers(x2)

Lazy Loading

Lazy Loading:推迟声明/初始化OP对象至载入图时 (不是指TF的延迟计算,是个人代码结构问题,虽然是TF延迟图计算 模型的结果)

  • 延迟加载容易导致向图中添加大量重复节点,影响图的载入、 传递

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    x = tf.Variable(10, name='x')
    y = tf.Variable(20, name='y')

    with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    writer = tf.summary.FileWriter('graphs/lazy_loading', sess.graph)
    for _ in range(10):
    # 延迟加载节点,每次执行都会添加`tf.add`OP
    sess.run(tf.add(x, y))
    print(tf.get_default_graph().as_graph_def())
    writer.close()
  • 解决方案

    • 总是把(图的搭建)OPs的定义、执行分开
    • python利用@property装饰器,使用单例模式函数 封装变量控制,保证仅首次调用函数时才创建OP

Eager Execution

1
2
3
4
import tensorflow as tf
import tensorflow.contrib.eager as tfe
# 启用TF eager execution
tfe.enable_eager_execution()
  • 优势

    • 支持python debug工具
    • 提供实时报错
    • 支持python数据结构
    • 支持pythonic的控制流

      1
      2
      3
      i = tf.constant(0)
      whlile i < 1000:
      i = tf.add(i, 1)
  • eager execution开启后

    • tensors行为类似np.ndarray
    • 大部分API和未开启同样工作,倾向于使用
      • tfe.Variable
      • tf.contrib.summary
      • tfe.Iterator
      • tfe.py_func
      • 面向对象的layers
      • 需要自行管理变量存储
  • eager execution和graph大部分兼容

    • checkpoint兼容
    • 代码可以同时用于python过程、构建图
    • 可使用@tfe.function将计算编译为图

示例

  • placeholder、sessions

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 普通TF
    x = tf.placholder(tf.float32, shape=[1, 1])
    m = tf.matmul(x, x)
    with tf.Session() as sess:
    m_out = sess.run(m, feed_dict={x: [[2.]]})

    # Eager Execution
    x = [[2.]]
    m = tf.matmul(x, x)
  • Lazy loading

    1
    2
    3
    4
    5
    x = tf.random_uniform([2, 2])
    for i in range(x.shape[0]):
    for j in range(x.shape[1]):
    # 不会添加多个节点
    print(x[i, j])

Device

设备标识

  • 设备标识:设备使用字符串进行标识

    • /cpu:0:所有CPU都以此作为名称
    • /gpu:0:第一个GPU,如果有
    • /gpu:1:第二个GPU
    1
    2
    3
    4
    5
    6
    # 为计算指定硬件资源
    with tf.device("/gpu:2"):
    a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0], name="a")
    b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0], name="b")
    c = tf.multiply(a, b)
    # creates a graph
  • 环境变量:python中既可以修改os.environ,也可以直接设置 中设置环境变量

    • CUDA_VISIBLE_DEVICES:可被使用的GPU id

设备执行

设备执行:TF将图形定义转换成分布式执行的操作以充分利用计算 资源

  • TF默认自动检测硬件配置,尽可能使用找到首个GPU执行操作

  • TF会默认占用所有GPU及每个GPU的所有显存(可配置)

    • 但只有一个GPU参与计算,其他GPU默认不参与计算(显存 仍然被占用),需要明确将OPs指派给其执行
    • 指派GPU数量需通过设置环境变量实现
    • 控制显存占用需设置Session config参数
  • 注意:有些操作不能再GPU上完成,手动指派计算设备需要注意

tf.ConfigProto

  • Session参数配置

    1
    2
    3
    4
    5
     # `tf.ConfigProto`配置方法
    conf = tf.ConfigProto(log_device_placement=True)
    conf.gpu_options.allow_growth=True
    sess = tf.Session(config=conf)
    sess.close()

TensorFlow Readme

常用参数说明

  • 函数书写声明同Python全局

  • 以下常用参数如不特殊注明,按照此解释

Session

  • target = ""/str

    • 含义:执行引擎
  • graph = None/tf.Graph

    • 含义:Session中加载的图
    • 默认:缺省为当前默认图
  • config = None/tf.ConfigProto

    • 含义:包含Session配置的Protocal Buffer
    • 默认:None,默认配置
  • fetches = tf.OPs/[tf.OPs]

    • 含义:需要获得/计算的OPs值列表
    • 默认:无
  • feed_dict = None/dict

    • 含义:替换/赋值Graph中feedable OPs的tensor字典
    • 默认:无
    • 说明
      • 键为图中节点名称、值为向其赋的值
      • 可向所有可赋值OPs传递值
      • 常配合tf.placeholder(强制要求)

Operators

  • name = None/str

    • 含义:Operations名
    • 默认:None/OP类型,后加上顺序后缀
    • 说明
      • 重名时TF自动加上_[num]后缀
  • axis = None/0/int

    • 含义:指定张量轴
    • 默认
      • None:大部分,表示在整个张量上运算
      • 0:有些运算难以推广到整个张量,表示在首轴(维)
  • keepdims=False/True

    • 含义:是否保持维度数目
    • 默认:False不保持
  • dtype=tf.int32/tf.float32/...

    • 含义:数据类型
    • 默认:根据其他参数、函数名推断
  • shape/dims=(int)/[int]

    • 含义:各轴维数
    • 默认:None/1???
    • 说明
      • -1表示该轴维数由TF计算得到
      • 有些情况下,此参数可省略,由TF隐式计算得到, 但显式指明方便debug
  • start=int

    • 含义:起始位置
    • 默认:0
  • stop=int

    • 含义:终点位置
    • 默认:一般无

TensorFlow基本概念

  • TensorFlow将计算的定义、执行分开

流程

组合计算图

  • 为输入、标签创建placeholder
  • 创建weigth、bias
  • 指定模型
  • 指定损失函数
  • 创建Opitmizer

在会话中执行图中操作

  • 初始化Variable
  • 运行优化器
  • 使用FileWriter记录log
  • 查看TensorBoard

PyTF 模块

tf.nn

tf.nn:神经网络功能支持模块

  • rnn_cell:构建循环神经网络子模块

tf.contrib

tf.contrib:包含易于变动、实验性质的功能

  • bayesflow:包含贝叶斯计算
  • cloud:云操作
  • cluster_resolver:集群求解
  • compiler:控制TF/XLA JIT编译器
  • copy_graph:在不同计算图之间复制元素
  • crf:条件随机场
  • cudnn_rnn:Cudnn层面循环神经网络
  • data:构造输入数据流水线
  • decision_trees:决策树相关模块
  • deprecated:已经、将被替换的summary函数
  • distributions:统计分布相关操作
  • estimator:自定义标签、预测的对错度量方式
  • factorization:聚类、因子分解
  • ffmpeg:使用FFmpeg处理声音文件
  • framework:框架类工具,包含变量操作、命令空间、 checkpoint操作
  • gan:对抗生成相关
  • graph_editor:计算图操作
  • grid_rnn:GridRNN相关
  • image:图像操作
  • input_pipeline:输入流水线
  • integrate:求解常微分方程
  • keras:Keras相关API
  • kernel_methods:核映射相关方法
  • kfac:KFAC优化器
  • labeled_tensor:有标签的Tensor
  • layers:类似nn里面的函数,经典CNN方法重构
  • learn:类似ski-learn的高级API
  • legacy_seq2seq:经典seq2seq模型
  • linalg:线性代数
  • linear_optimizer:训练线性模型、线性优化器
  • lookup:构建快速查找表
  • losses:loss相关
  • memory_stats:设备内存使用情况
  • meta_graph_transform:计算图转换
  • metrics:各种度量模型表现的方法
  • nccl:收集结果的操作
  • ndlstm:ndlstm相关
  • nntf.nn某些方法的其他版本
  • opt:某些优化器的其他版本
  • predictor:构建预测器
  • reduce_slice_ops:切片规约
  • remote_fused_graph
  • resampler:重抽样
  • rnn:某些循环神经网络其他版本
  • saved_model:更加易用的模型保存、继续训练、模型转换
  • seq2seq:seq2seq相关模型
  • session_bundle
  • signal:信号处理相关
  • slim:contrib主模块交互方式、主要入口
  • solvers:贝叶斯计算
  • sparsemax:稀疏概率激活函数、相关loss
  • specs
  • staging:分段输入
  • stat_summarizer:查看运行状态
  • statless:伪随机数
  • tensor_forest:可视化工具
  • testing:单元测试工具
  • tfprof:查看模型细节工具
  • timeseries:时间序列工具
  • tpu:TPU配置
  • training:训练及输入相关工具
  • util:Tensors处理相关工具

tf.train

tf.train:训练模型支持

  • 优化器

    • AdadeltaOptimizer:Adadelta优化器
    • AdamOptimizer:Adam优化器
    • GradientDescentOptimizer:SGD优化器
    • MomentumOptimizer:动量优化器
    • RMSPropOptimizer:RMSProp优化器
  • 数据处理

    • Coordinator:线程管理器
    • QueueRunner:管理读写队列线程
    • NanTensorHook:loss是否为NaN的捕获器
    • create_global_step:创建global step
    • match_filenames_once:寻找符合规则文件名称
    • start_queue_runners:启动计算图中所有队列
  • tfrecord数据

    • Example:tfrecord生成模板
    • batch:生成tensor batch
    • shuffle_batch:创建随机tensor batch
  • 模型保存、读取

    • Saver:保存模型、变量类
    • NewCheckpointReader:checkpoint文件读取
    • get_checkpoint_state:从checkpoint文件返回模型状态
    • init_from_checkpoint:从checkpoint文件初始化变量
    • latest_checkpoint:寻找最后checkpoint文件
    • list_variable:返回checkpoint文件变量为列表
    • load_variable:返回checkpoint文件某个变量值

tf.summary

tf.summary:配合tensorboard展示模型信息

  • FileWriter:文件生成类
  • Summary
  • get_summary_description:获取计算节点信息
  • histogram:展示变量分布信息
  • image:展示图片信息
  • merge:合并某个summary信息
  • merge_all:合并所有summary信息至默认计算图
  • scalar:展示标量值
  • text:展示文本信息

TensorFlow 安装配置

安装

CUDA、CUDNN、CUDAtookit、NVCC

  • CUDA:compute unified device architecture,通用并行计算 平台和编程模型,方便使用GPU进行通用计算
  • cuDNN:深度学习加速库,计算设计的库、中间件
    • C++STL的thrust的实现
    • cublas:GPU版本blas
    • cuSparse:稀疏矩阵运算
    • cuFFT:快速傅里叶变换
    • cuDNN:深度学习网络加速
  • CUDA Toolkit:包括以下组件
    • 编译器nvcc:CUDA-C、CUDA-C++编译器,依赖nvvm 优化器 (nvvm本身依赖llvm编译器)
    • ·debuggersprofiler等工具
    • 科学库、实用程序库
      • cudart
      • cudadevrt
      • cupti
      • nvml
      • nvrtc
      • cublas
      • cublas_device
    • 示例
    • 驱动:

TensorBoard

TensorBoard是包括在TensorFlow中可视化组件

  • 运行启动了TB的TF项目时,操作都会输出为事件日志文件
  • TB能够把这些日志文件以可视化的方式展示出来
    • 模型图
    • 运行时行为、状态
1
$ tensorboard --logdir=/path/to/logdir --port XXXX

问题

指令集

Your CPU supports instructions that this TensorFlow binary was not cmpiled to use: SSE1.4, SSE4.2, AVX AVX2 FMA

  • 没从源代码安装以获取这些指令集的支持
    • 从源代码编译安装
    • 或者设置log级别
      1
      2
      3
      import os
      os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"
      import tensorflow as tf