用Flask在伺服器上部署訓練好的模型

yifanwu發表於2021-09-09

本教程的三個部分是:

1、先訓練好一個模型

2、構建Flask微框架所需的元件以建立Web app

3、執行web app

需要安裝的元件

如果要從此頁面複製和貼上程式碼,請確保已安裝以下元件:

Python 3.6+
python packages:
Flask
Pandas
Sklearn
Xgboost
Seaborn
Matplotlib

複製程式碼

1、先訓練好一個模型

模型這裡我就不闡述了, 隨便什麼模型都可以,不管是用tensorflow還是用pytorch寫的,也都行。

2、構建Flask微框架所需的元件以建立Web app

我們需要做一些事情將Web app整合在一起:

a、Python程式碼 包括載入我們訓練好的模型,從Web表單獲取使用者輸入,進行預測並返回結果

b、HTML模板 允許使用者輸入自己的資料並顯示結果

該web app的初始結構如下:

圖片描述

首先我將建立一個非常基本的app.py和main.html,以演示flask如何工作。我們將在後面擴充套件程式以適應我們的需求

app.py

這是web app的核心。它將在伺服器上執行,傳送網頁並處理使用者的輸入

import flask
app = flask.Flask(__name__, template_folder='templates')
@app.route('/')
def main():
    return(flask.render_template('main.html'))
if __name__ == '__main__':
    app.run(host = '0.0.0.0')
複製程式碼

main.html

這就是前端的介面。它現在所做的只是顯示一條簡單的訊息,我們稍後將對其進行編輯以適合我們的需求





Web app name

Hello world.

複製程式碼

Running the test app

要在伺服器上先啟動flask,開啟終端,請確保您位於該webapp資料夾中,然後執行以下命令: flask run

圖片描述 然後按CTRL+C退出

再執行app.python檔案 python app.python

圖片描述

然後在本地電腦的瀏覽器中輸入(127.0.0.1:5000),由於我們是在伺服器上部署的,所以應該把127.0.0.1替換成訪問伺服器的域名 ,假如還是不行,有可能是5000埠沒有開

圖片描述

到這裡我們的一個基本web app已經完成了,接下來我們將需要再修改程式,使其滿足我們的需求。

我用我寫的模型進行修改,你們只需要按照你們的模型進行相應的修改就行了 我訓練好的是一個食物識別的模型,用tensorflow寫的,我把訓練好的模型儲存到model/下

圖片描述

然後加在我的模型,載入模型的相關程式碼是

model = 'R50+ViT-B_16'
VisionTransformer = models.KNOWN_MODELS[model].partial(num_classes=172)
params = checkpoint.load(f'/model/best_model.npz')
params['pre_logits'] = {}  # Need to restore empty leaf for Flax.
複製程式碼

如果你用的pytorch寫的模型,載入模型的程式碼可以參考

# Use pickle to load in the pre-trained model.
with open(f'./model/bike_model_xgboost.pkl', 'rb') as f:
    model = pickle.load(f)
複製程式碼

模型載入好了,我做的是圖片識別,我要從前端獲取上傳的照片,然後做預測再返回

先把照片儲存到資料夾下來,我在前端main.html檔案中是使用標籤來上傳照片的

#當前絕對路徑
basedir = os.path.abspath(os.path.dirname(__file__))
f = request.files.get('file')
# 獲取安全的檔名 正常的檔名
filename = secure_filename(f.filename)


# f.filename.rsplit('.', 1)[1] 獲取檔案的字尾
# 把檔案重新命名
filename = datetime.now().strftime("%Y%m%d%H%M%S") + "." + "JPG"
print(filename)
# 儲存的目標絕對地址
file_path = basedir + "/images/"
# 儲存檔案到目標資料夾
f.save(file_path + filename)
複製程式碼

獲取照片,做預測,返回結果

img = PIL.Image.open('./images/' + filename)
img = img.resize((384,384))
logits, = VisionTransformer.call(params, (np.array(img) / 128 - 1)[None, ...])
#後面就是做softmax,得到機率最大值的結果,然後返回預測結果
preds = flax.nn.softmax(logits)
labels = dict(enumerate(open('labels.txt'),start=1))
for idx in preds.argsort()[:-11:-1]:
    print(f'{preds[idx]:.5f} : {labels[idx+1]}', end='')
    predict = labels[idx+1]
    break
predict = predict[1:-1]
print(predict)
return flask.render_template('main.html', result = predict,)
 
複製程式碼

整個app.py的程式碼

import flask
import pickle
import pandas as pd
from datetime import datetime
from flask import Flask, request, jsonify
import os
from werkzeug.utils import secure_filename
from vit_jax import models
from vit_jax import checkpoint
import flax
import PIL
import numpy as np

#當前絕對路徑
basedir = os.path.abspath(os.path.dirname(__file__))

# Initialise the Flask app
app = flask.Flask(__name__, template_folder='templates')

# Set up the main route
@app.route('/', methods=['GET', 'POST'])
def main():
    if flask.request.method == 'GET':
        # Just render the initial form, to get input
        return(flask.render_template('main.html'))
    
    if flask.request.method == 'POST':
        f = request.files.get('file')
        # 獲取安全的檔名 正常的檔名
        filename = secure_filename(f.filename)
        
        # f.filename.rsplit('.', 1)[1] 獲取檔案的字尾
        # 把檔案重新命名
        filename = datetime.now().strftime("%Y%m%d%H%M%S") + "." + "JPG"
        print(filename)
        # 儲存的目標絕對地址
        file_path = basedir + "/images/"
        # 儲存檔案到目標資料夾
        f.save(file_path + filename)
        
        #載入模型
        model = 'R50+ViT-B_16'
        VisionTransformer = models.KNOWN_MODELS[model].partial(num_classes=172)
        params = checkpoint.load(f'./model/best_model.npz')
        params['pre_logits'] = {}  # Need to restore empty leaf for Flax.
 
        #讀取圖片,做預測,返回結果
        img = PIL.Image.open('./images/' + filename)
        img = img.resize((384,384))
        logits, = VisionTransformer.call(params, (np.array(img) / 128 - 1)[None, ...])
        labels = dict(enumerate(open('labels.txt'),start=1))
        preds = flax.nn.softmax(logits)
        for idx in preds.argsort()[:-11:-1]:
            print(f'{preds[idx]:.5f} : {labels[idx+1]}', end='')
            predict = labels[idx+1]
            break
        predict = predict[1:-1]
        return flask.render_template('main.html', result = predict,)
 
if __name__ == '__main__':
    app.run(host = '0.0.0.0')
    
    

複製程式碼

app.py前後端互動就寫好了,現在開始修改前端介面

由於我要的輸入是一張圖片,所以我要上傳圖片,如果你要的輸入是文字,你就用文字框就行了





Food Recognition Model
Input values:

{% if result %}
The food is:

{{ result }}

{% endif %}
複製程式碼

到這裡,整個web app我們就完成了,現在趕快試一試吧

3、執行web app

在終端輸入python app.py

然後再瀏覽器輸入(換成自己的域名)

圖片描述

圖片描述

作者:PeterHai
連結:
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2157/viewspace-2797575/,如需轉載,請註明出處,否則將追究法律責任。

相關文章