【问题标题】:Saving / Restoring Tensorflow Model using softmax_cross_entropy_with_logits使用 softmax_cross_entropy_with_logits 保存/恢复 TensorFlow 模型
【发布时间】:2018-01-20 22:47:02
【问题描述】:

我在使用 tf.layers 和 tf.nn.softmax_cross_entropy_with_logits 的 tensorflow 模型上恢复和执行推理时遇到问题。一旦我回忆起保存的文件,我就无法弄清楚将什么定义为我的预测函数。我的训练代码是:

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))

这成功训练并拥有 98% 的 PCC。

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

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 激活函数。也许我完全不知道如何恢复这个东西,但任何帮助将不胜感激。

【问题讨论】:

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


    【解决方案1】:

    首先,您提供的列表是变量列表。您感兴趣的是 placeholder inputdata 和对应于 output 的 op (在您的情况下,这是 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')
    

    ...然后:

    prediction = graph.get_operation_by_name('softmax')
    

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

    【讨论】:

    • 非常感谢您的帮助。当我使用prediction = graph.get_operation_by_name('output/BiasAdd') 时,我仍然没有得到正确的结果,但是如果我将它更改为prediction = graph.get_tensor_by_name('output/BiasAdd:0'),它就像一个魅力。我不确定我是否理解为什么该操作不起作用,但使用 tensor_by_name 却可以。
    • 两者都应该实际工作。但我会更新答案
    猜你喜欢
    • 1970-01-01
    • 2016-08-16
    • 2020-01-16
    • 2019-11-25
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 2018-09-06
    • 2016-05-01
    相关资源
    最近更新 更多