TensorFlow音频预测重复上传报错:无法解析feed_dict键为张量
问题分析与解决方案
嘿,这个问题和Cookie完全没关系哈!咱们来拆解下你遇到的问题:
问题根源
你碰到的是TensorFlow在多请求场景下的计算图上下文冲突问题。
每次处理POST请求时,你都重新加载了一遍模型(model_from_json + load_weights),但TensorFlow的默认计算图(default graph)在后续请求里会和之前加载的模型张量产生上下文不匹配——第一次请求加载的模型张量属于当时的默认图,第二次请求加载新模型时,新的张量要么被绑定到了新的图,要么旧图的残留张量导致混淆,这就出现了"Tensor is not an element of this graph"的错误。
解决方案
最靠谱的办法是让模型只加载一次,而不是每次请求都重新加载,这样所有请求共享同一个模型实例,彻底避免图上下文的冲突。下面是针对你代码的修改方案:
1. 全局加载模型(推荐)
把模型加载的逻辑移到请求处理函数外面,只在服务器启动时加载一次:
# 在文件顶部,请求处理函数之外加载模型 from tensorflow.keras.models import model_from_json import numpy as np from django.core.files.storage import FileSystemStorage # 全局模型变量,确保只加载一次 loaded_model = None def load_model_once(): global loaded_model if loaded_model is None: # 加载模型结构和权重 json_file = open('TrainedModels/model_CNN.json', 'r') loaded_model_json = json_file.read() json_file.close() loaded_model = model_from_json(loaded_model_json) loaded_model.load_weights("TrainedModels/model_CNN.h5") loaded_model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy']) print("Model restored from disk (仅加载一次)") # 服务器启动时立即加载模型 load_model_once() def creatematrix(request): if request.method == 'POST': myfile = request.FILES['sound'] fs = FileSystemStorage() filename = fs.save(myfile.name, myfile) uploaded_file_url = fs.url(filename) sound_file_paths = myfile.name parent_dir = 'learning/static/media/' sound_names = ["air conditioner","car horn","children playing","dog bark","drilling","engine idling","gun shot","jackhammer","siren","street music"] predict_file = parent_dir + sound_file_paths predict_x = extract_feature_array(predict_file) test_x_cnn = predict_x.reshape(predict_x.shape[0], 20, 41, 1).astype('float32') # 直接用全局已经加载好的模型做预测 predictions = loaded_model.predict(test_x_cnn) # 处理预测结果的逻辑保持不变 ind = np.argpartition(predictions[0], -2)[-9:] ind[np.argsort(predictions[0][ind])] ind = ind[::-1] a = sound_names[ind[0]], 100 * round(predictions[0,ind[0]],3) b = sound_names[ind[1]], 100 * round(predictions[0,ind[1]],3) c = sound_names[ind[2]], 100 * round(predictions[0,ind[2]],3) d = sound_names[ind[3]], 100 * round(predictions[0,ind[3]],3) e = sound_names[ind[4]], 100 * round(predictions[0,ind[4]],3) f = sound_names[ind[5]], 100 * round(predictions[0,ind[5]],3) g = sound_names[ind[6]], 100 * round(predictions[0,ind[6]],3) h = sound_names[ind[7]], 100 * round(predictions[0,ind[7]],3) i = sound_names[ind[8]], 100 * round(predictions[0,ind[8]],3) return render(request, 'base.html', { 'a': a, 'b': b, 'c': c, 'd': d, 'e': e, 'f': f, 'g': g, 'h': h, 'i': i, }) else: return render(request, 'base.html', { })
2. 显式指定图上下文(备选)
如果因为某些限制必须每次请求都加载模型,那你需要显式创建新的计算图,并让模型在这个新图的上下文里运行:
def creatematrix(request): if request.method == 'POST': import tensorflow as tf # 创建新的计算图,并设置为当前默认图 graph = tf.Graph() with graph.as_default(): myfile = request.FILES['sound'] fs = FileSystemStorage() filename = fs.save(myfile.name, myfile) uploaded_file_url = fs.url(filename) # 加载模型结构和权重 json_file = open('TrainedModels/model_CNN.json', 'r') loaded_model_json = json_file.read() json_file.close() loaded_model = model_from_json(loaded_model_json) loaded_model.load_weights("TrainedModels/model_CNN.h5") loaded_model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy']) sound_file_paths = myfile.name parent_dir = 'learning/static/media/' sound_names = ["air conditioner","car horn","children playing","dog bark","drilling","engine idling","gun shot","jackhammer","siren","street music"] predict_file = parent_dir + sound_file_paths predict_x = extract_feature_array(predict_file) test_x_cnn = predict_x.reshape(predict_x.shape[0], 20, 41, 1).astype('float32') # 在当前图的上下文内执行预测 predictions = loaded_model.predict(test_x_cnn) # 处理预测结果的逻辑保持不变 ind = np.argpartition(predictions[0], -2)[-9:] ind[np.argsort(predictions[0][ind])] ind = ind[::-1] a = sound_names[ind[0]], 100 * round(predictions[0,ind[0]],3) b = sound_names[ind[1]], 100 * round(predictions[0,ind[1]],3) c = sound_names[ind[2]], 100 * round(predictions[0,ind[2]],3) d = sound_names[ind[3]], 100 * round(predictions[0,ind[3]],3) e = sound_names[ind[4]], 100 * round(predictions[0,ind[4]],3) f = sound_names[ind[5]], 100 * round(predictions[0,ind[5]],3) g = sound_names[ind[6]], 100 * round(predictions[0,ind[6]],3) h = sound_names[ind[7]], 100 * round(predictions[0,ind[7]],3) i = sound_names[ind[8]], 100 * round(predictions[0,ind[8]],3) return render(request, 'base.html', { 'a': a, 'b': b, 'c': c, 'd': d, 'e': e, 'f': f, 'g': g, 'h': h, 'i': i, }) else: return render(request, 'base.html', { })
为什么第一次请求能成功?
第一次请求时,TensorFlow会自动创建一个默认计算图,模型的所有张量都绑定到这个图上,预测自然能正常执行。但第二次请求时,系统可能复用了之前的图,或者新加载的模型尝试使用旧图的张量,导致上下文不匹配,这就抛出了你看到的错误。
内容的提问来源于stack exchange,提问作者mrx
相关产品推荐
相关产品推荐

