TensorFlow:V1.8.0
本例程中使用了TensorFlow中的高级API:Estimator
Estimator入门导读 https://www.tensorflow.org/programmers_guide/estimators
Estimator: https://www.tensorflow.org/api_docs/python/tf/estimator/Estimator
Estimator类用于训练和评估TensorFlow模型,Estimator体封装了一个由model_fn构建的模型,其中model_fn需要传入输入和一系列其他的参数,返回优化器来执行训练,评估和预测。可见,模型函数model_fn是每个Estimator的核心,这是一种为训练、评估和预测构建图的方法。
除了自定义Estimator,TensorFlow提供了很多预创建的Estimator ,我们可以直接拿过来用,如果预创建的Estimator不能满足你的需求,你就需要自定义Estimator了。
关于Estimator如何创建可见https://www.tensorflow.org/get_started/custom_estimators
例程代码如下:
简单解释一下,下面的代码实现了对MNIST库的训练,MNIST是一堆包含了0-9数字的图片(大小28*28),包含训练样本和测试样本,经过40000步的训练之后,识别精度可以达到99%左右。
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import numpy as np
import tensorflow as tf
tf.logging.set_verbosity(tf.logging.INFO)
def cnn_model_fn(features, labels, mode):
input_layer = tf.reshape(features["x"], [-1, 28, 28, 1])
conv1 = tf.layers.conv2d(
inputs = input_layer,
filters = 32,
kernel_size = [5, 5],
padding = 'same',
activation = tf.nn.relu)
#conv1 shape: 28*28*32
pool1 = tf.layers.max_pooling2d(inputs = conv1, pool_size=[2, 2], strides = 2)
#pool1 shape: 14*14*32
conv2 = tf.layers.conv2d(
inputs = pool1,
filters = 64,
kernel_size = [5, 5],
padding = 'same',
activation = tf.nn.relu)
#conv2 shape: 14*14*64
pool2 = tf.layers.max_pooling2d(inputs = conv2, pool_size=[2, 2], strides = 2)
#pool2 shape: 7*7*64
pool2_flat = tf.reshape(pool2, [-1, 7*7*64])
dense = tf.layers.dense(inputs = pool2_flat, units = 1024, activation = tf.nn.relu)
dropout = tf.layers.dropout(
inputs=dense, rate=0.4, training = mode== tf.estimator.ModeKeys.TRAIN)
logits = tf.layers.dense(inputs = dropout, units=10)
predictions = {
"classes": tf.argmax(input = logits, axis=1),
"probabilities": tf.nn.softmax(logits, name= "softmax_tensor")
}
# predict mode
if mode == tf.estimator.ModeKeys.PREDICT:
return tf.estimator.EstimatorSpec(mode=mode, predictions = predictions)
onehot_labels = tf.one_hot(tf.cast(labels, tf.int32), depth=10)
#calculate loss for both train and eval mode
loss = tf.losses.softmax_cross_entropy(onehot_labels = onehot_labels, logits = logits)
# train mode
if mode== tf.estimator.ModeKeys.TRAIN:
opt = tf.train.GradientDescentOptimizer(learning_rate = 0.001)
train_op = opt.minimize(loss = loss, global_step= tf.train.get_global_step())
return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op = train_op)
#Add evaluation metrics
eval_metric_ops = {
"accuracy": tf.metrics.accuracy(
labels = labels, predictions = predictions["classes"])
}
return tf.estimator.EstimatorSpec(mode=mode, loss= loss, eval_metric_ops = eval_metric_ops)
def main(unused_argv):
#get dataset from tf.keras
train, test = tf.keras.datasets.mnist.load_data()
train_data, train_labels = train
train_data = np.asarray(train_data, dtype= np.float32)
train_labels = np.asarray(train_labels, dtype= np.int32)
eval_data, eval_labels = test
eval_data = np.asarray(eval_data, dtype= np.float32)
eval_labels = np.asarray(eval_labels, dtype= np.int32)
# create new Estimator object
mnist_classifier = tf.estimator.Estimator(
model_fn = cnn_model_fn,
model_dir = "/tmp/mnist_convnet_model"
)
tensors_to_log = {"probabilities": "softmax_tensor"}
logging_hook = tf.train.LoggingTensorHook(tensors = tensors_to_log, every_n_iter = 50)
#Create input function, used for feed dict of numpy arrays into the model
train_input_fn = tf.estimator.inputs.numpy_input_fn(
x = {"x": train_data}, #this item will be passed to model_fn as first argument
y = train_labels, #this item will be passed to model_fn as second argument
batch_size = 100,
num_epochs = None,
shuffle = True
)
mnist_classifier.train(input_fn = train_input_fn, steps=20000, hooks=[logging_hook])
eval_input_fn = tf.estimator.inputs.numpy_input_fn(
x = {"x": eval_data},
y = eval_labels,
num_epochs = 1,
shuffle = False
)
eval_results = mnist_classifier.evaluate(input_fn = eval_input_fn)
print(eval_results)
if __name__ == "__main__":
tf.app.run()