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

使用Flask部署Keras模型执行预测时出现报错求助

解决Keras模型Flask部署时的Tensor图错误与JSON解析问题

嘿,这个问题我太熟了!这是Keras在Flask这类多线程Web框架里部署的典型坑,咱们一步步把它搞定:

问题根源分析

首先看服务器端的报错 ValueError: Tensor ... is not an element of this graph:

  • Keras加载模型时会把模型绑定到主线程的默认TensorFlow图上,但Flask的debug模式默认是多线程的,当预测请求过来时,会在子线程处理,子线程没有继承主线程的图上下文,就会出现这个“Tensor不在当前图”的错误。
  • 另外,model.predict_classes在新版TensorFlow(2.x+)的Keras里已经被弃用了,用这个方法也可能带来版本兼容问题。

而请求端的JSONDecodeError是连锁反应:服务器端抛出异常后,没有返回合法的JSON响应,请求端拿到空内容自然解析失败。

修复后的服务器代码(server.py)

咱们直接修改代码解决核心问题,同时让API更健壮:

from flask import Flask, request, jsonify
import numpy as np
from tensorflow.keras.models import load_model
import tensorflow as tf

app = Flask(__name__)

# 加载模型时保存全局图和会话,确保后续预测用同一个上下文
model_path = 'dom-loc.h5'
model = load_model(model_path)
graph = tf.get_default_graph()
session = tf.Session(graph=graph)

@app.route('/api', methods=['POST'])
def predict():
    try:
        data = request.get_json(force=True)
        dompath = np.array(data['dompath'])
        
        # 在保存的图和会话上下文里执行预测
        with graph.as_default():
            with session.as_default():
                # 用argmax替代已弃用的predict_classes,兼容性更好
                predictions = model.predict(dompath)
                location = np.argmax(predictions, axis=1)
        
        output = location[0]
        print('OUTPUT', output)
        # 返回标准JSON对象,避免解析问题
        return jsonify({'result': output})
    except Exception as e:
        print(f'Error occurred: {str(e)}')
        # 错误时返回带信息的JSON,方便调试
        return jsonify({'error': str(e)}), 500

if __name__ == '__main__':
    app.run(port=5000, debug=True)

关键修改点说明

  • 保存了模型加载时的TensorFlow图和会话,预测时强制在这个上下文里执行,解决多线程图不匹配的问题。
  • 移除了不必要的GET方法,预测接口用POST更合理。
  • 用np.argmax(model.predict(...), axis=1)替代predict_classes,适配新版TensorFlow。
  • 添加了异常捕获,错误时返回合法的JSON响应,避免请求端解析失败。
  • 返回的JSON用键值对包装,符合API规范,也避免了单独返回数字可能导致的解析问题。

请求端代码优化(request.py)

其实原请求代码没问题,但加个异常处理会更健壮:

import requests

url = 'http://localhost:5000/api'
try:
    r = requests.post(url, json={'dompath':[[2, 3, 5, 1, 3, 3, 1, 5, 6, 8, 4, 8]]})
    r.raise_for_status()  # 检查请求是否成功(比如4xx/5xx错误)
    print(r.json())
except requests.exceptions.RequestException as e:
    print(f'Request failed: {str(e)}')
except ValueError as e:
    print(f'JSON parse error: {str(e)}')

这样修改后,两个错误都会解决,你可以重新启动服务器再测试请求~

内容的提问来源于stack exchange,提问作者zengod

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:57:17