Skip to main content
 首页 » 编程设计

python之使用 softmax_cross_entropy_with_logits 保存/恢复 Tensorflow 模型

2024年09月07日29dudu

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

请您参考如下方法:

首先,您提供的列表是变量 的列表。您感兴趣的是 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') 

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