Tensorflow学习笔记(二)——Tensorboard和数据类型

课程名称:CS20: Tensorflow for Deep Learning Research
视频地址:https://www.bilibili.com/video/av15898988/index_4.html#page=2
课程资源:http://web.stanford.edu/class/cs20si/index.html
参考资料:https://zhuanlan.zhihu.com/p/28674996


一、Tensorboard

我们上节课提到了tensorboard工具,这节课我们就来介绍如何使用它。例如,我们想要可视化下面的程序:

import tensorflow as tf

a=tf.constant(2)
b=tf.constant(3)
x=tf.add(a,b)

with tf.Session() as sess:
    print(sess.run(x))

使用方法非常简单,使用 writer = tf.summary.FileWriter('./graph', sess.graph)就能够创建一个文件写入器,./graph 是存储目录,sess.graph 表示读入的图结构

import tensorflow as tf

a=tf.constant(2)
b=tf.constant(3)
x=tf.add(a,b)

#writer = tf.summary.FileWriter('./graphs', tf.get_default_graph())
with tf.Session() as sess:
    #add this line to use tensorboard
    writer = tf.summary.FileWriter('./graphs', sess.graph)
    print(sess.run(x))
writer.close() # close the writer when you’re done using it

然后打开终端,运行程序,接着输入tensorboard --logdir="./graphs",然后打开网页输入 http://localhost:6006/,就能够进入tensorboard,可以得到下面的图。

我在这里出现了错误,Tensorboard 打开以后提示“No graph definition files were found”,后来参考博客tensorboard:No graph definition files were found. 常见情况及解决方法解决了这个问题,我将存储目录 ./graph 改为:"D:/graph",后面命令行中的地址也改为此地址,就可以了。需要注意以下两点:

  • tensorboard –logdir= 后面必须是绝对地址
  • 地址不能有中文

上面的结点是TF自动为其命名,为了变量更可读我们可以自己给变量命名。代码如下:

import tensorflow as tf

a = tf.constant(2, name='a')
b = tf.constant(3, name='b')
x = tf.add(a, b, name='add')
writer = tf.summary.FileWriter("D:/graph", tf.get_default_graph())
with tf.Session() as sess:
    print(sess.run(x)) 

# >> 5

二、常数类型

创建常数
我们能够通过下面这个函数创建一个常数:

tf.constant(
value,
dtype=None,
shape=None,
name='Const',
verify_shape=False)

这里的 verify_shape默认为 False,我们分别来看一下它设为 True 和 False 时的情况:

① 当 verify_shape=False

import tensorflow as tf

a=tf.constant(2,shape=[2,2])
tf.InteractiveSession()
print(a.eval())

#>> [[2 2]
#    [2 2]]

b=tf.constant([2,1],shape=[3,3])
print(b.eval())

#>> [[2 1 1]
#    [1 1 1]
#    [1 1 1]]

我们可以看出如果输入的 value 与 shape 不符,系统会默认用最后一个数字将后面缺少的部分补齐。

② 当 verify_shape=True
如果输入的 value 与 shape 不符,系统会报错。

下面我们建立一维向量和矩阵,然后将它们乘起来:

import tensorflow as tf
a = tf.constant([2, 2], name='a')
b = tf.constant([[0, 1], [2, 3]], name='b')
x = tf.multiply(a, b, name='mul')
with tf.Session() as sess:
    print(sess.run(x))

# >> [[0 2]
#     [4 6]]

创建特殊的张量
这里和 Numpy 差不多,同样的你也可以用Tensorflow创建一些特殊的张量:

这和numpy最大的区别在于其不能迭代,即

除此以外,TF还可以产生一些随机数,详见这里

运算OPerations
再来看一些运算:

关于常数的其他细节这里不再详述,可登录官方网站查看。


三、变量

使用常量会存在什么问题呢?常量会存在计算图的定义当中,如果常量过多,这会使得加载计算图变得非常慢,同时常量的值不可改变,所以引入了变量。

创建变量
创建一个变量的简单方法是:tf.Variable(<initial-value>, name=<optional-name>)

s =tf.Variable(2,name="scalar") 
v=tf.Variable([2,3],name="vector")
m =tf.Variable([[0, 1], [2, 3]],name="matrix") 
W =tf.Variable(tf.zeros([784,10]))

不过这种方法不建议,我们推荐大家使用另一个函数:tf.get_Variable

tf.get_variable(name,
shape=None,
dtype=None,
initializer=None,
regularizer=None,
trainable=True,
collections=None,
caching_device=None,
partitioner=None,
validate_shape=True,
use_resource=None,
custom_getter=None,
constraint=None
)
s =tf.get_variable("scalar",initializer=tf.constant(2)) 
m =tf.get_variable("matrix",initializer=tf.constant([[0, 1], [2, 3]]))
W =tf.get_variable("big_matrix",shape=(784,10),initializer=tf.zeros_initializer()) 

变量初始化
在使用变量之前必须对其进行初始化,如果没有初始化就使用变量,系统会报错。
最简单的初始化方式是一次性初始化所有的变量:

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

也可以对部分变量进行初始化:

with tf.Session() as sess:
    sess.run(tf.variables_initializer([s,m]))

也可以对一个变量进行初始化:

with tf.Session() as sess:
    sess.run(W.initializer)

获取变量的值
如果我们想获取变量的值有两种方法:

# W is a 784 x 10 variable of random values
W =tf.get_variable("normal_matrix",shape=(784, 10), 
initializer=tf.truncated_normal_initializer())
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(W))
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(W.eval())

为变量分配值
我们看下面一段代码及其输出:

W =tf.Variable(10)
W.assign(100)
with tf.Session() as sess:
    sess.run(W.initializer)
    print(W.eval()) 
# >> 10

上面这个程度会得到10,这是因为我们虽然定义了assign操作,但是tensorflow是在session中执行操作,所以我们需要执行assign操作。

W =tf.Variable(10)
assign_op =W.assign(100)
with tf.Session() as sess:
    sess.run(assign_op)
    print(W.eval())
# >> 100

我们注意到上面程序并没有初始化变量W,这是因为 tf.Variable.assign() 帮我们初始化了。
我们看下面一个例子及其输出:

# create a variable whose original value is 2
a =tf.get_variable('scalar',initializer=tf.constant(2)) 
a_times_two =a.assign(a * 2)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer()) 
    sess.run(a_times_two) # >> 4
    sess.run(a_times_two) # >> 8
    sess.run(a_times_two) # >> 16

为了实现变量简单的自减与自增,Tensorflow里设置了函数 tf.Variable.assign_add()tf.Variable.assign_sub(),但与 tf.Variable.assign() 不同的是它们不会帮你初始化变量。

W =tf.Variable(10)
with tf.Session() as sess:
    sess.run(W.initializer)
    print(sess.run(W.assign_add(10))) # >> 20
    print(sess.run(W.assign_sub(2)))  # >> 18

另外tensorflow的每个session是相互独立的,我们可以看看下面这个例子:

W =tf.Variable(10)
sess1 =tf.Session()
sess2 =tf.Session()
sess1.run(W.initializer)
sess2.run(W.initializer)
print(sess1.run(W.assign_add(10))) # >> 20
print(sess2.run(W.assign_sub(2))) # >> 8
print(sess1.run(W.assign_add(100))) # >> 120
print(sess2.run(W.assign_sub(50))) # >> -42
sess1.close()
sess2.close()

当你有一个变量是根据另一个变量来定义的,例如: U=W×2

# W is a random 700 x 10 tensor
W =tf.Variable(tf.truncated_normal([700, 10]))
U =tf.Variable(W * 2)

在这种情况下,你如果用W的值来初始化U,就需要用 initialized_value() 确保 W已经初始化。

U =tf.Variable(W.initialized_value() * 2)

四、占位符Placeholder

tensorflow中一般有两步,第一步是定义图,第二步是在session中进行图中的计算。对于图中我们暂时不知道值的量,我们可以定义为占位符,之后再用feed_dict去赋值。

定义占位符的方式非常简单:

tf.placeholder(dtype, shape=None, name=None)

dtype是必须要指定的参数,shape如果是None,说明任何大小的tensor都能够接受,使用shape=None很容易定义好图,但是在debug的时候这将成为噩梦,所以最好是指定好shape。

a =tf.placeholder(tf.float32,shape=[3]) # a is placeholder for a vector of 3 elements
b =tf.constant([5, 5, 5],tf.float32) 
c =a+b # use the placeholder as you would any tensor
with tf.Session() as sess:
    print(sess.run(c, feed_dict={a: [1, 2, 3]})) 

你也可以给不是占位符的张量赋值,例如:

a =tf.add(2, 5)
b =tf.multiply(a, 3)
with tf.Session() as sess:
    print(sess.run(b))  # >> 21
    # compute the value of b given the value of a is 15
    print(sess.run(b,feed_dict={a: 15}))  # >> 45

五、lazy loading

lazy loading是指你推迟变量的创建直到你必须要使用他的时候。下面我们看看一般的loading和lazy loading的区别。

# normal loading
x = tf.Variable(10, name='x')
y = tf.Variable(20, name='y')
z = tf.add(x, y)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for _ in range(10):
        sess.run(z)

# lazy loading
x = tf.Variable(10, name='x')
y = tf.Variable(20, name='y')
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for _ in range(10):
        sess.run(tf.add(x, y))

normal loading 会在图中创建x和y变量,同时创建x+y的运算,而lazy loading只会创建x和y两个变量。这不是一个bug,那么问题在哪里呢?

normal loading在session中不管做多少次x+y,只需要执行z定义的加法操作就可以了,而lazy loading在session中每进行一次x+y,就会在图中创建一个加法操作,如果进行1000次x+y的运算,normal loading的计算图没有任何变化,而lazy loading的计算图会多1000个节点,每个节点都表示x+y的操作。

这就是lazy loading造成的问题,这会严重影响图的读入速度。所以我们要尽量避免lazy loading。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值