疑问汇总2

tf.get_variable()函数

tf.get_variable(
    name,
    shape=None,
    dtype=None,
    initializer=None,
    regularizer=None,
    trainable=None,
    collections=None,
    caching_device=None,
    partitioner=None,
    validate_shape=True,
    use_resource=None,
    custom_getter=None,
    constraint=None,
    synchronization=tf.VariableSynchronization.AUTO,
    aggregation=tf.VariableAggregation.NONE
)

参数:

name:新变量或现有变量的名称。
shape:新变量或现有变量的形状。
dtype:新变量或现有变量的类型(默认为DT_FLOAT)。
initializer:如果创建了变量的初始化器。可以是初始化器对象,也可以是张量。如果它是一个张量,它的形状必须是已知的,除非validate_shape是假的。
regularizer:A(张量->张量或无)函数;将其应用于新创建的变量的结果将添加到集合tf.GraphKeys中。正则化-损耗,可用于正则化。
trainable:如果为真,也将变量添加到图形集合GraphKeys中。TRAINABLE_VARIABLES(见tf.Variable)。
collections:要向其中添加变量的图形集合键的列表。默认为GraphKeys.GLOBAL_VARIABLES(见tf.Variable)。
caching_device:可选的设备字符串或函数,描述变量应该缓存到什么地方以便读取。变量的设备的默认值。如果没有,则缓存到另一个设备上。典型的用途是在使用该变量的操作系统所在的设备上缓存,通过Switch和其他条件语句来重复复制。
partitioner:可选的callable,它接受要创建的变量的完全定义的TensorShape和dtype,并返回每个轴的分区列表(目前只能分区一个轴)。
validate_shape:如果为False,则允许用一个未知形状的值初始化变量。如果为真,默认情况下,initial_value的形状必须是已知的。要使用它,初始化器必须是一个张量,而不是初始化器对象。
use_resource:如果为False,则创建一个常规变量。如果为真,则创建一个具有定义良好语义的实验性资源变量。默认值为False(稍后将更改为True)。当启用紧急执行时,该参数总是强制为真。
custom_getter: Callable,它将true getter作为第一个参数,并允许覆盖内部get_variable方法。custom_getter的签名应该与这个方法的签名相匹配,但是未来最可靠的版本将允许更改:def custom_getter(getter、*args、**kwargs)。还允许直接访问所有get_variable参数:def custom_getter(getter、name、*args、**kwargs)。一个简单的身份自定义getter,简单地创建变量与修改的名称是:
constraint:优化器更新后应用于变量的可选投影函数(例如,用于为层权重实现规范约束或值约束)。函数必须将表示变量值的未投影张量作为输入,并返回投影值的张量(其形状必须相同)。在进行异步分布式培训时使用约束并不安全。
synchronization:指示何时聚合分布式变量。可接受的值是在tf.VariableSynchronization类中定义的常量。默认情况下,同步设置为AUTO,当前分发策略选择何时同步。如果同步设置为ON_READ,则不能将trainable设置为True。
aggregation:指示如何聚合分布式变量。可接受的值是在tf.VariableAggregation类中定义的常量。
返回值:

创建的或现有的变量(或PartitionedVariable,如果使用了分区器)。
可能产生的异常:

ValueError: when creating a new variable and shape is not declared, when violating reuse during variable creation, or when initializer dtype and dtype don’t match. Reuse is set inside variable_scope.

tensorflow之tf.train.exponential_decay()指数衰减法

exponential_decay(learning_rate, global_steps, decay_steps, decay_rate, staircase=False, name=None)
使用方式:
tf.tf.train.exponential_decay()
例子:
tf.train.exponential_decay(self.config.e_lr, self.e_global_steps,self.config.decay_steps, self.config.decay_rate, staircase=True)
在 Tensorflow 中,exponential_decay()是应用于学习率的指数衰减函数(实现指数衰减学习率)。
在训练模型时,通常建议随着训练的进行逐步降低学习率。该函数需要global_step值来计算衰减的学习速率。
该函数返回衰减后的学习率。该函数的计算方程式如下
在这里插入图片描述
参数:
learning_rate - 初始学习率
global_step - 用于衰减计算的全局步骤。 一定不为负数。喂入一次 BACTH_SIZE 计为一次 global_step
decay_steps - 衰减速度,一定不能为负数,每间隔decay_steps次更新一次learning_rate值
decay_rate - 衰减系数,衰减速率,其具体意义参看函数计算方程(对应α^t中的α)。
staircase - 若 ‘ True ’ ,则学习率衰减呈 ‘ 离散间隔 ’ (discrete intervals),具体地讲,global_step / decay_steps是整数除法,衰减学习率( the decayed learning rate )遵循阶梯函数;若为 ’ False ‘ ,则更新学习率的值是一个连续的过程,每步都会更新学习率。

返回值:
与初始学习率 ‘ learning_rate ’ 相同的标量 ’ Tensor ‘ 。

优点:
训练伊始可以使用较大学习率,以快速得到比较优的解。
后期通过逐步衰减后的学习率进行迭代训练,以使模型在训练后期更加稳定。

示例代码:

import tensorflow as tf
import matplotlib.pyplot as plt

learning_rate = 0.1
decay_rate = 0.96
global_steps = 1000
decay_steps = 100

global_step = tf.Variable(0, trainable = Fasle)
c = tf.train.exponential_decay(learning_rate, global_step, decay_steps, decay_rate, staircase=True)
d = tf.train.exponential_decay(learning_rate, global_step, decay_steps, decay_rate, staircase=False)

T_C = []
F_D = []

with tf.Session() as sess:
for i in range(global_steps):
T_c = sess.run(c, feed_dict={global_step: i})
T_C.append(T_c)
F_d = sess.run(d, feed_dict={global_step: i})
F_D.append(F_d)

plt.figure(1)
plt.plot(range(global_steps), F_D, 'r-')
plt.plot(range(global_steps), T_C, 'b-')

plt.show()

实操:
在这里插入图片描述
运行结果:
在这里插入图片描述
备注:

(1)

台阶形状的蓝色线是 staircase = True
线条形状的红色线是 staircase = Fasle

(2)
初始学习率 learning_rate 为0.1,总训练次数 global_setps 为 1000 次;staircase=True时,每隔 decay_steps = 100 次更新一次 学习率 learning_rate,而staircase=True时,每一步均会更新一次学习率 learning_rate ,

(3)
训练过程中,decay_rate的数值保持步不变。

tensorflow——optimizer.minimize()、optimizer.compute_gradients()、optimizer.apply_gradients()

优化函数

#损失函数
loss = ...
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1)
train_op =optimizer.minimize(loss,global_step=global_step)

其中minimize()包含两个步骤:
1.计算loss对指定val_list的梯度(导数),返回元组列表[(gradient,variable),…]
compute_gradients(loss,val_list)
注:tf.gradients(loss, tf.variables)与compute_gradients(loss,val_list)作用类似,但是只返回梯度
2.用计算得到的梯度来更新对应的变量(权重)
optimizer.apply_gradients(grads_and_vars, global_step=global_step, name=None)将
compute_gradients(loss,val_list)的返回值作为输入对variable更新
注意:在程序中global_step初始化为0,每次更新参数时,自动加1

等价于上面的代码
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1)
grads_and_vars = optimizer.compute_gradients(loss)
train_op = optimizer.apply_gradients(grads_and_vars)

将minimize()分成两个步骤
原因:在某种情况下对梯度进行修正,防止梯度消失或者梯度爆炸
如 tf.clip_by_norm()对梯度进行裁剪,通过控制梯度的最大范式,防止梯度爆炸的问题,是一种比较常用的梯度规约的方式

example:

import tensorflow as tf

w = tf.Variable(2,dtype=tf.float32)
x = tf.Variable(3,dtype=tf.float32)
loss = w*x*x
optimizer = tf.train.GradientDescentOptimizer(0.1)
grads_and_vars = optimizer.compute_gradients(loss,[w,x])
grads = tf.gradients(loss,[w,x])

#修正梯度
for i,(gradient,var) in enumerate(grads_and_vars):
    if gradient is not None:
        grads_and_vars[i] = (tf.clip_by_norm(gradient,5),var)
train_op = optimizer.apply_gradients(grads_and_vars)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(grads_and_vars))
     # 梯度修正前[(9.0, 2.0), (12.0, 3.0)];梯度修正后 ,[(5.0, 2.0), (5.0, 3.0)]
    print(sess.run(grads))  #[9.0, 12.0],
    print(train_op)

computer_gradients(loss, val_list)

参数含义:

loss: 需要被优化的Tensor
val_list: Optional list or tuple of tf.Variable to update to minimize loss. Defaults to the list of variables collected in the graph under the key GraphKeys.TRAINABLE_VARIABLES.
简单说该函数就是用于计算loss对于指定val_list的导数的,最终返回的是元组列表,即[(gradient, variable),…]。

看下面的示例

x = tf.Variable(initial_value=50., dtype='float32')
w = tf.Variable(initial_value=10., dtype='float32')
y = w*x
 
opt = tf.train.GradientDescentOptimizer(0.1)
grad = opt.compute_gradients(y, [w,x])
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(grad))

返回值如下:

[(50.0, 10.0), (10.0, 50.0)]
可以看到返回了一个list,list中的元素是元组。第一个元组第一个元素是50,表示∂y∂w的计算结果,第二个元素表示w。第二个元组同理不做赘述。

tf.get_collection()用法解析

官方文档:

variables = tf.get_collection(tf.GraphKeys.VARIABLES)
  	for i in variables:
  	    print(i)

该函数有两个参数

key: The key for the collection. For example, the GraphKeys class contains many standard names for collections.

scope: (可选参数) If supplied, the resulting list is filtered to include only items whose name attribute matches using re.match. Items without a name attribute are never returned if a scope is supplied and the choice or re.match means that a scope without special tokens filters by prefix.

该函数可以用来获取key集合中的所有元素,返回一个列表。列表的顺序依变量放入集合中的先后而定。scope为可选参数,表示的是名称空间(名称域),如果指定,就返回名称域中所有放入‘key’的变量的列表,不指定则返回所有变量。

例子:

variables = tf.get_collection(tf.GraphKeys.VARIABLES)
  	for i in variables:
  	    print(i)

out:

<tf.Variable ‘conv1/weights:0’ shape=(3, 3, 3, 96) dtype=float32_ref>
<tf.Variable ‘conv1/biases:0’ shape=(96,) dtype=float32_ref>
<tf.Variable ‘conv2/weights:0’ shape=(3, 3, 96, 64) dtype=float32_ref>
<tf.Variable ‘conv2/biases:0’ shape=(64,) dtype=float32_ref>
<tf.Variable ‘local3/weights:0’ shape=(16384, 384) dtype=float32_ref>
<tf.Variable ‘local3/biases:0’ shape=(384,) dtype=float32_ref>
<tf.Variable ‘local4/weights:0’ shape=(384, 192) dtype=float32_ref>
<tf.Variable ‘local4/biases:0’ shape=(192,) dtype=float32_ref>
<tf.Variable ‘softmax_linear/softmax_linear:0’ shape=(192, 10) dtype=float32_ref>
<tf.Variable ‘softmax_linear/biases:0’ shape=(10,) dtype=float32_ref>

又如

tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES,
scope=“hidden[123]”)
表示获取第1,2,3隐藏层的权重

tf.control_dependencies()函数

tf.control_dependencies(control_inputs)
此函数指定某些操作执行的依赖关系
返回一个控制依赖的上下文管理器,使用 with 关键字可以让在这个上下文环境中的操作都在 control_inputs 执行

with tf.control_dependencies([a, b]):
     c = ....
     d = ...

在执行完 a,b 操作之后,才能执行 c,d 操作。意思就是 c,d 操作依赖 a,b 操作

with tf.control_dependencies([train_step, variable_averages_op]):
     train_op = tf.no_op(name='train')

tf.no_op()表示执行完 train_step, variable_averages_op 操作之后什么都不做

tf.group()用于组合多个操作

tf.group()用于创造一个操作,可以将传入参数的所有操作进行分组。API手册如:

tf.group(
    *inputs,
    **kwargs
)

ops = tf.group(tensor1, tensor2,…)
其中*inputs是0个或者多个用于组合tensor,一旦ops完成了,那么传入的tensor1,tensor2,…等等都会完成了,经常用于组合一些训练节点,如在Cycle GAN中的多个训练节点,例子如:

generator_train_op = tf.train.AdamOptimizer(g_loss, …)
discriminator_train_op = tf.train.AdamOptimizer(d_loss,…)
train_ops = tf.groups(generator_train_op ,discriminator_train_op)

with tf.Session() as sess:
sess.run(train_ops)
一旦运行了train_ops,那么里面的generator_train_op和discriminator_train_op都将被调用

注意的是,tf.group()返回的是个操作,而不是值,如果你想下面一样用,返回的将不是值

a = tf.Variable([5])
b = tf.Variable([6])
c = a+b
d = a*b
e = a/b
ops = tf.group(c,d,e)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
ee = sess.run(ops)

返回的将不是c,d,e的运算结果,而是一个None,就是因为这个是一个操作,而不是一个张量。如果需要返回结果,请参考tf.tuple()

Tensorflow中tf.ConfigProto()详解

tf.ConfigProto()主要的作用是配置tf.Session的运算方式,比如gpu运算或者cpu运算

具体代码如下:

import tensorflow as tf

session_config = tf.ConfigProto(
      log_device_placement=True,
      inter_op_parallelism_threads=0,
      intra_op_parallelism_threads=0,
      allow_soft_placement=True)

sess = tf.Session(config=session_config)

a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2,3], name='b')
b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3,2], name='b')

c = tf.matmul(a,b)
print(sess.run(c))

具体解释

log_device_placement=True

设置为True时,会打印出TensorFlow使用了那种操作

inter_op_parallelism_threads=0

设置线程一个操作内部并行运算的线程数,比如矩阵乘法,如果设置为0,则表示以最优的线程数处理

intra_op_parallelism_threads=0

设置多个操作并行运算的线程数,比如 c = a + b,d = e + f . 可以并行运算

allow_soft_placement=True

有时候,不同的设备,它的cpu和gpu是不同的,如果将这个选项设置成True,那么当运行设备不满足要求时,会自动分配GPU或者CPU。

其他选项

当使用GPU时候,Tensorflow运行自动慢慢达到最大GPU的内存

session_config.gpu_options.allow_growth = True

当使用GPU时,设置GPU内存使用最大比例

session_config.gpu_options.per_process_gpu_memory_fraction = 0.4

是否能够使用GPU进行运算

tf.test.is_built_with_cuda()

另外的处理方法

import tensorflow as tf

sess = tf.Session()

with tf.device('/cpu:0'):
    a = tf.constant([1.0, 3.0, 5.0], shape=[1, 3])
    b = tf.constant([2.0, 4.0, 6.0], shape=[3, 1])

    with tf.device('/gpu:0'):
        c = tf.matmul(a, b)
        c = tf.reshape(c, [-1])

    with tf.device('/gpu:0'):
        d = tf.matmul(b, a)
        flat_d = tf.reshape(d, [-1])

    combined = tf.multiply(c, flat_d)
    print(sess.run(combined))

Tensorflow模型的保存、载入、使用

通过这篇文章,你可以学到:

  • 两种方法模型的保存
  • 两种方法对于模型的载入和使用

方法一:tf.train.Saver()
涉及到的方法:

保存:
tf.add_to_collection(‘logits’,y)
saver = tf.compat.v1.train.Saver()
saver.save(sess,"./model/model",global_step=200)

载入:
input_model=tf.train.import_meta_graph(’./model/model-200.meta’)
input_model.restore(sess,’./model/model-200’)
sess.graph.get_operation_by_name(‘input_x’).outputs[0]
tf.get_collection(‘logits’)[0]
在这里插入图片描述

add_to_collection()
这个方法是将某一变量添加到集合中,可以在之后模型调用的时候再拿出来用。

saver.save(a,b,c)
< a参数是会话 也就是tf.compat.v1.Session()
< b参数是路径和名称,如图所示,model文件下,文件开头是model。
< c参数也可以当作给文件命名,如果你想在程序训练的第200步进行模型存储,可以给它赋值200 此时,文件名后面就会多一个-200

tf.train.import_meta_graph(a)
input_model.restore(c,d’)
这两个方法就是对模型的导入和恢复。
< a参数为之前保存的后缀名是.meta的文件地址
< c参数是会话sess,即tf.compat.v1.Session()
< d 参数是文件名,不带后缀 比如上图的model-200

下面简单说一下图中四个文件的用处
checkpoint 最新的文件保存地址记录
model-200.data-00000-of-00001、保存了所有的训练变量
model-200.meta 保存了整个模型的图(Graph)

tf.add_to_collection(‘logits’,y)

tf.get_collection(‘logits’)[0]

前者是在模型中保存变量,后者是在加载完模型中,获得模型中的变量

方法二:tf.saved_model.builder.SavedModelBuilder()

保存:
#builder = tf.saved_model.builder.SavedModelBuilder(‘check_path_mnist’)#保存模型方法二
#builder.add_meta_graph_and_variables(sess,[‘predict_mnist’])#保存模型方法二
#builder.save()#保存模型方法二

载入:
tf.saved_model.loader.load(sess,[‘predict_mnist’],“check_path_mnist”)
在这里插入图片描述

TensorFlow用expand_dim()来增加维度

TensorFlow中,想要维度增加一维,可以使用tf.expand_dims(input, dim, name=None)函数。当然,我们常用tf.reshape(input, shape=[])也可以达到相同效果,但是有些时候在构建图的过程中,placeholder没有被feed具体的值,这时就会包下面的错误:TypeError: Expected binary or unicode string, got 1
在这种情况下,我们就可以考虑使用expand_dims来将维度加1。比如我自己代码中遇到的情况,在对图像维度降到二维做特定操作后,要还原成四维[batch, height, width, channels],前后各增加一维。如果用reshape,则因为上述原因报错

one_img2 = tf.reshape(one_img, shape=[1, one_img.get_shape()[0].value, one_img.get_shape()[1].value, 1])
用下面的方法可以实现:

one_img = tf.expand_dims(one_img, 0)
one_img = tf.expand_dims(one_img, -1) #-1表示最后一维

在最后,给出官方的例子和说明

# 't' is a tensor of shape [2]
shape(expand_dims(t, 0)) ==> [1, 2]
shape(expand_dims(t, 1)) ==> [2, 1]
shape(expand_dims(t, -1)) ==> [2, 1]

# 't2' is a tensor of shape [2, 3, 5]
shape(expand_dims(t2, 0)) ==> [1, 2, 3, 5]
shape(expand_dims(t2, 2)) ==> [2, 3, 1, 5]
shape(expand_dims(t2, 3)) ==> [2, 3, 5, 1]

tf.concat()详解

tensorflow中用来拼接张量的函数tf.concat(),用法:
tf.concat([tensor1, tensor2, tensor3,…], axis)
先给出tf源代码中的解释:

t1 = [[1, 2, 3], [4, 5, 6]]
  t2 = [[7, 8, 9], [10, 11, 12]]
  tf.concat([t1, t2], 0)  # [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
  tf.concat([t1, t2], 1)  # [[1, 2, 3, 7, 8, 9], [4, 5, 6, 10, 11, 12]]
 
  # tensor t3 with shape [2, 3]
  # tensor t4 with shape [2, 3]
  tf.shape(tf.concat([t3, t4], 0))  # [4, 3]
  tf.shape(tf.concat([t3, t4], 1))  # [2, 6]

这里解释了当axis=0和axis=1的情况,怎么理解这个axis呢?其实这和numpy中的np.concatenate()用法是一样的。
axis=0 代表在第0个维度拼接
axis=1 代表在第1个维度拼接

对于一个二维矩阵,第0个维度代表最外层方括号所框下的子集,第1个维度代表内部方括号所框下的子集。维度越高,括号越小。
对于这种情况,我可以再解释清楚一点:

对于[ [ ], [ ]]和[[ ], [ ]],低维拼接等于拿掉最外面括号,高维拼接是拿掉里面的括号(保证其他维度不变)。注意:tf.concat()拼接的张量只会改变一个维度,其他维度是保存不变的。比如两个shape为[2,3]的矩阵拼接,要么通过axis=0变成[4,3],要么通过axis=1变成[2,6]。改变的维度索引对应axis的值。
这样就可以理解多维矩阵的拼接了,可以用axis的设置来从不同维度进行拼接。

对于三维矩阵的拼接,自然axis取值范围是[0, 1, 2]。

对于axis等于负数的情况

负数在数组索引里面表示倒数(countdown)。比如,对于列表ls = [1,2,3]而言,ls[-1] = 3,表示读取倒数第一个索引对应值。

axis=-1表示倒数第一个维度,对于三维矩阵拼接来说,axis=-1等价于axis=2。同理,axis=-2代表倒数第二个维度,对于三维矩阵拼接来说,axis=-2等价于axis=1。

一般在维度非常高的情况下,我们想在最’高’的维度进行拼接,一般就直接用countdown机制,直接axis=-1就搞定了。

tf.reduce_mean()

tf.reduce_mean(input_tensor, axis=None, keep_dims=False, name=None, reduction_indices=None)

根据给出的axis在input_tensor上求平均值。除非keep_dims为真,axis中的每个的张量秩会减少1。如果keep_dims为真,求平均值的维度的长度都会保持为1.如果不设置axis,所有维度上的元素都会被求平均值,并且只会返回一个只有一个元素的张量。

import numpy as np
import tensorflow as tf
x = np.array([[1.,2.,3.],[4.,5.,6.]])
sess = tf.Session()
mean_none = sess.run(tf.reduce_mean(x))
mean_0 = sess.run(tf.reduce_mean(x, 0))
mean_1 = sess.run(tf.reduce_mean(x, 1))
print (x)
print (mean_none)
print (mean_0)
print (mean_1)
sess.close()

结果如下:

x=
[[ 1.  2.  3.]
 [ 4.  5.  6.]]

mean_none= 3.5

mean_0= [ 2.5  3.5  4.5]

mean_1= [ 2.  5.]

tf.reset_default_graph

tf.reset_default_graph函数用于清除默认图形堆栈并重置全局默认图形.
注意:默认图形是当前线程的一个属性.该tf.reset_default_graph函数只适用于当前线程.当一个tf.Session或者tf.InteractiveSession激活时调用这个函数会导致未定义的行为.调用此函数后使用任何以前创建的tf.Operation或tf.Tensor对象将导致未定义的行为.

可能引发的异常:

AssertionError:如果在嵌套图中调用此函数则会引发此异常.

posted @ 2020-09-21 16:27  野哥李  阅读(14)  评论(0编辑  收藏  举报  来源