在上一篇文章中,我们使用了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