[Python] Flask API Always Predicts the Same Class When Called from PHP Script

Discussão em 'Python' iniciado por Stack, Novembro 28, 2024.

  1. Stack

    Stack Membro Participativo

    I have developed an API using Flask to integrate a deep learning model trained on chest X-ray images for pneumonia detection. To test the connection between PHP and the Flask API, I used the Fashion MNIST model (for clothing classification) successfully, and the model was predicting classes correctly.

    However, when I try to use my custom trained model for pneumonia detection (which performs very well during evaluation), I noticed that the model always predicts the class "PNEUMONIA" even when the image is in the "NORMAL" class.

    Model Performance (on test set):

    Test loss: 11.41 % Test accuracy: 97.10 % Test precision: 97.46 % Test recall: 98.60 % Test AUC: 98.33 %

    Steps Taken:

    Training: I trained the model using ResNet50 layers with additional custom layers.

    Testing: I tested the model on a test set containing NORMAL and PNEUMONIA images, and it performed well.

    Testing via Flask API: I tried sending images via PHP to the Flask API, but the model always predicts "PNEUMONIA".

    Flask API Code:

    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 Code to Send Image to Flask API:

    <?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'];
    }
    }
    }
    }
    ?>



    Issue: Despite the model working well when tested locally with good performance metrics on NORMAL and PNEUMONIA images, when I test it through the Flask API (via PHP), the model always predicts "PNEUMONIA", even when the image is from the "NORMAL" class.

    Is there any issue with the way I'm sending the image or how the Flask API is processing it?

    Continue reading...

Compartilhe esta Página