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

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')),对比接收后的图像与原上传图像是否一致,排查传输过程中的图像损坏问题。
  • 模型加载准确性:
    • 确认API中path_to_your_model指向的是测试集验证过的正确模型,避免加载了旧的、未训练完成的模型文件。

内容的提问来源于stack exchange,提问作者أروى صالح

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 23:53:21