最近在学习用TensorFlow开发CNN的时候,看到官方的一篇教程Creating Estimators in tf.contrib.learn,介绍了使用封装好的一些工具开发训练程序的方法,觉得很不错,在这里记录一下学习的心得。
tf.contrib下面的东西很多,google自己没有称之为框架,但我感觉借助于tf.contrib.learn.Estimator,也等于是定义了一个框架,因为好多训练程序的流程是差不多的。
文档中建议的流程如下:
系统中已经有一些现成的,在learn.estimator目录下,比如:
看样子应该是可以直接就用了,但是暂时还没有去研究。
nn = tf.contrib.learn.Estimator(model_fn=model_fn, model_dir=None, config=None, params=model_params, feature_engineering_fn=None)
原文的例子:
# Learning rate for the model
LEARNING_RATE = 0.001
# Set model params
model_params = {"learning_rate": LEARNING_RATE}
nn = tf.contrib.learn.Estimator(
model_fn=model_fn, params=model_params)
model_fn的参数是:
def model_fn(features, targets, mode, params):
# Logic to do the following:
# 1. Configure the model via TensorFlow operations
# 2. Define the loss function for training/evaluation
# 3. Define the training operation/optimizer
# 4. Generate predictions
return predictions, loss, train_op
返回结果是一个三元组:
predictions (required in INFER and EVAL modes)
predictions = {"results": tensor_of_predictions}
In INFER mode, the dict that you return from model_fn will then be returned by predict(), so you can construct it in the format in which you’d like to consume it. 也就是说这个prediction dict的格式没有要求,根据需要来定义。
In EVAL mode, the dict is used by metric functions to compute metrics. Any MetricSpec objects passed to the metrics argument of evaluate() must have a prediction_key that matches the key name of the corresponding predictions in predictions. 看这个意思,是说evaluate的时候,要指定要用predictions中的哪个key来做比较(是不是这样,待验证)
loss (required in EVAL and TRAIN mode). 这个就是通常意义的loss;
对于卷积神经网络来说,一般就是卷积层和池化层,tf.contrib.layers下有一些定义好的类:
系统有一些预定义的类:
relu(inputs, num_outputs). Create a layer of num_outputs nodes fully connected to the previous layer inputs with a ReLu activation function (tf.nn.relu):
hidden_layer = tf.contrib.layers.relu(inputs=input_layer, num_outputs=10)
relu6(inputs, num_outputs). Create a layer of num_outputs nodes fully connected to the previous layer hidden_layer with a ReLu 6 activation function (tf.nn.relu6):
second_hidden_layer = tf.contrib.layers.relu6(inputs=hidden_layer, num_outputs=20)
output_layer = tf.contrib.layers.linear(inputs=second_hidden_layer, num_outputs=3)
当然还可以通过定制fully_connected的参数来定义自己需要的全连接层:
output_layer = tf.contrib.layers.fully_connected(inputs=second_hidden_layer, num_outputs=10, activation_fn=tf.sigmoid)
tf.contrib.losses 下包含一些预定义的loss, 比如:
一般按这样来定义:
train_op = tf.contrib.layers.optimize_loss(
loss=loss,
global_step=tf.contrib.framework.get_global_step(),
learning_rate=params["learning_rate"],
optimizer="SGD")
optimizer: 优化方法,指定在tf.contrib.layers.optimizers中定义的方法,比如
RMSProp. Implementation of the RMSprop algorithm (tf.train.RMSPropOptimizer)
除了名称之外,还可以有多种方法指定optimizer,参见文档。
def model_fn(features, targets, mode, params):
“”“Model function for Estimator.”“”# Connect the first hidden layer to input layer
# (features) with relu activation
first_hidden_layer = tf.contrib.layers.relu(features, 10)#Connect the second hidden layer to first hidden layer with relu
second_hidden_layer = tf.contrib.layers.relu(first_hidden_layer, 10)# Connect the output layer to second hidden layer (no activation fn)
output_layer = tf.contrib.layers.linear(second_hidden_layer, 1)# Reshape output layer to 1-dim Tensor to return predictions
predictions = tf.reshape(output_layer, [-1])
predictions_dict = {“ages”: predictions}# Calculate loss using mean squared error
loss = tf.contrib.losses.mean_squared_error(predictions, targets)train_op = tf.contrib.layers.optimize_loss(
loss=loss,
global_step=tf.contrib.framework.get_global_step(),
learning_rate=params[“learning_rate”],
optimizer=”SGD”)return predictions_dict, loss, train_op
# Fit
nn.fit(x=training_set.data, y=training_set.target, steps=5000)
# Score accuracy
ev = nn.evaluate(x=test_set.data, y=test_set.target, steps=1)
loss_score = ev["loss"]
print("Loss: %s" % loss_score)
# Print out predictions
predictions = nn.predict(x=prediction_set.data,
as_iterable=True)
for i, p in enumerate(predictions):
print("Prediction %s: %s" % (i + 1, p["ages"]))