Tensoflow:从函数调用预测返回' RuntimeError:尝试使用已关闭的Session'

时间:2017-09-27 14:14:30

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

我在tensorflow中实现了一个简单的MLP。结构是神经网络类

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
    
  • 测试(测试准确度):

    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
    

运行预测方法时,它会返回RuntimeError: ('Attempted to use a closed Session.')

我的问题是

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

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

1 个答案:

答案 0 :(得分:0)

我无法运行您的代码,但我有一个假设。 也许你在装修结束后运行测试功能。 在测试函数中,您使用上下文管理器('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()方法。

P.S。为什么首先将interactiveSession()分配给sess,并运行tf.global_variables_initializer()? 我想你可以使用tf.global_variables_initializer()一次,在点图构造完成和点开始训练之间。

<强>已更新 在我的假设中,你第一次运行哪个函数并不重要,因为两个函数都使用'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

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