python中的常量是指_第1话 TensorFlow基础概念 (计算图、张量、会话、常量、变量、占位符)...

(代码基于tensorflow 1.14 cpu版本,读者需要具有良好的python基础和线性代数知识)

第三章主要介绍TensorFlow的计算模型、数据模型和运行模型,对TensorFlow的工作原理能有一个大致了解。

TensorFlow程序一般分为两个阶段。第一阶段:定义计算图中所有的计算,然后定义一个计算来得到他们的和;第二阶段:执行计算。

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

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

print(a.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

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)

名字name:一个张量的唯一标识符以及这个张量是如何计算出来的。

张量的命名形式:“node:src_output”,node为节点的名称,src_output表示当前张量来自来自节点的第几个输出。

比如上面的代码的输出"add:0"说明张量result是计算节点“add”输出的第一个结果(编号从0开始)

张量和计算图上节点的计算结果是一一对应的。

维度shape:描述了一个张量的维度信息。

上面样例的shape(2,)表示一个一维数组,这个数组的长度是2。

类型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)

'''

2.第二类情况是计算图构造完成后,张量可以用来获取计算结果

使用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

shape ()

name big:0

dtype

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('安静宇', name='cute')

god = tf.Variable('安静宇', 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())

'''

输出>>>

安静宇

安静宇

'''

4.2.3.保存和恢复变量

最后给你们看看安静宇

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值