【TensorFlow】TensorFlow快速入门

TensorFlow背景

  在介绍TensorFlow(以下简称为TF)之前,我们首先了解一下相关背景。

  TF是一种机器学习框架,而机器学习经常和人工智能,深度学习联系在一起,那么三者到底是什么关系呢?

  简单来讲三者可以理解为包含于被包含的关系。其中最大的是人工智能AI,AI最早起源于1956年的达特茅斯会议,当时AI的几位先驱在会上展示了最早的AI程序:Logic Theorist,能够自动推导数学原理第二章前52个定理中的38个,甚至其中一个定理的证明过程比书中给出的还要优雅,他们甚至曾尝试要发表这一新的证明方式(不过后来被拒了)。总之,简单来说,AI就是赋予机器以人的智能,让机器具有学习和认知的能力。

  机器学习(以下简称为ML)则是实现AI的一种方法。举个简单的垃圾邮件过滤的例子,我们人类判断一个邮件是否是垃圾邮件很简单,通过标题或内容很快就可以辨别。但是让机器完成这样的任务就没这么简单。对于经典的ML算法,首先需要从原始数据(邮件)中提取特征,比如发信人地址、邮件标题、邮件内容关键词等,从而将文字的邮件转换成包含多个特征的向量,然后利用逻辑回归算法在已经标定的数据集上进行训练,得到每个特征的权重。这些权重构成我们的预测模型,对于一封新的邮件,就可以用这个模型判断其是否是垃圾邮件。

  传统的ML最大的问题就是特征提取。比如让机器识别照片中的动物是猫还是狗,如何设计特征。深度学习(以下简称为DL)正是为了解决特征提取的问题,我们不再需要人工设计特征,而是让算法从数据中自动学习特征,将简单的特征组合形成复杂的特征来解决这些问题,所以DL可以说是实现ML的一种技术。


TensorFlow简介

  什么是TensorFlow ?

  Tensorflow是一个Google开发的第二代机器学习系统,克服了第一代系统 DistBelief 仅能开发神经网络算法、难以配置、依赖Google内部硬件等局限性,应用更加广泛,并且提高了灵活性和可移植性,速度和扩展性也有了大幅提高。字面上理解,TensorFlow就是以张量(Tensor)在计算图(Graph)上流动(Flow)的方式的实现和执行机器学习算法的框架。

  TensorFlow的特点:

  • 灵活性。TensorFlow不是一个严格的“神经网络”库。只要可以将计算表示成数据流图,就可以使用TensorFlow,比如科学计算中的偏微分求解等。(实际上其官网的介绍中对TF的定位就是基于数据流图的科学计算库,而非仅仅是机器学习库)

  • 可移植性。同一份代码几乎不经过修改既可以部署到有任意数量CPU、GPU或TPU(Tensor Processing Unit,Google专门为机器学习开发的处理器)的PC、服务器或移动设备上。

  • 自动求微分。同Theano一样,TensorFlow也支持自动求微分,用户不需要再通过反向传播求解梯度。

  • 多语言支持。TensorFlow官方支持Python、C++、Go和Java接口,用户可以在硬件配置较好的机器中用Python进行实验,在资源较紧张或需要低延迟的环境中用C++进行部署。

  • 性能。虽然TensorFlow最开始发布时仅支持单机,在性能评测上并不出色,但是凭借Google强大的开发实力,TensorFlow性能已经追上了其他框架。

  Google为什么开源Tensorflow

  Google第一代分布式机器学习框架DistBelief在内部大规模使用后没有选择开源,而第二代TensorFlow于2015年11月在GitHub上开源,并在持续快速开发迭代中。TensorFlow最早由Google Brain的工程师开发,设计初衷是加速机器学习的研究,并快速地将研究原型转化为产品。Google选择开源TensorFlow的原因很简单:第一是希望借助社区的力量,大家一起完善TensorFlow。第二是回馈社区,Google希望让这个优秀的工具得到更多的应用,提高学术界和工业界使用机器学习的效率。

  自从2015年11月开源以来,TensorFlow迅速在众多的机器学习框架中脱颖而出,在Github上获得了最多的Star。下图统计了Github上流行的机器学习框架的Star数量:

  TensorFlow大事记

2015年11月9日,Google Research 发布了文章:TensorFlow - Google’s latest machine learning system, open sourced for everyone,正式宣布其新一代机器学习系统开源。

2016年4月13日,TensorFlow v0.8发布,提供分布式计算支持。

2016年4月12日,基于TensorFlow的世界最准确的语法解析器SyntaxNet宣布开源。

2016年6月27日,TensorFlow v0.9发布,提高对移动设备的支持。

2016年8月30日,TF-Slim——TensorFlow的高层库发布,用户可以更简单快速地定义模型。

2017年2月15日,TensorFlow v1.0发布,提高了速度和灵活性,并且承诺提供稳定的Python API。

  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)
f = compile(D)                          # compiles the function
d = f(A=np.ones(10), B=np.ones(10)*2)

  当前四步执行后,程序并没有A、B、C、D的值,仅仅是构建了由这四个符号构成的计算图,如下图所示:

  大多数符号式编程的程序中都或显式或隐式地包含编译的步骤,将前面定义的计算图打包成可以调用的函数,而实际的计算则发生在编译后。

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


TensorFlow基本概念

  要使用TensorFlow,我们必须理解TensorFlow:

使用图(Graph)表示计算流程
在会话(Session)中执行图
使用张量(Tensor)表示数据
使用变量(Variable)维护状态
使用feed和fetch为任意的操作赋值或从中获取数据

  TF使用graph表示计算流程。图中的节点称为操作(Operation,以下简称OP)。每个OP接受0到多个Tensor,执行计算,输出0到多个Tensor。图是对计算流程的描述,需要在Session中运行。Session将计算图的OP分配到CPU或GPU等计算单元,并提供相关的计算方法,并且会返回OP的结果。

  1、张量(Tensor)

  TF使用Tensor表示所有数据,相当于Numpy中的ndarray,0维的数值、一维的矢量、二维的矩阵到n维数组都是Tensor。相对于Numpy,TensorFlow提供了创建张量函数的方法,以及导数的自动计算。下表对比了Numpy和TensorFlow的基本用法。

  2、变量(Variable)

  在训练模型时,Variable被用来存储和更新参数。Variable包含张量储存在内存的缓冲区中,必须显式地进行初始化,在训练后可以写入磁盘。下面代码中的Variable充当了一个简单的计数器角色:

state = tf.Variable(0, name="counter")      # Create a Variable, that will be initialized to the scalar value 0.

one = tf.constant(1)                        # Create an Op to add one to `state`.

new_value = tf.add(state, one)

update = tf.assign(state, new_value)        # Variables must be initialized by running an `init` Op after having
                                            # launched the graph. We first have to add the `init` Op to the graph.
init_op = tf.initialize_all_variables()

with tf.Session() as sess:                  # Launch the graph and run the ops.

sess.run(init_op)                           # Run the 'init' op

print(sess.run(state))                      # Print the initial value of 'state'

for _ in range(3):                          # Run the op that updates 'state' and print 'state'.

sess.run(update)
# output:
# 0
# 1
# 2
# 3

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

  一般来说,用户使用一系列Variable来表示一个统计模型,在训练过程中运行图计算来不断更新,训练完成后可以使用这些Variable构成的模型进行预测。

  3、Feed

  TensorFlow除了可以使用Variable和Constant引入数据外,还提供了Feed机制实现从外部导入数据。一般Feed总是与占位符placeholder一起使用。

input1 = tf.placeholder(tf.float32)

input2 = tf.placeholder(tf.float32)

output = tf.mul(input1, input2)

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

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

  4、Fetch

  要获取操作的输出,需要执行会话的run()函数,并且提供需要提取的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)

result = sess.run([mul, intermed])

print(result)

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

  5、图和会话

  由于TF采用符号式编程模式,所以TF程序通常可以分为两部分:图的构建和图的执行。

  6、图的构建

  构建图的第一步,是创建源OP(source op),源操作不需要任何输入,例如常量(constant),源操作的输出被传递给其它操作做运算。

  Python库中,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)

  上面使用TensorFlow提供的默认图构建了包含三个节点的计算图:两个constant()操作和一个matmul()操作。要实际执行矩阵乘法,必须在Session中运行该计算图。

  7、图的执行

  要执行计算图,首先需要创建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.

result = sess.run(product)

# Close the Session when we're done.

sess.close()

  Session结束后,需要关闭以释放资源。用户也可以使用with控制语句自动关闭会话。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值