ConfigProto
一般用在创建session
的时候。用来对session
进行参数配置
#tf.ConfigProto()的参数
log_device_placement=True : 是否打印设备分配日志
allow_soft_placement=True : 如果你指定的设备不存在,允许TF自动分配设备
tf.ConfigProto(log_device_placement=True,allow_soft_placement=True)
控制GPU资源使用率
#allow growth
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
session = tf.Session(config=config, ...)
# 使用allow_growth option,刚一开始分配少量的GPU容量,然后按需慢慢的增加,由于不会释放
#内存,所以会导致碎片
# per_process_gpu_memory_fraction
gpu_options=tf.GPUOptions(per_process_gpu_memory_fraction=0.7)
config=tf.ConfigProto(gpu_options=gpu_options)
session = tf.Session(config=config, ...)
#设置每个GPU应该拿出多少容量给进程使用,0.4代表 40%
控制使用哪块GPU
os.environ["CUDA_DEVICE_ORDER"]="PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"]="0"
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
self.sess = tf.Session(config=config)
Tensorflow中的随机数生成种子是在数据流图资源上运作的。每一个数据流图中,我们可以执行针对随机数生成种子应用不同的操作(operation)。
https://blog.csdn.net/qq_31878983/article/details/79495810
tf.variable_scope(): 可以让变量有相同的命名,包括tf.get_variable得到的变量,还有tf.Variable变量
它返回的是一个用于定义创建variable(层)的op的上下文管理器。
可变范围允许创建新的variable并分享已创建的variable,同时提供检查,不会意外创建或共享
https://blog.csdn.net/gqixf/article/details/82770192?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
tf.nn.embedding_lookup(params, ids, partition_strategy='mod', max_norm=None)
这个函数的目的是按照ids从params这个矩阵中拿向量(行),所以ids就是这个矩阵索引(行号),需要int类型。
#!/usr/bin/env/python
# coding=utf-8
import tensorflow as tf
import numpy as np
input_ids = tf.placeholder(dtype=tf.int32, shape=[None])
embedding = tf.Variable(np.identity(5, dtype=np.int32))
input_embedding = tf.nn.embedding_lookup(embedding, input_ids)
sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
print(embedding.eval())
print(sess.run(input_embedding, feed_dict={input_ids:[1, 2, 3, 0, 3, 2, 1]}))
代码中先使用palceholder定义了一个未知变量input_ids用于存储索引,和一个已知变量embedding,是一个5*5的对角矩阵。
运行结果为:
embedding = [[1 0 0 0 0]
[0 1 0 0 0]
[0 0 1 0 0]
[0 0 0 1 0]
[0 0 0 0 1]]
input_embedding = [[0 1 0 0 0]
[0 0 1 0 0]
[0 0 0 1 0]
[1 0 0 0 0]
[0 0 0 1 0]
[0 0 1 0 0]
[0 1 0 0 0]]
如果将input_ids改写成下面的格式
input_embedding = tf.nn.embedding_lookup(embedding, input_ids)
print(sess.run(input_embedding, feed_dict={input_ids:[[1, 2], [2, 1], [3, 3]]}))
[[[0 1 0 0 0]
[0 0 1 0 0]]
[[0 0 1 0 0]
[0 1 0 0 0]]
[[0 0 0 1 0]
[0 0 0 1 0]]]
https://blog.csdn.net/u013041398/article/details/60955847?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
tf.nn.dropout()是tensorflow里面为了防止或减轻过拟合而使用的函数,它一般用在全连接层
Dropout就是在不同的训练过程中随机扔掉一部分神经元。也就是让某个神经元的激活值以一定的概率p,让其停止工作,这次训练过程中不更新权值,也不参加神经网络的计算。但是它的权重得保留下来(只是暂时不更新而已),因为下次样本输入时它可能又得工作了
tf.nn.dropout(x, keep_prob,noise_shape=None, seed=None, name=None)
参数说明:
x:指输入,输入tensor
keep_prob: float类型,每个元素被保留下来的概率,设置神经元被选中的概率,在初始化时keep_prob是一个占位符, keep_prob = tf.placeholder(tf.float32) 。tensorflow在run时设置keep_prob具体的值,例如keep_prob: 0.5
noise_shape : 一个1维的int32张量,代表了随机产生“保留/丢弃”标志的shape。
seed : 整形变量,随机数种子。
name:指定该操作的名字
dropout必须设置概率keep_prob,并且keep_prob也是一个占位符,跟输入是一样的
keep_prob = tf.placeholder(tf.float32)
train的时候才是dropout起作用的时候,test的时候不应该让dropout起作用
dense :全连接层 相当于添加一个层
函数如下:
tf.layers.dense(
inputs,
units,
activation=None,
use_bias=True,
kernel_initializer=None, ##卷积核的初始化器
bias_initializer=tf.zeros_initializer(), ##偏置项的初始化器,默认初始化为0
kernel_regularizer=None, ##卷积核的正则化,可选
bias_regularizer=None, ##偏置项的正则化,可选
activity_regularizer=None, ##输出的正则化函数
kernel_constraint=None,
bias_constraint=None,
trainable=True,
name=None, ##层的名字
reuse=None ##是否重复使用参数
)
部分参数解释:
inputs:输入该网络层的数据
units:输出的维度大小,改变inputs的最后一维
activation:激活函数,即神经网络的非线性变化
use_bias:使用bias为True(默认使用),不用bias改成False即可,是否使用偏置项
trainable=True:表明该层的参数是否参与训练。如果为真则变量加入到图集合中
GraphKeys.TRAINABLE_VARIABLES (see tf.Variable)
在其他网站上看到的使用现象
dense1 = tf.layers.dense(inputs=pool3, units=1024, activation=tf.nn.relu,
kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
#全连接层
dense1 = tf.layers.dense(inputs=pool3, units=1024, activation=tf.nn.relu)
dense2= tf.layers.dense(inputs=dense1, units=512, activation=tf.nn.relu)
logits= tf.layers.dense(inputs=dense2, units=10, activation=None)
输出结果的最后一维度就等于神经元的个数,即units的数值(神经元的个数)
inputs = tf.ones([5,12,15,128])
a= tf.layers.dense(inputs, units=1, activation=None)
print(a.get_shape())
结果为:
(5,12,15,1)
参见:https://blog.csdn.net/yangfengling1023/article/details/81774580
https://blog.csdn.net/ningyanggege/article/details/91491553
CNN中最重要的就是参数了,包括W,b。 我们训练CNN的最终目的就是得到最好的参数,使得目标函数取得最小值。参数的初始化也同样重要,因此微调受到很多人的重视,那么tf提供了哪些初始化参数的方法呢.
tf.constant_initializer()
也可以简写为tf.Constant()
初始化为常数,这个非常有用,通常偏置项就是用它初始化的。
由它衍生出的两个初始化方法:
a、 tf.zeros_initializer(), 也可以简写为tf.Zeros()
b、tf.ones_initializer(), 也可以简写为tf.Ones()
或者简写为tf.TruncatedNormal()
生成截断正态分布的随机数,这个初始化方法好像在tf中用得比较多。
它有四个参数(mean=0.0, stddev=1.0, seed=None, dtype=dtypes.float32),分别用于指定均值、标准差、随机数种子和随机数的数据类型,一般只需要设置stddev这一个参数就可以了。
可简写为 tf.RandomNormal()
生成标准正态分布的随机数,参数和truncated_normal_initializer一样。
可简写为tf.RandomUniform()
生成均匀分布的随机数,参数有四个(minval=0, maxval=None, seed=None, dtype=dtypes.float32),分别用于指定最小值,最大值,随机数种子和类型。
可简写为tf.UniformUnitScaling()
和均匀分布差不多,只是这个初始化方法不需要指定最小最大值,是通过计算出来的。参数为(factor=1.0, seed=None, dtype=dtypes.float32)
max_val = math.sqrt(3 / input_size) * factor
这里的input_size是指输入数据的维数,假设输入为x, 运算为x * W,则input_size= W.shape[0]
它的分布区间为[ -max_val, max_val]
可简写为tf.VarianceScaling()
参数为(scale=1.0,mode="fan_in",distribution="normal",seed=None,dtype=dtypes.float32)
scale: 缩放尺度(正浮点数)
mode: "fan_in", "fan_out", "fan_avg"中的一个,用于计算标准差stddev的值。
distribution:分布类型,"normal"或“uniform"中的一个。
当 distribution="normal" 的时候,生成truncated normal distribution(截断正态分布) 的随机数,其中stddev = sqrt(scale / n) ,n的计算与mode参数有关。
简写为tf.Orthogonal()
生成正交矩阵的随机数。
当需要生成的参数是2维时,这个正交矩阵是由均匀分布的随机数矩阵经过SVD分解而来。
也称之为Xavier uniform initializer,由一个均匀分布(uniform distribution)来初始化数据。
假设均匀分布的区间是[-limit, limit],则
limit=sqrt(6 / (fan_in + fan_out))
其中的fan_in和fan_out分别表示输入单元的结点数和输出单元的结点数。
也称之为 Xavier normal initializer. 由一个 truncated normal distribution来初始化数据.
stddev = sqrt(2 / (fan_in + fan_out))
其中的fan_in和fan_out分别表示输入单元的结点数和输出单元的结点数。
tf.nn.l2_normalize(x, dim, epsilon=1e-12, name=None)
上式:
x为输入的向量;
dim为l2范化的维数,dim取值为0或0或1;
epsilon的范化的最小值边界;
tf.nn.l2_normalize(x, dim, epsilon=1e-12, name=None)
上式:
x为输入的向量;
dim为l2范化的维数,dim取值为0或0或1;
epsilon的范化的最小值边界;
按列计算
import tensorflow as tf
input_data = tf.constant([[1.0,2,3],[4.0,5,6],[7.0,8,9]])
output = tf.nn.l2_normalize(input_data, dim = 0)
with tf.Session() as sess:
print sess.run(input_data)
print sess.run(output)
[[1./norm(1), 2./norm(2) , 3./norm(3) ]
[4./norm(1) , 5./norm(2) , 6./norm(3) ] =
[7./norm(1) , 8./norm(2) , 9./norm(3) ]]
[[0.12309149 0.20739034 0.26726127]
[0.49236596 0.51847583 0.53452253]
[0.86164045 0.82956135 0.80178374]]
按行计算
import tensorflow as tf
input_data = tf.constant([[1.0,2,3],[4.0,5,6],[7.0,8,9]])
output = tf.nn.l2_normalize(input_data, dim = 1)
with tf.Session() as sess:
print sess.run(input_data)
print sess.run(output)
[[1./norm(1), 2./norm(1) , 3./norm(1) ]
[4./norm(2) , 5./norm(2) , 6./norm(2) ] =
[7./norm(3) , 8..norm(3) , 9./norm(3) ]]
[[0.12309149 0.20739034 0.26726127]
[0.49236596 0.51847583 0.53452253]
[0.86164045 0.82956135 0.80178374]]
https://blog.csdn.net/abiggg/article/details/79368982
reduce_sum()
用于计算张量tensor沿着某一维度的和,可以在求和后降维。
tf.reduce_sum(
input_tensor,
axis=None,
keepdims=None,
name=None,
reduction_indices=None,
keep_dims=None)
下面举个多维tensor例子简单说明。下面是个 2 * 3 * 4 的tensor。
[[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]],
[[ 13 14 15 16]
[ 17 18 19 20]
[ 21 22 23 24]]]
tf.reduce_sum(tensor, axis=0) axis=0 说明是按第一个维度进行求和。那么求和结果shape是3*4
[[1+13 2+14 3+15 4+16]
[5+17 6+18 7+19 8+20]
[9+21 10+22 11+23 12+24]]
依次类推,如果axis=1,那么求和结果shape是2*4,即:
[[ 1 + 5 + 9 2 + 6+10 3 + 7+11 4 + 8+12]
[13+17+21 14+18+22 15+19+23 16+20+24]]
如果axis=2,那么求和结果shape是2*3,即:
[[1+2+3+4 5+6+7+8 9+10+11+12]
[13+14+15+16 17+18+19+20 1+22+23+24]]
链接:https://www.jianshu.com/p/30b40b504bae
tf.reduce_mean 函数用于计算张量tensor沿着指定的数轴(tensor的某一维度)上的的平均值,主要用作降维或者计算tensor(图像)的平均值。
reduce_mean(input_tensor,
axis=None,
keep_dims=False,
name=None,
reduction_indices=None)
类似函数还有:
tensorflow中的tile()函数是用来对张量(Tensor)进行扩展的,其特点是对当前张量内的数据进行一定规则的复制。最终的输出张量维度不变。
tf.tile(
input,
multiples,
name=None
)
input是待扩展的张量,multiples是扩展方法。
假如input是一个3维的张量。那么mutiples就必须是一个1x3的1维张量。这个张量的三个值依次表示input的第1,第2,第3维数据扩展几倍。
https://blog.csdn.net/tsyccnh/article/details/82459859
tensorflow中用来拼接张量的函数tf.concat(),用法:
tf.concat([tensor1, tensor2, tensor3,...], axis)
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 代表在第0个维度拼接
axis=1 代表在第1个维度拼接
注意:tf.concat()拼接的张量只会改变一个维度,其他维度是保存不变的。
tf.clip_by_value(A, min, max):输入一个张量A,把A中的每一个元素的值都压缩在min和max之间。小于min的让它等于min,大于max的元素的值等于max。
import tensorflow as tf;
import numpy as np;
A = np.array([[1,1,2,4], [3,4,8,5]])
with tf.Session() as sess:
print sess.run(tf.clip_by_value(A, 2, 5))
输出:
[[2 2 2 4]
[3 4 5 5]]
*tf.add_to_collection(‘list_name’, element):将元素element添加到列表list_name中
*tf.get_collection(‘list_name’):返回名称为list_name的列表
*tf.add_n(list):将列表元素相加并返回
import tensorflow as tf
tf.add_to_collection('losses', tf.constant(2.2))
tf.add_to_collection('losses', tf.constant(3.))
with tf.Session() as sess:
print(sess.run(tf.get_collection('losses')))
print(sess.run(tf.add_n(tf.get_collection('losses'))
结果:
[2.2, 3.0]
5.2
注意:
使用tf.add_n对列表元素进行相加时,列表内元素类型必须一致,否则会报错。
global_step在滑动平均、优化器、指数衰减学习率等方面都有用到,这个变量的实际意义非常好理解:代表全局步数,比如在多少步该进行什么操作,现在神经网络训练到多少轮等等,类似于一个钟表。
根据代码可以发现global_step的初始化值是0:
global_step=tf.Variable(0, trainable=False)
https://blog.csdn.net/leviopku/article/details/78508951
https://blog.csdn.net/TeFuirnever/article/details/88933368
我们都知道,TensorFlow为我们提供了丰富的优化函数,例如GradientDescentOptimizer。这个方法会自动根据loss计算对应variable的导数。示例如下:
loss = ...
opt = tf.tf.train.GradientDescentOptimizer(learning_rate=0.1)
train_op = opt.minimize(loss)
init = tf.initialize_all_variables()
with tf.Seesion() as sess:
sess.run(init)
for step in range(10):
session.run(train_op)
首先我们看一下minimize()
的源代码(为方便说明,部分参数已删除):
def minimize(self, loss, global_step=None, var_list=None, name=None):
grads_and_vars = self.compute_gradients(loss, var_list=var_list)
vars_with_grad = [v for g, v in grads_and_vars if g is not None]
if not vars_with_grad:
raise ValueError(
"No gradients provided for any variable, check your graph for ops"
" that do not support gradients, between variables %s and loss %s." %
([str(v) for _, v in grads_and_vars], loss))
return self.apply_gradients(grads_and_vars, global_step=global_step,
name=name)
由源代码可以知道minimize()
实际上包含了两个步骤,即compute_gradients
和apply_gradients
,前者用于计算梯度,后者用于使用计算得到的梯度来更新对应的variable。下面对这两个函数做具体介绍。
compute_gradients
(loss,var_list)参数含义:
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∂y∂w的计算结果,第二个元素表示ww。第二个元组同理不做赘述。
其中tf.gradients(loss, tf.variables)
的作用和这个函数类似,但是它只会返回计算得到的梯度,而不会返回对应的variable。
tf.train.Optimizer.apply_gradients(grads_and_vars, global_step=None, name=None)
该函数的作用是将compute_gradients()
返回的值作为输入参数对variable进行更新。
那为什么minimize()
会分开两个步骤呢?原因是因为在某些情况下我们需要对梯度做一定的修正,例如为了防止梯度消失(gradient vanishing)或者梯度爆炸(gradient explosion),我们需要事先干预一下以免程序出现Nan的尴尬情况;有的时候也许我们需要给计算得到的梯度乘以一个权重或者其他乱七八糟的原因,所以才分开了两个步骤。
https://www.cnblogs.com/marsggbo/p/10056057.html
http://www.tensorfly.cn/tfdoc/api_docs/python/train.html#Optimizer
tf.trainable_variables(), tf.all_variables(), tf.global_variables()查看变量
在使用tensorflow搭建模型时,需要定义许多变量,例如一个映射层就需要权重与偏置。当网络结果越来越复杂,变量越来越多的时候,就需要一个查看管理变量的函数,在tensorflow中,tf.trainable_variables(), tf.all_variables(),和tf.global_variables()可以来满足查看变量的要求,来简单说一下他们的不同。
tf.trainable_variables()
顾名思义,这个函数可以也仅可以查看可训练的变量,在我们生成变量时,无论是使用tf.Variable()还是tf.get_variable()生成变量,都会涉及一个参数trainable,其默认为True。以tf.Variable()为例:
链接:https://blog.csdn.net/cerisier/article/details/86523446