【Tensorflow_DL_Note5】Tensorflow中计算图、会话、feed和fetch

一 Tensorflow的基本使用

      在Tensorflow进行深度神经网络模型的具体设计之前,我们必须明白以下几点:

      【1】在Tensorflow中,使用【图:Graph】来表示计算任务。

      【2】在被称之为【会话:Session】的上下文执行【图:Graph】

      【3】使用Tensor表示【数据】

      【4】使用变量Variable维护状态

      【5】使用feed和fecth可以为任意的操作赋值或者从中获取数据

二 综述

      Tensorflow是一个编程系统,使用【图】来表示【计算任务】。图中的【节点】被称为op(operating的缩写),一个op获得0个或者多个Tensor,执行计算,产生0个或者多个Tensor。每个Tensor是一个类型化的【多维数组】,例如:你可以将一小组图像集合表示为一个四维浮点数数组,这四个维度分别是[batch,height,width,channels]

      一个Tensorflow图描述了计算的过程。为了进行计算,图必须在【会话】里面启动。【会话】将图的【op】分发到诸如CPU或者GPU之类的设备上,同时提供执行【op】的方法。在这些方法执行后,将产生的Tensor返回。在Python语言中,返回的Tensor是numpy中的ndarry对象;在C/C++语言中,返回的Tensor是tensorflow::Tensor的实例。

三 计算图Graph的概念

3.1 图Graph的综述

       Tensorflow中的程序通常被组织成一个【构建阶段】和一个【执行阶段】。在Tensorflow代码的【构建阶段】,op的执行步骤被描述成一个图的执行阶段,使用Session执行图中的op。例如:通常在构建阶段创建一个图来表示和训练神经网络,然后,在执行阶段,再反复执行图中的训练op。Tensorflow支持C/C++、python等。目前,Tensorflow的Python库更加容易使用,它提供了大量的辅助函数来简化构建图的工作,这些函数尚未被C和C++库支持。

      Tensorflow的名字已经说明了它最重要的两个概念---Tensor和Flow。Tensor就是张量。在Tensorflow中,张量可以被简单的理解为【多维数组】。如果说Tensorflow的第一个单词【Tensor】表明了它的【数据结构】,那么【Flow】则体现了它的【 】计算模型。Flow翻译成中文,就是“流”的意思,它直观的表达了Tensor之间 通过计算相互转化的过程。Tensorflow是一个通过【计算图】的形式来表达【计算】的【编程系统】。Tensorflow中的每一个计算都是计算图Graph上的一个节点,而节点op之间的边则描述了计算之间的依赖关系

3.2 图Graph的使用

       在Tensorflow中,图的使用一般分为两个阶段。

              【1】构建图:第一阶段为构建图,在这个阶段中,需要定义计算图中所有的计算。

              【2】执行图:在图的构建完成之后,才能启动图。启动图的第一步是创建一个Session对象,如果没有任何创建参数,会话Session构建函数将启动默认的图。

#========================================================================================================
#详细说明:
#      【1】下面这个创建图的过程,Tensorflow会自动的将定义转化为计算图Graph上的节点Node.在Tensorflow程序中,系统会
#           自动的维护一个默认的计算图,通过tf.get_default_graph()函数可以获得当前默认的计算图。
#      【2】下面的代码给出了图创建阶段的定义样例
#      【3】示意了如何获取默认的计算图,以及如何查看一个运算所属的计算图
#========================================================================================================
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
#通过a.graph可以查看张量所属的计算图。因为没有特意的指定,所以这个计算图应该等于当前默认的计算图。所以下面的这个结果应
#该输出为True
print(a.graph is tf.get_default_graph())

         除了使用默认的计算图,Tensorflow也支持通过tf.Graph函数来生成新的计算图。不同计算图上的张量和运算都不会共享。下面的代码示意了如何在不同的计算图上定义和使用变量Variable.

#========================================================================================================
#详细说明:
#      【1】下面这个创建图的过程,Tensorflow会自动的将定义转化为计算图Graph上的节点Node.在Tensorflow程序中,系统会
#           自动的维护一个默认的计算图,通过tf.get_default_graph()函数可以获得当前默认的计算图。
#      【2】下面的代码给出了图创建阶段的定义样例
#      【3】示意了如何获取默认的计算图,以及如何查看一个运算所属的计算图
#========================================================================================================
import  tensorflow as tf
#【0】创建一个新的空的【计算图】【图:Graph】
#【1】在【计算图:Graph】中定义变量"Var",并设置其初始值为0.
globalGraph = tf.Graph()
with globalGraph.as_default():
    var = tf.get_variable("var",shape=[1],initializer=tf.zeros_initializer)


#【0】创建一个新的空的【计算图】【图:Graph】
globalGraph2 = tf.Graph()
with globalGraph2.as_default():
    #【2】计算图globalGraph2中定义的变量“var”,并设置初始值为1
    var = tf.get_variable("var",shape=[1],initializer=tf.ones_initializer)


#【0】在图globalGraph1中读取变量var的取值
with tf.Session(graph=globalGraph) as sess:
     tf.global_variables_initializer().run()
     with tf.variable_scope("",reuse=True):
        #   在计算图g1中,变量“v”的取值应该为0,所以下面这行会输出[0.]
        print(sess.run(tf.get_variable("var")))


#【0】在图global2中读取变量var的取值
with tf.Session(graph=globalGraph2) as sess:
    tf.global_variables_initializer().run()
    with tf.variable_scope("",reuse=True):
        #【4】在图globalGraph2中,变量“var”的取值应该为1,所以下面这行的输出应该为[1.]
        print(sess.run(tf.get_variable("var")))
#========================================================================================================
#详细说明:
#      【1】上面的代码产生了两个【图】,每个【图】中定义了一个名字为“var”的变量。在【图】globalGraph中,将变量初始化
#           为0;在【图】globalGraph中,将图初始化为1。
#      【2】可以看到,当运行不同的【图】时,变量var的值也是不一样的。
#      【3】Tensorflow中的【图】不仅仅可以用来【隔离】【张量】和【计算】,它还提供了【管理张量】和【计算的机制】。【图】
#           可以通过【tf.Graph.device函数】来【指定】【运行计算的设备】。这为Tensorflow使用GPU提供了机制。下面的程序
#           可以将【加法】计算跑在GPU上。
#========================================================================================================
globalVal = tf.Graph()
#【1】指定计算运行的设备
with globalVal.device(‘/gpu:0’):
    result = a+b
#========================================================================================================
#详细说明:
#      【1】有效的整理Tensorflow程序中的资源也是【图】的一个非常重要的功能。
#      【2】在一个【图】中,可以通过集合cellection来管理不同类别的资源。比如通过tf.add_to_collection函数可以将资源
#           加入到一个或者多个集合中,然后,通过tf.get_collection获取一个集合里面的所有的资源。这里的资源可以是张量、
#           变量或者运行Tensorflow程序所需的【队列资源】
#========================================================================================================

四 Tensorflow的数据模型---张量

4.1 张量的概念

      Tensorflow程序使用Tensor数据结构来代表所有的数据,图中,操作间传递的数据都是tensor,你可以把Tensor看做是一个能为的数组或者python中的列表。一个Tensor包含一个静态类型的rank和一个shape。虽然,可以讲tensor看成是一个n维的数组,但是Tensor在Tensorflow中的实现并不是直接采用数据的形式实现的,它只是对Tensorflow中运算结果的引用。在Tensor中并没有保存真正的数字,它保存的是如何得到这些数字的计算过程。还是以向量的加法 为例,当运行下面的代码时,并不会得到具体的数值结果,而会得到对结果的一个引用。

#========================================================================================================
#函数原型:
#       constant(value, dtype=None, shape=None, name="Const", verify_shape=False)
#函数说明:
#       Tensorflow中常量的常见函数
#参数说明:
#       【1】value------初始化常量变量的值
#       【2】dtype------常量的数据类型
#       【3】shape------常量的维度
#========================================================================================================
import tensorflow as tf
#【0】tf.constant()是Tensorflow中常量的创建函数
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)
#========================================================================================================
#模块说明:
#       【1】从上面的代码可以看出Tensorflow中的【张量】Tensor和Numpy中的【数组】不同,Tensorflow计算的结果不是一个
#           具体的数字,而是一个【张量】的【结构】。从上面代码运行的结果可以看出,一个张量中主要保存的三个属性为:名字、
#           维度和类型
#       【2】张量的三个属性:
#               【1】name :名字
#               【2】shape: 维度
#               【3】type :类型
#       【3】张量的第一个属性名字不仅是一个张量的唯一标识符,它同样也给出了这个张量是如何计算出来的,在前面,我们知道
#           Tensorfloe中的计算都可以通过【图模型】来建立,而【图】上的每一个节点Node带一个计算,计算的结果就存储在
#           张量之中。所以,张量和图上节点所代表的计算结果是对应的。这样张量的命名就可以通过node:src_output的形式给
#           出。其中node为节点的名称,src_output代表当前张量来自节点的第几个输出。比如上面程序的输出add:0就说明了
#           result这个张量是计算节点add输出的第一个结果。
#       【4】张量的第二个属性是张量的维度(shape)。这个属性描述了一个张量的维度信息,比如上面样例中的shape=(2,),说明了
#           张是一个一维数组,这个数组的长度为2,【维度】是【张量】一个非常重要的属性。围绕张量的维度Tensorflow也给出了
#           很多有用的运算。
#       【5】张量的第三个属性是类型(dtype),每一个张量都会有一个唯一的类型。Tensorflow会对参与运算的所有张量进行类型
#           的检查;当发现类型不匹配是时,就会报错。
#========================================================================================================

4.2 张量的使用

        和Tensorflow的计算模型相比,Tensorflow的数据模型相对比较简单,张量的使用主要归结为两大类:

        第一类用途是:对中间计算结果的引用。当一个计算包含很多中间结果时,使用张量可以大大提高代码的可读性。

       第二类情况是:当【图】构造完成之后,张量可以用来获得计算结果,也就是得到真实的数字。虽然张量本身并没有存储具体数字的能力,但是通过【会话】Session,就可以得到这些具体的数字,如下面的代码所示:

import tensorflow as tf
#【0】tf.constant()是Tensorflow中常量的创建函数
a=tf.constant([1.0,2.0],name="a")
b=tf.constant([2.0,3.0],name="b")

result = a+b
print(tf.Session().run(result))

五 Tensorflow执行模型---会话Session

      此块,我们将介绍如何使用Tensorflow中的会话Session来执行定义好的运算。【会话】Session拥有并管理Tensorflow程序 运行时的【所有资源】。当所有的计算完成之后,需要关闭【会话】Session来帮助系统回收资源,否则,就可能会出现资源泄露的问题。

      Tensorflow中使用【会话】Session的模式一般有两种模式,第一种模式需要明确调用【会话生成函数】和【关闭会话函数】,这种模式的代码流程遵循【三步骤战略】,具体代码如下所示:

import tensorflow as tf
#【1】创建一个会话
sess = tf.Session()
#【2】使用这个创建好的会话Session来得到关心的运算的结果,比如可以调用sess.run(result)
sess.run(result)
#【3】关闭会话使得本次运行中使用的资源可以被释放
sess.close()
          使用这种模式时,在所有计算完成之后,需要明确的调用Session.close()会话关闭函数来关闭会话,并释放掉资源。然而,当程序因为异常退出时,关闭会话的函数可能就不会被执行而导致资源泄露。为了解决异常退出时,资源能够正确释放的问题,Tensorflow可以通过Python中的上下文管理器来使用会话Session。以下代码展示了如何使用这种模式。
import tensorflow as tf
#【1】创建一个会话,并通过Python中的上下文管理器来管理这个会话Session
with tf.Session() as sess:
    #【2】使用创建好的会话Session来计算关心的结果
    sess.run()
    #【3】不需要再调用Session.close()函数来关闭会话,当上下文退出时会关闭会话,也会释放掉资源

       通过python的【上下文管理器机制】,只要将所有的计算放在【with语句】的内部就可以。当上下文管理器退出的时候,会自动的释放掉资源。这样既解决了因为异常退出时,资源释放的问题,同事也解决了忘记调用Session.close()函数而产生的资源泄露问题。

       前面提到过,Tensorflow会自动的生成一个默认的【图】,如果没有特殊的指定,运算会自动的加入到这个默认的【图】总,tf.get_default_graph()。Tensorflow中的会话Session也有类似的机制,但Tensorflow不会自动的生成默认的会话,而是需要手动的指定。当默认的会话被指定之后,可以通过tf.Tensor.eval函数来计算一个张量的取值。下面的代码展示了通过设定默认的会话计算张量的取值:

import tensorflow as tf

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

     在交互式环境下,比如说python脚本或者Jupyter的编辑器下,通过设置【默认会话】的方式来获取张量的取值更加的方便。所以,Tensorflow提供了一种在交互式环境下直接构建会话的函数,这个函数就是tf.InteractiveSession。使用这个函数会自动将生成的【会话】注册为【默认的会话】。下面的代码展示了这个函数的使用:

import tensorflow as tf

sess = tf.InteractiveSession()
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分配策略】、【运算超时时间】等参数,在这些参数中,最常用的有两个。第一个是allow_soft_placement,这是一个布尔型的参数,当它为True时,在以下任意一个条件成立的时候,GPU上的运算可以放到CPU上运行。

     【1】运算无法在GPU上执行

     【2】没有GPU资源(比如计算被指定到了第二个GPU上,但是计算机只有一个GPU)

     【3】运算的输入中,包含对CPU计算结果的引用


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
mysqli_fetch_row()和mysqli_fetch_array()都是PHP用于从MySQL查询结果集获取数据的函数。它们的区别如下: 1. mysqli_fetch_row()函数返回一个基于数字索引的数组,数组的下标是从0开始的整数,数组的值是结果集的一行数据。例如: ```php $result = mysqli_query($conn, "SELECT id, name, age FROM users"); while ($row = mysqli_fetch_row($result)) { echo $row[0] . ", " . $row[1] . ", " . $row[2] . "<br>"; } ``` 2. mysqli_fetch_array()函数返回一个既包含基于数字索引的数组,也包含关联索引的数组,数组的下标可以是数字或者字符串,数组的值是结果集的一行数据。例如: ```php $result = mysqli_query($conn, "SELECT id, name, age FROM users"); while ($row = mysqli_fetch_array($result)) { echo $row[0] . ", " . $row[1] . ", " . $row[2] . "<br>"; echo $row['id'] . ", " . $row['name'] . ", " . $row['age'] . "<br>"; } ``` 3. mysqli_fetch_array()函数比mysqli_fetch_row()函数更灵活,因为它可以通过指定参数来控制返回的数组类型。例如: ```php $result = mysqli_query($conn, "SELECT id, name, age FROM users"); while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) { echo $row['id'] . ", " . $row['name'] . ", " . $row['age'] . "<br>"; } ``` 在上面的例子,mysqli_fetch_array()函数的第二个参数指定为MYSQLI_ASSOC,表示返回一个关联索引的数组。 总之,mysqli_fetch_row()函数返回一个基于数字索引的数组,而mysqli_fetch_array()函数返回一个既包含基于数字索引的数组,也包含关联索引的数组。如果需要更灵活的控制返回的数组类型,应该使用mysqli_fetch_array()函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值