TensorFlow入门教程

简介

TensorFlow是目前最流行的深度学习框架。咱们先引用一段官网对于TensorFlow的介绍,来看一下Google对于它这个产品的定位。node

TensorFlow™ is an open source software library for numerical computation using data flow graphs. Nodes in the graph represent mathematical operations, while the graph edges represent the multidimensional data arrays (tensors) communicated between them. The flexible architecture allows you to deploy computation to one or more CPUs or GPUs in a desktop, server, or mobile device with a single API.python

上文并无提到大红大紫的Deep Learning,而是聚焦在一个更普遍的科学计算应用领域。引文的关键词有:算法

  • Numerical Computation:应用领域是数值计算,因此TensorFlow不只能支持Deep Learning,还支持其余机器学习算法,甚至包括更通常的数值计算任务(如求导、积分、变换等)。segmentfault

  • Data Flow Graph:用graph来描述一个计算任务。数组

  • Node:表明一个数学运算(mathmatical operations,简称ops),这里面包括了深度学习模型常常须要使用的ops。网络

  • Edge:指向node的edge表明这个node的输入,从node引出来的edge表明这个node的输出,输入和输出都是multidimensional data arrays,即多维数组,在数学上又称之为tensor。这也是TensorFlow名字的由来,表示多维数组在graph中流动。session

  • CPUs/GPUs:支持CPU和GPU两种设备,支持单机和分布式计算。框架

TensorFlow提供多种语言的支持,其中支持最完善的是Python语言,所以本文将聚焦于Python API。dom

Hello World

下面这段代码来自于TensorFlow官网的Get Started,展现了TensorFlow训练线性回归模型的能力。机器学习

import tensorflow as tf
import numpy as np

# Create 100 phony x, y data points in NumPy, y = x * 0.1 + 0.3
x_data = np.random.rand(100).astype(np.float32)
y_data = x_data * 0.1 + 0.3

# Try to find values for W and b that compute y_data = W * x_data + b
# (We know that W should be 0.1 and b 0.3, but TensorFlow will
# figure that out for us.)
W = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
b = tf.Variable(tf.zeros([1]))
y = W * x_data + b

# Minimize the mean squared errors.
loss = tf.reduce_mean(tf.square(y - y_data))
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)

# Before starting, initialize the variables.  We will 'run' this first.
init = tf.global_variables_initializer()

# Launch the graph.
sess = tf.Session()
sess.run(init)

# Fit the line.
for step in range(201):
    sess.run(train)
    if step % 20 == 0:
        print(step, sess.run(W), sess.run(b))

# Learns best fit is W: [0.1], b: [0.3]

下面咱们来剖析一下关键代码。TensorFlow的代码每每由两个部分组成:

A construction phase, that assembles a graph, and an execution phase that uses a session to execute ops in the graph.

Session是一个类,做用是把graph ops部署到Devices(CPUs/GPUs),并提供具体执行这些op的方法。

为何要这么设计呢?考虑到Python运行性能较低,咱们在执行numerical computing的时候,都会尽可能使用非python语言编写的代码,好比使用NumPy这种预编译好的C代码来作矩阵运算。在Python内部计算环境和外部计算环境(如NumPy)切换须要花费的时间称为overhead cost。对于一个简单运算,好比矩阵运算,从Python环境切换到Numpy,Numpy运算获得结果,再从Numpy切回Python,这个成本,比纯粹在Python内部作同类运算的成本要低不少。可是,一个复杂数值运算由多个基本运算组合而成,若是每一个基本运算来一次这种环境切换,overhead cost就不可忽视了。为了减小来回的环境切换,TensorFlow的作法是,先在Python内定义好整个Graph,而后在Python外运行整个完整的Graph。所以TensorFlow的代码结构也就对应为两个阶段了。

Build Graph

W = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
b = tf.Variable(tf.zeros([1]))

tf.Variable是TensorFlow的一个类,是取值可变的Tensor,构造函数的第一个参数是初始值initial_value

initial_value: A Tensor, or Python object convertible to a Tensor, which is the initial value for the Variable.

tf.zeros(shape, dtype=tf.float32, name=None)是一个op,用于生成取值全是0的Constant Value Tensor

tf.random_uniform(shape, minval=0, maxval=None, dtype=tf.float32, seed=None, name=None)是一个op,用于生成服从uniform distribution的Random Tensor

y = W * x_data + b

y是线性回归运算产生的Tensor。运算符*+,等价为tf.multiple()tf.add()这两个TensorFlow提供的数学类ops。tf.multiple()的输入是W和x_data;W是Variable,属于Tensor,能够直接做为op的输入;x_data是numpy的多维数组ndarray,TensorFlow的ops接收到ndarray的输入时,会将其转化为tensor。tf.multiple()的输出是一个tensor,和b一块儿交给optf.add(),获得输出结果y。

至此,线性回归的模型已经创建好,但这只是Graph的一部分,还须要定义损失。

loss = tf.reduce_mean(tf.square(y - y_data))

loss是最小二乘法须要的目标函数,是一个Tensor,具体的op再也不赘述。

optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)

这一步指定求解器,并设定求解器的最小化目标为损失。train表明了求解器执行一次的输出Tensor。这里咱们使用了梯度降低求解器,每一步会对输入loss求一次梯度,而后将loss里Variable类型的Tensor按照梯度更新取值。

init = tf.global_variables_initializer()

Build Graph阶段的代码,只是在Python内定义了Graph的结构,并不会真正执行。在Launch Graph阶段,全部的变量要先进行初始化。每一个变量能够单独初始化,但这样作有些繁琐,因此TensorFlow提供了一个方便的函数global_variables_initializer()能够在graph中添加一个初始化全部变量的op。

When you launch the graph, variables have to be explicitly initialized before you can run Ops that use their value. All variables are automatically collected in the graph where they are created. By default, the constructor adds the new variable to the graph collection GraphKeys.GLOBAL_VARIABLES. The convenience function global_variables() returns the contents of that collection. The most common initialization pattern is to use the convenience function global_variables_initializer() to add an Op to the graph that initializes all the variables.

Launch Graph

sess.run(init)

在进行任何计算之前,先给Variable赋初始值。

for step in range(201):
    sess.run(train)

train操做对应梯度降低法的一步迭代。当step为0时,train里的variable取值为初始值,根据初始值能够计算出梯度,而后将初始值根据梯度更新为更好的取值;当step为1时,train里的variable为上一步更新的值,根据这一步的值能够计算出一个新的梯度,而后将variable的取值更新为更好的取值;以此类推,直到达到最大迭代次数。

print(step, sess.run(W), sess.run(b))

若是咱们将sess.run()赋值给Python环境的变量,或者传给Python环境的print,能够fetch执行op的输出Tensor取值,这些取值会转化为numpy的ndarray结构。所以,这就须要一次环境的切换,会增长overhead cost。因此咱们通常会每隔必定步骤才fetch一下计算结果,以减小时间开销。

基础练习:线性模型

TensorFlow是一个面向数值计算的通用平台,能够方便地训练线性模型。下面这几篇文章采用TensorFlow完成Andrew Ng主讲的Deep Learning课程练习题,提供了整套源码。

进阶练习1:深度学习

TensorFlow虽然是面向通用的数值计算,可是对深度学习的支持是它最大的特点,也是它可以引爆业界得到目前这么大的流行度的主要缘由。下面这几篇文章采用TensorFlow对MNIST进行建模,涵盖了Deep Learning中最重要的两类模型:卷积神经网络CNN和循环神经网络RNN。

进阶练习2:TensorBoard

TensorFlow安装时自带了一个TensorBoard,能够对数据集进行可视化地探索分析,能够对学习过程进行可视化,能够对Graph进行可视化,对于咱们分析问题和改进模型有极大的帮助。

部署

相关文章
相关标签/搜索