刚装上TensorFlow,还是不太会用,主要去官网还要翻墙太麻烦了。。随手翻一下教程备用
初期准备:
安装好TensorFlow知道如何在Python中编程懂一点数组知识最好了解机器学习(不必要)TensorFLow提供多种APIs,从低级到高级,满足不同使用需求,越高级越容易学习和使用。下面的一些模型都可以用tf.contrib.learn
高级API实现。
TensorFlow最重要的数据单元就是tensor(张量)。一个tensor包括了任意维度的数组的原始值。tensor的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]直观感觉有几层[]
括号就有几个rank。而shape是从括号外向里,数,
的个数。
python下基本的导入声明:
import tensorflow as tf大多数的文档都假设已经导入了tf模块。
你可以把TensorFlow核心程序想成两个独立的模块:
搭建计算图运行计算图计算图computational graph是一系列布置为节点图的TensorFlow操作。每个节点将0个或更多张量作为输入并产生一个张量作为输出。常数是其中一个节点类型,他没有输入,输出其储存的常量,建立两个浮点数张量node1
和node2
:
打印为:
Tensor("Const:0", shape=(), dtype=float32) Tensor("Const_1:0", shape=(), dtype=float32)注意其输出并不是3.0
和4.0
。相反,他们是节点,当被评价(when evaluated)时,就会输出3.0
和4.0
。为了确切评价节点,我们必须用session运行一个计算图。一个session封装了TensorFlow运行时的控件和状态。
下面是一个使用Session
运行的例子:
得到输出:
[3.0, 4.0]我们可以将Tensor节点与运算(运算操作也是节点)结合搭建更为复杂的计算图。比如我们可以将两个常数相加:
node3 = tf.add(node1, node2)print("node3: ", node3)print("sess.run(node3): ",sess.run(node3))输出:
node3: Tensor("Add_2:0", shape=(), dtype=float32)sess.run(node3): 7.0TensorFlow提供了一个名为TensorBoard的工具用来显示计算图,上面的计算过程可以可视化表示为下图:
由于输入是常数,这张图的输出结果是恒定的。一个图可以参数化为接受外部输入,称为placeholders(占位符),用于为之后的数据占取空间。
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可视化之后: 在机器学习中,我们通常需要一个可以接受任意输入的模型,例如上面的模型。 为了使模型可训练,我们需要能够修改图以获得具有相同输入的新输出。 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时,常量被初始化,它们的值永远不会改变。 相比之下,当调用tf.Variable
时,变量不会被初始化。 要初始化TensorFlow程序中的所有变量,必须显式调用特殊操作,如下所示:
重要的是理解init
是TensorFlow子图的句柄,它初始化所有的全局变量。 直到我们调用sess.run,变量是未初始化的。
由于x
是一个占位符,我们可以同时对多个值进行输入:
结果为:
[ 0. 0.30000001 0.60000002 0.90000004]我们已经创建了一个模型,但无法评价其性能。为了评估训练数据的模型,需要一个占位符y
来提供所需的值,我们需要写一个损失函数。 损失函数测量当前模型与提供的数据之间的距离。 我们将使用用于线性回归的标准损失模型,其将当前模型和提供的数据之间的增量的平方求和。 用linear_model - y
创建一个向量,其中每个元素是对应的示例的误差增量。 我们调用tf.square
来平方误差。 然后,我们对所有平方误差求和,创建一个单一的标量,使用tf.reduce_sum
抽象所有示例的错误:
结果为:
23.66我们可以通过将W
和b
的值重新赋值为-1和1的完美值来手动改进。变量初始化为提供给tf.Variable
的值,但可以使用类似tf.assign
的操作来更改。 例如,W = -1
和b = 1
是我们模型的最佳参数。 我们可以相应地改变W和b:
最终的输出为0:
0.0我们人为猜测了W
和b
的“完美”值,但机器学习的整个要点是自动找到正确的模型参数。 我们将在下一节中说明如何完成这一任务。
机器学习的完整讨论超出了本教程的范围。 然而,TensorFlow提供了优化器,其缓慢地改变每个变量以便最小化损失函数。 最简单的优化器是梯度下降。 它根据相对于该变量的损失导数的大小来修改每个变量。 一般来说,人工计算符号导数是繁琐的并且容易出错。 因此,TensorFlow可以使用函数tf.gradients
自动产生仅给出模型描述的导数。 为了简单起见,优化器通常会为您执行此操作。 例如,
输出的最终结果:
[array([-0.9999969], dtype=float32), array([ 0.99999082], dtype=float32)]现在我们已经做了实际的机器学习! 虽然做这个简单的线性回归不需要太多的TensorFlow核心代码,但是更复杂的模型和方法来将数据输入到模型中需要更多的代码。 因此,TensorFlow为通用模式、结构和功能提供了更高级别的抽象。 我们将在下一节中学习如何使用这些抽象。
运行后结果:
W: [-0.9999969] b: [ 0.99999082] loss: 5.69997e-11其可视化图:
tf.contrib.learn
是一个高级TensorFlow库,它简化了机器学习的机制,包括以下内容:
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
不会只能运行其预定义的模型。 假设我们想创建一个未内置到TensorFlow中的自定义模型。 我们仍然可以保留tf.contrib.learn
的数据集,馈送,训练等的高级抽象。 为了说明,我们将演示如何使用我们的低级TensorFlow API的知识来实现我们自己的等效模型到LinearRegressor。 要定义与tf.contrib.learn
一起使用的自定义模型,我们需要使用tf.contrib.learn.Estimator
。 tf.contrib.learn.LinearRegressor
实际上是tf.contrib.learn.Estimator
的子类。 而不是子类别Estimator
,我们只是提供Estimator
一个函数model_fn
,告诉tf.contrib.learn
如何评估预测,训练步骤和损失。 代码如下:
运行后输出:
{'loss': 5.9819476e-11, 'global_step': 1000}注意自定义model()
函数的内容与下层API的手动模型训练循环非常相似。
用惯了caffe,感觉TensorFlow有点麻烦呢
TensorFlow Develop
新闻热点
疑难解答