TensorFlow入门
本指南可让您在TensorFlow中进行编程。使用本指南之前, 请安装TensorFlow。为了充分利用本指南,您应该了解以下内容:
· 如何用Python编程
· 至少有点数组。
· 理想的是关于机器学习的东西。但是,如果您对机器学习知之甚少,那么这仍然是您应该阅读的第一个指南。
TensorFlow提供多种API。最低级API - TensorFlow Core - 为您提供完整的编程控制。我们推荐用于机器学习研究人员和需要对其模型进行良好控制的其他人的TensorFlow Core。更高级别的API构建在TensorFlow Core之上。这些更高级别的API通常比TensorFlow Core更容易学习和使用。此外,较高级别的API使重复任务在不同用户之间更容易,更一致。像tf.contrib.learn这样的高级API可以帮助您管理数据集,估计器,培训和推理。请注意,一些高级TensorFlow API(方法名称包含的contrib那些)仍在开发中。某些contrib方法可能会在随后的TensorFlow版本中发生变化或变得过时。
本指南从TensorFlow Core教程开始。稍后我们演示如何在tf.contrib.learn中实现相同的模型。了解TensorFlow核心原则将为您提供一个伟大的心理模型,以便您在使用更紧凑的更高级别的API时内部工作。
张量
TensorFlow中的中心数据单位是张量。张量由一组成形为任意数量的数组的原始值组成。张量的等级是其维数。以下是张量的一些例子:
登录后复制
3# a rank 0tensor; this is a scalar with shape []
[1. ,2., 3.] # a rank 1tensor; this is a vector with shape [3]
[[1., 2., 3.], [4., 5., 6.]] # a rank 2tensor; a matrix with shape [2, 3]
[[[1., 2., 3.]], [[7., 8., 9.]]] # a rank 3tensor with shape [2, 1, 3]
TensorFlow核心教程
进口TensorFlow
TensorFlow程序的规范导入声明如下:
importtensorflow as tf
这使Python可以访问TensorFlow的所有类,方法和符号。大多数文档假定您已经完成了。
计算图
您可能会认为TensorFlow Core程序由两个独立部分组成:
1. 构建计算图。
2. 运行计算图。
甲计算图形是一系列排列成节点的图形TensorFlow操作。我们来构建一个简单的计算图。每个节点采用零个或多个张量作为输入,并产生张量作为输出。一种类型的节点是一个常数。像所有TensorFlow常数一样,它不需要任何输入,它输出一个内部存储的值。我们可以创建两个浮点式传感器node1 ,node2如下所示:
登录后复制
node1 = tf.constant(3.0, dtype=tf.float32)
node2 = tf.constant(4.0) # alsotf.float32 implicitly
print(node1, node2)
最终的打印声明生成
登录后复制
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节点与操作相结合来构建更复杂的计算(操作也是节点)。例如,我们可以添加我们的两个常量节点并生成一个新的图,如下所示:
登录后复制
node3 = tf.add(node1, node2)
print("node3:",node3)
print("sess.run(node3):",sess.run(node3))
最后两个print语句生成
登录后复制
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),然后对它们进行一个操作。我们可以使用feed_dict参数来指定多个输入的图表来指定为这些占位符提供具体值的Tensors:
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为常见的模式,结构和功能提供了更高级别的抽象。我们将在下一节中学习如何使用其中的一些抽象。
完成程序
完成的可训练线性回归模型如下所示:
登录后复制
importnumpy as np
import tensorflow as tf
# Modelparameters
W = tf.Variable([.3], dtype=tf.float32)
b = tf.Variable([-.3], dtype=tf.float32)
# Model inputand 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})
# evaluatetraining 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 是一个高级TensorFlow库,简化了机器学习的机制,其中包括:
· 运行训练循环
· 运行评估循环
· 管理数据集
· 管理喂养
tf.contrib.learn定义了许多常见的模型。
基本用法
注意线性回归程序变得简单得多 tf.contrib.learn:
登录后复制
importtensorflow as tf
# NumPy is oftenused to load, manipulate and preprocess data.
import numpy as np
# Declare listof features. We only have one real-valued feature. There are many
# other types ofcolumns that are more complicated and useful.
features = [tf.contrib.layers.real_valued_column("x", dimension=1)]
# An estimatoris the front end to invoke training (fitting) and evaluation
# (inference).There are many predefined types like linear regression,
# logisticregression, linear classification, logistic classification, and
# many neuralnetwork classifiers and regressors. The following code
# provides anestimator that does linear regression.
estimator = tf.contrib.learn.LinearRegressor(feature_columns=features)
# TensorFlowprovides many helper methods to read and set up data sets.
# Here we usetwo data sets: one for training and one for evaluation
# We have totell 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.contrib.learn.io.numpy_input_fn({"x":x_train}, y_train,
batch_size=4,
num_epochs=1000)
eval_input_fn = tf.contrib.learn.io.numpy_input_fn(
{"x":x_eval}, y_eval, batch_size=4, num_epochs=1000)
# We can invoke1000 training steps by invoking the method and passing the
# training dataset.
estimator.fit(input_fn=input_fn, steps=1000)
# Here weevaluate how well our model did.
train_loss = estimator.evaluate(input_fn=input_fn)
eval_loss = estimator.evaluate(input_fn=eval_input_fn)
print("trainloss: %r"% train_loss)
print("eval loss:%r"%eval_loss)
运行时,它会产生
train loss: {'global_step': 1000, 'loss': 4.3049088e-08}
evalloss: {'global_step': 1000, 'loss': 0.0025487561}
注意我们的eval数据的损失是多少,但仍然接近于零。这意味着我们正在学习。
自定义模型
tf.contrib.learn不会锁定您的预定义模型。假设我们想创建一个没有内置到TensorFlow中的自定义模型。我们仍然可以保留数据集,饲养,培训等的高层抽象 tf.contrib.learn。为了说明,我们将展示如何实现我们自己的等效模型,以LinearRegressor使用我们对较低级别TensorFlow API的了解。
要定义一个适合的自定义模型tf.contrib.learn,我们需要使用tf.contrib.learn.Estimator。tf.contrib.learn.LinearRegressor实际上是一个子类tf.contrib.learn.Estimator。Estimator我们只是提供Estimator一个功能model_fn来告诉tf.contrib.learn它如何评估预测,训练步骤和损失,而不是分类 。代码如下:
登录后复制
importnumpy as np
import tensorflow as tf
# Declare listof 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 ourdata 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.contrib.learn.io.numpy_input_fn({"x": x_train}, y_train, 4, num_epochs=1000)
# train
estimator.fit(input_fn=input_fn, steps=1000)
# Here weevaluate how well our model did.
train_loss = estimator.evaluate(input_fn=input_fn)
eval_loss = estimator.evaluate(input_fn=eval_input_fn)
print("trainloss: %r"% train_loss)
print("eval loss:%r"%eval_loss)运行时,它会产生
train loss: {'global_step': 1000, 'loss': 4.9380226e-11}
eval loss: {'global_step': 1000, 'loss': 0.01010081}
请注意,自定义model()函数的内容与下一级API的手动模型训练循环非常相似。
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删