TensorFlow保存和恢复训练有素的CNN模型不起作用

时间:2018-10-25 08:39:29

标签: python tensorflow machine-learning deep-learning

我使用TensorFlow和python3构建了CNN(卷积神经网络)模型来训练和预测MNIST手写数字数据库。

from tensorflow.examples.tutorials.mnist import input_data

我将CNIST训练为MNIST训练数据库,并预测MNIST测试数据库。我的模型的准确性超过95%。没关系。

import tensorflow as tf
import os

from tensorflow.examples.tutorials.mnist import input_data

tf.logging.set_verbosity(tf.logging.ERROR)


def compute_accuracy(v_xs, v_ys):
    global prediction
    y_pre = sess.run(prediction, feed_dict={xs: v_xs, keep_prob: 1})
    correct_prediction = tf.equal(tf.argmax(y_pre, 1), tf.argmax(v_ys, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    result = sess.run(accuracy, feed_dict={xs: v_xs, ys: v_ys, keep_prob: 1})
    return result


def weight_variable(shape):
    initial = tf.truncated_normal(shape, stddev=0.1)
    return tf.Variable(initial)


def bias_variable(shape):
    initial = tf.constant(0.1, shape=shape)
    return tf.Variable(initial)


def conv2d(x, W):
    return tf.nn.conv2d(input=x, filter=W, strides=[1, 1, 1, 1], padding='SAME')


def max_pool_2x2(x):
    return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')


IMAGE_WIDTH = 28
IMAGE_HEIGHT = 28
CHANNEL_COUNT = 1
CONV1_FEATURE_MAP_COUNT = 32
CONV1_FILTER_HEIGHT = 5
CONV1_FILTER_WEIGHT = 5
CONV2_FILTER_HEIGHT = 5
CONV2_FILTER_WEIGHT = 5
CONV2_FEATURE_MAP_COUNT = 64
FULL_CONNECTED_OUTPUT_SIZE = 1024
OUTPUT_TYPE_COUNT = 10

mnist = input_data.read_data_sets('MNIST_data', one_hot=True)

pb_file_dir = "{path}{sep}pb_modelsaved_model".format(path=os.getcwd(), sep=os.path.sep)
ckpt_file_dir = "{path}{sep}ckpt_model{sep}model.ckpt".format(path=os.getcwd(), sep=os.path.sep)

with tf.name_scope('input'):
    xs = tf.placeholder(tf.float32, [None, IMAGE_WIDTH * IMAGE_HEIGHT], name="images") / 255.  # 28x28
    ys = tf.placeholder(tf.float32, [None, 10], name="labels")
    keep_prob = tf.placeholder(tf.float32, name="keep_prob")

x_image = tf.reshape(xs, [-1, IMAGE_HEIGHT, IMAGE_WIDTH, CHANNEL_COUNT])

with tf.name_scope("conv_layer1"):
    with tf.name_scope('weights'):
        W_conv1 = weight_variable([CONV1_FILTER_HEIGHT, CONV1_FILTER_WEIGHT, CHANNEL_COUNT, CONV1_FEATURE_MAP_COUNT])
    with tf.name_scope('biases'):
        b_conv1 = bias_variable([CONV1_FEATURE_MAP_COUNT])
    with tf.name_scope('conv'):
        h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
    with tf.name_scope('pool'):
        h_pool1 = max_pool_2x2(h_conv1)

with tf.name_scope("conv_layer2"):
    with tf.name_scope('weights'):
        W_conv2 = weight_variable(
            [CONV2_FILTER_HEIGHT, CONV2_FILTER_WEIGHT, CONV1_FEATURE_MAP_COUNT, CONV2_FEATURE_MAP_COUNT])
    with tf.name_scope('biases'):
        b_conv2 = bias_variable([CONV2_FEATURE_MAP_COUNT])
    with tf.name_scope('conv'):
        h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
    with tf.name_scope('pool'):
        h_pool2 = max_pool_2x2(h_conv2)

with tf.name_scope("fc_layer1"):
    with tf.name_scope('weights'):
        W_fc1 = weight_variable([7 * 7 * 64, FULL_CONNECTED_OUTPUT_SIZE])
    with tf.name_scope('biases'):
        b_fc1 = bias_variable([FULL_CONNECTED_OUTPUT_SIZE])
    with tf.name_scope('output'):
        h_pool2_flat = tf.reshape(h_pool2, [-1, 7 * 7 * 64])
        h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

with tf.name_scope("fc_layer2"):
    with tf.name_scope('weights'):
        W_fc2 = weight_variable([FULL_CONNECTED_OUTPUT_SIZE, OUTPUT_TYPE_COUNT])
    with tf.name_scope('biases'):
        b_fc2 = bias_variable([OUTPUT_TYPE_COUNT])
    with tf.name_scope('output'):
        h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob, name="drop")
        prediction = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2, name="prediction")

with tf.name_scope('loss'):
    cross_entropy = tf.reduce_mean(
        -tf.reduce_sum(ys * tf.log(prediction), reduction_indices=[1]),
        name="loss")

with tf.name_scope('train'):
    train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy, name="train_step")

saver = tf.train.Saver()
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for i in range(1000):
        batch_xs, batch_ys = mnist.train.next_batch(100)
        sess.run(train_step, feed_dict={xs: batch_xs, ys: batch_ys, keep_prob: 0.5})
        if i % 50 == 0:
            accuracy = compute_accuracy(mnist.test.images[:1000], mnist.test.labels[:1000])
    save_path = saver.save(sess, ckpt_file_dir)

但是,当我尝试保存模型并恢复模型以预测MNIST测试数据库时。我的模型的准确度是10%!

import tensorflow as tf
import os

from tensorflow.examples.tutorials.mnist import input_data

tf.logging.set_verbosity(tf.logging.ERROR)

mnist = input_data.read_data_sets('MNIST_data', one_hot=True)

ckpt_file_dir = "{path}{sep}ckpt_model{sep}model.ckpt".format(path=os.getcwd(), sep=os.path.sep)


def compute_accuracy(v_xs, v_ys):
    global prediction
    y_pre = sess.run(prediction, feed_dict={xs: v_xs, keep_prob: 1})
    correct_prediction = tf.equal(tf.argmax(y_pre, 1), tf.argmax(v_ys, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    result = sess.run(accuracy, feed_dict={xs: v_xs, ys: v_ys, keep_prob: 1})
    return result


tf.reset_default_graph()

with tf.Session() as sess:
    saver = tf.train.import_meta_graph(ckpt_file_dir + ".meta")
    saver.restore(sess, ckpt_file_dir)
    xs = sess.graph.get_tensor_by_name('input/images:0')
    ys = sess.graph.get_tensor_by_name('input/labels:0')
    keep_prob = sess.graph.get_tensor_by_name('input/keep_prob:0')
    prediction = sess.graph.get_tensor_by_name('fc_layer2/output/prediction:0')

    cross_entropy = sess.graph.get_tensor_by_name('loss/loss:0')

    print(compute_accuracy(mnist.test.images[:1000], mnist.test.labels[:1000]))

对我来说很难,因为我是TensorFlow的新手。我尝试在保存的模型中打印所有变量,并发现它们与训练后的模型相同。

我还尝试用“ pb”文件保存我的模型,并且模型的准确性也达到10%!

我迷上了这个问题,希望您能帮助我解决它!谢谢!


我尝试在模型中打印所有砝码名称:

W_conv1 conv_layer1/weights/Variable:0
W_conv2 conv_layer2/weights/Variable:0
W_fc1 fc_layer1/weights/Variable:0
W_fc2 fc_layer2/weights/Variable:0

我尝试打印标签值的结果并预测值:

the result of the CNN model has trained

the result of the CNN model restored

1 个答案:

答案 0 :(得分:0)

我发现我的代码有问题。

我更改此行:

xs = tf.placeholder(tf.float32, [None, IMAGE_WIDTH * IMAGE_HEIGHT], name="images") / 255

收件人:

xs = tf.placeholder(tf.float32, [None, IMAGE_WIDTH * IMAGE_HEIGHT], name="images")

没关系!