I am currently trying to build a simple ML web app, that takes the input image from the user and displays the image and model's prediction result on output page.
Model itself is simply image classification model, train with Cat vs. Dogs image data from Kaggle, built with Keras.
I'm having a trouble with last step - I had no issue with displaying the input image at the result page, but when I try to display the model's prediction as well, it shows an internal server error:
"The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application."
Here is my app_ml.py file
from flask import Flask, render_template, request, session
import os
import keras
from keras.preprocessing import image
import numpy as np
import pickle
from werkzeug.utils import secure_filename
# WSGI Application
# Defining upload folder path
UPLOAD_FOLDER = os.path.join('static', 'uploads')
# Define allowed files
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.secret_key = 'This is your secret key to utilize session in Flask'
filename = 'cats-dogs_small_2.pkl'
model = pickle.load(open(filename, 'rb'))
@app.route('/')
def home():
return render_template('home.html')
@app.route('/', methods=("POST", "GET"))
def uploadFile():
if request.method == 'POST':
# Upload file flask
uploaded_img = request.files['uploaded-file']
# Extracting uploaded data file name
img_filename = secure_filename(uploaded_img.filename)
# Upload file to database (defined uploaded folder in static path)
uploaded_img.save(os.path.join(app.config['UPLOAD_FOLDER'], img_filename))
# Storing uploaded file path in flask session
session['uploaded_img_file_path'] = os.path.join(app.config['UPLOAD_FOLDER'], img_filename)
return render_template('home2.html')
@app.route('/result')
def displayImage():
# Retrieving uploaded file path from session
img_file_path = session.get('uploaded_img_file_path', None)
img = image.load_img(img_file_path, target_size=(150, 150))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
images = np.vstack([x])
classes = model.predict(images/255.0, batch_size=8, verbose=0)
pic = os.path.join(app.config['UPLOAD_FOLDER'], imagefile.filename)
if classes[0]>0.5:
return render_template('result.html', user_image=pic, prediction_text='this is likely to be cat')
else:
return render_template('result.html', user_image=pic, prediction_text='this is likely to be dog')
if __name__ == '__main__':
app.run(debug=True)
here is my home2.html (home.html takes user input, and home2.html simply gets changed to 'upload complete').
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href='/static/styles.css' />
</head>
<body>
<h1>Upload and display image in Flask</h1>
<p>Show image in html using FLASK</p>
<form method="POST" enctype="multipart/form-data" action="/">
<input type="file" id="myFile" name="uploaded-file" accept=".png">
<input type="submit" value="Submit">
</form>
<br>
<p style="color:green;">File uploaded successfully</p>
<form action="/result" target="_blank">
<input type="submit" value="Display Image" />
</form>
</body>
</html>
and here is my result.html, where I try to display both image and model prediction result.
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href='/static/styles.css' />
</head>
<body>
<h1>Upload and display image in Flask</h1>
<p>flask display image from uploaded folder</p>
<img src="{{ user_image }}" alt="Italian Trulli" width="500" height="400">
<div id ="prediction_text">
<strong style="color:red">{{prediction_text}}</strong>
</div>
</body>
</html>
I will appreciate if someone can help me what am I doing wrong with either py file / html file / or both.