Flask肺炎检测API经PHP调用时始终预测为PNEUMONIA类问题排查
肺炎检测模型API预测异常排查问题
我开发了一个基于Flask的API,用于集成针对胸部X光图像训练的肺炎检测深度学习模型。使用Fashion MNIST模型测试PHP与Flask API的连接时,模型预测结果正常。但使用自定义训练的ResNet50架构肺炎检测模型(测试集性能:测试损失11.41%、准确率97.10%、精确率97.46%、召回率98.60%、AUC值98.33%)时,通过PHP向Flask API发送图像,无论图像属于NORMAL类还是PNEUMONIA类,模型始终预测为PNEUMONIA类。以下为Flask API代码及PHP调用代码,请排查图像传输或API处理环节的问题。
Flask API 代码
from flask import Flask, request, jsonify from tensorflow import keras import numpy as np from PIL import Image app = Flask(__name__) # Load the model model = keras.models.load_model('path_to_your_model') # Class names class_names = ['NORMAL', 'PNEUMONIA'] @app.route('/predict', methods=['POST']) def predict(): if 'image' not in request.files: return jsonify({'error': 'No image file provided'}), 400 image = request.files['image'] try: # Convert the image to RGB and resize it img = Image.open(image).convert('RGB') img = img.resize((224, 224)) # Convert the image to an array and expand dimensions to match model input img_array = np.array(img) / 255.0 img_array = np.expand_dims(img_array, axis=0) # Add batch dimension # Make prediction prediction = model.predict(img_array) # Get the predicted class predicted_class = class_names[int(prediction[0] > 0.5)] return jsonify({ 'prediction': predicted_class, 'probability': float(prediction[0]) }) except Exception as e: return jsonify({'error': f"An error occurred: {str(e)}"}), 500 if __name__ == '__main__': app.run(debug=True)
PHP 调用代码
<?php if (isset($_POST['submit'])) { if (isset($_FILES['img']) && $_FILES['img']['error'] == 0) { $image = $_FILES['img']['name']; $image_tmp_name = $_FILES['img']['tmp_name']; $folder = 'uploaded_img/'; $image_folder = $folder . $image; if (!is_dir($folder)) { mkdir($folder, 0777, true); } if (move_uploaded_file($image_tmp_name, $image_folder)) { $url = 'http://localhost:5000/predict'; $cfile = new CURLFile($image_folder, 'image/jpeg', $image); $data = array('image' => $cfile); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); if ($response === false) { echo "Error in prediction!"; } else { $result = json_decode($response, true); echo "Prediction: " . $result['prediction']; } } } } ?>
排查方向
- 图像预处理不一致:
- 核对训练模型时的预处理流程,比如是否使用了ImageNet的均值和标准差归一化(ResNet50常用该预处理),若训练时做了此操作但API中未实现,会导致输入数据分布与训练时偏差过大,引发预测异常。
- 确认训练时图像的通道顺序:若训练用的是BGR通道(比如用OpenCV读取图像),而API中用PIL转成RGB,会导致颜色通道颠倒,影响模型判断。
- 模型输出逻辑匹配问题:
- 检查模型最后一层激活函数:如果是二分类用的
softmax,输出是两个类别的概率,应该用np.argmax(prediction)获取类别,而非直接和0.5比较;如果用的是sigmoid,要确认训练时正类是否对应PNEUMONIA(即标签1),以及阈值0.5是否符合训练时的设定。 - 建议在API中打印
prediction的具体数值,观察所有输入图像的预测概率是否都远大于0.5,以此区分是预处理问题还是阈值逻辑问题。
- 检查模型最后一层激活函数:如果是二分类用的
- 图像传输完整性:
- 检查PHP端上传后保存到
uploaded_img/的图像是否正常,确认无损坏、变形。 - 在Flask API中添加临时保存接收图像的代码(比如
img.save('received_test.jpg')),对比接收后的图像与原上传图像是否一致,排查传输过程中的图像损坏问题。
- 检查PHP端上传后保存到
- 模型加载准确性:
- 确认API中
path_to_your_model指向的是测试集验证过的正确模型,避免加载了旧的、未训练完成的模型文件。
- 确认API中
内容的提问来源于stack exchange,提问作者أروى صالح
相关产品推荐
相关产品推荐

