You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:49:47