<<< TensorFlow Win10 stage.2
>>> TensorFlow Win10 stage.4

文章目录

  • TensorFlow 基本概念详解
    • 1. TensorFlow计算模型——计算图 Graph
      • 1.1 计算图的概念
      • 1.2 结点
        • 1.2.1 常量结点 tf.constant
        • 1.2.2 占位符 tf.placeholder 和 feed_dict
        • 1.2.4 操作 Operator
        • 1.2.1 变量 Variable
      • 1.3 计算图的使用
    • 2. TensorFlow数据模型——张量 Tensor
      • 2.1 张量的概念
      • 2.2 张量的使用
        • 2.2.1 引用中间结果
        • 2.2.2 获取计算结果
    • 3. TensorFlow运行模型——会话 Session
      • 3.1 会话的创建和使用
      • 3.2 配置会话
        • 3.2.1 allow_soft_placement - tf.bool
        • 3.2.2 log_device_placement - tf.bool
    • 总结

TensorFlow 基本概念详解


使用 TensorFlow, 你必须明白 TensorFlow:

  • 使用 (graph) 来表示计算任务.
  • 在被称之为会话session)的上下文 (context) 中执行图.
  • 使用tensor表示数据.
  • 通过变量(Variable)维护状态.
  • 使用feedfetch可以为任意的操作(arbitrary operation) 赋值或者从其中获取数据.

1. TensorFlow计算模型——计算图 Graph

1.1 计算图的概念

TensorFlow是一种采用数据流图(data flow graphs),即计算图,用于数值计算的开源软件库。事实上,TensorFflow的名字本身就已经告诉我们两个重要的概念了:

  • 一个是Tensor(n. 张量),在TensorFlow中张量可以简单的理解为多维数组
  • 另一个就是Flow(n. 流),表达了张量之间通过计算相互转化的过程

数据流图用「结点」 (nodes)和「」(edges)组成的有向图来描述数学运算:

  • 结点可以表示施加的数值运算,也可以表示数据输入的起点和输出的终点,或者是读取/写入持久变量(persistent variable)的终点。在计算图中,一个结点可以是一个变量Variable),可以是一个常量Constant*),也可以是一个占位符Placeholder)还可以是一个加法操作adder_node with an add-operation
  • 表示结点之间输入与输出的关系

一个计算图一般分为两个部分:

  • 定义构建计算图
  • 使用feed_dict字典馈送输入张量,运行计算图

而对于一个机器学习模型来说,则会是:

  • 构建计算图
  • 馈送输入张量
  • 更新权重并返回输出值。

下面给出的是一张非常生动的流程图,这基本上是所有 TensorFlow 机器学习模型所遵循的构建流程:
我们再次用到stage.1向量加法的代码:

import tensorflow as tf# 计算图计算的定义阶段,也成为计算图模型构建阶段
#
# 创建了一个常量op,为a
a = tf.constant([1.0, 2.0], name = "a")
# 创建了一个常量op,为b
b = tf.constant([2.0, 3.0], name = "b")
# 创建了一个加法运算op:add,输入来自于a和b的输出,add的输出结果保存在张量result中
result = a + b# 执行阶段
#
# 通过创建一个会话来执行计算
with tf.Session() as sess:sess.run(result)

下面展示了用TensorBoard画出来的向量相加的例子,这个例子构建了一个非常简单,只有三个结点的计算图:

其中,ab是两个常量(Constant),在TensorFlow中,常量都是被定义为一个固定输出的结点(方便建模)。因为我们使用的是常量,所以这里不需要使用feed_dict提供输入字典。如果我们定义的是两个占位符placeholder),则可以采用类似:

with tf.Session() as sess:sess.run(result, feed_dict={a:[1.0, 2.0], b:[2.0, 3.0]})

这样的方法提供输入,运行计算图得到result的结果。后面我们会介绍占位符feed_dict
add结点定义了一个向量加法运算,因为没有计算依赖于add得到的结果,所以add结点没有任何指向其他结点的边。所有TensorFlow的程序都可以根据类似上面的计算图的形式来表示,这就是TensorFlow的基本计算模型。

1.2 结点

我们说,计算图中的结点事实上就是一个操作(Op,Operation)
事实上,tf.Variable是Python的类,返回的是Python的实例,而不是在计算图中的一个结点。注意!大写的都是Python的类,创建的是实例!
tf.constanttf.placeholder这样的就是一个op(operation),是计算图中的一个结点。

1.2.1 常量结点 tf.constant

正如我们前面所介绍的,常量是一个非常简单的结点,固定输出。例如在向量加法的例子中,我们创建了两个常量向量:

# 创建了一个常量op,为a
a = tf.constant([1.0, 2.0], name = "a")
# 创建了一个常量op,为b
b = tf.constant([2.0, 3.0], name = "b")

并且,常量在定义之后值和维度不可以发生变化。

1.2.2 占位符 tf.placeholder 和 feed_dict

占位符和常量不同的是,占位符只是对这个结点分配了必要的内存,而没有赋任何的初值。我们可以在会话中,用feed_dict馈送数据。这对于我们更新数据有很大的帮助。如果使用的是常量结点的话,那每次开始一次新的迭代的时候,都会注册一个新的常量结点,这会导致一个非常庞大的计算图。而使用占位符的话只需要每次馈送新的数据,占位符始终只有一个结点。
假如我们使用占位符来实现我们前面的向量加法的话:

a = tf.placeholder(tf.float32)
b = tf.placeholder(tf.float32)
result = a + bwith tf.Session as sess:sess.run(result, feed_dict={a:[1.0, 2.0], b:[2.0, 3.0]})
1.2.4 操作 Operator

但是它们并不像我们所熟悉的操作(例如加法),而是特殊op类型,但却是计算图中最为基本的单位。不过,他们并没有涉及到任何的计算。真正决定一个计算图模型的功能的,是计算图的操作符节点(Operator op)。
例如,向量加法的例子中:

result = a + b

在这个过程中,在计算图中注册了一个加法结点,也就是我们上面的计算图这个结点有两个输入:一个来自a,一个来自b;我们用一个张量result来引用这个结点的输出。

我们知道,TensorFlow的数据都是存储在计算图中的。既然tf.Variable()是一个Python类,那么它就不是在计算图中,也就不会参与构造计算图。那么tf.Variable()创建的实例该怎么使用呢?

1.2.1 变量 Variable

事实上,当我们调用tf.Variable创建一个变量类时,会提供一系列操作(Op,Operation)可以用来初始化一个变量。
官方文档:Variable How To
我根据官方文档简单总结了一些变量的相关内容:TensorFlow Variable

1.3 计算图的使用

我们说TensorFlow的程序一般可以分为两个阶段:

  • 计算图中所有计算的定义
  • 执行计算

例如向量加法,在这个过程中,TensorFlow会把上面的定义都转化为计算图中的结点。在TensorFlow的程序中,系统会自动维护一个默认的计算图,通过tf.get_default_graph函数可以获取当前默认的计算图。下面代码展示了如何查看默认计算图以及如何查询一个运算所属的计算图的:

# a.graph可以查看张量a所属的计算图
print(a.graph)
# 当前的默认的计算图其实就是a所属的计算图所以下面会打印出true
print(a.graph is tf.get_default_graph)

此外我们还可以使用tf.Graph()来生成一个新的计算图对象。不同计算图上的张量和运算都不会共享。下面展示了如何在不同的计算图上定义和使用变量:

graph1 = tf.Graph()
# 把graph1当成当前默认的计算图
with graph1.as_default():# 在计算图graph1中创建变量v1,初始化为0# tf.get_variable(<name>, <shape>, <initializer>) 创建或返回给定名称的变量# shape[1] 初始化维度为1v = tf.get_variable("v", shape=[1], initializer = tf.zeros_initializer())graph2 = tf.Graph()
# 把graph2当成当前默认的计算图
with graph2.as_default():# 在计算图graph2中创建变量v1,初始化为1v = tf.get_variable("v", shape=[1], initializer = tf.ones_initializer())# 在计算图1中读取变量v的值
with tf.Session(graph = graph1) as sess:# 对所有变量进行初始化tf.initialize_all_variables().run()# 在计算图1定义的所有变量的作用范围中# reuse = True,即确定重用,如果变量已经有定义,则获取该变量,否则创建新的变量# reuse = False,始终创建新变量with tf.variable_scope("", reuse = True):# 利用会话计算出变量v的值print(sess.run(tf.get_variable("v"))
# 在计算图2中读取变量v的值
with tf.Session(graph = graph2) as sess:tf.initialize_all_variables().run()with tf.variable_scope("", resuse = True):# 用会话计算出变量v的值print(sess.run(tf.get_variable("v"))

上面出现的都是一些非常常用的用于变量共享的TensorFlow函数,以及变量的初始化函数:

  • tf.variable_scope(name_or_scope, reuse=None, intializer=None)
    这个函数会返回一个变量作用域的上下文
  • tf.get_variable(name, shpae=None, dtype=tf.float32, initializer=None, trainable=True, collections=None)
    获取一个已经存在的变量,或者是新建一个变量。
    这个方程把当前的变量作用域variable scope)的名字添加到变量名的前缀中,并且会根据tf.variable_scope函数的reuse参数是否为True,判断是否重用已经存在的变量还是创建新的变量
  • tf.initialize_all_variables()
    这个方法会返回一个op,我们可以调用.run()方法运行这个op,对所有的变量进行初始化

这里介绍了一些变量作用域相关的内容

2. TensorFlow数据模型——张量 Tensor

TensorFlow中用张量tensor)数据结构来代表所有的数据。TensorFlow中不同的结点op)之间传递的数据都是以tensor来进行的。一个结点可以有0个或者多个张量的输入以及0个或者多个张量的输出。

2.1 张量的概念

简单的理解,张量就是一个多维数组:

n阶数 张量类型
0 标量(Scalar),就是一个数,没有方向(direction)
1 向量(Vector),也就是一个一维数组,有方向
≥\ge≥ 2 n维数组

但是我们知道,我们只能获得计算图中结点(op)的输出,事实上张量只是对结点输出的引用。张量中并没有真正的保留数字,而是得到这些数字的过程。还是以stage.1中两个向量加法为例,我们将a,b相加的结果result打印:

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)

输出结果为:

我们可以看到,打印的结果并不是一个简单的向量[3.0, 5.0],而是一个张量结构:

属性attribute 值value
name 名字 “add:0”
shpae 维度 (2,)
dtype 数据类型 float32

name:这是张量的第一个属性,也是用来唯一标识张量的属性,相当于数据库中的id,所以你很容易会想到的就是:每个张量只能由一个名字,而它所来自的结点(op)也只有一个名字,因为事实上,我们打印出来的这个张量就是result对应的加法运算结点add的运算结果,保存在这个张量中,result这个张量就是结点add的一个输出。我们可以看到名字为add:0,也就是add结点的第一个输出(从0开始)
shape:很简单,就是描述张量的维度信息
dtype:每个张量具有一个唯一的数据类型。要注意,张量有唯一的类型,但是张量只是一个结点(op)的输入或者输出,这意味着,一个结点(op)可以有多种类型的输入和输出。张量的数据类型如下表:

数据类型 Python类型 描述
DT_FLOAT tf.float32 32 位浮点数.
DT_DOUBLE tf.float64 64 位浮点数.
DT_INT64 tf.int64 64 位有符号整型.
DT_INT32 tf.int32 32 位有符号整型.
DT_INT16 tf.int16 16 位有符号整型.
DT_INT8 tf.int8 8 位有符号整型.
DT_UINT8 tf.uint8 8 位无符号整型.
DT_STRING tf.string 可变长度的字节数组.每一个张量元素都是一个字节数组.
DT_BOOL tf.bool 布尔型.
DT_COMPLEX64 tf.complex64 由两个32位浮点数组成的复数:实数和虚数.
DT_QINT32 tf.qint32 用于量化Ops的32位有符号整型.
DT_QINT8 tf.qint8 用于量化Ops的8位有符号整型.
DT_QUINT8 tf.quint8 用于量化Ops的8位无符号整型.

另外,参与同一个计算的张量必须具有相同的类型,否则将会抛出异常。例如我们将上面的代码修改如下:

import tensorflow as tf
a = tf.constant([1, 2], name='a')
b = tf.constant([2.0, 3.0], name='b')
result = a + b
print(result)

输出如下:

可以看到错误信息:TypeError: Input ‘y’ of ‘Add’ Op has type float32 that does not match type int32 of argument’x’. 简单来说就是float32类型和int32类型不匹配,抛出了一个类型错误(TypeError)
这段程序唯一不一样的地方就是把第一个常量的浮点数部分去掉了,结果自动被当作了一个int32位的类型。所以建议在创建时指明类型(dtype):

a = tf.constant([1, 2], name='a', dtype=tf.float32)
b = tf.constant([2, 3], name='b', dtype=tf.float32)
result = a + b

2.2 张量的使用

可以总结为两种:

  • 对中间计算结果的引用
  • 在计算图构建完成之后获取计算结果
2.2.1 引用中间结果

事实上,我们一直在使用的向量加法例子中的常量a,b,就是中间结果的引用。如果是直接计算向量和的话,将会是这个样子的:

result = tf.constant([1, 2], name='a', dtype=tf.float32)+ tf.constant([2, 3], name='b', dtype=tf.float32)

通过转化为:

a = tf.constant([1, 2], name='a', dtype=tf.float32)
b = tf.constant([2, 3], name='b', dtype=tf.float32)
result = a + b

用a,b进行引用来使用,这样我们就不用每次都需要去使用tf.constant生成了

2.2.2 获取计算结果

我们说过,张量是一种数据结构,没有具体数字,但是,我们可以通过建立一个会话Session),调用会话的run(tensor)方法得出计算结果,例如我们前面代码中用来得到向量相加的结果:

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

输出结果如下,可以看到输出的是一个二维的向量[3. 5.]:

下面我们将进一步介绍什么是会话和会话的更多用法

3. TensorFlow运行模型——会话 Session

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

3.1 会话的创建和使用

一般来说一个会话流程如下:

# 创建一个会话
sess = tf.Session()
#
# do sth(例如向量加法)
#
# 获得运行结果
sess.run(result)
# 关闭会话释放资源
sess.close()

而更多时候,正如我们前面有提到的,我们采用Python的上下文管理器——with可以很好的解决创建和资源释放问题:

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

这样当会话退出时会自动释放资源,不需要再使用sess.close()来关闭会话了。即使出现异常,也不用担心资源没有释放的问题。
在运行会话的时候我们可以指定加入计算的计算图:

with tf.Session(graph = someGraph) as sess:# do sth

如果没有指定,则将会把计算加入默认的计算图中。对于会话来说也是,但是TensorFlow不会产生默认的会话,需要手动指定。会话当指定了默认会话之后,可以使用tf.Tensor.eval来计算一个张量的值:

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

也可以是这样:

sess = tf.Session()
# 下面具有相同的结果
# 直接在该会话中运行result的结果
print(sess.run(result))
# 将会话作为参数,指定默认会话
print(result.eval(session=sess))

但是,很多情况下,我们创建一个会话,自然希望接下来能够使用它,也就是说,我们希望我们创建的会话能够第一时间自动注册成为默认会话,而不是仍然需要我们手动指定。这时我们用到tf.InteractiveSession(),这个函数会自动将生成的会话注册成为默认会话:

is = tf.InteractiveSession()
print(result.eval())
is.close()

这样可以省去指定默认会话的过程。

3.2 配置会话

可以通过ConfigProto Protocol Buffer来配置会话:

config = tf.ConfigProto(allow_soft_placement=True,log_device_placement=True)
sess1 = tf.InteractiveSession(config=config)
sess2 = tf.Session(config=config)

可以配置的参数:

  • 并行的线程数
  • GPU分配策略
  • 运算超时时间

常用的两个,正如你在例子中看到:allow_soft_placementlog_device_placement

3.2.1 allow_soft_placement - tf.bool

当这个参数为True时,满足下面任意一个条件的话,运算将会被放置在CPU上:

  • 运算无法在GPU上进行
  • 没有GPU资源(比如运算指定在第二个GPU上,但是只有一个GPU)
  • 运算输入包含对CPU运算结果的引用

这个参数的默认值为False,但是一般在有GPU的情况下,为了增强代码的可移植性,都会设置成True

3.2.2 log_device_placement - tf.bool

当这个参数为True时,日志中将会记录每个结点被安排在了哪个设备上以方便调试。而在生产环境中将这个参数设置为False可以减少日志

总结

简单来说,TensorFlow的数据和运算都是存储在计算图当中的,通过定义计算图中的结点来构造一个计算图,可以是常量结点,占位符,或者是运算符结点,还可以定义变量,我们通过张量对这些数据和运算的结果进行引用,通过会话运行计算图,执行得到的结果(即使只是一个常量,我们也需要通过一个会话来获得它输出的张量的值)。后面我们会进一步介绍TensorFlow和神经网络相关的知识。

TensorFlow Win10 stage.3相关推荐

  1. Tensorflow Win10 stage.2

    << Tensorflow Wiin10 stage.1 Tensorflow Win10 stage.3 >> 文章目录 一,Tensorflow 的主要依赖包 1.Prot ...

  2. Anaconda+tensorflow+win10安装包和教程(2021年12月)

    安装包: Anaconda+tensorflow+win10安装包和教程.rar-机器学习文档类资源-CSDN文库 安装Anaconda3 下一步下一步即可 红色路径记得选上 使用WIn + R,打开 ...

  3. tensorflow python3.6_[教程]Tensorflow + win10 + CPU + Python3.6+ 安装教程

    由于各种原因,清华镜像源已经彻底挂掉了,但是目前网上的各种教程基本上都是采取设置清华镜像源来加快下载速度,所以这给小白带来了很大的困扰!这里我将通过合理上网工具来直接下载源镜像. 注意:本次教程适用于 ...

  4. [教程]Tensorflow + win10 + CPU + Python3.6+ 安装教程

    由于各种原因,清华镜像源已经彻底挂掉了,但是目前网上的各种教程基本上都是采取设置清华镜像源来加快下载速度,所以这给小白带来了很大的困扰!这里我将通过合理上网工具来直接下载源镜像. 注意:本次教程适用于 ...

  5. Anaconda + tensorflow + win10 安装

    就是脑子短路,趟了很多坑,感觉得写点什么(过了一小段时间才写的,可能会点遗漏). python很多工程中,经常会用到第三方库,比如numpy等.Anaconda指的是一个开源的Python发行版本,其 ...

  6. 光头老法师手持尼康却能玩出佳能的效果

    title: 光头老法师手持尼康却能玩出佳能的效果 tags: 老法师 尼康 佳能 categories: 老法师 摄影 相机品牌拍人像的奇妙比喻 相机品牌拍人像的奇妙比喻 富则与子偕老,索则齐人之妙 ...

  7. Win10 Anaconda下TensorFlow-GPU环境搭建详细教程(包含CUDA+cuDNN安装过程)(转载)...

    win7(win10也适用)系统安装GPU/CPU版tensorflow Win10 Anaconda下TensorFlow-GPU环境搭建详细教程(包含CUDA+cuDNN安装过程) 目录 2.配置 ...

  8. windows安装Python+tensorflow机器学习开发环境搭建

    2019独角兽企业重金招聘Python工程师标准>>> 安装版本: python版本:3.6.4 发布或时间: 2017-12-19 下载地址:https://www.python. ...

  9. Tensorflow + PyTorch 安装(CPU + GPU 版本)

    目录 一.Anaconda 安装 二.安装 TensorFlow-CPU 1.配置环境 2.安装 Tensorflow 三.安装TensorFlow-GPU 1.是否可安装GPU版Tensorflow ...

最新文章

  1. ubuntu上玩3D,把状态栏面板栏给玩没了
  2. ajax 在新选卡打开,JavaScript在新窗口中打开,而不是选项卡
  3. MySQL中如何修改表
  4. mysql 批量增加字段命令_sql使用命令批量给一个表添加字段
  5. Javascript 問題汇总(不定期更新)【一】
  6. Android公共jar,使用JitPack管理Android项目中公共模块库
  7. 20.校准相机——SVD技巧第1部分,SVD技巧第2部分,SVD技巧第3部分_2
  8. loss值多少才算收敛_库存究竟多少才算合理?
  9. .NET多线程编程(2)——Thread类
  10. CMU 15-213 Introduction to Computer Systems学习笔记(5) Machine-Level Programming-Control
  11. 老人机java游戏模拟器_KEmulator(JAVA手机游戏模拟器)
  12. 登录功能使用 JWT 技术
  13. Android studio 之 Menu(菜单)
  14. 怎么拼魔方6个面方法_怎么拼齐魔方6个面
  15. 无人机民航执照、多旋翼、固定翼视距内驾驶员、机长考证试题
  16. win10戴尔游侠GTX1050TI+TensorFlow-gpu+CUDA10.0.130+CUDNN7.4.1.5配置深度学习环境
  17. nginx设置代理后端服务器增加前缀
  18. [智慧供热]-论供热收费系统价值和意义?
  19. 场馆坪效这么低?关键在这两方面
  20. 电脑有线无线同时上网

热门文章

  1. vscode 中C++运行编译运行多文件问题总结
  2. wireshark手机抓包分析(一)
  3. C++中,结构体vector使用sort排序
  4. 程序化自动生成视频实现Youtube掘金
  5. linux 段错误分析
  6. SQL查询最大在线人数(通用方法)
  7. CANoe的数据回放(Replay Block),还是要结合CAPL脚本才能说的明白
  8. 关于iOS中图片处理的小结
  9. LED音乐频谱之概述
  10. 2018美团CodeM 题解