TensorFlow学习笔记(二)

1.tf.reduce_mean()

        TensorFlow提供了大量的规约计算函数,比如tf.reduce_max(),tf.reduce_min(),tf.reduce_sum()等,这里我们仔细看一下tf.reduce_mean()。

        函数定义如下:

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

      该函数用于对输入的Tensor求取均值,如果不给定reduction_indices的话,就默认为对整个Tensor求取均值,而如果reduction_indices=0,则表示对第一维的元素取均值,即每一列求平均值;reduction_indices=1,则为对第二维的元素取平均值,即每一行求平均值。下面我们举例进行说明:

import tensorflow as tf
import numpy as np

sess=tf.InteractiveSession()
v=np.array([1,2,3,4])
x=tf.constant(v,dtype=tf.float32,shape=[2,2])
print tf.reduce_mean(x).eval()
print tf.reduce_mean(x,0).eval()
print tf.reduce_mean(x,1).eval()
        运行结果:

       

        从上面的运行结果可以看出来,该函数默认对整个Tensor求取均值,如果传入reduction_indices=0,则对列求取均值,如果传入reduction_indices=1,则对行求取均值。


2.TensorFlow中的layers

        突然发现TensorFlow也并不是一味地需要自己去构建神经网络层,比如全连接层,我们也可以使用TensorFlow提供的dense来实现,而非自己声明W和b,然后利用op来实现。

        TensorFlow学习笔记(二)_第1张图片

        在core.py中定义了全连接层Dense类和正则化层Dropout类,我们可以通过core.py文件中的dense()和dropout()函数接口对此进行调用。用起来还挺方便的,和tflearn差不多,可以参考全连接层。

        dense函数的签名如下:

dense(inputs,units,activation=None,use_bias=True,kernel_initialize=None,bias_initializer=init_ops.zeros_initializer(),kernel_regularizer=None,bias_regularizer=None,activity_regularizer=None,trainable=True,name=None,reuse=None)

        TFLearn中的fully_connected函数签名如下:

fully_connected(incoming,n_units,activation='linear',bias=True,weights_init='truncated_normal',bias_init='zeros',regularzer=None,weight_decay=0.001,trainable=True,name='FullyConnected')

        下面我们对dense函数的使用进行举例:

import tensorflow as tf
import numpy as np

sess=tf.InteractiveSession()
x=tf.placeholder(dtype=tf.float32,shape=[None,3])
net=tf.layers.dense(x,5)
y=tf.layers.dense(net,1)
sess.run(tf.global_variables_initializer())
inputs=[[1,2,3],[4,5,6]]
print sess.run(y,feed_dict={x: inputs})
       
        值得注意的是,其中的x=tf.placeholder(dtype=tf.float32,shape=[None,3]),如果我们步给出dtype,则会报错:TypeError: placeholder() takes at least 1 argument (1 given)。

 3.TensorFlow可视化

        TensorFlow可视化是使用summary和tensorboard合作完成的,这里的summary也是一个op。

        首先,我们来看如何输出网络结构: 

import tensorflow as tf

with tf.Session() as sess:
	x=tf.placeholder(dtype=tf.float32,shape=[None,3])
	net=tf.layers.dense(x,5)
	y=tf.layers.dense(net,1)
	writer=tf.summary.FileWriter('/home/moran/DRL/visualization',sess.graph)
        运行完成之后,会将sess.graph保存到指定目录下:

        TensorFlow学习笔记(二)_第2张图片

     此时我们在命令行运行tensorboard --logdir /home/moran/DRL/visualization,然后在浏览器中输入127.0.1.1 : 6006(tf1.1.0版本换为了0.0.0.0:6006):

        TensorFlow学习笔记(二)_第3张图片

        下面我们介绍数据序列化:

        TensorBoart通过读取TensorFlow的事件文件来运行。TensorFlow的事件文件包括了我们会在TensorFlow运行中涉及到的主要数据。下面介绍一下TensorBoard中汇总数据(Summary data)的大体生命周期。

        首先,创建你想要汇总数据的TensorFlow图,然后选择我们想要在哪个节点进行汇总(summary)操作。

        比如,我们正在训练一个卷积神经网络,用于识别MNIST标签,我们可能希望记录学习速度如何变化以及目标函数如何变化,通过向节点添加scalar_summary操作来分别输出学习速度和期望误差,然后我们可以给每个scalar_summary分配一个有意义的标签,比如'learning rate'和'loss function'。

     或者,我们还希望显示一个特殊层中激活(activations)的分布,或者梯度权重的分布,可以通过分别附加histogram_summary运算来收集权重变量和梯度输出。

        所有可用的summary操作详细信息,可以看summary_operation文档。

       在TensorFlow中,所有的操作只有当你执行,或另一个操作依赖于它的输出时才会运行。我们刚才创建的这些节点(summary nodes)都围绕着我们的图像:没有任何操作依赖于它们的结果。因此,为了生成汇总信息,我们需要运行所有的节点,这样的工作很乏味,不过可以使用tf.merge_all_summaries来将它们合为一个操作。

        我们执行合并命令,它会将所有的数据生成一个序列化的Summary protobuf对象。最后,为了将汇总数据写入磁盘,需要将汇总的protobuf对象传递给tf.train.Summarywriter。

       SummaryWriter的构造函数中包含了参数 logdir。这个 logdir 非常重要,所有事件都会写到它所指的目录下。此外,SummaryWriter中还包含了一个可选择的参数GraphDef。如果输入了该参数,那么 TensorBoard 也会显示我们的图像。

        现在已经修改了我们的图,也有了SummaryWriter,现在就可以运行我们的神经网络了!如果愿意的话,我们可以每一步执行一次合并汇总,这样将会得到一大堆训练数据。这很有可能超过了我们想要的数据量。我们也可以每一百步执行一次合并汇总,或者如下面代码里示范的这样。

merged_summary_op = tf.merge_all_summaries()
summary_writer = tf.train.SummaryWriter('/tmp/mnist_logs', sess.graph)
total_step = 0
while training:
        total_step += 1
        session.run(training_op)
        if total_step % 100 == 0:
                summary_str = session.run(merged_summary_op)
                summary_writer.add_summary(summary_str, total_step)

       值得注意的是,函数的具体写法依版本而定,比如tf.merge_all_summaries(old)和tf.summary.merge_all(new),tf.train_SummaryWriter(old)和tf.summary.FileWriter(new),这是一定要注意的。

        现在已经准备好用 TensorBoard 来可视化这些数据了。

        首先启动TensorBoard:

        python tensorflow/tensorboard/tensorboard.py --logdir=path/to/log-directory

        这里的参数logdir指向SummaryWriter序列化数据的存储路径。如果logdir目录的子目录中包含另一次运行时的数据,那么 TensorBoard 会展示所有运行的数据。一旦 TensorBoard 开始运行,我们可以通过在浏览器中输入localhost:6006来查看 TensorBoard。

        此外,如果我们已经利用pip安装了TensorBoard,那么我们可以执行更为简单的命令来访问TensorBoard:

        tensorboard --logdir=/path/to/log-directory

        进入TensorBoart界面时,我们会在右上角看见导航的选项卡,每一个选项卡将展现一组可视化的序列化数据集。对于我们查看的每一个选项卡,如果TensorBoard中没有数据与这个选项卡相关的话,则会显示一条提示信息指示我们如何序列化相关数据。

        更多说明请参考:TensorBoard图标可视化。

        最后,具体介绍几个函数:

1)tf.summary.merge_all:将之前定义的所有summary op整合到一起;

2)FileWriter:创建一个file writer用于向硬盘写summary数据;

3)  tf.summary.scalar(summary_tags, Tensor/variable, collections=None):用于标量的summary;

4)  tf.summary.histogram(tag, values, collections=None, name=None):生成直方图summary;

    注意到其中的collections参数,它是一个list,如果不指定collections,那么这个summary将会被添加到tf.GraphKey.SUMMARIES中,如果指定了,就会被放在collections中。

       对了,上面的add_summary仅仅是向FileWriter对象的缓存中存放event data,而向disk上写数据是由FileWriter对象控制的。

       注意:

1)如果使用writer.add_summary(summary,global_step)时没有传global_step参数,会使得scalar_summary变为一条直线;

2)只要是在计算图上面 的summary op,都会被merge_all捕获,不需要考虑变量的生存期空间问题;

3)如果执行一次,disk上没有保存summary数据的话,可以尝试一下file_writer.flush()。

4)如果想要生成的summary有层次的话,记得在summary外面加一个name_scope:

with tf.name_scope("summary_gradients"):
        tf.summary.histogram("name",gradients)





你可能感兴趣的:(TensorFlow学习笔记)