【翻译】TensorFlow入门文档

阅读英语原文, 点击这里
这篇文档会教你如何用TF(TensorFlow)编程。在开始这篇文档之前,请先 安装TensorFlow。为了能够很好的学习这篇文档,你需要有以下了解:
  • Python编程;
  • 至少有一些矩阵的了解;
  • 最好有一些机器学习的了解。如果你对机器学习知之甚少,那这篇文档也是你该阅读入门的文档。

TensorFlow提供了许多种类的API,最底层的API(TensorFlow核心)提供完全的编程控制。建议那些机器学习的研究人员或者对底层核心模块有很深了解的开发者使用TF(TensorFlow,下同)核心。上层的API是基于底层的API构建起来的。上层的API比底层核心更容易学习和使用。另外,对于不同的用户,上层的API能让重复的任务更简单和一致。诸如tf.contrib.learn,这些上层api能帮助你管理好数据集(data sets),估计量(estimators),训练(training)和推理(inference)。注意一点,一些上层的API(他们的方法中包含contrib的字样)仍然在开发阶段。这些“contrib”的方法在随后的TF版本中有可能改变,也有可能遗弃。

文档开始会介绍一些TF的核心,之后会演示用 tf.contrib.learn来实现相同模型。在使用更紧凑的上层API时,了解一些TF核心原理,会让你更清楚TF的内部工作原理。

张量(Tensors)
在TF中,主要的数据单元就是张量,一个张量由一组的原始数据组成,这些数据被变换成一个不同维度的矩阵。一个张量的秩(Rank)就是他的维度的值,以下是一些张量的例子:
3# a rank 0 tensor; this is a scalar with shape []
[1.,2.,3.]# a rank 1 tensor; this is a vector with shape [3]
[[1.,2.,3.],[4.,5.,6.]]# a rank 2 tensor; a matrix with shape [2, 3]
[[[1.,2.,3.]],[[7.,8.,9.]]]# a rank 3 tensor with shape [2, 1, 3]



TensorFlow核心的指导

导入TensorFlow

典型导入TensorFlow的语句如下所示:
import tensorflow as tf
这条语句给编程者所有tf类,方法,符合的使用权限,下面的大部分语句,都是需要做这个操作。

计算图(The Computational Graph)

你可以认为TF核心程序的运行是由两个独立的部分组成的:
1.构建计算图
2.执行计算图
计算图是由一系列被放入计算图节点的TF运算组成,下面构建一个简单的运算图,一个节点有输入和输出,一个或者多个张量作为输入,有些情况下,也可以没有输入,经过运算后,输出一个张量。有一个节点的类型是常数(constant),像所有tf的常数类型一样,常数(constant)作为一个节点时,它不会有输入,他输出一个存储在它内部的值,如下所示,我们创建2个(float)浮点型张量node1 , node2:
node1 = tf.constant(3.0, tf.float32)
node2
= tf.constant(4.0)# also tf.float32 implicitly
print(node1, node2)
最后的print函数输出如下结果:

Tensor
("Const:0", shape=(), dtype=float32)Tensor("Const_1:0", shape=(), dtype=float32)

要注意的是,它不是按照你的想法输出 3.0,4.0这两个值。相反的,这两个节点(node)在求值(evaluate)时,会分别输出3.0 ,4.0。事实上,求节点的值,我们必须让计算图在会话(session)里面运行,会话封装(encapsulates )了TF运行环境的控制和状态。

下面的代码创建了一个会话对象,然后调用了run方法去执行计算图来计算node1和node2节点,在一个会话中执行计算图实例代码如下:
sess = tf.Session()
print(sess.run([node1, node2]))
这里我们会看到我们期待的结果,3.0 ,4.0:
[3.0,4.0]
我们能用张量节点执行更多复杂的计算。例如,把两个节点相加形成一个新的计算图:
node3 = tf.add(node1, node2)
print("node3: ", node3)
print("sess.run(node3): ",sess.run(node3))
最后两行print语句输出结果如下:
node3:  Tensor("Add_2:0", shape=(), dtype=float32)
sess
.run(node3):  7.0
TF提供一个功能叫做TensorBoard,这个功能可以显示一个计算图的图片,这里有一个图片显示TensorBoard形象化表示计算图的构成:


就现在的情况来说,这个图并不是十分有意义,因为它始终产生一个固定的数值。一个图可以用placeholders参数化来接受外部的输入,占位符(placeholders)表示占有这个输入,向程序保证,后面会提供一个值
a = tf.placeholder(tf.float32)
b
= tf.placeholder(tf.float32)
adder_node
= a + b  # + provides a shortcut for tf.add(a, b)

这三行的定义有点像一个函数或者匿名函数,这个函数定义两个输入参数,和作用在这个两个参数上的操作。可以用feed_dict(字典)指定张量,这些张量将具体的值传递给placeholder(占位符):
print(sess.run(adder_node,{a:3, b:4.5}))
print(sess.run(adder_node,{a:[1,3], b:[2,4]}))
输出结果:
7.5
[3. ,  7.]
在TensorBoard里面,图是下面这个样子

接下来我们再添加另外一个运算,让这个图变得更复杂,如下:
add_and_triple = adder_node *3.
print(sess.run(add_and_triple,{a:3, b:4.5}))
产生结果:
22.5
在TensorBoard中,以上的计算图就会像下图所示:


在机器学习中,一般情况下,我们都需要一个可以接受任意输入的模块,就像上面的计算图那样。为了让模块具有训练能力,我们需要修正模块,以便它有相同的输入时有不同的输出。Variables可以让我们把一个可训练的参数加入到一个图。它需要用一个类型和初始值来构建:
W = tf.Variable([.3], tf.float32)
b
= tf.Variable([-.3], tf.float32)
x
= tf.placeholder(tf.float32)
linear_model
= W * x + b

常量在调用tf.constant的时候,被初始化,并且他们的值永远不会被改变,然而,variables不会在你调用tf.Variable的时候初始化。如果要初始化一个variable变量,那么你必须明确的调用一个特别的方法,如下所示:
init = tf.global_variables_initializer()
sess
.run(init)
要着重了解到init是一个TensorFlow子图的一个句柄,这个图可以初始化所有的全局变量。当执行Session.run时,这些变量才被初始化。
由于x是一个占位符,我们在求linear_model的值的同时,我们可以赋予x许多不同的值: 
print(sess.run(linear_model,{x:[1,2,3,4]}))

输出:
[0.          0.30000001  0.60000002  0.90000004]

        我们创建了一个模型,但是我们还不知道它的正确性,为了评估这个模型对于在训练数据上的正确性,我们需要一个占位符y,来提供一个期望的数值,并且我们需要写一个损失函数(loss function)。
损失函数测量现在的模型与提供的数据之间的差距,我们对线性回归(linear regression)用一个标准的损失模型,这个损失计算的是现模型估计出来的值与实际值之间的差平方的和。 linear_model - y 构建了一个由各个元素与他们对应的样本之间的误差组成的向量。我们调用tf.square方法来求误差的平方,然后我们会把所有的差平方加起来创建一个标量,用tf.reduce_sum提前了所有样本的误差:
y = tf.placeholder(tf.float32)
squared_deltas
= tf.square(linear_model - y)
loss
= tf.reduce_sum(squared_deltas)
print(sess.run(loss,{x:[1,2,3,4], y:[0,-1,-2,-3]}))

输出损失值:
23.66

我们可以重新再手动分配一个完美的数值给 W 和 b这两个值。一个变量可以用tf.Variable来初始化,但是可以用tf.assgin来改变变量的值。比如:对于我们这个模型来说,W=-1和b=1是最完美的参数,我们可以通过如下代码来改变W 和 b的值:
fixW = tf.assign(W,[-1.])
fixb
= tf.assign(b,[1.])
sess
.run([fixW, fixb])
print(sess.run(loss,{x:[1,2,3,4], y:[0,-1,-2,-3]}))

最后输出损失值现在是
0.0
我们认为这对于W 和 b 是最完美的值。但是机器学习的重点就是程序自动找到这个正确的模型参数。我们会 下一节 示这一功能的实现。

tf.train API
在这个一部分,不会去讨论一个完整的机器学习,然而,TF提供优化器(optimiziers)来缓慢改变各个变量的值来让损失函数最小化。最简单的优化器是梯度下降法(gradient descent)。它根据变量损失函数的导数大小来调整这个变量值,总的来说,计算一个带符号的导数是乏味而且容易出错的,因此,TF中的tf.gradients能根据你给的模型来自动的产生导数.
optimizer = tf.train.GradientDescentOptimizer(0.01)
train
= optimizer.minimize(loss)
sess.run(init)# reset values to incorrect defaults.
for i in range(1000):
  sess
.run(train,{x:[1,2,3,4], y:[0,-1,-2,-3]})

print(sess.run([W, b]))

输出结果:

[
array([-0.9999969], dtype=float32), array([0.99999082],
 dtype
=float32)]
现在我们已经完成了一个真正的机器学习,虽然这个简单的线性回归没需要许多TF代码,更复杂的模型和方法需要输入数据时,就需要更多编程。因此TF提供更上层的共同性的结构和功能化的抽象(abstraction)。我们会在下一节学习这些抽象概念。

完整的代码
以下是一个完整的可训练的线性回归模型:
import numpy as np
import tensorflow as tf

# Model parameters
W
= tf.Variable([.3], tf.float32)
b
= tf.Variable([-.3], tf.float32)
# Model input and output
x
= tf.placeholder(tf.float32)
linear_model
= W * x + b
y
= tf.placeholder(tf.float32)
# loss
loss
= tf.reduce_sum(tf.square(linear_model - y))# sum of the squares
# optimizer
optimizer
= tf.train.GradientDescentOptimizer(0.01)
train
= optimizer.minimize(loss)
# training data
x_train
=[1,2,3,4]
y_train
=[0,-1,-2,-3]
# training loop
init
= tf.global_variables_initializer()
sess
= tf.Session()
sess
.run(init)# reset values to wrong
for i in range(1000):
  sess
.run(train,{x:x_train, y:y_train})

# evaluate training accuracy
curr_W
, curr_b, curr_loss  = sess.run([W, b, loss],{x:x_train, y:y_train})
print("W: %s b: %s loss: %s"%(curr_W, curr_b, curr_loss))
它的执行结果如下:
W:[-0.9999969] b:[0.99999082] loss:5.69997e-11

更复杂的程序都可以在TensorBoard中显示出计算图来:



tf.contrib.learn
tf.contrib.learn是一个上层的TF库,这个库简化了机器学习的结构,简化以下步骤:
  • 执行训练循环
  • 执行求职循环
  • 管理数据集
  • 管理数据输入(feeding)
    tf.contrib.learn定义了许多共通的模块。

    基本使用
    用tf.contrib.learn会发现线性回归简单太多了:
    import tensorflow as tf
    # NumPy is often used to load, manipulate and preprocess data.
    import numpy as np

    # Declare list of features. We only have one real-valued feature. There are many
    # other types of columns that are more complicated and useful.
    features
    =[tf.contrib.layers.real_valued_column("x", dimension=1)]

    # An estimator is the front end to invoke training (fitting) and evaluation
    # (inference). There are many predefined types like linear regression,
    # logistic regression, linear classification, logistic classification, and
    # many neural network classifiers and regressors. The following code
    # provides an estimator that does linear regression.
    estimator
    = tf.contrib.learn.LinearRegressor(feature_columns=features)

    # TensorFlow provides many helper methods to read and set up data sets.
    # Here we use `numpy_input_fn`. We have to tell the function how many batches
    # of data (num_epochs) we want and how big each batch should be.
    x
    = np.array([1.,2.,3.,4.])
    y
    = np.array([0.,-1.,-2.,-3.])
    input_fn
    = tf.contrib.learn.io.numpy_input_fn({"x":x}, y, batch_size=4,
                                                  num_epochs
    =1000)

    # We can invoke 1000 training steps by invoking the `fit` method and passing the
    # training data set.
    estimator
    .fit(input_fn=input_fn, steps=1000)

    # Here we evaluate how well our model did. In a real example, we would want
    # to use a separate validation and testing data set to avoid overfitting.
    estimator
    .evaluate(input_fn=input_fn)
    执行结果:
    {'global_step':1000,'loss':1.9650059e-11}

    定制模块
    tf.contrib.learn不会让你固定得使用它预先定义好的模型,    假设我们想要创建一个定制模型,这个模型不是在TF的函数中构建,我们仍然可以保留上层tf.contrib.learn的一些数据集,输入,训练的抽象概念。为了进行说明,我们仍然做一个线性回归的等价模型,但是我们运用的是底层tf api 。
    定义一个基于tf.contrib.learn的定制模块,需要用到tf.contrib.learn.Estimator。tf.contrib.learn.LinearRegressor 事实上是tf.contrib.learn.Estimator的一个子类,我们不用这个这个子类,在定制的过程中,我们直接定义一个模块,让它来传递估值,训练步骤,和损失函数给tf.contrib.learn :
    import numpy as np
    import tensorflow as tf
    # Declare list of features, we only have one real-valued feature
    def model(features, labels, mode):
     
    # Build a linear model and predict values
      W
    = tf.get_variable("W",[1], dtype=tf.float64)
      b
    = tf.get_variable("b",[1], dtype=tf.float64)
      y
    = W*features['x']+ b
     
    # Loss sub-graph
      loss
    = tf.reduce_sum(tf.square(y - labels))
     
    # Training sub-graph
      global_step
    = tf.train.get_global_step()
      optimizer
    = tf.train.GradientDescentOptimizer(0.01)
      train
    = tf.group(optimizer.minimize(loss),
                       tf
    .assign_add(global_step,1))
     
    # ModelFnOps connects subgraphs we built to the
     
    # appropriate functionality.
     
    return tf.contrib.learn.ModelFnOps(
          mode
    =mode, predictions=y,
          loss
    = loss,
          train_op
    =train)

    estimator
    = tf.contrib.learn.Estimator(model_fn=model)
    # define our data set
    x
    =np.array([1.,2.,3.,4.])
    y
    =np.array([0.,-1.,-2.,-3.])
    input_fn
    = tf.contrib.learn.io.numpy_input_fn({"x": x}, y,4, num_epochs=1000)

    # train
    estimator
    .fit(input_fn=input_fn, steps=1000)
    # evaluate our model
    print(estimator.evaluate(input_fn=input_fn, steps=10))
    输出结果:
    {'loss':5.9819476e-11,'global_step':1000}
    注意到我们定制的模块model()函数,跟我们用底层api编写的模块训练模式十分的类似。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值