Tensorflow-除非我重新创建“ saver”对象,否则无法初始化保存的变量。为什么?

时间:2018-11-04 07:58:06

标签: python tensorflow

我很确定我缺少关于tensorflow工作原理的信息,因为我的解决方案没有任何意义。

我正在尝试训练神经网络(从头开始,不使用Estimators或其他抽象方法),将其保存,并加载其简化版本以进行推断。

下面的代码训练但给了我错误:FailedPreconditionError (see above for traceback): Attempting to use uninitialized value hidden0/biases/Variable [[Node: hidden0/biases/Variable/read = Identity[T=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"](hidden0/biases/Variable)]]。如果添加注释行-如果我重新创建保护器对象我将不使用也不返回,则该代码将正常工作。

为什么要创建一个(无用的)保护程序对象以恢复保存的权重?

import tensorflow as tf
import numpy as np

def add_fc_layer(input_tensor, input_dimensions, output_dimensions, layer_name, activation=None):
    with tf.variable_scope(layer_name):
        with tf.variable_scope('weights'):
            weights = tf.Variable(tf.truncated_normal([input_dimensions, output_dimensions]))
        with tf.variable_scope('biases'):
            biases = tf.Variable(tf.zeros([output_dimensions]))
        with tf.variable_scope('Wx_plus_b'):
            preactivate = tf.matmul(input_tensor, weights) + biases
        if activation is None:
            return preactivate
        with tf.variable_scope('activation'):
            activations = activation(preactivate)
        return activations


def make_network(model_phase):
    if model_phase not in {"train", "test"}:
        raise ValueError("invalid type")

    hidden0_units = 25
    hidden1_units = 15
    hidden2_units = 10
    input_size = 10
    output_size = 4

    with tf.variable_scope('InputVector'):
        inputs = tf.placeholder(shape=[1, input_size], dtype=tf.float32)

    hidden0_out = add_fc_layer(inputs, input_size, hidden0_units, "hidden0", activation=tf.nn.sigmoid)
    hidden1_out = add_fc_layer(hidden0_out, hidden0_units, hidden1_units, "hidden1", activation=tf.nn.sigmoid)
    hidden2_out = add_fc_layer(hidden1_out, hidden1_units, hidden2_units, "hidden2", activation=tf.nn.sigmoid)

    out =  add_fc_layer(hidden2_out, hidden2_units, output_size, "regression")

    if model_phase == "test":
        # UNCOMMENTIN THIS LINE MAKES THE SCRIPT WORK
        # saver = tf.train.Saver(var_list=tf.trainable_variables())
        return inputs, out

    saver = tf.train.Saver(var_list=tf.trainable_variables())

    with tf.variable_scope('training'):
        with tf.variable_scope('groundTruth'):
            ground_truth = tf.placeholder(shape=[1, output_size], dtype=tf.float32)
        with tf.variable_scope('loss'):
            loss = tf.reduce_sum(tf.square(ground_truth - out))
            tf.summary.scalar('loss', loss)
        with tf.variable_scope('optimizer'):
            trainer = tf.train.AdamOptimizer(learning_rate=0.001)
        with tf.variable_scope('gradient'):
            updateModel = trainer.minimize(loss)


    with tf.variable_scope('predict'):
        predict = tf.random_shuffle(tf.boolean_mask(out, tf.equal(out, tf.reduce_max(out, axis=None))))[0]


    writer = tf.summary.FileWriter('/tmp/test', tf.get_default_graph())


    return inputs, out, ground_truth, updateModel, writer, saver


train_graph = tf.Graph()
with tf.Session(graph=train_graph) as sess:
    tf.set_random_seed(42)
    inputs, out, ground_truth, updateModel, writer, saver = make_network(model_phase='train')
    init = tf.initialize_all_variables()
    sess.run(init)
    print('\nLearning...')
    for _ in range(10):
        sess.run([updateModel], feed_dict={inputs:np.arange(10)+np.random.random((1,10)), ground_truth:np.arange(4).reshape(1, 4)})
    saver.save(sess,'./tensorflowModel.ckpt')

new_graph = tf.Graph()
with tf.Session(graph=new_graph) as sess:
    inputs, out = make_network(model_phase='test')
    saver = tf.train.import_meta_graph('./tensorflowModel.ckpt.meta')
    saver.restore(sess, tf.train.latest_checkpoint('./'))

    # evaluation
    print('\nEvaluation...')
    for _ in range(10):
        _ = sess.run(out, feed_dict={inputs:np.arange(10).reshape(1,10)})

1 个答案:

答案 0 :(得分:0)

我不知道为什么创建一个未使用的Saver可以使问题消失,但是代码背叛了人们的误解。

还原时,将创建两次模型图。首先,调用make_network()来创建计算图和变量。然后,您还调用import_meta_graph,它还会创建一个图形和变量。您应该使用简单的saver = tf.train.Saver()而不是saver = tf.train.import_meta_graph('./tensorflowModel.ckpt.meta')

创建一个保护程序