Python 张量不是此图的元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47115946/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 18:01:00  来源:igfitidea点击:

Tensor is not an element of this graph

pythonmachine-learningtensorflowmemory-leaksneural-network

提问by ashkan

I'm getting this error

我收到这个错误

'ValueError: Tensor Tensor("Placeholder:0", shape=(1, 1), dtype=int32) is not an element of this graph.'

'ValueError: Tensor Tensor("Placeholder:0", shape=(1, 1), dtype=int32) 不是这个图的一个元素。'

The code is running perfectly fine without with tf.Graph(). as_default():. However I need to call M.sample(...)multiple times and each time the memory won't be free after session.close(). Probably there is a memory leak but not sure where is it.

没有with tf.Graph(). as_default():. 但是,我需要M.sample(...)多次调用,并且每次session.close(). 可能存在内存泄漏,但不确定它在哪里。

I want to restore a pre-trained neural network, set it as default graph, and testing it multiple times (like 10000) over the default graph without making it larger each time.

我想恢复一个预训练的神经网络,将其设置为默认图,并在默认图上多次测试(如 10000),而不是每次都放大。

The code is:

代码是:

def SessionOpener(save):
    grph = tf.get_default_graph()
    sess = tf.Session(graph=grph)
    ckpt = tf.train.get_checkpoint_state(save)
    saver = tf.train.import_meta_graph('./predictor/save/model.ckpt.meta')
    if ckpt and ckpt.model_checkpoint_path:
        saver.restore(sess, ckpt.model_checkpoint_path)
        tf.global_variables_initializer().run(session=sess)
    return sess

def LoadPredictor(save):
    with open(os.path.join(save, 'config.pkl'), 'rb') as f:
        saved_args = cPickle.load(f)
    with open(os.path.join(save, 'words_vocab.pkl'), 'rb') as f:
        words, vocab = cPickle.load(f)
    model = Model(saved_args, True)
    return model, words, vocab

if __name__ == '__main__':
    Save = './save'
    M, W, V = LoadPredictor(Save)
    Sess = SessionOpener(Save)
    word = M.sample(Sess, W, V, 1, str(123), 2, 1, 4)
    Sess.close()

And the model is:

模型是:

class Model():
    def __init__(self, args, infer=False):
        with tf.Graph().as_default():
            self.args = args
            if infer:
                args.batch_size = 1
                args.seq_length = 1

            if args.model == 'rnn':
                cell_fn = rnn.BasicRNNCell
            elif args.model == 'gru':
                cell_fn = rnn.GRUCell
            elif args.model == 'lstm':
                cell_fn = rnn.BasicLSTMCell
            else:
                raise Exception("model type not supported: {}".format(args.model))

            cells = []
            for _ in range(args.num_layers):
                cell = cell_fn(args.rnn_size)
                cells.append(cell)

            self.cell = cell = rnn.MultiRNNCell(cells)

            self.input_data = tf.placeholder(tf.int32, [args.batch_size, args.seq_length])
            self.targets = tf.placeholder(tf.int32, [args.batch_size, args.seq_length])
            self.initial_state = cell.zero_state(args.batch_size, tf.float32)
            self.batch_pointer = tf.Variable(0, name="batch_pointer", trainable=False, dtype=tf.int32)
            self.inc_batch_pointer_op = tf.assign(self.batch_pointer, self.batch_pointer + 1)
            self.epoch_pointer = tf.Variable(0, name="epoch_pointer", trainable=False)
            self.batch_time = tf.Variable(0.0, name="batch_time", trainable=False)
            tf.summary.scalar("time_batch", self.batch_time)

            def variable_summaries(var):
            """Attach a lot of summaries to a Tensor (for TensorBoard visualization)."""
                with tf.name_scope('summaries'):
                    mean = tf.reduce_mean(var)
                    tf.summary.scalar('mean', mean)
                    tf.summary.scalar('max', tf.reduce_max(var))
                    tf.summary.scalar('min', tf.reduce_min(var))


            with tf.variable_scope('rnnlm'):
                softmax_w = tf.get_variable("softmax_w", [args.rnn_size, args.vocab_size])
                variable_summaries(softmax_w)
                softmax_b = tf.get_variable("softmax_b", [args.vocab_size])
                variable_summaries(softmax_b)
                with tf.device("/cpu:0"):
                    embedding = tf.get_variable("embedding", [args.vocab_size, args.rnn_size])
                    inputs = tf.split(tf.nn.embedding_lookup(embedding, self.input_data), args.seq_length, 1)
                    inputs = [tf.squeeze(input_, [1]) for input_ in inputs]

            def loop(prev, _):
                prev = tf.matmul(prev, softmax_w) + softmax_b
                prev_symbol = tf.stop_gradient(tf.argmax(prev, 1))
                return tf.nn.embedding_lookup(embedding, prev_symbol)

            outputs, last_state = legacy_seq2seq.rnn_decoder(inputs, self.initial_state, cell, loop_function=loop if infer else None, scope='rnnlm')
            output = tf.reshape(tf.concat(outputs, 1), [-1, args.rnn_size])
            self.logits = tf.matmul(output, softmax_w) + softmax_b
            self.probs = tf.nn.softmax(self.logits)
            loss = legacy_seq2seq.sequence_loss_by_example([self.logits],
                    [tf.reshape(self.targets, [-1])],
                    [tf.ones([args.batch_size * args.seq_length])],
                    args.vocab_size)
            self.cost = tf.reduce_sum(loss) / args.batch_size / args.seq_length
            tf.summary.scalar("cost", self.cost)
            self.final_state = last_state
            self.lr = tf.Variable(0.0, trainable=False)
            tvars = tf.trainable_variables()
            grads, _ = tf.clip_by_global_norm(tf.gradients(self.cost, tvars),
                args.grad_clip)
            optimizer = tf.train.AdamOptimizer(self.lr)
            self.train_op = optimizer.apply_gradients(zip(grads, tvars))

    def sample(self, sess, words, vocab, num=200, prime='first all', sampling_type=1, pick=0, width=4):
        def weighted_pick(weights):
            t = np.cumsum(weights)
            s = np.sum(weights)
            return(int(np.searchsorted(t, np.random.rand(1)*s)))

        ret = ''
        if pick == 1:
            state = sess.run(self.cell.zero_state(1, tf.float32))

            if not len(prime) or prime == ' ':
                prime  = random.choice(list(vocab.keys()))
            for word in prime.split()[:-1]:
                x = np.zeros((1, 1))
                x[0, 0] = vocab.get(word,0)
                feed = {self.input_data: x, self.initial_state:state}
                [state] = sess.run([self.final_state], feed)

            ret = prime
            word = prime.split()[-1]
            for n in range(num):
                x = np.zeros((1, 1))
                x[0, 0] = vocab.get(word, 0)
                feed = {self.input_data: x, self.initial_state:state}
                [probs, state] = sess.run([self.probs, self.final_state], feed)
                p = probs[0]

                if sampling_type == 0:
                    sample = np.argmax(p)
                elif sampling_type == 2:
                    if word == '\n':
                        sample = weighted_pick(p)
                    else:
                        sample = np.argmax(p)
                else: # sampling_type == 1 default:
                    sample = weighted_pick(p)

                ret = words[sample]
        return ret

and the output is:

输出是:

Traceback (most recent call last):
  File "/rcg/software/Linux/Ubuntu/16.04/amd64/TOOLS/TENSORFLOW/1.2.1-GPU-PY352/lib/python3.5/site-packages/tensorflow/python/client/session.py", line 942, in _run
    allow_operation=False)
  File "/rcg/software/Linux/Ubuntu/16.04/amd64/TOOLS/TENSORFLOW/1.2.1-GPU-PY352/lib/python3.5/site-packages/tensorflow/python/framework/ops.py", line 2584, in as_graph_element
    return self._as_graph_element_locked(obj, allow_tensor, allow_operation)
  File "/rcg/software/Linux/Ubuntu/16.04/amd64/TOOLS/TENSORFLOW/1.2.1-GPU-PY352/lib/python3.5/site-packages/tensorflow/python/framework/ops.py", line 2663, in _as_graph_element_locked
    raise ValueError("Tensor %s is not an element of this graph." % obj)
ValueError: Tensor Tensor("Placeholder:0", shape=(1, 1), dtype=int32) is not an element of this graph.

采纳答案by Maxim

When you create a Model, the session hasn't been restored yet. All placeholders, variables and ops that are defined in Model.__init__are placed in a new graph, which makes itself a default graph inside withblock. This is the key line:

创建 时Model,会话尚未恢复。中定义的所有占位符、变量和操作Model.__init__都放置在一个新的 graph 中,这使自己成为with块内的默认图。这是关键行:

with tf.Graph().as_default():
  ...

This means that this instance of tf.Graph()equals to tf.get_default_graph()instance inside withblock, but not before or after it. From this moment on, there exist two different graphs.

这意味着此实例tf.Graph()等于块tf.get_default_graph()内的实例with但不在它之前或之后。从这一刻起,存在两个不同的图形。

When you later create a session and restore a graph into it, you can't access the previous instance of tf.Graph()in that session. Here's a short example:

当您稍后创建会话并将图形恢复到其中时,您无法访问该tf.Graph()会话中的前一个实例。这是一个简短的例子:

with tf.Graph().as_default() as graph:
  var = tf.get_variable("var", shape=[3], initializer=tf.zeros_initializer)

# This works
with tf.Session(graph=graph) as sess:
  sess.run(tf.global_variables_initializer())
  print(sess.run(var))  # ok because `sess.graph == graph`

# This fails
saver = tf.train.import_meta_graph('/tmp/model.ckpt.meta')
with tf.Session() as sess:
  saver.restore(sess, "/tmp/model.ckpt")
  print(sess.run(var))   # var is from `graph`, not `sess.graph`!

The best way to deal with this is give names to all nodes, e.g. 'input', 'target', etc, save the model and then look up the nodes in the restoredgraph by name, something like this:

解决这个问题的最好方法是为所有节点命名,例如'input',,'target'等,保存模型,然后按名称在恢复的图中查找节点,如下所示:

saver = tf.train.import_meta_graph('/tmp/model.ckpt.meta')
with tf.Session() as sess:
  saver.restore(sess, "/tmp/model.ckpt")      
  input_data = sess.graph.get_tensor_by_name('input')
  target = sess.graph.get_tensor_by_name('target')

This method guarantees that all nodes will be from the graph in session.

此方法保证所有节点都来自会话中的图形。

回答by Ilyas

Try first:

先试试:

import tensorflow as tf
graph = tf.get_default_graph()

Then, when you need to use predict:

然后,当您需要使用 predict 时:

with graph.as_default():
     y = model.predict(X)

回答by colby-ham

If you are calling the python function that calls Tensorflow from an external module, make sure that you the model isn't being loaded as a global variable or else it may not be loaded in time for usage. This happened to me calling a Tensorflow model from the Flask server.

如果您正在调用从外部模块调用 Tensorflow 的 python 函数,请确保您的模型没有作为全局变量加载,否则它可能无法及时加载以供使用。这发生在我从 Flask 服务器调用 Tensorflow 模型的时候。

回答by Vahid Ghafourian

Use this line before making models:

在制作模型之前使用此行:

keras.backend.clear_session()

This will make a new graph to use in new models.

这将制作一个用于新模型的新图。

回答by Ruthvik Vaila

I had this issue when trying to make a model using another class that uses keras to create a model. I got this issue corrected by doing the following

我在尝试使用另一个使用 keras 创建模型的类创建模型时遇到了这个问题。我通过执行以下操作纠正了这个问题

import nn_classifierclass as cls
from keras import backend
for repeat in range(repeats):
    backend.clear_session() ##NOTICE THIS
    neural_net = cls.Classifier(.....)
    neural_net.keras_fcn_classifier()

回答by Prateek Gulati

Inside def LoadPredictor(save):
Just after loading the model, add model._make_predict_function()
So the function becomes:

里面 def LoadPredictor(save):
刚加载完模型, addmodel._make_predict_function()
所以函数就变成了:

def LoadPredictor(save):
    with open(os.path.join(save, 'config.pkl'), 'rb') as f:
        saved_args = cPickle.load(f)
    with open(os.path.join(save, 'words_vocab.pkl'), 'rb') as f:
        words, vocab = cPickle.load(f)
    model = Model(saved_args, True)
    model._make_predict_function()
    return model, words, vocab

回答by Keki

For me, this issue was resolved by using Keras' APIs to save and load model. I had more than one models being trained in my code and I had to use the particular model for prediction under a condition.

对我来说,这个问题是通过使用 Keras 的 API 来保存和加载模型解决的。我在我的代码中训练了不止一个模型,我不得不使用特定模型在某种条件下进行预测。

So I saved the entire model to a HDF5 file after model training

所以我在模型训练后将整个模型保存到一个 HDF5 文件中

# The '.h5' extension indicates that the model should be saved to HDF5.
model.save('my_model.h5')

and then recreate/reload the saved model at the time of prediction

然后在预测时重新创建/重新加载保存的模型

my_model = tf.keras.models.load_model('my_model.h5')

This helped me get rid of

这帮助我摆脱了

Tensor not an element of this graph

张量不是此图的元素

error. Hope this helps!

错误。希望这可以帮助!