一起学 TensorFlow(一)---快速入门(1)

最近在读《TensorFlow实战Google深度学习框架》,本着理论实践相结合的目标,就开博记录一下(主要是遇到的坑:P),这个系列主要是实践书中的例子,大佬勿喷,谢谢,嘻嘻。至于官方文档嘛也稍微看了一下,但还是觉得看书比较适合我,好了不废话,开坑啦!

安装什么的很简单(可以百度,不行我到时候再记录一下,因为装好了就懒得再写啦)

入门篇

通过对TensorFlow的计算模型、数据模型、和运行模型的介绍,对TensorFlow的工作原理做个梳理。

1.计算模型---计算图

1.1概念

TensorFlow是一个通过计算图的形式来表述计算的编程系统,每个计算都是计算图上的一个节点,而结点之间的边描述了计算间的依赖关系。

图中a和b不依赖于任何计算,而add计算则依赖读取a和b的值

1.2使用

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
sess = tf.Session()
sess.run(result)
#通过a.graph可以查看张量a所属的计算图
#tf.get_default_graph()查看当前默认计算图
print(a.graph is tf.get_default_graph())

控制台:

True

True就是判断a的计算图是否为当前默认计算图的结果。

除了使用默认计算图,还支持通过tf.Graph来生成新的计算图,不同计算图上的张量和运算都不会共享。

g1=tf.Graph()
#在计算图g1上定义变量v,并设置初始值为0
with g1.as_default():
    #下面代码写法是TensorFlow旧版本的写法
    #v=tf.get_variable("v",initializer=tf.zeros_initializer(shape=[1]))
    v=tf.get_variable("v",initializer=tf.zeros_initializer()(shape=[1]))

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

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

控制台:

[ 0.]
[ 1.]

很好很好没问题掌声鼓励一下。

可能在这里会有疑问,什么是张量?这个输出代表了什么意思?不急,我们往下继续。

2.数据模型---张量

2.1概念

在TensorFlow程序中,所有数据通过张量的形式表示

从功能角度看,张量被理解为多维数组, 0阶张量表示标量,也就是一个数;一阶张量表示向量,也就是一维数组;n阶张量理解为n阶数组

but,张量在TensorFlow中的实现并不是直接采用数组的形式,它只是对TensorFlow中计算结果的引用 ,张量中保存的不是数字,而是这些计算过程(划重点!计算过程!)

举个栗子吧,执行如下代码,并不会得到一个具体的结果,而是得到一个对结果的引用:

import tensorflow as tf
#tf.constant为一个计算,这个计算的结果是一个张量,保存在a中
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)

看看输出是什么:

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

好,那我们来解释一下这个输出代表了什么。对了Tensor就是张量的意思哦。

首先,这是一个计算结果的引用,其中包含了3个属性:

第一个属性是名字,形式为“node:src_output”, node表示计算图节点的名称,src_output表示结果来自结点的第几个输出,0表示第一个

        add:0,表示结果来自add结点的第1个输出

第二个属性是张量的维度

        shape=(2,)表示张量是一个一维数组,长度为2

第三个属性是类型,每个张量有一个唯一的类型,TensorFlow会对参与运算的所有张量进行类型检查,不匹配时会报错,如果不指定类型,会按照默认类型来进行匹配,所以一般建议制定类型 a=tf.constant([1,2],name="a",type="float32")

2.2 使用

张量的两大用处:

1.对中间计算结果的引用,当一个计算包含很多中间结果时,使用张量可以加强可读性,也可方便获取中间结果

2.当计算图构造完成后,张量可以用来获取最终计算结果,也就是具体的数字,虽然本身并没有存储,但可以通过会话获取

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(a)
print(result)

输出结果a和result都是张量,a保存了一个常数,以后计算时可以直接用,就不用在生成这个常量了;result保存了add计算

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

3.运行模型---会话

3.1概念

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

在TensorFlow中有两种使用会话的方式,第一种需要明确地调用会话生成函数和关闭会话函数:

#创建一个会话
sess = tf.Session()

#使用这个会话来得到关心的结果
sess.run(...)

#关闭会话使得资源被释放
sess.close()

那要是还没关闭之前程序异常了怎么办?那不就会发生资源泄漏???

还好,我们在第二种方式里,通过使用Python的上下文管理器,只要将所有计算放在with里就好了,上下文管理器退出时会自动释放资源的,这样也不用显式地去close它了,真棒!

with tf.Session() as sess:
    sess.run(...)
#不需要使用sess.close()了

TensorFlow不会自动生成默认会话,而是需要手动指定它as_default(),当默认会话被指定后可以通过tf.Tensor.eval来获取一个张量的值

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

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

输出则是a与b做加法的结果:

[ 3.  5.]

注意:sess.run()和result.eval(session=sess)等效

在交互式环境下,通过设置默认会话的方式来获取张亮的取值更加方便,所以TensorFlow提供了一种在交互式环境下直接构建默认会话的函数,tf.InteractiveSession。 使用这个函数会把自动生成的会话注册为默认会话。

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

sess = tf.InteractiveSession()
#在这里就不用之前的sess.as_default()了
print(result.eval())
sess.close()

无论使用哪种方式,都可以通过ConfigProto Protocol Buffer来配置需要生成的会话。

#通过ConfigProto配置会话
import tensorflow as tf
config = tf.ConfigProto(allow_soft_placement=True,log_device_placement=True)

sess1 = tf.InteractiveSession(config=config)
sess2 = tf.Session(config=config)

通过使用ConfigProto可以配置类似并行线程数,GPU分配策略,运算超时时间等参数。其中最常用的有两个:

(1)allow_soft_placement:当它为True时,以下条件任意一个成立,GPU上的运算可以放在CPU上进行:

         1.运算无法在CPU上运行

         2.没有GPU资源可用

         3.运算输入包括对CPU计算结果的引用

         为了使代码的可移植性更强,通常设置为True(默认False);不同版本的GPU对计算的支持略有差别,当无法被支持时可以移植到CPU上而不是报错;而且设置为True可以让程序运行在拥有不同数量的GPU上。

(2)log_device_placement:当它为True时,日志中将会记录每个节点被安排在哪个设备上以方便调试,在生产环境中设置为False可以减少日质量。

好啦,至此,3个部分都梳理完了,明天继续学习用TensorFlow实现一个简单的神经网络~(期待)

猜你喜欢

转载自blog.csdn.net/qq_25353433/article/details/81461912
今日推荐