【TensorFlow】TensorFlow入门(一)——TensorFlow简介(基本理念,张量,常量变量占位符,计算图)

Tensorflow是一个Google开发,基于数据流编程(dataflow programming)的符号数学系统,被广泛应用于各类机器学习(machine learning)算法的编程实现。

TensorFlow简介

顾名思义,TensorFlow就是以张量(Tensor)在计算图(Graph)上流动(Flow)的方式的实现和执行机器学习算法的框架。它具有以下特点:

  • 灵活性。TensorFlow 不是一个严格的“神经网络”库(实际上TF的官方定位是 基于数据流图的科学计算库,而不仅仅是机器学习库)。只要可以将计算表示成数据流图,就可以使用TensorFlow,比如科学计算中的偏微分求解等。
  • 可移植性。同一份代码几乎不经过修改既可以部署到有任意数量CPU、GPU或TPU(Tensor Processing Unit,Google专门为机器学习开发的处理器)的PC、服务器或移动设备上。
  • 自动求微分。同Theano一样,TensorFlow也支持自动求微分,用户不需要再通过反向传播求解梯度。
  • 多语言支持。TensorFlow官方支持Python、C++、Go和Java接口,用户可以在硬件配置较好的机器中用Python进行实验,在资源较紧张或需要低延迟的环境中用C++进行部署。
  • 性能。虽然TensorFlow最开始发布时仅支持单机,在性能评测上并不出色,但是凭借Google强大的开发实力,TensorFlow性能已经追上了其他框架。

TensorFlow架构

在这里插入图片描述
TF的系统构架分为两部分:

  • 前端:提供编程模型,负责构造计算图,提供Python,C++,Java,Go等多种语言支持。
  • 后端:提供运行时环境,负责执行计算图,采用C++实现

用户在搭建算法时,可以根据个人喜好和实际需求采用合适的前端语言来构建计算图。图搭建完成后,以Session为桥梁连接TF的后端,启动并执行图的计算过程。TF的后端根据当前硬件环境调用Operation的Kernal(Operation在某种硬件设备的特定实现)完成具体的计算。

TensorFlow编程模式

符号式编程 vs 命令式编程

和我们一般常用的命令式(Imperative)编程模式不同,TF采用的是符号式(Symbolic)编程。我们先认识一下两种编程模式:

命令式编程 是很常见的编程模式,大多数Python或C++程序都采用命令式编程。命令式编程 明确输入变量,根据程序逻辑逐步运算。下面是一段命令式编程的Python代码:

import numpy as np
a = np.ones(10)
b = np.ones(10) * 2
c = b * a
d = c + 1

执行完第一步a = np.ones(10)后,程序得到了输入变量a,第二句后得到了b,当执行c = b * a时,程序通过乘法计算而得到了c。

符号式编程将计算过程抽象为计算图**,**即将所有输入节点、运算节点和输出节点(计算图的三个主体)均符号化处理。将上述命令式编程代码转换为符号式编程:

A = Variable('A')
B = Variable('B')
C = B * A
D = C + Constant(1)
# compiles the function
f = compile(D)
d = f(A=np.ones(10), B=np.ones(10)*2)

当前四步执行后,程序并没有A、B、C、D的值,仅仅是构建了由这四个符号构成的计算图(计算关系、计算流程),如下图所示:
在这里插入图片描述
大多数符号式编程的程序中都或显式或隐式地包含编译的步骤,将前面定义的计算图打包成可以调用的函数,而实际的计算则发生在编译后。

Theano和TensorFlow属于典型的符号式编程模式,而Torch则是命令式编程模式。在灵活性上,命令式编程模式更优,而在内存和计算上,符号式编程效率更高


TensorFlow基本理念

使用TensorFlow,我们必须了解TensorFlow:

  • 使用计算图(Graph)表示计算流程,计算图中的 节点(Nodes) 表示数学操作(Operation,op)节点的连线(edges) 表示在操作间传递流动的数据 (多维数组),即张量(tensor)
  • 会话(Session)执行图
  • 使用常量(constant)变量(variable)占位符(placeholder)三种源op向计算图中引入数据
  • 使用 Fetch 从操作中获取数据

1、张量(Tensor)

TF使用tensor表示所有数据,从0维的数值、一维的矢量、二维的矩阵到n维数组。TF中的tensor相当于Numpy中的ndarray。

Tensorflow 在设计之时参考了很多 numpy 的设计理念,故你可以感受到两者在使用上有很多相似之处。不过相比于Numpy,TensorFlow提供了创建张量函数的方法(这是什么?),以及导数的自动计算。

下表对比了Numpy和TensorFlow的基本用法。

NumpyTensorFlow
创建数组a = np.zeros((2,2)); b = np.ones((2,2))a = tf.zeros((2,2)); b = tf.ones((2,2))
求和np.sum(b, axis=1)tf.reduce_sum(a, reduction_indices=[1])
查看数组尺寸a.shapea.get_shape
数组调整形状np.reshape(a, (1, 4))tf.reshape(a, (1, 4))
数组算数运算b * 5 + 1b * 5 + 1
数组索引切片a[0,0], a[:,0}, a[0,:]a[0,0], a[:,0}, a[0,:]

2、数学操作(Operation)

计算图中的节点(Node)表示数学操作(Operation,简称OP)。类似于门单元,每个OP接受0到多个Tensor输入,执行计算,输出0到多个Tensor

常见的operation

① 算术函数

② 线性代数

3、源op

作为一种特殊的 op ,源op(source op),顾名思义,是数据的源头,作用是为计算图引入数据。具体地,源op不需要接受op输入,自己提供输出传递给其它op做运算。

TensorFlow 支持以下三种类型的源op

  • constant(常量):即 值不能改变 的量。
  • variable(变量):当一个量在会话中的 值需要更新 时,使用变量来表示。在机器学习算法中,模型参数在训练期间需要不断更新,故我们将其声明为变量类型
  • placeholder(占位符):用于将外部数据导入计算图中。在机器学习算法中,通常用于提供样本数据

1)常量(Constant)

t_1 = tf.constant(4)  # 定义一个标量常量

t_2 = tf.constant([4,3,8])  # 定义一个向量常量

tf.zeros([M,N], tf.dtype = tf.int32)  # 创建一个形状为 [M,N] 的零元素矩阵,dtype可以是 int32、float32等

tf.ones([M,N], tf.dtype)  # 创建一个形状为 [M,N]、元素均为 1 的矩阵

tf.linspace(start, stop, num)  # 创建一个从初值(start)到终值(stop),元素数目为num的等差序列

tf.range(start,limit,delta)  # 创建一个从初值(start)到终值(limit),增量为 delta(默认值 = 1)的等差数列

创建具有不同分布的随机张量

# 均值为1(默认值=0.0)和标准差为2(默认值=1.0)、形状为 [M,N] 的正态分布随机数组
tf.random_normal([3,6],mean=1,stddev=2) 
# 均值为1(默认值=0.0)和标准差为2(默认值=1.0)、形状为 [M,N] 的截尾正态分布随机数组
tf.truncated_normal([2,3],mean=2,stddev=4)
# 在种子的 [minval(default=0),maxval] 范围内创建形状为 [M,N] 的给定伽马分布随机数组
tf.random_uniform([3,6],maxval=10)

2)变量(Variable)

在机器学习中,Variable被用来存储和更新参数

与Constant不同,Variable必须显式地进行初始化。另一方面,变量可以存储在磁盘中。

变量的创建

通过将一个constant作为初始值传入构造函数Variable()来创建变量。初始值张量的shape自动成为变量的shape。

变量的初始化

变量的初始化必须在模型的其它操作运行之前先明确地完成。最简单的方法就是添加一个给所有变量初始化的操作,并在使用模型之前(会话中的第一句)首先运行那个操作。

示例代码:简单计数器

# 创建一个变量, 初始化为标量 0.
state = tf.Variable(0, name="counter")

# 创建一个 op, 其作用是使 state 增加 1

one = tf.constant(1)
new_value = tf.add(state, one) #加法运算
update = tf.assign(state, new_value) #

# 启动图后, 变量必须先经过`初始化` (init) op 初始化,
# 首先必须增加一个`初始化` op 到图中.
init_op = tf.initialize_all_variables()

# 启动图, 运行 op
with tf.Session() as sess:
	# 运行 'init' op
	sess.run(init_op)
	# 打印 'state' 的初始值
	print sess.run(state)
	# 运行 op, 更新 'state', 并打印 'state'
	for _ in range(3):
		sess.run(update)
		print sess.run(state)

# 输出:

# 0
# 1
# 2
# 3

上述代码中assign()操作同add()一样,都是在构建计算图而没有执行实际的计算。直到run()函数才会真正执行赋值等计算操作。

变量的保存、加载、选择性保存加载

  • 另外写一篇

3)占位符(placeholder)

placeholder用于引入外部数据。

placeholder一般与feed一起使用,在调用run方法时,通过使用feed_dict作为 run() 调用的参数来为占位符赋值。

feed 只在调用它的方法内有效, 方法结束, feed 就会消失。

占位符的创建

X = tf.placeholder(dtype=tf.float32, shape=[144, 10], name='X')
  • dtype:数据类型,必填,默认为value的数据类型,传入参数为tensorflow下的枚举值(float32,float64…)
  • shape:数据形状,选填,不填则随传入数据的形状自行变动,可以在多次调用中传入不同形状的数据
  • name:常量名,选填,默认值不重复,根据创建顺序为(Placeholder,Placeholder_1,Placeholder_2…)
input1 = tf.placeholder(tf.float32)
input2 = tf.placeholder(tf.float32)
output = tf.mul(input1, input2)

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

# output:
# [array([ 14.], dtype=float32)]

4、Fetch 获取数据

为了获得操作的输出值,需要执行会话sessionrun()函数,并且提供需要提取的op。我们可以同时取回多个op的值:

input1 = tf.constant([3.0])
input2 = tf.constant([2.0])
input3 = tf.constant([5.0])
intermed = tf.add(input2, input3)
mul = tf.mul(input1, intermed)

with tf.Session() as sess:
result = sess.run([mul, intermed])
print(result)

# output:
# [array([ 21.], dtype=float32), array([ 7.], dtype=float32)]

需要获取的多个 op 值,在一次运行中一起获得(而不是逐个去获取)

5、计算图(graph)

上面说了,TF采用符号式编程模式,一个TF程序通常可以分为两部分:

  1. 图的构建。使用图构建计算流程的描述
  2. 图的执行。在Session中运行实际计算。Session将计算图的op分配到CPU或GPU等计算单元,并提供相关的计算方法,并且会返回op的结果。

1)图的构建

构建计算图,需要定义所有要使用的数据,同时定义要执行的所有计算。

构建图的第一步,是创建源op(source op),例如常量(constant)源op的作用是为计算图引入数据源op 不需要接受op的输入,其输出被传递给其它op做运算。

TensorFlow Python库有一个 默认图 (default graph) ,OP构造器可以为其增加节点。这个默认图对许多程序来说已经足够用了。(不是很懂)

import tensorflow as tf

# Create a Constant op that produces a 1x2 matrix. The op is
# added as a node to the default graph.
#
# The value returned by the constructor represents the output
# of the Constant op.
matrix1 = tf.constant([[3., 3.]])

# Create another Constant that produces a 2x1 matrix.
matrix2 = tf.constant([[2.],[2.]])

# Create a Matmul op that takes 'matrix1' and 'matrix2' as inputs.
# The returned value, 'product', represents the result of the matrix
# multiplication.
product = tf.matmul(matrix1, matrix2)

上面的代码里,我们在默认图中添加了三个节点:两个constant() op和一个matmul() op。要实际执行矩阵乘法,必须在Session中运行该计算图。

2)图的执行

构造阶段完成后, 才能启动图。

要执行计算图,首先需要创建 Session(会话) 对象,在Session里将图启动。如果不提供参数,Session构造器将运行默认图。

# Launch the default graph.
sess = tf.Session()

# To run the matmul op we call the session 'run()' method, passing 'product'
# which represents the output of the matmul op. This indicates to the call
# that we want to get the output of the matmul op back.
#
# All inputs needed by the op are run automatically by the session. They
# typically are run in parallel.
#
# The call 'run(product)' thus causes the execution of three ops in the
# graph: the two constants and matmul.
#
# The output of the op is returned in 'result' as a numpy `ndarray` object.

# 调用 sess 的 'run()' 方法来执行矩阵乘法 op, 传入 'product' 作为该方法的参数.
# 上面提到, 'product' 代表了矩阵乘法 op 的输出, 传入它是向方法表明, 我们希望取回
# 矩阵乘法 op 的输出.
result = sess.run(product)
print(result)
# ==> [[ 12.]]

# Close the Session when we're done.
sess.close()

Session结束后,需要关闭以释放资源。除了显式调用 close() 外, 用户也可以使用with控制语句自动关闭会话。

with tf.Session() as sess:
result = sess.run([product])
print(result)

TensorFlow学习资料整理

[1] TensorFlow中文社区文档
[2] TensorFlow官网中文教程
[3] TensorFlow教程:TensorFlow快速入门教程(非常详细)——C语言中文网
[4] Bobby0322的TensorFlow入门极简教程

TensorFlow基础系列笔记:

【深度学习框架】TensorFlow入门教程(一)——TensorFlow简介(基本理念,张量,常量变量占位符,计算图)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值