在上一篇文章中,我们使用了Estimator自带的LinearClassfier,本文将会重写6.3的程序,使用自定义的Estimator。
在上一篇文章中,我们使用了Estimator自带的LinearClassfier,本文将会重写6.3的程序,使用自定义的Estimator。
参考[1],构建一个estimator,主要还是两部分,第一部分是model function, 第二部分是input function,其中input function跟上一篇文章相同,所以这里我会主要说一下model function。其实构建方法也很简单,主要就是构建一个网络,和一个loss(损失函数)。
model_fn会有三个参数,features,labels以及mode。mode是一个枚举类型的参数,分为三种,分别是TRAIN EVAL 和PERDICT,很遗憾,原作者没有写这个,我们会在本文中弥补这个遗憾。
一个Estimator的skeleton(骨架)应该是这样:
def model_fn(features, labels, mode, params):
# 满足以下逻辑:
# 1. 通过TensorFlow的operations来配置model
# 2. 定义training/evaluation的损失函数
# 3. 定义training用的ptimizer
# 4. 生成预测(predictions)
# 5. 返回 EstimatorSpec 对象
return EstimatorSpec(mode, predictions, loss, train_op, eval_metric_ops)
完整的代码如下,欢迎讨论
import glob import numpy as np import matplotlib.pyplot as plt import tensorflow as tf datadir='data/cifar-10-batches-bin/' N_CLASS=10 #类别数目 X_FEATURE = 'x' # name of the input feature plt.ion() G = glob.glob (datadir + '*.bin') A = np.fromfile(G[0],dtype=np.uint8).reshape([10000,3073]) labels = A [:,0] images = A [:,1:].reshape([10000,3,32,32]).transpose (0,2,3,1) plt.imshow(images[15]) images_unroll = A [:,1:] def max_pool_2x2(tensor_in): return tf.nn.max_pool(tensor_in, ksize= [1,2,2,1], strides= [1,2,2,1], padding='SAME') def conv_model (features, labels,mode): #这里的参数必须是这样 X=features[X_FEATURE] X= tf. reshape(X, [-1, 32, 32, 3]) with tf.variable_scope('conv_layer1'): h_conv1=tf.layers.conv2d(X, filters=16, kernel_size=[5,5], activation=tf.nn.relu) h_pool1=max_pool_2x2(h_conv1)#print (h_pool1) with tf.variable_scope('conv_layer2'): h_conv2=tf.layers.conv2d(h_pool1, filters=16, kernel_size=[5,5], activation=tf.nn.relu) #print (h_conv2) h_pool2=max_pool_2x2(h_conv2) #h_pool2_flat = tf.reshape(h_pool2, [-1,8*8*16 ]) #this line not work becasue there no batch_size here #h_fc1 = tf.contrib.layers.stack(h_pool2_flat, tf.contrib.layers.fully_connected ,[96,48], activation_fn=tf.nn.relu ) net_shape = h_pool2.get_shape().as_list() h_pool2_flat = tf.reshape(h_pool2, [-1, net_shape[1] * net_shape[2] * net_shape[3]]) logits = tf.layers.dense(h_pool2_flat,N_CLASS,activation=None) predicted_classes = tf.argmax(logits, 1) if mode == tf.estimator.ModeKeys.PREDICT: predictions = { 'class': predicted_classes, 'prob': tf.nn.softmax(logits) } return tf.estimator.EstimatorSpec(mode, predictions=predictions) # Compute loss. loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits) # Create training op. if mode == tf.estimator.ModeKeys.TRAIN: optimizer = tf.train.AdagradOptimizer(learning_rate=0.01) train_op = optimizer.minimize(loss, global_step=tf.train.get_global_step()) return tf.estimator.EstimatorSpec(mode, loss=loss, train_op=train_op) # Compute evaluation metrics. eval_metric_ops = { 'accuracy': tf.metrics.accuracy( labels=labels, predictions=predicted_classes) } return tf.estimator.EstimatorSpec( mode, loss=loss, eval_metric_ops=eval_metric_ops) images = np.array(images,dtype=np.float32) classifier = tf.estimator.Estimator(model_fn=conv_model) train_input_fn = tf.estimator.inputs.numpy_input_fn( x={X_FEATURE: images}, y=labels.astype(np.int32), batch_size=100, num_epochs=30, shuffle=True) test_input_fn = tf.estimator.inputs.numpy_input_fn( x={X_FEATURE: images}, y=labels.astype(np.int32), num_epochs=1, shuffle=False) classifier.train(input_fn=train_input_fn,steps=10000) score =classifier.evaluate(input_fn=test_input_fn) print ('Accuracy: {0:f}'.format(score['accuracy']))
Reference
[1] 构建Estimator
[2] resnet.py