TensorFlow/TFLearn聊天机器人报错:RuntimeError(尝试使用已关闭会话)
深度学习聊天机器人运行报错(RuntimeError: Attempted to use a closed Session)解决办法
问题背景
按照教程制作深度学习聊天机器人,代码运行时报错RuntimeError: Attempted to use a closed Session。尝试手动添加model.tflearn文件无效,每次运行必须删除data.pickle才能执行,但仍无法解决核心报错。
原始代码
import nltk from nltk.stem.lancaster import LancasterStemmer stemmer = LancasterStemmer() import numpy import tflearn import tensorflow import random import json import pickle with open("intents.json") as file: data = json.load(file) try: with open("data.pickle", "rb") as f: words, labels, training, output = pickle.load(f) except: words = [] labels = [] docs_x = [] docs_y = [] for intent in data["intents"]: for pattern in intent["patterns"]: wrds = nltk.word_tokenize(pattern) words.extend(wrds) docs_x.append(wrds) docs_y.append(intent["tag"]) if intent["tag"] not in labels: labels.append(intent["tag"]) words = [stemmer.stem(w.lower()) for w in words if w != "?"] words = sorted(list(set(words))) labels = sorted(labels) training = [] output = [] out_empty = [0 for _ in range(len(labels))] for x, doc in enumerate(docs_x): bag = [] wrds = [stemmer.stem(w.lower()) for w in doc] for w in words: if w in wrds: bag.append(1) else: bag.append(0) output_row = out_empty[:] output_row[labels.index(docs_y[x])] = 1 training.append(bag) output.append(output_row) training = numpy.array(training) output = numpy.array(output) with open("data.pickle", "wb") as f: pickle.dump((words, labels, training, output), f) tensorflow.compat.v1.reset_default_graph() net = tflearn.input_data(shape=[None, len(training[0])]) net = tflearn.fully_connected(net, 8) net = tflearn.fully_connected(net, 8) net = tflearn.fully_connected(net, len(output[0]), activation="softmax") net = tflearn.regression(net) model = tflearn.DNN(net) try: model.load("model.tflearn") except: model.fit(training, output, n_epoch=100, batch_size=8, show_metric=True) model.save("model.tflearn") def bag_of_words(s, words): bag = [0 for _ in range(len(words))] s_words = nltk.word_tokenize(s) s_words = [stemmer.stem(word.lower()) for word in s_words] for se in s_words: for i, w in enumerate(words): if w == se: bag[i] = 1 return numpy.array(bag) def chat(): print("Start talking with the bot (type quit to stop)!") while True: inp = input("You: ") if inp.lower() == "quit": break results = model.predict([bag_of_words(inp, words)]) results_index = numpy.argmax(results) tag = labels[results_index] for tg in data["intents"]: if tg['tag'] == tag: responses = tg['responses'] print(random.choice(responses)) chat()
终端报错信息
tflearn.is_training(True, session=self.session) File "/usr/local/lib/python3.7/site-packages/tflearn/config.py", line 95, in is_training tf.get_collection('is_training_ops')[0].eval(session=session) File "/usr/local/lib/python3.7/site-packages/tensorflow/python/framework/ops.py", line 913, in eval return _eval_using_default_session(self, feed_dict, self.graph, session) File "/usr/local/lib/python3.7/site-packages/tensorflow/python/framework/ops.py", line 5512, in _eval_using_default_session return session.run(tensors, feed_dict) File "/usr/local/lib/python3.7/site-packages/tensorflow/python/client/session.py", line 958, in run run_metadata_ptr) File "/usr/local/lib/python3.7/site-packages/tensorflow/python/client/session.py", line 1104, in _run raise RuntimeError('Attempted to use a closed Session.') RuntimeError: Attempted to use a closed Session.
问题分析
- 会话关闭问题:TFlearn加载预训练模型后,TensorFlow会话被自动关闭,后续调用
model.predict()时无法访问已关闭的会话,引发报错。 - 数据逻辑错误:原始代码中,数据预处理逻辑(分词、词干提取、生成训练集)不在
except块内,导致无论是否成功加载data.pickle,都会重新生成并覆盖数据,这就是必须删除data.pickle才能运行的原因。 - 版本兼容问题:TFlearn对TensorFlow 2.x的兼容性较差,当前使用的TensorFlow 2.x环境和TFlearn的会话管理逻辑冲突。
解决步骤
1. 调整数据加载逻辑
把数据预处理的所有代码放入except块内,确保只有当data.pickle不存在时才重新生成数据:
try: with open("data.pickle", "rb") as f: words, labels, training, output = pickle.load(f) except: words = [] labels = [] docs_x = [] docs_y = [] for intent in data["intents"]: for pattern in intent["patterns"]: wrds = nltk.word_tokenize(pattern) words.extend(wrds) docs_x.append(wrds) docs_y.append(intent["tag"]) if intent["tag"] not in labels: labels.append(intent["tag"]) words = [stemmer.stem(w.lower()) for w in words if w != "?"] words = sorted(list(set(words))) labels = sorted(labels) training = [] output = [] out_empty = [0 for _ in range(len(labels))] for x, doc in enumerate(docs_x): bag = [] wrds = [stemmer.stem(w.lower()) for w in doc] for w in words: if w in wrds: bag.append(1) else: bag.append(0) output_row = out_empty[:] output_row[labels.index(docs_y[x])] = 1 training.append(bag) output.append(output_row) training = numpy.array(training) output = numpy.array(output) with open("data.pickle", "wb") as f: pickle.dump((words, labels, training, output), f)
2. 修复模型会话问题
在加载模型后,显式重新初始化TensorFlow会话,或者在创建模型时指定会话并保持活跃。以下是适配的代码:
# 替换原模型创建和加载部分 tensorflow.compat.v1.reset_default_graph() sess = tensorflow.compat.v1.Session() net = tflearn.input_data(shape=[None, len(training[0])]) net = tflearn.fully_connected(net, 8) net = tflearn.fully_connected(net, 8) net = tflearn.fully_connected(net, len(output[0]), activation="softmax") net = tflearn.regression(net) model = tflearn.DNN(net, session=sess) try: model.load("model.tflearn") except: model.fit(training, output, n_epoch=100, batch_size=8, show_metric=True) model.save("model.tflearn")
3. 版本兼容建议
如果上述调整仍有问题,建议安装TensorFlow 1.15.x版本(TFlearn的稳定兼容版本):
pip uninstall tensorflow -y pip install tensorflow==1.15.5
修正后的完整代码
import nltk from nltk.stem.lancaster import LancasterStemmer stemmer = LancasterStemmer() import numpy import tflearn import tensorflow import random import json import pickle with open("intents.json") as file: data = json.load(file) try: with open("data.pickle", "rb") as f: words, labels, training, output = pickle.load(f) except: words = [] labels = [] docs_x = [] docs_y = [] for intent in data["intents"]: for pattern in intent["patterns"]: wrds = nltk.word_tokenize(pattern) words.extend(wrds) docs_x.append(wrds) docs_y.append(intent["tag"]) if intent["tag"] not in labels: labels.append(intent["tag"]) words = [stemmer.stem(w.lower()) for w in words if w != "?"] words = sorted(list(set(words))) labels = sorted(labels) training = [] output = [] out_empty = [0 for _ in range(len(labels))] for x, doc in enumerate(docs_x): bag = [] wrds = [stemmer.stem(w.lower()) for w in doc] for w in words: if w in wrds: bag.append(1) else: bag.append(0) output_row = out_empty[:] output_row[labels.index(docs_y[x])] = 1 training.append(bag) output.append(output_row) training = numpy.array(training) output = numpy.array(output) with open("data.pickle", "wb") as f: pickle.dump((words, labels, training, output), f) tensorflow.compat.v1.reset_default_graph() sess = tensorflow.compat.v1.Session() net = tflearn.input_data(shape=[None, len(training[0])]) net = tflearn.fully_connected(net, 8) net = tflearn.fully_connected(net, 8) net = tflearn.fully_connected(net, len(output[0]), activation="softmax") net = tflearn.regression(net) model = tflearn.DNN(net, session=sess) try: model.load("model.tflearn") except: model.fit(training, output, n_epoch=100, batch_size=8, show_metric=True) model.save("model.tflearn") def bag_of_words(s, words): bag = [0 for _ in range(len(words))] s_words = nltk.word_tokenize(s) s_words = [stemmer.stem(word.lower()) for word in s_words] for se in s_words: for i, w in enumerate(words): if w == se: bag[i] = 1 return numpy.array(bag) def chat(): print("Start talking with the bot (type quit to stop)!") while True: inp = input("You: ") if inp.lower() == "quit": break results = model.predict([bag_of_words(inp, words)]) results_index = numpy.argmax(results) tag = labels[results_index] responses = "" for tg in data["intents"]: if tg['tag'] == tag: responses = tg['responses'] print(random.choice(responses)) chat()
内容的提问来源于stack exchange,提问作者Hyun Sim
相关产品推荐
相关产品推荐

