Building and Deploying a Machine Learning Model with Flask (Model & Deploy Guide)
Photo by Joel Rivera-Camacho on Unsplash

Building and Deploying a Machine Learning Model with Flask (Model & Deploy Guide)

We have completed the first part of our project, which was building the Machine Learning model.?

Now, let’s move on to the second part: deployment. We’ve finished one universe, and now we’re entering another.

What does this?mean??

The first universe involves a vast array of techniques, procedures, tools, algorithms, and extensive knowledge required to deliver the model.?

Once that universe concludes, we step into the next one, which also demands a significant amount of techniques, tools, and procedures to deliver the result: the deployment of the digital learning model. Now, let’s delve into this second universe.

All the files mentioned in this article can be found on my GitHub repository.

What is Deployment?

Deployment is simply taking the model and using it. That’s it. You take the model and put it to use. There are various ways to do this, multiple ways to deploy a model.

?Implementation of the Model Deployment Software

Now, I will present an alternative for you, which is through a web application using the Flask Framework, also available for the Python language.?

This is not just a sequence of isolated commands or a typical Machine Learning script.

This is an application, an actual app. It has the characteristics of software because it is, indeed, software. The final part of our code proves this:

if __name__ == '__main__':
 app.run(        

This tells the Python interpreter that this is an application, a program, software that needs to be executed as a unit.?

Run as a?Unit

In Machine Learning, each step of the script is just a sequence of operations. Here, it’s different. You cannot execute the commands step-by-step; the entire script must run as a unit:?

from flask import Flask, render_template, request, jsonify
import joblib

app = Flask(__name__)

# Load the model and transformers from disk
model = joblib.load('models/logistic_model.pkl')
le_package_type = joblib.load('models/transformer_package_type.pkl')
le_product_type = joblib.load('models/transformer_product_type.pkl')

@app.route('/', methods=['GET'])
def index():
    return render_template('template.html')

@app.route('/predict', methods=['POST'])
def predict():
    weight = int(request.form['Weight'])
    package_type = le_package_type.transform([request.form['package_type']])[0]
    prediction = model.predict([[weight, package_type]])[0]
    product_type = le_product_type.inverse_transform([prediction])[0]
    return render_template('template.html', prediction=product_type)

if __name__ == '__main__':
    app.run()        

This is because the whole script is, in fact, software, a computer program. It involves software engineering characteristics, web form connections, HTTP connections, and much more. That’s why I call it another universe.

First, I import Flask, the web framework:

from flask import Flask, render_template, request, jsonify
import joblib        

Why a Web Framework?

I chose a web framework because I want an application that runs in the browser. Any application you access via your browser is a web application. There’s a web service somewhere in the world, on a server, running that service, running that application.

Since I will be running this on my local machine, I need a web service. Flask provides that for us. It offers several useful functions:

  • Flask: to create the application
  • Render Template: to load an HTML page
  • Request: to handle incoming form data and connections, allowing us to capture the data submitted through the form and prepare it for the model - JSONify: to format JSON files

This setup allows us to efficiently handle the data flow between the web interface and the Machine Learning model, making it easy to deploy and use the model in a real-world scenario.

Why Joblib?

We used Joblib to save the model. It allowed us to dump the model from the computer’s memory to disk. This is thanks to Joblib’s dump function.

# Saving the Model and Transformers
os.makedirs('models', exist_ok=True)
joblib.dump(model, 'models/decision_tree_model.pkl')
joblib.dump(le_package_type, 'models/transformer_package_type.pkl')
joblib.dump(le_product_type, 'models/transformer_product_type.pkl')        

Now, we’ll use Joblib to do the reverse: load the model back into the computer’s memory.

# Loading the Model and Transformers from Disk
model = joblib.load('models/logistic_model.pkl')
le_package_type = joblib.load('models/transformer_package_type.pkl')
le_product_type = joblib.load('models/transformer_product_type.pkl')        

Before anything else, I create a Flask app, which is the logical organization of this software.

# 1. App
app = Flask(__name__)        

I don’t have to worry about HTTP protocols, connections, or request types. Flask handles all of this for us. I just need to specify what my application will do, which I outline below. Here, I am creating the app and telling Flask to set up the entire web application infrastructure. I don’t want to worry about these details. Instead, I’ll focus on defining what my application will execute.

Executing the Flask Application

Next, we tell Flask what we want it to execute in our application. First, I load the model and transformers from disk back into the computer’s memory.

Defining Routes

Following this, I will create two routes. This is where web application knowledge with Flask comes in.?

We have completely left the data science universe and entered the web application universe with Flask.

# 3. Define the Main Route for the Home Page
@app.route('/', methods=['GET'])
def index():
 return render_template('template.html')        

The first route is the root. See the slash here? This indicates it is the root, the base of the application. How do I know it is the root? Because this is knowledge of how you build a web application.

When you access, for example, linkedin.com, you land on LinkedIn’s root application. It is generally the main address, though it doesn’t have to be.

When you land on the root, you have to load something for the browser, right??

What do I?load??

This HTML page, which I will show you soon.

# 4. Render the Home Page Using Template.html
return render_template('template.html'        

It will render an HTML page. Why does it have to do this? Because that’s how the web browser works. Every browser loads an HTML page. This HTML page can have CSS for styling and JavaScript for dynamic elements.

In fact, it is possible to train a machine learning model via a browser. There are JavaScript libraries that allow you to train a model using the web browser. However, this is quite heavy, mainly because the browser consumes a lot of RAM, but it is possible.

The render_template runction will load the HTML page that shows the form. For whom? For the user, so they can enter the package weight and select the type of packaging.

When the user clicks the Predict button, it will call another route, which is /predict.

# 5. Define a Route for Making Predictions and Accept Only POST Requests
@app.route('/predict', methods=['POST'])
def predict():
 weight = int(request.form['Weight'])
 package_type = le_package_type.transform([request.form['package_type']])[0]
 prediction = model.predict([[weight, package_type]])[0]
 product_type = le_product_type.inverse_transform([prediction])[0]
 return render_template('template.html', prediction=product_type)        

This predict function is a Python function. When the user submits the form, I will capture the weight and package type submitted through the form.

# a. Extract the 'Weight' Value from the Submitted Form
weight = int(request.form['Weight'])        

Then, I will get the package type, which also comes from the web form.

# b. Transform the Package Type Using the Previously Fitted Label Encoder
package_type = le_package_type.transform([request.form['package_type']])[0        

Attention: The package type comes in as text from the web form. Did I use text to train the Machine Learning model? No.

What do I have to do? Apply the transformer.

Every transformation applied to the training data must also be applied to the test data and new?data.

I don’t need to apply anything to the weight because I didn’t apply anything to it when training the model. For the package_type variable, I applied a transformation.?

So, I cannot give the model the text; I must provide the numerical value used for training. Thus, I transform and set the package_type.

# c. Use the Model to Make a Prediction Based on Weight and Package Type
prediction = model.predict([[weight, package_type]])[0]        

After this, I use the predict method of the model. The model will deliver the output, which is our product_type, like smartphone, tablet, etc.

# c. Use the Model to Make a Prediction Based on Weight and Package Type
prediction = model.predict([[weight, package_type]])[0]

# d. Convert the Encoded Prediction Back to Its Original Label
product_type = le_product_type.inverse_transform([prediction])[0]        

The model predicts in numeric format. Why? Let’s look at the model creation script.?

We split X and y, right? Input variable for Package_Weight_Gr and Package_Type, output variable for Product_Type.?

df = pd.DataFrame(data)
X = df[['Package_Weight_Gr', 'Package_Type']]
y = df['Product_Type']        

I performed the train-test split.

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1)        

I created the encoders for the categorical variables.

# Encoding Categorical Variables
le_package_type = LabelEncoder()
le_product_type = LabelEncoder()
X_train['Package_Type'] = le_package_type.fit_transform(X_train['Package_Type'])
X_test['Package_Type'] = le_package_type.transform(X_test['Package_Type'])
y_train = le_product_type.fit_transform(y_train)
y_test = le_product_type.transform(y_test)        

One of the categorical variables is the output variable, precisely the variable in y_train, which is Product_Type.

So, I am delivering all data to the model in numeric format. When the model predicts, I provide it with the input data in X, and it predicts the numeric value representing the Product_Type.

# Model Evaluation
y_pred = model.predict(X_test)
acc_model = accuracy_score(y_test, y_pred)
report = classification_report(y_test, y_pred)        

In this case, it predicts 0, 1. I then compare the model’s prediction y_pred with y_test. Both are numbers, and I calculate the accuracy.

But now there’s a problem. When the model makes a prediction, I need to present the prediction to the end user. The end user doesn’t want to see 0 and 1. They will ask what it means. So, I take the transformer loaded above and reverse the transformation.

#  c. Load the Model and Transformers from Disk
le_product_type = joblib.load('models/transformer_product_type.pkl')

# d. Convert the Encoded Prediction Back to Its Original Label
product_type = le_product_type.inverse_transform([prediction])[0]        

I must use the same transformer. When the model predicts, it predicts a numeric value. I reverse the transformation, converting 0 back to the corresponding text and 1 back to the text.

Finally, I render the web page again, filling in the product type.

# e. Render the Initial Page with the Prediction Included
return render_template('template.html', prediction=product_type)        

The user sees the predicted product types available. To finalize, I create the application indicating to the Python interpreter that this is software.

# 6. App
if __name__ == '__main__':
 app.run()        

This software will now run as a unit. All pieces must be executed for the software to function via the web application. Thus, we conclude the entire project construction.

Executing the?Project

Let’s conclude the project by running it, putting our model into production. To execute, keep a web page open.

Start the application. Go to the terminal, navigate to the folder where you saved the files, and type:

python deploy.py        

Press Enter, wait a few moments, and Flask will be running. It prompts you to open the address that appears, such as https://127.0.0.1:5000

Copy this address, go to your browser, paste it, press Enter, and your application is live.

You are now accessing the application. What is this form? When I click the Predict button, it calls the predict method. Opening the application in the web browser executes this main route, which is the root.

# 3. Define the Main Route for the Home Page and Accept Only GET Requests
@app.route('/', methods=['GET'])
def index():
 return render_template('template.html')        

This route loads the HTML, showing the form. When you click the “Predict” button, it calls the /predict method, executing all this:

# a. Extract the 'Weight' Value from the Submitted Form
weight = int(request.form['Weight'])

# b. Transform the Package Type Using the Previously Fitted Label Encoder
package_type = le_package_type.transform([request.form['package_type']])[0]

# c. Use the Model to Make a Prediction Based on Weight and Package Type
prediction = model.predict([[weight, package_type]])[0]

# d. Convert the Encoded Prediction Back to Its Original Label
product_type = le_product_type.inverse_transform([prediction])[0]

# e. Render the Initial Page with the Prediction Included
return render_template('template.html', prediction=product_type)        

It takes the form data, processes it, renders the page again, and displays the prediction. It is essential to see the HTML page now.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Machine Learning Model Deployment</title>
    <style>
        body {
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
            background-color: #f5f5f7;
            color: #333;
            margin: 0;
            padding: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
        }
        .container {
            background: #fff;
            padding: 40px;
            border-radius: 12px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
            width: 100%;
            max-width: 500px;
            text-align: center;
        }
        h1 {
            font-size: 24px;
            font-weight: 600;
            margin-bottom: 30px;
        }
        label {
            display: block;
            margin-bottom: 10px;
            font-size: 16px;
            color: #555;
            text-align: left;
        }
        input[type="text"], select {
            width: 100%;
            padding: 12px 20px;
            margin-bottom: 20px;
            border: 1px solid #ddd;
            border-radius: 8px;
            box-sizing: border-box;
            font-size: 16px;
        }
        input[type="submit"] {
            background-color: #0071e3;
            color: white;
            padding: 14px 20px;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            font-size: 16px;
            font-weight: 600;
            transition: background-color 0.3s ease;
        }
        input[type="submit"]:hover {
            background-color: #005bb5;
        }
        .prediction {
            margin-top: 20px;
            padding: 20px;
            background-color: #f0f0f5;
            border: 1px solid #dcdcdc;
            border-radius: 8px;
            font-size: 18px;
            font-weight: 500;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Machine Learning Model Deployment</h1>
        <form method="POST" action="/predict">
            <label for="Weight">Package Weight (grams):</label>
            <input type="text" id="Weight" name="Weight" required>
            <label for="package_type">Package Type:</label>
            <select id="package_type" name="package_type" required>
                <option value="Cardboard Box">Cardboard Box</option>
                <option value="Bubble Wrap">Bubble Wrap</option>
            </select>
            <input type="submit" value="Predict">
        </form>
        {% if prediction %}
        <div class="prediction">
            <h2>Prediction: {{ prediction }}</h2>
        </div>
        {% endif %}
    </div>
</body>
</html>        

The HTML defines a page where the user can enter data for predicting a Machine Learning model. The form action sends this data via POST method to the predict function, which processes the data and returns the prediction.

The predict function takes the package weight and type entered by the user, transforms this data, and passes it to the Machine Learning model to get the prediction. The function then displays this prediction on the page. The Flask framework manages all this communication between the web page and the Python function that processes the prediction.

The user fills out the form with the weight and packaging type, and upon clicking Predict, the data is sent to the server, which processes the prediction and returns the result displayed on the page. Flask simplifies this interaction by handling the communication between the form and the Python function.

We have successfully built and deployed our Machine Learning application. Does it take work? Yes, of course. Many steps are involved, and you need extensive knowledge to put it all together. This is a simple project, but to do much more complex things, make sure you understand the process well.?

Thank you!

要查看或添加评论,请登录