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}