Keras报错:'keras.src'模块无utils属性(疑似循环导入)
解决Keras与Flask集成时的
AttributeError: partially initialized module 'keras.src' has no attribute 'utils'错误 问题原因
这个错误是由Keras版本兼容性冲突或导入路径错误引发的循环导入问题,常见于Keras 3.x版本(Keras整合进TensorFlow生态后,官方导入路径发生了变更)。
修复方案
方案1:修正Keras导入路径
将原导入语句:
from keras.models import load_model
替换为TensorFlow官方推荐的导入方式:
from tensorflow.keras.models import load_model
该方案适配绝大多数场景,能有效避免独立Keras包与TensorFlow内置Keras的版本冲突。
方案2:降级Keras版本(仅特殊场景使用)
若需坚持使用独立Keras包,可降级至2.x稳定版,执行命令:
pip install keras==2.15.0
降级后保留原导入语句即可正常运行。
方案3:排查文件命名冲突
确保项目目录下不存在名为keras.py的文件或keras文件夹,这类命名会导致Python优先导入本地文件,而非官方库,进而触发循环导入错误。
修复后的完整代码
from flask import Flask, render_template, request, jsonify from tensorflow.keras.models import load_model # 修正导入路径 from PIL import Image, ImageOps import numpy as np app = Flask(__name__) # 加载模型与标签 model = load_model('/Users/Pratik/PycharmProjects/SIG_Project/keras_model.h55', compile=False) class_names = open("/Users/Pratik/PycharmProjects/SIG_Project/labels.txt", "r").readlines() # 设置置信度阈值 confidence_threshold = 0.2 @app.route('/') def index(): return ''' <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Image Classifier</title> </head> <body> <h1>Image Classifier</h1> <form id="upload-form" enctype="multipart/form-data"> <input type="file" name="file" accept="image/*"> <button type="button" onclick="predict()">Predict</button> </form> <div id="result"></div> <script> function predict() { var form = document.getElementById('upload-form'); var formData = new FormData(form); fetch('/predict', { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { var resultDiv = document.getElementById('result'); resultDiv.innerHTML = ''; data.forEach(prediction => { var classDiv = document.createElement('div'); classDiv.innerHTML = `<p>Class: ${prediction.class}</p><p>Confidence Score: ${prediction.confidence.toFixed(8)}</p>`; resultDiv.appendChild(classDiv); }); }) .catch(error => console.error('Error:', error)); } </script> </body> </html> ''' @app.route('/predict', methods=['POST']) def predict(): # 获取前端上传的图片 file = request.files['file'] # 预处理图片 image = Image.open(file).convert("RGB") size = (224, 224) image = ImageOps.fit(image, size, Image.Resampling.LANCZOS) image_array = np.asarray(image) normalized_image_array = (image_array.astype(np.float32) / 127.5) - 1 data = np.ndarray(shape=(1, 224, 224, 3), dtype=np.float32) data[0] = normalized_image_array # 执行预测 prediction = model.predict(data) # 整理响应结果 response = [] for i in range(len(class_names)): class_name = class_names[i].strip() confidence_score = prediction[0][i] if confidence_score > confidence_threshold: response.append({ 'class': class_name[2:], 'confidence': float(confidence_score) }) return jsonify(response) if __name__ == '__main__': app.run(debug=True)
额外注意事项
- 运行Flask应用时,若Jupyter默认端口被占用,可通过
app.run(debug=True, port=xxxx)指定其他端口。 - 验证模型文件路径是否正确,路径错误可能间接引发导入类问题。
内容的提问来源于stack exchange,提问作者Pratik
相关产品推荐
相关产品推荐

