【问题标题】:Tensoflow: Calling prediction from a function returns 'RuntimeError: Attempted to use a closed Session'Tensorflow:从函数调用预测返回“RuntimeError:尝试使用关闭的会话”
【发布时间】:2018-03-09 01:54:29
【问题描述】:

我在 tensorflow 中实现了一个简单的 MLP。结构是一个类NeuralNet:

class NeuralNet:
    def __init__(self,  **options):
        self.type = options.get('net_type') # MLP, CNN, RNN
        self.n_class = options.get('classes')
        self.alpha = options.get('alpha')
        self.batch_size = options.get('batch_size')
        self.epoch = options.get('epochs')
        self.model = {}

它有 3 个不同的功能:

  • 适合:

    def fit (self, features, labels):
      if self.type == 'MLP':
        input_size = len(features[0])
        n_nodes_hl1 = input_size//5
        batch_size = 50
    
        sess = tf.InteractiveSession()
    
        x = tf.placeholder(tf.float32, [None, input_size])
        y = tf.placeholder(tf.float32, [None, self.n_class])
        labels = self.labels_to_onehot(labels)
    
        weights = {'hidden_1': tf.Variable(tf.random_normal([input_size, n_nodes_hl1])),
                        'output': tf.Variable(tf.random_normal([n_nodes_hl1, self.n_class]))}
    
        biases = {'hidden_1': tf.Variable(tf.random_normal([n_nodes_hl1])),
                        'output': tf.Variable(tf.random_normal([self.n_class]))}
    
        def neural_network_model(data, weight, bias):
    
                l1 = tf.add(tf.matmul(data, weight['hidden_1']), bias['hidden_1'])
                l1 = tf.nn.relu(l1)
    
                output = tf.matmul(l1, weight['output']) + bias['output']
    
                return output
    
        sess.run(tf.global_variables_initializer())
    
        prediction = neural_network_model(x, weights, biases)
        l2 = self.alpha * tf.nn.l2_loss(weights['hidden_1']) + self.alpha * tf.nn.l2_loss(weights['output'])
        cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=prediction)+l2)
        train_step = tf.train.AdamOptimizer(0.005).minimize(cross_entropy)
    
        sess=tf.Session()
        sess.run(tf.global_variables_initializer())
    
        for epoch in range(self.epoch):
                epoch_loss = 0
                i = 0
                while i < len(features):
                    start = i
                    end = i + batch_size
                    batch_x = np.array(features[start:end])
                    batch_y = np.array(labels[start:end])
    
                    _, c = sess.run([train_step, cross_entropy], feed_dict={x: batch_x,
                                                                  y: batch_y})
                    epoch_loss += c
                    i += batch_size
    
    
    
        self.model['session'] = sess
        self.model['y'] = y
        self.model['x'] = x
        self.model['prediction'] = prediction
    
  • Test(测试精度):

    def test(self, test_features, test_labels):
        with self.model['session']:
            test_labels = np.eye(self.n_class)[[int(int(i)/2) for i in test_labels]]
            correct = tf.equal(tf.argmax(self.model['prediction'], 1), tf.argmax(self.model['y'], 1))
            accuracy = tf.reduce_mean(tf.cast(correct, 'float'))
            accuracy = accuracy.eval({self.model['x']: test_features, self.model['y']: test_labels})
            print('Accuracy:', accuracy)
            return accuracy
    
  • 预测

    def predict(self, test_features):
        with self.model['session']:
            pred = self.model['prediction']
            predicted = pred.eval({self.model['x']: test_features})
            return predicted
    

在运行 predict 方法时,它返回一个RuntimeError: ('Attempted to use a closed Session.')

我的问题是

为什么test方法运行流畅,而predict方法中以同样方式调用会话失败?

我必须创建一个 tf 对象并对其进行评估吗?如果是,应该是哪个对象?

【问题讨论】:

    标签: python session tensorflow neural-network with-statement


    【解决方案1】:

    我无法运行您的代码,但我有一个假设。 也许您在拟合结束后运行测试功能。 在测试函数中,您使用上下文管理器('with block')处理会话。 所以,我的假设是,会话上下文管理器块完成后,您的会话会自动关闭。

    def test(self, test_features, test_labels):
        with self.model['session']:
            test_labels = np.eye(self.n_class)[[int(int(i)/2) for i in test_labels]]
            correct = tf.equal(tf.argmax(self.model['prediction'], 1), tf.argmax(self.model['y'], 1))
            accuracy = tf.reduce_mean(tf.cast(correct, 'float'))
            accuracy = accuracy.eval({self.model['x']: test_features, self.model['y']: test_labels})
            print('Accuracy:', accuracy)
            return accuracy
        ## at this point, your session is maybe closed.
    

    如果我的假设是正确的,您可以只传递 sess,然后使用 sess.run(~) 运行图形并使用 sess.close() 方法手动关闭。

    附:为什么你首先将 interactiveSession() 分配给 sess,然后运行 ​​tf.global_variables_initializer()? 我认为您只需在点图构建完成和点开始训练之间使用 tf.global_variables_initializer() 一次。

    更新 在我的假设中,你第一次运行哪个函数并不重要,因为这两个函数都使用'with'块。任何首先运行的函数都会在 with 块结束时关闭会话。

    我建议通过 sess,也就是说,

    def fit(self, ~):
        # construct graph
        self.sess = tf.Session()
    
    def test(self, ~):
         # codes will be here
         acc_val = self.sess.run([accuracy], feed_dict={~})
         return acc_val
    
    def predict(self, ~):
        # codes will be here
        predicted = self.sess.run([pred], feed_dict={~})
        return predicted
    

    希望这段代码能给你一个预感。

    【讨论】:

    • 您好,感谢您的回答。这让我很好地理解了这个问题,但不是一个实际的解决方案。实际上,当我首先运行 test 或 predict 时没有问题,但我不能再次使用它们中的任何一个。但是我无法理解如何使用您提到的内容。你能更新你的代码吗?
    猜你喜欢
    • 1970-01-01
    • 2021-03-09
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    • 2019-01-06
    • 1970-01-01
    • 2021-01-21
    • 2017-07-07
    相关资源
    最近更新 更多