TensorFlow提供了优化器,可以缓慢地更改每个变量,以便最小化损失函数。最简单的优化器是梯度下降。它根据相对于该变量的损失导数的大小修改每个变量。通常,手动计算符号导数是冗长乏味且容易出错的。因此,TensorFlow可以使用函数tf.gradients自动生成仅给出模型描述的导数。为了简单起见,优化器通常为您做这个。例如

optimizer = tf.train.GradientDescentOptimizer(0.01)
train = optimizer.minimize(loss)

1.tf.train API:
简单的线性回归

import numpy as np
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)
#优化器最小化loss
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})

#送入训练好的参数,求出loss
# 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

2.tf.contrib.learn:
tf.contrib.learn是一个高级TensorFlow库,它简化了机器学习的机制,其中包括:
(1)运行training 循环
(2)运行evaluation循环
(3)管理data sets
(4)管理feeding
tf.contrib.learn定义了许多常见的模型。

注意tf.contrib.learn可以简化线性回归程序:

import tensorflow as tf
import numpy as np

#声明特征列,这里声明了一个实值特征。
features = [tf.contrib.layers.real_valued_column("x", dimension=1)]

#一个estimator是调用训练(拟合)和评估(推理)的前端。提供很多预#定义的类型,如线性回归,逻辑回归,线性分类,逻辑分类和许多神经#网络分类器和回归。下面是linear regression:
estimator = tf.contrib.learn.LinearRegressor(feature_columns=features)

#TensorFlow提供了许多帮助方法来读取和设置数据集。
#这里我们使用两个数据集:一个用于训练,一个用于评估
#我们必须告诉功能我们想要多少batch的数据(num_epochs),每个#batch应该有多大。

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)

#我们可以通过调用方法和传递训练数据集来迭代1000次训练步骤。
estimator.fit(input_fn=input_fn, steps=1000)

#验证模型误差
train_loss = estimator.evaluate(input_fn=input_fn)
eval_loss = estimator.evaluate(input_fn=eval_input_fn)
print("train loss: %r"% train_loss)
print("eval loss: %r"% eval_loss)

运行结果:

train loss: {'global_step': 1000, 'loss': 4.3049088e-08}
eval loss: {'global_step': 1000, 'loss':0.0025487561}

3.定制自己的模型

tf.contrib.learn不会将您锁定到其预定义的模型中。 假设我们想创建一个没有内置到TensorFlow中的自定义模型。 我们仍然可以保留tf.contrib.learn的数据集,feeding,training等。

demo:如何使用LinearRegressor实现我们自己的等效模型而非Tensorflow内置模型。

要定义使用tf.contrib.learn的自定义模型,我们需要使用tf.contrib.learn.Estimator。 tf.contrib.learn.LinearRegressor实际上是一个tf.contrib.learn.Estimator的子类。 我们只是给Estimator提供一个函数model_fn来告诉tf.contrib.learn如何评估预测,训练步骤和损失,而不是分类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 
estimator = tf.contrib.learn.Estimator(model_fn=model)
# 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.contrib.learn.io.numpy_input_fn({"x": x_train}, y_train, 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)
# train
estimator.fit(input_fn=input_fn, steps=1000)
# Here we evaluate how well our model did.
train_loss = estimator.evaluate(input_fn=input_fn)
eval_loss = estimator.evaluate(input_fn=eval_input_fn)
print("train loss: %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}