refer:https://www.tensorflow.org/programmers_guide/?hl=zh-cn

组成

Graph(Variable, Constant, placeholder), Session

高级别 API

1.Estimators
高级API
2.导入数据
tf.data.Dataset

# 1. 数据来源
# 1.1 from numpy
features, labels = (np.random.sample((100,2)), np.random.sample((100,1)))
dataset = tf.data.Dataset.from_tensor_slices((features,labels))
# 1.2 from tensor
dataset = tf.data.Dataset.from_tensor_slices(tf.random_uniform([100, 2]))
# 1.3 from placeholder
x = tf.placeholder(tf.float32, shape=[None,2])
dataset = tf.data.Dataset.from_tensor_slices(x)
# 1.4 from generator
sequence = np.array([[1],[2,3],[3,4]])
def generator():
    for el in sequence:
        yield el
dataset = tf.data.Dataset().from_generator(generator,
                                           output_types=tf.float32, 
                                           output_shapes=[tf.float32])

# 2. build iterator
# 2.1 one-shot
# 创建iterator
train_it = train_dataset.make_one_shot_iterator()
# 一次获取一个clip
train_videos_clips_tensor = train_it.get_next()

# 2.2 initializablere
# 2.3 initializable
# 2.4 feedable

# 3. 使用数据

低级别 API

显式创建自己的图和会话

步骤
1.定义图
2.填数据
3.session下运行图(更新参数,返回计算结果)

0. Tensor Definition
tf.Tensor
tensor包括tf.Variable,tf.constant,tf.placeholder,tf.SparseTensor
只有Variable可变

rankmath entitypython example
0scalar(magnitude only)12
1vector(magnitude and direction)[1,2,3]
2matrix(table of number)[[1,2],[2,3]]
33-tensor(cube of numbers)[[[1],[2]],[[3],[4]]]
nn-tensor

1. Variable
tf.Variable
存储持久变量w,b 于磁盘,便于下次调用(模型保存)
多个session可以共用
1.两种创建变量方式
Variable和get_variable
Variable每次都会新建(自动处理冲突(重命名),get_variable对未存在变量会新建,已存在则报错;

    import tensorflow as tf
    w_1 = tf.Variable(3,name="w_1", dtype = tf.int32)
    w_2 = tf.Variable(1,name="w_1")
    print w_1.name
    print w_2.name
    #输出,自动为冲突重命名
    #w_1:0
    #w_1_1:0


    w_1 = tf.get_variable(name="w_1", shape=(), initializer=tf.zeros_initializer())
    w_2 = tf.get_variable(name="w_1",shape=(),initializer=tf.zeros_initializer())
    #错误信息
    #ValueError: Variable w_1 already exists, disallowed. Did
    #you mean to set reuse=True in VarScope?

2.variable_scope和name_scope
name_scope:
用于定义命名空间,对变量和操作进行封装;
variable_scope:
除了新建新的变量,还可以通过设置reuse=True并使用tf.get_variable()实现变量共享
想要用共享变量,前面就一定要写上variable_scope,之后才能调用

    with tf.variable_scope('generator', reuse=None):
        ...

    with tf.variable_scope('generator', reuse=True):
        ...

3.定义变量Variable后,使用前一定要在session里先初始化
tf.contrib.slim、tf.estimator.Estimator 和 Keras 等大多数高级框架在训练模型前会自动初始化变量
添加操作进行初始化,再在session里先运行该操作进行变量初始化

    import tensorflow as tf

    # 此时只是定义了如何初始化,而并没有真正初始化
    state = tf.Variable(0, name='counter')

    # 定义常量 one
    one = tf.constant(1)

    # 定义加法步骤 (注: 此步并没有直接计算)
    new_value = tf.add(state, one)

    # 将 State 更新成 new_value
    update = tf.assign(state, new_value)

    # 1. 如果定义 Variable, 就一定要 initialize
    # init = tf.initialize_all_variables() # tf 马上就要废弃这种写法
    init = tf.global_variables_initializer()  # 替换成这样就好

    # 2  在Session里初始化
    with tf.Session() as sess:
        sess.run(init)
        for _ in range(3):
            sess.run(update)
            print(sess.run(state))

4.设定是否需要计算梯度
默认情况下,每个 tf.Variable 都放置在以下两个集合中:
tf.GraphKeys.GLOBAL_VARIABLES - 可以在多个设备共享的变量
==tf.GraphKeys.TRAINABLE_VARIABLES== - TensorFlow 将计算其梯度的变量(一般是这个)
不计算变量梯度的方法:
1.放在tf.GraphKeys.LOCAL_VARIABLES
2.定义时设置

my_non_trainable = tf.get_variable("my_non_trainable",
                                   shape=(),
                                   trainable=False)

5.实际使用中,通过tf.contrib.layers 构造网络层,该高级操作接口已经封装了内部的变量Variable的创建和管理
2. placeholder
用作输入的占位符
Tensorflow 如果想要从外部传入data, 那就需要用到 tf.placeholder(), 然后以这种形式传输数据sess.run(***, feed_dict={input: **}).

import tensorflow as tf

#在 Tensorflow 中需要定义 placeholder 的 type ,一般为 float32 形式
input1 = tf.placeholder(tf.float32)
input2 = tf.placeholder(tf.float32)

# mul = multiply 是将input1和input2 做乘法运算,并输出为 output 
ouput = tf.multiply(input1, input2)

with tf.Session() as sess:
    print(sess.run(ouput, feed_dict={input1: [7.], input2: [2.]}))
# [ 14.]

3. 构建graph
构造graph(包含变量和操作op)
可以用tf.device制定操作运行的设备

# Operations created outside either context will run on the "best possible"
# device. For example, if you have a GPU and a CPU available, and the operation
# has a GPU implementation, TensorFlow will choose the GPU.
weights = tf.random_normal(...)

with tf.device("/device:CPU:0"):
  # Operations created in this context will be pinned to the CPU.
  img = tf.decode_jpeg(tf.read_file("img.jpg"))

with tf.device("/device:GPU:0"):
  # Operations created in this context will be pinned to the GPU.
  result = tf.matmul(weights, img)

4.Session.run
session拥有物理资源(例如 GPU 和网络连接),它通常用作上下文管理器(在 with 代码块中),该管理器可在您退出代码块时自动关闭会话

# Create a default in-process session.
with tf.Session() as sess:
    # 可一次计算多个操作
  y_val, output_val = sess.run([y, output])


# Create a remote session.
with tf.Session("grpc://example.org:2222"):
  # ...
  1. v = session.run(in)
    v和in同维度

  2. v = session.run(in,feed_dict=xx)
    用了placeholder的才需要feed_dict

  3. with语句
    Session 对象在使用完后需要关闭以释放资源. 除了显式调用 close 外, 也可以使用 “with” 代码块 来自动完成关闭动作;

扩展

1. tensorboard可视化

tf.summary.xxx定义需要保存的信息
Run:
$ tensorboard –logdir=./summary –port=10086

# add all to summaries
tf.summary.scalar(tensor=train_psnr_error, name='train_psnr_error')
tf.summary.scalar(tensor=test_psnr_error, name='test_psnr_error')
tf.summary.scalar(tensor=g_loss, name='g_loss')
tf.summary.scalar(tensor=adv_loss, name='adv_loss')
tf.summary.scalar(tensor=dis_loss, name='dis_loss')
tf.summary.image(tensor=train_outputs, name='train_outputs')
tf.summary.image(tensor=train_gt, name='train_gt')
tf.summary.image(tensor=test_outputs, name='test_outputs')
tf.summary.image(tensor=test_gt, name='test_gt')
summary_op = tf.summary.merge_all()

with tf.Session(config=config) as sess:
    # summaries
    summary_writer = tf.summary.FileWriter(summary_dir, graph=sess.graph)
    sess.run([..., summary_op])
    summary_writer.add_summary(_summaries, global_step=_step)

可以使用 tensorboard –help 查看tensorboard的详细参数

2. 保存和重载模型

主要用于TensorFlow Serving
TF Serving是一个将训练好的模型部署至生产环境的系统。
可以用同一份inference的代码(或者被封装成API)复用不同模型;
2.1 SavedModel方式
tensorflow推荐使用
SavedModel
是一种与语言无关,可恢复的密封式序列化格式

builder = tf.saved_model.builder.SavedModelBuilder(export_dir)
1.save

import tensorflow as tf

export_dir = 'savedModel_dir'

x1 = tf.placeholder(tf.float32, [3,])
x2 = tf.placeholder(tf.float32, [3,])

# Variable 在声明是必须要给定一个 初始值的
v = tf.Variable([1,1,1],dtype=tf.float32)
output = x1+x2+v

# build_tensor_info将信息序列化为 TensorInfo protocol buffer
# 为输入输出约定别名:input_x 和 output
# x 为输入tensor, keep_prob为dropout的prob tensor 
inputs = {'input_x1': tf.saved_model.utils.build_tensor_info(x1), 
            'input_x2': tf.saved_model.utils.build_tensor_info(x2)}

# y 为最终需要的输出结果tensor 
outputs = {'output' : tf.saved_model.utils.build_tensor_info(output)}

# 第三个参数method_name暂时先随便给一个
signature = tf.saved_model.signature_def_utils.build_signature_def(inputs, outputs, 'test_sig_name')

# export_dir 模型保存路径
builder = tf.saved_model.builder.SavedModelBuilder(export_dir)

# 初始化模型的参数
init = tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init)   # 执行初始化,此时变量被填值
    # 导入图和变量
    # 第一个参数就是当前的session
    # 第二个参数是在保存的时候定义的meta graph的标签,导入时需要匹配标签
    # signature_def_map 一个dict,value是是输入输出tensor信息的
    print("result={}".format(sess.run(output, feed_dict={x1:[1,2,3],x2:[3,2,1]})))
    builder.add_meta_graph_and_variables(sess,
                                       ["tag-orli"],
                                       signature_def_map={'signature-orli':signature})
# 将模型序列化到指定目录
# 保存好以后到saved_model_dir目录下,会有一个saved_model.pb文件以及variables文件夹。
# # 顾名思义,variables保存所有变量,saved_model.pb用于保存模型结构等信息
builder.save()

2.1.1 load

import tensorflow as tf

export_dir = 'savedModel_dir'

signature_key = 'signature-orli'
input_key1 = 'input_x1'
input_key2 = 'input_x2'
output_key = 'output'
a = [3,2,1]

with tf.Session() as sess:
  meta_graph_def = tf.saved_model.loader.load(sess, ["tag-orli"], export_dir)

  # 从meta_graph_def中取出SignatureDef对象
  signature = meta_graph_def.signature_def

  # 从signature中找出具体输入输出的tensor name 
  x1_tensor_name = signature[signature_key].inputs[input_key1].name
  x2_tensor_name = signature[signature_key].inputs[input_key2].name
  y_tensor_name = signature[signature_key].outputs[output_key].name

  # 通过获取tensor 并inference
  # 使得输入输出的tensor名称被隐藏,实现复用
  x1 = sess.graph.get_tensor_by_name(x1_tensor_name)
  x2 = sess.graph.get_tensor_by_name(x2_tensor_name)
  y = sess.graph.get_tensor_by_name(y_tensor_name)

  print("result={}".format(sess.run(y, feed_dict={x1:[2,3,4], x2:[4,3,2]})))

2.2 MetaGraph方式
==不推荐使用==
两种方案:
1. 用 tf.train.Saver() 来保存变量,重新定义图并用saver.restore()载入变量
2. 用 tf.train.Saver() 来保存/载入变量,再使用tf.train.import_meta_graph导入graph信息。
此法不需要重定义图,但只能通过graph.get_tensor_by_name()来获取定义的tensor。这样就需要再维护一个配置文件保存图定义时的tensor名称。
1.保存
saver.save(sess, FLAGS.train_dir, global_step=step)

# Create some variables.
v1 = tf.Variable(..., name="v1")
v2 = tf.Variable(..., name="v2")
...
# Add an op to initialize the variables.
init_op = tf.global_variables_initializer()

# Add ops to save and restore all the variables.
saver = tf.train.Saver()

使用这种方法保存模型,模型的图结构和变量会分开存储;
会产生三种binary文件:
.meta:存储metagraph 图结构
.data-00000-of-00001:保存图中variable的值
.index:用来indetify checkpoint

model.ckpt.data-00000-of-00001
model.ckpt.index
model.ckpt.meta

2.2.1复原
saver.restore(sess, FLAGS.train_dir)
==Even though there is no file named model.ckpt,== you still refer to the saved checkpoint by that name when restoring it;
重载模型:
1.图结构和变量都需要加载

```
with tf.Session() as sess:
    saver = tf.train.import_meta_graph('/tmp/model.ckpt.meta')
    saver.restore(sess, "/tmp/model.ckpt")
```
或者

2.重新定义相同的图,只加载变量

    # Recreate the EXACT SAME variables
    v1 = tf.Variable(..., name="v1")
    v2 = tf.Variable(..., name="v2")
    ...

    # Now load the checkpoint variable values
    with tf.Session() as sess:
        saver = tf.train.Saver()
        saver.restore(sess, "/tmp/model.ckpt")
3. GPU占用
# 1. 会默认占用所有GPU显存
with tf.Session() as sess:
# 2. 按比例分配,占用每块的60%
config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction=0.6
with tf.Session(config=config) as sess:
# 3. 设置GPU的显存占用按需增长, default it will use full GPU
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
sess = tf.Session(config=config)

1适合自己机器,多人服务器使用2,3.2存在GPU浪费风险,3则可能因为申请不到GPU内存而崩溃

4. 指定使用的GPU
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐