TensorFlow学习笔记(二):TensorFlow入门
在安装完TensorFlow后,如果要将TensorFlow用好,我们需要有如下的知识:
如何使用Python编程
需要有基础的矩阵知识
需要一些机器学习相关的知识。
TensorFlow提供了多种API。最低级的API是TensorFlow Core,为你提供更完整的程序控制。如果需要精确的控制TensorFlow中的模型,那么推荐使用TensorFlow Core。高级的API是在TensorFlow Core的基础上构建的,这些高级API会比TensorFlow Core更易于使用。另外,高级API使得重复的任务更加坚定,更适合各类用户。其中,高级API tf.contrib.learn 能够帮助你完成一整套的管理数据集,估计,训练和推理的流程。一小部分高级TensorFlow API被放在contrib中,这些是属于尚在开发的一些API。所以,contrib中的API 可能会在之后的版本中发生变化。
接下来,将会介绍一些TensorFlow Core的入门,然后会介绍如何用tf.contrib.learn来进行建模。对TensorFlow Core工作原理的理解,能够让你在使用高级API的时候,理解高级API构建的模型的运作方式。
Tensor
TensorFlow核心的数据单元是张量(tensor)。一个Tensor由多维数据的组成,一个Tensor的Rank(等级)就是它的维度。以下是一些例子
3 # rank为0的tensor
[1. ,2., 3.] # rank为1
[[1., 2., 3.], [4., 5., 6.]] # rank为2
[[[1., 2., 3.]], [[7., 8., 9.]]] # rank为3
TensorFlow教程
importing TensorFlow
TensorFlow较为常用的import声明如下
import tensorflow as tf
这样Python就有权使用TensorFlow所有的类,方法,标识。
计算图
TensorFlow Core编程由以下两个步骤组成:
构建计算图
运行计算图
一个计算图(computational graph)是由一系列拥有TensorFlow操作的图节点组成的。接下来将构建一个简单的计算图。每个节点得到0或者其他tensor作为输入,然后输出一个Tensor。节点中有一个为常量。在TensorFlow中,常量不能输入,且输出就是它所存储的值。下面将创建两个浮点数Tensor,node1和node2
node1 = tf.constant(3.0, tf.float32)
node2 = tf.constant(4.0) # also tf.float32 implicitly
print(node1, node2)
最后得到的输出是
Tensor("Const:0", shape=(), dtype=float32) Tensor("Const_1:0", shape=(), dtype=float32)
得到的结果和设想中的输出3.0与4.0不同。如果需要得到这两个节点的值,我们必须用session运行计算图。一个Session包含了TensorFlow运行中的控制器和状态。
下列代码创建了一个Session对象,并且调用了run方法去执行计算图,来将node1和node2赋值。在一个session中运行计算图的代码如下所示:
sess = tf.Session()
print(sess.run([node1, node2]))
得到预期的结果
[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.0
TensorFlow提供了一个实用的工具——TensorBoard,TensorBoard能够显示出计算图。这里将TensorBoard的可视化图截图如下:
如图所示,图中输出的结果仍是个常量。在一个图中,如果要表示一个数据作为参数输入,则需要使用到placeholder,一个placeholder表示一个承诺,其将会在之后进行赋值。
a = tf.placeholder(tf.float32)
b = tf.placeholder(tf.float32)
adder_node = a + b #+是tf.add(a, b)的简写
前面的三行有点像我们定义了一个有两个输入参数的函数或者表达式,并且定义了它们的行为。我们首先用run函数的feed_dict参数来指定特定的Tensor,而这些Tensor提供了具体的值给这些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
上面代码的计算图如下所示:
在机器学习中,我们通常想让一个模型能够随意输入。为了让模型能够训练,我们需要修改图,让同一个输入值时,获取新的输出。Variable能够让我们添加可训练的参数到计算图中。它们由类型和定义的值组成。
W = tf.Variable([.3], tf.float32)
b = tf.Variable([-.3], tf.float32)
x = tf.placeholder(tf.float32)
linear_model = W * x + b
tf.Train API
TensorFlow提供的优化器能够慢慢的改变variable,使其损失函数达到最小。最简单的优化器就是梯度下降。它根据损失函数的大小来改变variable的值。通常,这些梯度计算都是乏味而且容易错误的。因此,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)]
完整代码
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是TensorFlow的高级库,它能精简机器学习的代码,其包括如下功能:
- 运行循环训练
- 运行循环评估
- 管理数据集
- 管理注入
tf.contrib.learn中定义了许多常用的模型。
Basic usage
用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自定义一个我们自己的线性模型。
为了定义一个能够在tf.contrib.learn上运行的自定义模型,我们需要用到tf.contrib.learn.Estimator。tf.contrib.learn.LinearRegressor就是tf.contrib.learn.Estimator的子类。我们只需要为Estimator提供一个函数 model_fn。model_fn告诉Estimator如何进行评估模型,训练步数以及损失函数。代码如下:
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构建模型训练

本文介绍了TensorFlow的基础知识,包括张量、计算图等概念,同时通过实例演示了如何使用TensorFlow Core及tf.contrib.learn进行模型训练。
:TensorFlow入门&spm=1001.2101.3001.5002&articleId=58647653&d=1&t=3&u=a124b441ca164081a5c69ebce7954a2b)
1839

被折叠的 条评论
为什么被折叠?



