本指南让您开始在TensorFlow中编程。在使用本指南以前, 请安装TensorFlow。为了充分利用本指南,您应该了解如下内容:node
TensorFlow提供了多个API。最低级别的API - TensorFlow核心 - 为您提供完整的编程控制。咱们推荐TensorFlow Core用于机器学习研究人员和其余须要对其模型进行精细控制的人员。更高层次的API创建在TensorFlow核心之上。这些更高级别的API一般比TensorFlow Core更容易学习和使用。另外,更高级别的API使得不一样用户之间的重复任务更容易和更一致。像tf.estimator这样的高级API能够帮助您管理数据集,估算器,培训和推理。编程
本指南从TensorFlow核心教程开始。稍后,咱们演示如何在tf.estimator中实现相同的模型。了解TensorFlow核心原则将给你一个很好的思惟模型,说明当你使用更紧凑的更高级别的API时,内部是如何工做的。数组
TensorFlow中的数据中心单位是张量。一个张量由一组造成任意数量维数的原始值组成。张量的等级是它的维数。这里是一些张量的例子:bash
3 # a rank 0 tensor; a scalar with shape []
[1., 2., 3.] # a rank 1 tensor; 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程序的规范导入语句以下所示:app
import tensorflow as tf
复制代码
这使得Python能够访问全部 TensorFlow 的类,方法和符号。大多数文档假定您已经完成了这个工做。机器学习
你可能会想到TensorFlow核心程序由两个独立的部分组成:ide
甲计算图形是一系列排列成节点的图形TensorFlow操做。咱们来构建一个简单的计算图。每一个节点将零个或多个张量做为输入,并产生张量做为输出。一种类型的节点是一个常量。像全部的TensorFlow常量同样,它不须要输入,而是输出一个内部存储的值。咱们能够建立两个浮点Tensors node1 ,node2以下所示:函数
node1 = tf.constant(3.0, dtype=tf.float32)
node2 = tf.constant(4.0) # also tf.float32 implicitly
print(node1, node2)
复制代码
最后的打印声明产生oop
Tensor("Const:0", shape=(), dtype=float32) Tensor("Const_1:0", shape=(), dtype=float32)
复制代码
请注意,打印节点不会输出值3.0,4.0正如您所指望的那样。相反,它们是在评估时分别产生3.0和4.0的节点。为了实际评估节点,咱们必须在会话中运行计算图。会话封装了TensorFlow运行时的控制和状态。
下面的代码建立一个Session对象,而后调用它的run方法来运行足够的计算图来评估node1和node2。经过在会话中运行计算图以下:
sess = tf.Session()
print(sess.run([node1, node2]))
复制代码
咱们看到了3.0和4.0的预期值:
[3.0, 4.0]
复制代码
咱们能够经过组合Tensor节点和操做来构建更复杂的计算(操做也是节点)。例如,咱们能够添加咱们的两个常量节点,并产生一个新的图形以下:
from __future__ import print_function
node3 = tf.add(node1, node2)
print("node3:", node3)
print("sess.run(node3):", sess.run(node3))
复制代码
最后两个打印语句产生
node3: Tensor("Add:0", shape=(), dtype=float32)
sess.run(node3): 7.0
复制代码
TensorFlow提供了一个名为TensorBoard的实用程序,能够显示计算图的图片。下面是一个屏幕截图,显示了TensorBoard如何将图形可视化:
就目前来看,这张图并非特别有趣,由于它老是会产生一个不变的结果。图形能够被参数化来接受称为占位符的外部输入。一个占位符是一个承诺后提供一个值。
a = tf.placeholder(tf.float32)
b = tf.placeholder(tf.float32)
adder_node = a + b # + provides a shortcut for tf.add(a, b)
复制代码
前面的三行有点像一个函数或lambda,咱们在其中定义两个输入参数(a和b),而后对它们进行操做。咱们能够经过使用run方法的feed_dict参数将多个输入的 具体值提供给占位符来评估这个图形。
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中,上面的计算图以下所示:
在机器学习中,咱们一般须要一个能够进行任意输入的模型,好比上面的模型。为了使模型可训练,咱们须要可以修改图形以得到具备相同输入的新输出。 变量容许咱们将可训练参数添加到图形中。它们被构形成一个类型和初始值:
W = tf.Variable([.3], dtype=tf.float32)
b = tf.Variable([-.3], dtype=tf.float32)
x = tf.placeholder(tf.float32)
linear_model = W*x + b
复制代码
常量在调用时被初始化tf.constant,其值永远不会改变。相比之下,变量在调用时不会被初始化tf.Variable。要初始化TensorFlow程序中的全部变量,您必须显式调用一个特殊的操做,以下所示:
init = tf.global_variables_initializer()
sess.run(init)
复制代码
实现initTensorFlow子图的一个句柄是初始化全部的全局变量,这一点很重要。在咱们调用以前sess.run,变量是未初始化的。
既然x是占位符,咱们能够同时评估linear_model几个值, x以下所示:
print(sess.run(linear_model, {x: [1, 2, 3, 4]}))
复制代码
产生输出
[ 0. 0.30000001 0.60000002 0.90000004]
复制代码
咱们已经建立了一个模型,但咱们不知道它有多好。为了评估培训数据模型,咱们须要一个y占位符来提供所需的值,咱们须要编写一个损失函数。
损失函数用于衡量当前模型距离提供的数据有多远。咱们将使用线性回归的标准损失模型,它将当前模型和提供的数据之间的三角形的平方相加。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为-1和1变量的值,完美初始化为提供的价值tf.Variable,但可使用操做等来改变tf.assign。例如, 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
复制代码
机器学习的完整讨论超出了本教程的范围。可是,TensorFlow提供了优化器,能够逐渐改变每一个变量,以最大限度地减小损失函数。最简单的优化器是梯度降低。它根据相对于该变量的损失导数的大小来修改每一个变量。通常来讲,手动计算符号派生是繁琐和容易出错的。所以,TensorFlow能够自动生成衍生产品,仅使用该函数对模型进行描述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)]
复制代码
如今咱们已经完成了机器学习!虽然这个简单的线性回归模型不须要太多的TensorFlow核心代码,可是更复杂的模型和方法将数据提供给模型须要更多的代码。所以,TensorFlow为常见的模式,结构和功能提供更高层次的抽象。咱们将在下一节学习如何使用这些抽象。
完整的程序 完成的可训练线性回归模型以下所示:
import tensorflow as tf
# Model parameters
W = tf.Variable([.3], dtype=tf.float32)
b = tf.Variable([-.3], dtype=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.estimator
复制代码
tf.estimator 是一个高级的TensorFlow库,它简化了机器学习的机制,包括如下内容:
tf.estimator定义了许多常见的模型。
基本用法 注意线性回归程序变得简单多了 tf.estimator:
# NumPy is often used to load, manipulate and preprocess data.
import numpy as np
import tensorflow as tf
# Declare list of features. We only have one numeric feature. There are many
# other types of columns that are more complicated and useful.
feature_columns = [tf.feature_column.numeric_column("x", shape=[1])]
# An estimator is the front end to invoke training (fitting) and evaluation
# (inference). There are many predefined types like linear regression,
# linear classification, and many neural network classifiers and regressors.
# The following code provides an estimator that does linear regression.
estimator = tf.estimator.LinearRegressor(feature_columns=feature_columns)
# TensorFlow provides many helper methods to read and set up data sets.
# Here we use two data sets: one for training and one for evaluation
# We have to tell the function how many batches
# of data (num_epochs) we want and how big each batch should be.
x_train = np.array([1., 2., 3., 4.])
y_train = np.array([0., -1., -2., -3.])
x_eval = np.array([2., 5., 8., 1.])
y_eval = np.array([-1.01, -4.1, -7, 0.])
input_fn = tf.estimator.inputs.numpy_input_fn(
{"x": x_train}, y_train, batch_size=4, num_epochs=None, shuffle=True)
train_input_fn = tf.estimator.inputs.numpy_input_fn(
{"x": x_train}, y_train, batch_size=4, num_epochs=1000, shuffle=False)
eval_input_fn = tf.estimator.inputs.numpy_input_fn(
{"x": x_eval}, y_eval, batch_size=4, num_epochs=1000, shuffle=False)
# We can invoke 1000 training steps by invoking the method and passing the
# training data set.
estimator.train(input_fn=input_fn, steps=1000)
# Here we evaluate how well our model did.
train_metrics = estimator.evaluate(input_fn=train_input_fn)
eval_metrics = estimator.evaluate(input_fn=eval_input_fn)
print("train metrics: %r"% train_metrics)
print("eval metrics: %r"% eval_metrics)
复制代码
运行时,会产生相似的东西
train metrics: {'average_loss': 1.4833182e-08, 'global_step': 1000, 'loss': 5.9332727e-08}
eval metrics: {'average_loss': 0.0025353201, 'global_step': 1000, 'loss': 0.01014128}
复制代码
请注意咱们的评估数据是如何有更高的损失,但仍然接近于零。这意味着咱们正在正确地学习。
自定义模型 tf.estimator不会将您锁定在预约义的模型中。假设咱们想建立一个没有内置到TensorFlow中的自定义模型。咱们仍然能够保留数据集,喂养,培训等的高层次抽象 tf.estimator。为了说明,咱们将展现如何实现咱们本身的等价模型,以LinearRegressor使用咱们对低级别TensorFlow API的知识。
要定义一个适用的自定义模型tf.estimator,咱们须要使用 tf.estimator.Estimator。tf.estimator.LinearRegressor其实是一个子类tf.estimator.Estimator。Estimator咱们只是简单地提供Estimator一个函数model_fn来讲明 tf.estimator如何评估预测,训练步骤和损失,而不是分类 。代码以下:
import numpy as np
import tensorflow as tf
# Declare list of features, we only have one real-valued feature
def model_fn(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))
# EstimatorSpec connects subgraphs we built to the
# appropriate functionality.
return tf.estimator.EstimatorSpec(
mode=mode,
predictions=y,
loss=loss,
train_op=train)
estimator = tf.estimator.Estimator(model_fn=model_fn)
# define our data sets
x_train = np.array([1., 2., 3., 4.])
y_train = np.array([0., -1., -2., -3.])
x_eval = np.array([2., 5., 8., 1.])
y_eval = np.array([-1.01, -4.1, -7., 0.])
input_fn = tf.estimator.inputs.numpy_input_fn(
{"x": x_train}, y_train, batch_size=4, num_epochs=None, shuffle=True)
train_input_fn = tf.estimator.inputs.numpy_input_fn(
{"x": x_train}, y_train, batch_size=4, num_epochs=1000, shuffle=False)
eval_input_fn = tf.estimator.inputs.numpy_input_fn(
{"x": x_eval}, y_eval, batch_size=4, num_epochs=1000, shuffle=False)
# train
estimator.train(input_fn=input_fn, steps=1000)
# Here we evaluate how well our model did.
train_metrics = estimator.evaluate(input_fn=train_input_fn)
eval_metrics = estimator.evaluate(input_fn=eval_input_fn)
print("train metrics: %r"% train_metrics)
print("eval metrics: %r"% eval_metrics)
复制代码
运行时产生
train metrics: {'loss': 1.227995e-11, 'global_step': 1000}
eval metrics: {'loss': 0.01010036, 'global_step': 1000}
复制代码
请注意,自定义model_fn()函数的内容与下层API的手动模型训练循环很是类似。
文章是根据官方英文文档翻译而来,扫一扫个人微信公众号一块儿学习吧。
我的网站:
http://chaodongyang.com