使用softmax_cross_entropy_with_logits保存/恢复Tensorflow模型

时间:2018-01-20 22:47:02

标签: python tensorflow machine-learning deep-learning conv-neural-network

我在使用tf.layerstf.nn.softmax_cross_entropy_with_logits的张量流模型上进行恢复和执行推理时遇到问题。一旦我回想起保存的文件,我无法弄清楚要定义什么作为我的预测函数。我的培训代码是:

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import os
import numpy as np
os.environ["CUDA_VISIBLE_DEVICES"] = "0" # Set GPU device

mnist = input_data.read_data_sets('/tmp/data/', one_hot=True) # Download MNIST data and class


saver_model = './tmp/saved_model'


n_classes = 10      # Number of classifiers (0-9)
num_input = 784     # Image size (28x28)
n_train = 20000     # number of images in data set
n_epoch = 10        # number of time to itterate over the data set
batch_size = 128    # Number of images to average for each training calculation
n_test = 6000        # Number of images to perform inference on
display_step = 200  # How often to show progress

# Create placeholders for input and classifier data (like maloc)
x = tf.placeholder('float', [None, num_input], name='inputdata')
y = tf.placeholder('float')


# Define the neural network structure:
# Input Data -> Conv -> Conv -> Fully Connected -> Fully Connected -> Output Data
def network(x_in):
    inputl = tf.reshape(x_in, shape=[-1, 28, 28, 1], name='inputl')  #[Batch Size, Height, Width, Channel]
    layer0 = tf.layers.conv2d(inputl, 32, [5, 5], activation=tf.nn.relu, name='layer0')
    layer1 = tf.layers.max_pooling2d(layer0, 2, 2, name='layer1')
    layer2 = tf.layers.conv2d(layer1, 64, [3, 3], activation=tf.nn.relu, name='layer2')
    layer3 = tf.layers.max_pooling2d(layer2, 2, 2, name='layer3')
    layer4 = tf.contrib.layers.flatten(layer3)
    layer5 = tf.layers.dense(layer4, 1024, activation=tf.nn.relu, name='layer5')
    output = tf.layers.dense(layer5, n_classes, name='output')
    return output

prediction = network(x)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=prediction, labels=y, name='softmax'))
optimizer = tf.train.AdamOptimizer().minimize(cost)
init = tf.global_variables_initializer()

sess = tf.Session()
sess.run(init)
saver = tf.train.Saver()

n_itter = n_epoch*(n_train/batch_size)
for i in range(n_itter):
    batch_x, batch_y = mnist.train.next_batch(batch_size)
    _, l = sess.run([optimizer, cost], feed_dict={x: batch_x, y: batch_y})
    if i % display_step == 0:
        print '%d / %d' % (i, n_itter)
saver.save(sess, saver_model)

# Infer
success_ctr = 0.0
for i in range(n_test):
    batch_x, batch_y = mnist.test.next_batch(1)
    g = sess.run(prediction, feed_dict={x: batch_x})
    success_ctr += float(np.argmax(g) == np.argmax(batch_y))
print('PCC = %1.3e' % (success_ctr/n_test))

这成功训练并且PCC为98%。

现在我想恢复已保存的模型并对其进行推理,但是我在定义预测函数时遇到了问题。我的恢复/推理代码是:

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import numpy as np
import os
import pprint

os.environ["CUDA_VISIBLE_DEVICES"] = "0" # Set GPU device
n_test = 6000        # Number of images to perform inference on
mnist = input_data.read_data_sets('/tmp/data/', one_hot=True) # Download MNIST data and class

saver_dir = './tmp'
saver_model = os.path.join(saver_dir, 'saved_model')

saver = tf.train.import_meta_graph(saver_model + '.meta')
graph = tf.get_default_graph()
sess = tf.Session()
saver.restore(sess, tf.train.latest_checkpoint(saver_dir))

pprint.pprint([v.name for v in tf.global_variables()])

x = graph.get_tensor_by_name('inputdata:0')
prediction = graph.get_tensor_by_name('output/bias:0')

# Infer
success_ctr = 0.0
for i in range(n_test):
    batch_x, batch_y = mnist.test.next_batch(1)
    g = sess.run(prediction, feed_dict={x: batch_x})
    success_ctr += float(np.argmax(g) == np.argmax(batch_y))
print('PCC = %1.3e' % (success_ctr/n_test))

输出:

[u'layer0/kernel:0',
 u'layer0/bias:0',
 u'layer2/kernel:0',
 u'layer2/bias:0',
 u'layer5/kernel:0',
 u'layer5/bias:0',
 u'output/kernel:0',
 u'output/bias:0',
 u'beta1_power:0',
 u'beta2_power:0',
 u'layer0/kernel/Adam:0',
 u'layer0/kernel/Adam_1:0',
 u'layer0/bias/Adam:0',
 u'layer0/bias/Adam_1:0',
 u'layer2/kernel/Adam:0',
 u'layer2/kernel/Adam_1:0',
 u'layer2/bias/Adam:0',
 u'layer2/bias/Adam_1:0',
 u'layer5/kernel/Adam:0',
 u'layer5/kernel/Adam_1:0',
 u'layer5/bias/Adam:0',
 u'layer5/bias/Adam_1:0',
 u'output/kernel/Adam:0',
 u'output/kernel/Adam_1:0',
 u'output/bias/Adam:0',
 u'output/bias/Adam_1:0']
PCC = 9.567e-02

我在想我应该定义的张量为预测是'输出/偏差:0',但这不起作用。我怀疑我的问题在于我正在使用tf.nn.softmax_cross_entropy_with_logits函数,该函数在我的network(x_in)函数外部应用了softmax激活函数。也许我完全不知道如何恢复这个东西,但任何帮助都会非常感激。

1 个答案:

答案 0 :(得分:2)

首先,您提供的列表是变量列表。您感兴趣的是占位符 inputdata以及与output对应的 op (这是{{1}中的最后一个操作在你的情况下,添加)。这不是偏见变量。

请注意,如果您只想在推理上执行tf.layers.dense,则无需执行argmax。所以你可以打电话:

softmax

但是,由于推断概率分布通常很有帮助,因此最好在图中为它创建另一个操作:

# Another option:
# prediction = graph.get_operation_by_name('output/BiasAdd')
prediction = graph.get_tensor_by_name('output/BiasAdd:0')

......然后:

result = tf.nn.softmax(prediction, name='softmax')

请注意,此操作仅在测试时不会用于培训。