tensorflow入门教程02-tensorflow基本概念(数据流图,张量,tensorboard)


TensorFlow程序一般分为两个阶段。

  • 第一阶段:定义计算图中所有的计算,张量计算只是构造了一个静态 图;
  • 第二阶段:执行计算,使用session.run才开始对图开始有向计算。

1 计算图————TensorFlow的计算模型

1.1 计算图的概念

TensorFlow这个单词由两部分组成:tensor代表张量,是数据模型;flow代表流,是计算模型。下面就引出Flow的具体内涵。

流动的事务具有有向性,计算图就是一个具有 “每一个节点都是计算图上的一个节点,而节点之间的边描述了计算之间的依赖关系” 性质的有向图。(计算图和数据结构这门课程中的有向图具有高度的相似性,现在可以回忆一下这段记忆)

计算图由边(表示依赖关系,又被叫做“张量”)和节点(又被叫做“神经元”、“算子”)组成。如果tensorflow程序只定义了一个Graph,那其内部包含了所有的op和tensor

1.2 计算图的使用

在TensorFlow程序中,系统会自动维护一个默认的计算图,通过tf.get_default_graph()函数可以获取这个默认的计算图。

import tensorflow as tf
a = tf.constant([1.0, 2.0], name='a')
b = tf.constant([1.0, 2.0], name='b')
result = a + b

aa
通过a.graph属性可以查看这个张量所属的计算图。因为没有特意指定,所以这个计算图应该等于当前默认的计算图
print(a.graph is tf.get_default_graph())

import tensorflow as tf
a = tf.constant([1.0, 2.0], name='a')
b = tf.constant([1.0, 2.0], name='b')
result = a + b
#任何一个图中张量的graph都在同一个默认图中
print(a.graph is tf.get_default_graph())
#True
print(result.graph is tf.get_default_graph())
#True

Tensorflow通过计算图把张量和算子等组合在一起,而在很多TensorFlow程序中,看不到Graph,这是为何?这是因为TensorFlow有个默认缺省的graph
(即Graph.as_default()),我们添加的tensor和op等都会自动添加到这个缺省计算图中,如果没有特别要求,使用这个默认缺省的Graph即可。当然,如果需要一些更复杂的计算,比如需要创建两个相互之间没有交互的模型,就需要自定义计算图。
除了使用默认的计算图,TensorFlow支持通过tf.Graph函数来生成新的计算图。TensorFlow中的计算图不仅可以隔绝张量和计算,它还提供了管理张量和计算的机制,不同计算图上的张量和运算不会共享。
以下代码示意了如何通过在不同的计算图上定义和使用变量。

import tensorflow as tf

g1 = tf.Graph()
with g1.as_default():
    v = tf.get_variable('v', shape=[1], initializer=tf.zeros_initializer)

g2 = tf.Graph()
with g2.as_default():
    v = tf.get_variable('v', shape=[1], initializer=tf.ones_initializer)
'''
tf.Graph()没有实现__enter__()方法,做不到下面那优雅pythonic的写法。
with tf.Graph() as g2:
    v = tf.get_variable('v', shape=[1], initializer=tf.ones_initializer)
    
这样写了就会抛出AttributeError异常

Traceback (most recent call last):
  File "D:/bb/TensorFlow/Untitled1.py", line 7, in <module>
    with tf.Graph() as g2:
AttributeError: __enter__
'''

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')))

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')))


输出>>>
[0.]
[1.]
注:先不要管代码是什么含义,继续往下看

如果有多个Graph,建议不使用默认的Graph,直接无视或者为其分配一个句柄,避免发生混乱

import tensorflow as tf

graph1 = tf.Graph()
graph2 = tf.Graph()  # 直接无视默认缺省的Graph
# graph2 = tf.get_default_graph() 为其分配一个句柄

with graph1.as_default():
    pass

with graph2.as_default():
    pass

2 张量————TensorFlow数据类型

2.1 张量的概念

在TensorFlow的程序中,所有的数据都通过张量(tensor)的形式表示。

张量(tensor)理解为多维数组(multidimensional array),0阶张量是标量(scalar),1阶是向量(vector)(即一维数组),2阶是二维数组,n阶为n维数组。

TensorFlow的运算结果不是一个数,而是一个张量结构。(运算和运行在tensorflow语境中不同,运算就是用过运算符操作,运行就和会话有关,3.3会提到)

import tensorflow as tf

a = tf.constant([1.0, 2.0], name='a')
b = tf.constant([1.0, 2.0], name='b')

result = tf.add(a, b, name='add')

print(result)

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

一个张量保存了三个属性:名字(name)、维度(shape)和类型(type)

  1. 名字name:一个张量的唯一标识符以及这个张量是如何计算出来的。
    张量的命名形式:“node:src_output”,node为节点的名称,src_output表示当前张量来自来自节点的第几个输出。
    比如上面的代码的输出"add:0"说明张量result是计算节点“add”输出的第一个结果(编号从0开始)
    张量和计算图上节点的计算结果是一一对应的。

  2. 维度shape:描述了一个张量的维度信息。
    上面样例的shape(2,)表示一个一维数组,这个数组的长度是2。

  3. 类型type:每一个张量都有一个唯一的类型,常用的是tf.int32,tf.float32。参与运算的张量需要保持数据类型相同,不然会报错。
    TensorFlow支持的14种数据类型:

有符号整型

  • tf.int8:8位整数
  • tf.int16:16位整数
  • tf.int32:32位整数
  • tf.int64:64位整数
    无符号整型
  • tf.uint8:8位无符号整数
  • tf.uint16:16位无符号整数
    浮点型
  • tf.float16:16位浮点数
  • tf.float32:32位浮点数
  • tf.float64:64位浮点数
  • tf.double:等同于tf.float64
    字符串型
  • tf.string:字符串
    布尔型
  • tf.bool:布尔型
    复数型
    tf.complex64:64位复数
    tf.complex128:128位复数
    TensorFlow数据类型和Python原生数据类型的关系

TensorFlow接受了Python自己的原生数据类型,例如Python中的布尔值类型,数值数据类型(整数,浮点数)和字符串类型。单一值将转换为0维张量(标量),列表值将转换为1维张量(向量),列表套列表将被转换成2维张量(矩阵)

TensorFlow数据类型和Numpy数据类型的关系

你可能已经注意到了Numpy和TensorFlow有很多相似之处。TensorFlow在设计之初就希望能够与Numpy有着很好的集成效果。Numpy软件包现在已经成为数据科学的通用语言。

TensorFlow数据类型很多也是基于Numpy的,事实上,如果你令 np.int32==tf.int32将会返回True.你也可以直接传递Numpy数据类型直接给TensorFlow中的ops。

tf.ones([2, 2], np.float32) ==> [[1.0 1.0], [1.0 1.0]]
请记得,我们的好朋友会话tf.Session.run(),要求的输入对象是一个Tensor但是它的输出是一个Numpy数组。事实上,在绝大多数场合,你可以同时混合使用TensorFlow类型和Numpy类型。

2.2 张量的使用

张量使用可以归结为两大类。

  1. 第一类对中间计算结果的引用,提升代码的可读性

使用张量和不使用张量的对比

import tensorflow as tf

#使用张量记录

a = tf.constant([1.0, 2.0], name='a')
b = tf.constant([1.0, 2.0], name='b')
result1 = a + b

不使用张量,简洁但是可读性降低

result2 = tf.constant([1.0, 2.0], name='a') + tf.constant([1.0, 2.0], name='b')

#jie'guo'xiang't
print(result1)
print(result2)

输出>>>
Tensor("add:0", shape=(2,), dtype=float32)
Tensor("add_1:0", shape=(2,), dtype=float32)
  1. 第二类情况是计算图构造完成后,张量可以用来获取计算结果
    使用tf.Session().run(result)语句可以得到计算结果

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

3.1会话的概念

计算图描述计算
张量是组织数据
会话执行定义好的运算

会话管理TensorFlow程序运行时的所有资源,并在运行结束后释放所有的资源。

会话机制类似于计算图机制:
计算图:在一开始就有一个默认的计算图存在,并且没有特别指定,运算会自动加入到这个默认的计算图中
会话:会要手动创建,张量自动添加。

3.2会话的使用

TensorFlow使用会话模式有两种方式

1.普通模式

import tensorflow as tf

加入了一个异常处理机制,确保释放资源

try:
    sess = tf.Session()  # 创建一个会话
    sess.run(...)  # 运行,得到计算结果
except Exception:
    pass
finally:
    sess.close()  # 关闭会话,释放资源

2.上下文模式
这才是pythonic的写法,极力推荐

import tensorflow as tf

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

运行到这个位置会自动释放sess的资源,优雅尼克
这是2.2程序的引用,会话的写法多种多样,我们应用最优雅、最pythinc的代码去阐述。

import tensorflow as tf

a = tf.constant([1.0, 2.0], name='a')
b = tf.constant([1.0, 2.0], name='b')

result = tf.add(a, b, name='add')

with tf.Session() as sess:
   # tf.Session.run(),要求的输入对象是一个Tensor但是它的输出是一个Numpy数组
   print(sess.run(result))

输出>>>
[2. 4.]

4 其他基本概念——常量、变量、占位符

4.1 常量

Python中使用常量很简单,如a=123,b=‘python’。TensorFlow表示常量稍微麻烦一点,需要使用tf.constant这个类,具体格式如下:

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

其中各参数说明如下:

  • value : 一个dtype类型(如果指定了)的常量值(列表)。要注意的是,若value是一个列表,那么列表的长度不能够超过形状参数指定的大小(如果指定了)。如果列表长度小于指定的大小,那么多余的空间由列表的最后一个元素来填充。
  • dtype : 返回的tensor的类型
  • shape : 返回的tensorflow的形状
  • name : tensor的名字
  • verify_shape : 布尔值,用于验证值的形状。
    示例如下:
import tensorflow as tf

构建计算图
a = tf.constant('something', name='a')

print(a)

with tf.Session() as sess:  # 创造会话
   result = sess.run(a)  # 在会话中执行张量a
   print(result)


输出>>>
Tensor("a:0", shape=(2,), dtype=float32)
b'something'

4.2 变量

变量是TensorFlow中的核心概念,创建一个类使用tf.Variable,具体格式如下:

tf.Variable(initial_value=None,trainable=None,collections=None,validate_shape=True,caching_device=None,name=None,variable_def=None,dtype=None,expected_shape=None,import_scope=None,constraint=None,use_resource=None,synchronization=VariableSynchronization.AUTO, aggregation=VariableAggregation.NONE,shape=None)

主要参数说明:

  • initial_value :一个 Tensor类型或者是能够转化为Tensor的python对象类型。它是这个变量的初始值。这个初始值必须指定形状信息,不然后面的参数validate_shape需要设置为False。当然,也能够传入一个无参数可调用并且返回指定初始值的对象,在这种情况下,dtype必须指定。
  • trainable :如果设置为True (默认也为True),这个变量可以被优化器类(optimizer)自动修改Variable的值;如果设置为False,则说明Variable 只能手工修改,不允许使用优化器类自动修改。
  • collections :图的collection键列表,新的变量被添加到这些collection 中。默认是
  • validate_shape :如果是False的话,就允许变量能够被一个形状未知的值初始化,默认是True,表示必须知道形状。
  • caching_device :可选,描述设备的字符串,表示哪个设备用来为读取缓存。默认是变量的device。
  • name :可选,变量的名称。
  • dtype :如果被设置,初始化的值就会按照这里的类型来定。

4.2.1.创建变量

1.现在让我们使用tf.Variable()创建变量,这是最简单的、最常用的变量创建方法。用的最多的两个参数initial_value和name

import tensorflow as tf

girl = tf.Variable('安静宇', name='big')  # 这个name大有作用,后面会讲到,需要注意的是,name的值不可以是中文,中文会报错

god = tf.Variable('安静宇', name='big')  # 使用tf.Variable()创建的实例,实例名是唯一标识符( Variable()内的参数都可以重复 )

写作girl = tf.Variable('安静宇', name='big'),就会覆盖第一个girl

print('initializer', girl.initializer)
print('initial_value', girl.initial_value)
print('graph', girl.graph)
print('shape', girl.shape)
print('name', girl.name)
print('dtype', girl.dtype)
print('value', girl.value())

'''
输出>>>
initializer name: "big/Assign"
op: "Assign"
input: "big"
input: "big/initial_value"
attr {
 key: "T"
 value {
   type: DT_STRING
 }
}
attr {
 key: "_class"
 value {
   list {
     s: "loc:@big"
   }
 }
}
attr {
 key: "use_locking"
 value {
   b: true
 }
}
attr {
 key: "validate_shape"
 value {
   b: true
 }
}

initial_value Tensor("big/initial_value:0", shape=(), dtype=string)
graph <tensorflow.python.framework.ops.Graph object at 0x000001DF1B542EF0>
shape ()
name big:0
dtype <dtype: 'string_ref'>
value Tensor("big/read:0", shape=(), dtype=string)

2.除了使用tf.Variable()创建变量,还有一个孪生兄弟,tf.get_variable(),他两的业务逻辑还是很不一样的,使用的唯一标识符不一样,前者使用实例名作为唯一标志,后者使用name参数作为唯一标志。

具体用法可以参考这篇博客Variable和get_variable的用法以及区别

按照习惯,get开头的函数都是“查询”、“获取”的意思,但是tf.get_variable()是创建变量,get取的是“创建”的意思

4.2.2.初始化变量

tensorflow中,程序存在变量,在使用前必须初始化

初始化变量有两个方法

一个一个手动初始化
一次性全局初始化
手动初始化就是

ses.run(var1.initializer)
ses.run(var2.initializer)
ses.run(var3.initializer)
一次性全局初始化只要使用一个函数 tf.global_variables_initializer()

init_op = tf.global_variables_initializer()
sess.run(init_op)
贴一个完整代码

import tensorflow as tf

girl = tf.Variable('aa', name='cute')

god = tf.Variable('aa', name='pretty')

with tf.Session() as sess:
   # 必须先初始化变量才能使用,tf.global_variables_initializer()可以初始化所有的变量
   sess.run(girl.initializer)
   sess.run(god.initializer)
   # 等价于 sess.run(tf.global_variables_initializer())
   print(sess.run(girl).decode())
   print(sess.run(god).decode())

输出>>>
aa
aa

4.3 placeholder占位符

在tensorflow中,有一个机制叫做placeholder,首先创建变量但是不进行赋值,在最后sess.run(op,feed_dict={ } )用feed_dict进行赋值操作,

import tensorflow as tf
 
input1=tf.placeholder(tf.float32)
input2=tf.placeholder(tf.float32)
output=tf.multiply(input1,input2)
 
with tf.Session() as sess:
	print(sess.run(output,feed_dict={input1:[7.],input2:[2.]})

5 tensorboard

tensorflow强大功能之一可以将数据整个静态图运行之后的过程用图像方式 展现出来,可以更加直观分析整个数据流图。

5.1 简介

Tensorflow,简单的说,就是tensor(张量)数据在图中flow(流动)计算(op)的过程。
官方数据流图:

在这里插入图片描述

5.2 案例

模拟使用几个数计算获取结果的图

import tensorflow as tf
#可以将一组操作定义一个scope 会合并到一个圆方形中。
with tf.name_scope('graph') as scope:
    a = tf.constant(11.8, name='a')  # 这里定义名字都会显示在对应快图中 方便定位
    b = tf.constant(12.8, name='b')
    x= tf.placeholder(dtype=tf.float32,name="x")
    result = tf.add(tf.multiply(a,x) , b)
with tf.Session() as session:
    writer=tf.summary.FileWriter("./graph",session.graph)
    session.run(tf.global_variables_initializer())
    result=session.run(result,feed_dict={x:10})
    print(result)
    writer.close() # 关闭时写入内存,否则它每隔120s写入一次

运行完成 后 在当前目录graph目录下生成日志文件 ,使用命令 tensorboard --logdir ./graph

E:\workspace\machinelearn\tensor_base\教程记录>tensorboard --logdir ./graph
TensorBoard 1.11.0 at http://jiaozi-PC:6006 (Press CTRL+C to quit)

浏览器访问localhost:6006
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值