Tensorflow代码笔记(一)
tf.app.run
函数入口,类似于c/c++中的main(),大概意思是通过处理flag解析,然后执行main函数。
有两种情况:
· 如果你的代码中的入口函数不叫main(),而是一个其他名字的函数,如test(),则你应该这样写入口tf.app.run(test)
· 如果你的代码中的入口函数叫main(),则你就可以把入口写成tf.app.run()
tf.Graph().as_default()
tf.Graph() 表示实例化了一个类,一个用于 tensorflow 计算和表示用的数据流图,通俗来讲就是:在代码中添加的操作(画中的结点)和数据(画中的线条)都是画在纸上的“画”,而图就是呈现这些画的纸,你可以利用很多线程生成很多张图,但是默认图就只有一张。
tf.Graph().as_default() 表示将这个类实例,也就是新生成的图作为整个 tensorflow 运行环境的默认图,如果只有一个主线程不写也没有关系,tensorflow 里面已经存好了一张默认图,可以使用tf.get_default_graph() 来调用(显示这张默认纸),当你有多个线程就可以创造多个tf.Graph(),就是你可以有一个画图本,有很多张图纸,这时候就会有一个默认图的概念了。
tf.placeholder
Tensorflow的设计理念称之为计算流图,在编写程序时,首先构筑整个系统的graph,代码并不会直接生效,这一点和python的其他数值计算库(如Numpy等)不同,graph为静态的,类似于docker中的镜像。然后,在实际的运行时,启动一个session,程序才会真正的运行。这样做的好处就是:避免反复地切换底层程序实际运行的上下文,tensorflow帮你优化整个系统的代码。我们知道,很多python程序的底层为C语言或者其他语言,执行一行脚本,就要切换一次,是有成本的,tensorflow通过计算流图的方式,帮你优化整个session需要执行的代码,还是很有优势的。
所以placeholder()函数是在神经网络构建graph的时候在模型中的占位,此时并没有把要输入的数据传入模型,它只会分配必要的内存。等建立session,在会话中,运行模型的时候通过feed_dict()函数向占位符喂入数据。
tf.name_scope
(1)在某个tf.name_scope()指定的区域中定义的所有对象及各种操作,他们的“name”属性上会增加该命名区的区域名,用以区别对象属于哪个区域;
(2)将不同的对象及操作放在由tf.name_scope()指定的区域中,便于在tensorboard中展示清晰的逻辑关系图,这点在复杂关系图中特别重要。
tf.name_scope()只是规定了对象和操作属于哪个区域,但这并不意味着他们的作用域也只限于该区域(with的这种写法很容易让人产生这种误会),不要将其和“全局变量、局部变量”的概念搞混淆,两者完全不是一回事。在name_scope中定义的对象,从被定义的位置开始,直到后来某个地方对该对象重新定义,中间任何地方都可以使用该对象。本质上name_scope只对对象的name属性进行圈定,并不会对其作用域产生任何影响。这就好比甲、乙、丙、丁属于陈家,这里“陈家”就是一个name_scope划定的区域,虽然他们只属于陈家,但他们依然可以去全世界的任何地方,并不会只将他们限制在陈家范围。
tf.Variable
在TensorFlow的世界里,变量的定义和初始化是分开的,所有关于图变量的赋值和计算都要通过tf.Session的run来进行。想要将所有图变量进行集体初始化时应该使用tf.global_variables_initializer。
两种定义图变量的方法:
· tf.Variable.init(initial_value, trainable=True, collections=None, validate_shape=True, name=None)虽然有一堆参数,但只有第一个参数initial_value是必需的
·tf.get_variable跟tf.Variable都可以用来定义图变量,但是前者的必需参数(即第一个参数)并不是图变量的初始值,而是图变量的名称。tf.Variable的用法要更丰富一点,当指定名称的图变量已经存在时表示获取它,当指定名称的图变量不存在时表示定义它。
tf.nn.relu
tf.nn.relu()函数的目的是,将输入小于0的值幅值为0,输入大于0的值不变。
tf.matmul
将矩阵 a 乘以矩阵 b,生成a * b
tf.nn.sparse_softmax_cross_entropy_with_logits
这是一个TensorFlow中经常需要用到的函数。官方文档里面有对它详细的说明,传入的logits为神经网络输出层的输出,shape为[batch_size,num_classes],传入的label为一个一维的vector,长度等于batch_size,每一个值的取值区间必须是[0,num_classes),其实每一个值就是代表了batch中对应样本的类别。
tf.nn.sparse_softmax_cross_entropy_with_logits()首先来说,这个函数的具体实现分为了两个步骤:
(1)Softmax
Softmax函数的作用就是将每个类别所对应的输出分量归一化,使各个分量的和为1,这样可以理解为将output vector的输出分量值,转化为了将input data分类为每个类别的概率。
(2)计算Cross-Entropy
tf.nn.sparse_softmax_cross_entropy_with_logits()输入的label格式为一维的向量,而如果你的label已经是one-hot格式,则可以使用tf.nn.softmax_cross_entropy_with_logits()函数来进行softmax和loss的计算
计算cross-entropy的公式:
H
y
′
(
y
)
=
−
∑
i
y
i
′
log
(
y
i
)
H_{y'}(y)=-\sum_{i}y'_i\log(y_i)
Hy′(y)=−∑iyi′log(yi),其中
y
i
′
y'_i
yi′为label中的第
i
i
i个值,
y
i
y_i
yi为经softmax归一化输出的vector中的对应分量,由此可以看出,当分类越准确时,
y
i
y_i
yi所对应的分量就会越接近于1,从而
H
y
′
(
y
)
H_{y'}(y)
Hy′(y)的值也就会越小。
tf.reduce_mean
tf.reduce_mean 函数用于计算张量tensor沿着指定的数轴(tensor的某一维度)上的的平均值,主要用作降维或者计算tensor(图像)的平均值。
·第一个参数input_tensor: 输入的待降维的tensor;
·第二个参数axis: 指定的轴,如果不指定,则计算所有元素的均值;
·第三个参数keep_dims:是否降维度,设置为True,输出的结果保持输入tensor的形状,设置为False,输出结果会降低维度;
·第四个参数name: 操作的名称;
tf.cast
tf.cast()函数的作用是执行 tensorflow 中张量数据类型转换,比如读入的图片如果是int8类型的,一般在要在训练前把图像的数据格式转换为float32
tf.reduce_sum
reduce_sum( ) 是求和函数,在 tensorflow 里面,计算的都是 tensor,可以通过调整 axis =0,1 的维度来控制求和维度。
tf.train.exponential_decay
一句话描述:对学习率learning_rate应用指数衰减。
多说点:固定的学习率总是显得笨拙:太小速度太慢,太大又担心得不到最优解。一个很直接的想法就是随着训练的进行,动态设置学习率——随着训练次数增加,学习率逐步减小。而tf.train.exponential_decay()就是tf内置的一个生成动态减小学习率的函数。
tf.summary.scalar
添加变量到直方图中,但是不配合其他的方法,根本就显示不出来它的意义!
tf.train.GradientDescentOptimizer
参数:
learning_rate: A Tensor or a floating point value. 要使用的学习率
use_locking: 要是True的话,就对于更新操作(update operations.)使用锁
name: 名字,可选,默认是”GradientDescent”
minimize() 函数处理了梯度计算和参数更新两个操作
compute_gradients() 函数用于获取梯度
apply_gradients() 用于更新参数
tf.gfile.Exists
与 os.path.exists功能相同
tf.gfile.DeleteRecursively
递归删除所有目录及其文件,dirname即目录名,无返回。
tf.constant
创建常量
tf.add
使x,和y两个参数的元素相加,返回的tensor数据类型和x的数据类型相同
tf.assign
赋值
sess.run()
sess.run()由fetches和feed_dict组成:sess.run(fetches,feed_dict)
sess.run是让fetches节点动起来,告诉tensorflow,想要此节点的输出。
· fetches 可以是list或者tensor向量
· feed_dict给使用placeholder创建出来的tensor赋值,用来替换原图中的某个tensor,feed 只在调用它的方法内有效, 方法结束, feed 就会消失.
tf.assign_add
tf.assign_add(ref,value,use_locking=None,name=None)
更新ref的值,通过增加value,即:ref = ref + value;
tf.group
tf.group()用于创造一个操作,可以将传入参数的所有操作进行分组
tf.group( *inputs, **kwargs)
其中 *inputs是0个或者多个用于组合tensor