tensorflow入门基础

tensorflow程序一般分为两个阶段,在第一个阶段需要定义图中所有的计算。在第二个阶段就是执行计算。

1. 计算图的使用

首先在tensorflow的程序中系统会维护一个默认的计算图,通过tf.get_default_graph()可以获取当前默认的计算图。

  • 下面展示了 如何获得一个运算所属的计算图以及默认的计算图:
import tensorflow as tf
a = tf.constant([1.0, 2.0], name="a")
b = tf.constant([2.0, 3.0], name="b")
result = a + b
print(result)
# 查看张量所属的计算图
print(a.graph)
print(tf.get_default_graph())
# 没有特别指定计算图,所以张量所属图应该是默认的计算图
print(a.graph is tf.get_default_graph())

运算结果:

Tensor("add_4:0", shape=(2,), dtype=float32)
<tensorflow.python.framework.ops.Graph object at 0x119d8c550>
<tensorflow.python.framework.ops.Graph object at 0x119d8c550>
True
  • 除了使用默认的计算图,tensorflow还支持通过tf.Graph函数获得新的计算图,这样的话不同的计算图上的张量和运算都不会共享。
import tensorflow as tf

# 产生第一个计算图g1
g1 = tf.Graph()
with g1.as_default():
    # 在g1计算图中定义变量v,并设置初始值为0
    v = tf.get_variable("v", [2], initializer = tf.zeros_initializer()) 

# 产生第二个计算图g2
g2 = tf.Graph()
with g2.as_default():
    # 在g2计算图中定义变量v,并设置初始值为1
    v = tf.get_variable("v", [1], initializer = tf.ones_initializer())  # 

# 在计算图g1中读取变量v的取值
with tf.Session(graph = g1) as sess:
    tf.global_variables_initializer().run()
    with tf.variable_scope("", reuse=True):
        print(sess.run(tf.get_variable("v")))

# 在计算图g1中读取变量v的取值
with tf.Session(graph = g2) as sess:
    tf.global_variables_initializer().run()
    with tf.variable_scope("", reuse=True):
        print(sess.run(tf.get_variable("v")))

运算结果:

runfile('/Users/lilong/Desktop/tt.py', wdir='/Users/lilong/Desktop')
[0. 0.]
[1.]

由运行结果可以看出,每个计算图中定义了名称相同的“v“变量,但是定义了不同的初始值,运行结果也显示值不同,可以看出不同的计算图可以独立运行,变量不会冲突。tensorflow不仅可以隔离运算张量,还可以指定运算的设备(tf.Graph.device),也即是管理张量的计算机制,这也就为tensorflow使用gpu提供了机制。示例:

g=tf.Graph()
# 指定计算运行的设备
with g.device('/gpu:0'):
    result=a+b
2. 张量

在tensorflow中所有的数据都是通过张量的形式表示的,张量也可以被简单理解为多维数组。其中0阶张量就是标量,也就是一个数;一阶张量为向量,也就是一维数组;n阶张量可以理解为一个n维数组。但是张量的实现并不是直接采用数组的形式,他只是对tensorflow运算结果的一个引用,里面保存的并不是真正的数字结果,保存的而是这些数字的计算过程,这也是为什么tensorflow程序初始化后还要打开会话运行才能得到张量的运算结果。

import tensorflow as tf
a = tf.constant([1.0, 2.0], name="a")
b = tf.constant([2.0, 3.0], name="b")
result=tf.add(a,b,name='add')
print('result:',result)

结果:

result: Tensor("add:0", shape=(2,), dtype=float32)

这里的显示表明得到的结果是一个张量的结构,并没有进行真正的计算。这里显示了张量的三个属性:名字、维度、类型。
张量的第一个属性名字是其唯一的标示符,同样也给出了该标量是如何计算出来的。其命名方式是:node:src_output的形式。其中node是节点的名称,src_output表示当前张量来自节点的第几个输出。
张量的第二个属性是张量的维度。比如上述的shape(2,)就代表是个一维数组,长度为2。
张量的第三个属性是类型。这里要注意的是tensorflow会对运算的所有张量进行类型检查,当发现不匹配时会报错,即是运算的张量类型必须一致。

张量的两个用途:

  • 第一个是对中间结果的引用。当一个计算模型很复杂时,会包含很多的中间计算结果,通过张量可以大大提高代码的可读性。
  • 第二个用处是当计算图构造完成时,通过张量可以获得计算结果,也就是真实的数值。虽然张量本身没有存储具体的数字,但通过会话tf.session().run(result)就可以得到具体的数字。这里的意思也就是说,通过张量可以大大使代码明了清晰,会话计算结果时不用引用一大段定义和参数,直接应用一个定义好的张量就可以了。
3. 会话

在定义好所有的运算之后,会话拥有并管理tensorflow的程序运行时的所有资源,当所有的计算完成后需要关闭会话并帮助系统收回资源,否则会出现资源泄漏的问题。

3.1 tensorflow的会话有两种形式:
  • 第一种是需要明确调用的会话生成函数和关闭会话函数。
# 创建一个会话。
sess = tf.Session()
# 使用会话得到之前计算的结果。
print(sess.run(result))
# 关闭会话使得本次运行中使用到的资源可以被释放。
sess.close()

使用第一种模式,在所有的计算完成后,需要明确调用session.close()函数来关闭会话,并释放资源,但是由于一些原因,关闭会话可能不会被执行从而导致资源泄漏。所以不推荐这种方式来使用会话。

  • 第二种是使用python的上下文管理器来使用会话。
# 不需要再调用session.close()来关闭会话,当上下文退出时会话关闭和资源释放也自动完成了
with tf.Session() as sess:
    print(sess.run(result))

这里是使用python的上下文管理器来的机制来管理这个会话,这样即解决了异常退出时资源释放的问题,同时也解决了忘记调用session.close函数而产生的资源泄漏。

3.2 指定默认会话

上面介绍过说tensorflow会自动生成一个默认的计算图,如果没有指定,运算会自动加入这个计算图中。tensorflow会话也有类似的机制,但其不会自动生成默认的会话,而需要手动指定默认会话,当默认的会话被指定后就可以通过tf.tensor.eval()函数来计算一个张量的取值了。

sess = tf.Session()
with sess.as_default():
     print(result.eval())

而上述计算result的方法还可以通过以下方式实现:

sess = tf.Session()
# 下面的两个命令有相同的功能。
print(sess.run(result)) # 会话调用计算
print(result.eval(session=sess)) # 张量直接eval计算
  • 这里还有一种:使用tf.InteractiveSession构建会话:

在交互式环境下(比如python),通过设置默认会话的方式来获取张量更加方便,所以tendorflow提供了一种交互式环境下直接构建默认会话的函数,那就是 tf.InteractiveSession,这个函数会自动将生成的会话注册为默认会话:

sess = tf.InteractiveSession ()
# 默认会话下的直接张量调用计算
print(result.eval())
sess.close()

通过tf.InteractiveSession函数可以省去将产生的会话注册为默认会话的过程。

  • 通过ConfigProto配置会话
config=tf.ConfigProto(allow_soft_placement=True, log_device_placement=True)
sess1 = tf.InteractiveSession(config=config)
sess2 = tf.Session(config=config)

通过ConfigProto可以配置类似并行的线程数、gpu分配策略、运算超时时间等参数,在这些参数中,最常用的有两个。
第一个是allow_soft_placement:当为true时,在某些情况下(gpu无法直接计算)可以将gpu的计算放到cpu上进行。这个参数的默认值为false,但是一般情况下都设置为true,这个是为了使代码的可移植性更强。也即是在某些情况下gpu无法计算,在不报错的情况下可以移植到cpu上继续计算。
第二个参数是log_device_placement,当为true时日志中将会记录每个节点被安排在了哪个设备上方便调试。而在生产环境中将这个参数设为false可以减少日志量。

以上只是tensorflow的一些基础,但很有必要要掌握。

参考:《Tensorflow实战Google深度学习框架》

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值