用Python將Keras深度學習模型部署爲Web應用程序

做者|Will Koehrsen
編譯|Flin
來源|towardsdatasciencecss

構建一個很棒的機器學習項目是一回事,但歸根結底,你但願其餘人可以看到你的辛勤工做。固然,你能夠將整個項目放在GitHub上,可是怎麼讓你的祖父母也看到呢?咱們想要的是將深度學習模型部署爲世界上任何人均可以訪問的Web應用程序。html

在本文中,咱們將看到如何編寫一個Web應用程序,該應用程序使用通過訓練的Keras遞歸神經網絡,並容許用戶生成新的專利文摘。這個項目創建在遞歸神經網絡的基礎上,可是瞭解如何建立RNN是沒必要要的。前端

如今咱們將其視爲黑匣子:咱們按一個開始的順序進行操做,它輸出一個全新的專利文摘,能夠在瀏覽器中顯示!python

傳統上,數據科學家會開發模型,而前端工程師則將模型展現給全世界。在這個項目中,咱們必須扮演兩個角色,並投入到Web開發中(儘管幾乎所有使用Python)。git

該項目須要將衆多主題結合在一塊兒:github

最終結果是一個網絡應用程序,該應用程序容許用戶使用通過訓練的循環神經網絡生成全新的專利文摘:

該項目的完整代碼可在GitHub上找到。

方法

目的是使Web應用程序儘快啓動並運行。爲此,我選擇了Flask,它容許咱們用Python編寫應用程序。我不喜歡搞亂樣式(這清楚地顯示了),因此幾乎全部的CSS都是複製和粘貼的。

Keras團隊的這篇文章(https://blog.keras.io/building-a-simple-keras-deep-learning-rest-api.html) 對基礎知識頗有幫助,本文也是一個有用的指南。

整體而言,該項目遵循個人設計原則:快速啓動並運行原型——根據須要進行復制和粘貼,而後進行迭代以製做出更好的產品。

帶Flask的基本Web應用程序

用Python構建Web應用程序的最快方法是使用Flask。要製做本身的應用程序,咱們可使用如下內容:

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "<h1>Not Much Going On Here</h1>"

app.run(host='0.0.0.0', port=50000)

若是你複製並粘貼此代碼並運行它,則能夠在 localhost:50000上查看本身的Web應用程序。固然,咱們還想作更多的事情,因此咱們將使用稍微複雜一點的功能,該功能基本上能夠完成相同的工做:處理來自瀏覽器的請求,並以HTML形式提供一些內容。對於咱們的主頁,咱們想向用戶顯示一個表單以輸入一些詳細信息。

用戶輸入表

當用戶到達應用程序的主頁時,咱們將向他們顯示一個帶有三個參數的表單供你選擇:

  1. 輸入RNN的開始序列或隨機選擇
  2. 選擇RNN預測的多樣性
  3. 選擇RNN輸出的字數

要在Python中構建表單,咱們將使用wtforms。建立表單的代碼爲:

from wtforms import (Form, TextField, validators, SubmitField, 
DecimalField, IntegerField)

class ReusableForm(Form):
    """User entry form for entering specifics for generation"""
    # Starting seed
    seed = TextField("Enter a seed string or 'random':", validators=[
                     validators.InputRequired()])
    # Diversity of predictions
    diversity = DecimalField('Enter diversity:', default=0.8,
                             validators=[validators.InputRequired(),
                                         validators.NumberRange(min=0.5, max=5.0,
                                         message='Diversity must be between 0.5 and 5.')])
    # Number of words
    words = IntegerField('Enter number of words to generate:',
                         default=50, validators=[validators.InputRequired(),
                                                 validators.NumberRange(min=10, max=100, 
                                                 message='Number of words must be between 10 and 100')])
    # Submit button
    submit = SubmitField("Enter")

這將建立以下所示的表單(樣式來自main.css):

validator代碼確保用戶輸入正確的信息。例如,咱們檢查全部框是否都已填寫,且其diversity介於0.5到5之間。必須知足這些條件才能接受該表格。

咱們Flask實際提供表單的方式是使用模板。

模板

模板是一個包含基本框架的文檔,咱們須要用它來填充細節。對於Flask Web應用程序,咱們可使用Jinja模板庫將Python代碼傳遞到HTML文檔。例如,在main函數中,咱們將把表單的內容發送到一個名爲index.html的文件.

from flask import render_template

# Home page
@app.route("/", methods=['GET', 'POST'])
def home():
    """Home page of app with form"""
    # Create form
    form = ReusableForm(request.form)

    # Send template information to index.html
    return render_template('index.html', form=form)

當用戶到達主頁時,咱們的應用程序將提供index.html表格上的細節。該模板是一個簡單的html框架,咱們在其中使用{{variable}}語法引用python變量。

<!DOCTYPE html>
<html>

<head>
  <title>RNN Patent Writing</title>
  <link rel="stylesheet" href="/static/css/main.css">
  <link rel="shortcut icon" href="/static/images/lstm.ico">
  
</head>

<body>
  <div class="container">
    <h1>
      <center>Writing Novel Patent Abstracts with Recurrent Neural Networks</center>
    </h1>

    {% block content %}
    {% for message in form.seed.errors %}
    <div class="flash">{{ message }}</div>
    {% endfor %}

    {% for message in form.diversity.errors %}
    <div class="flash">{{ message }}</div>
    {% endfor %}

    {% for message in form.words.errors %}
    <div class="flash">{{ message }}</div>
    {% endfor %}

    <form method=post>

      {{ form.seed.label }}
      {{ form.seed }}

      {{ form.diversity.label }}
      {{ form.diversity }}

      {{ form.words.label }}
      {{ form.words }}

      {{ form.submit }}
    </form>
    {% endblock %}

  </div>
</body>

</html>

對於表單中的每一個錯誤(那些沒法驗證的條目),對應的一個錯誤將閃爍。除此以外,此文件將顯示上述表單。

當用戶輸入信息並點擊submit(POST請求)時,若是信息是正確的,咱們但願將輸入轉移到適當的函數,以使用通過訓練的RNN進行預測。這意味着修改home()

from flask import request
# User defined utility functions
from utils import generate_random_start, generate_from_seed

# Home page
@app.route("/", methods=['GET', 'POST'])
def home():
    """Home page of app with form"""
    
    # Create form
    form = ReusableForm(request.form)

    # On form entry and all conditions met
    if request.method == 'POST' and form.validate():
        # Extract information
        seed = request.form['seed']
        diversity = float(request.form['diversity'])
        words = int(request.form['words'])
        # Generate a random sequence
        if seed == 'random':
            return render_template('random.html', 
                                   input=generate_random_start(model=model, 
                                                               graph=graph, 
                                                               new_words=words, 
                                                               diversity=diversity))
        # Generate starting from a seed sequence
        else:
            return render_template('seeded.html', 
                                   input=generate_from_seed(model=model, 
                                                            graph=graph, 
                                                            seed=seed, 
                                                            new_words=words, 
                                                            diversity=diversity))
    # Send template information to index.html
    return render_template('index.html', form=form)

如今,當用戶點擊submit而且信息正確時,根據輸入的不一樣,輸入將被髮送到generate_random_startgenerate_from_seed。這些函數使用通過訓練的Keras模型生成具備用戶指定的diversitynum_words的新穎專利。這些函數的輸出依次被髮送到其中一個模板random.html或者seeded.html做爲一個網頁。

使用預先訓練的Keras模型進行預測

模型參數是通過訓練的Keras模型,加載以下:

from keras.models import load_model
import tensorflow as tf

def load_keras_model():
    """Load in the pre-trained model"""
    global model
    model = load_model('../models/train-embeddings-rnn.h5')
    # Required for model to work
    global graph
    graph = tf.get_default_graph()
    
load_keras_model()

tf.get_default_graph()是基於這個要點的一種解決方案。

我將不展現這兩個util函數的所有內容(這裏是代碼),你須要理解的是它們使用通過訓練的Keras模型以及參數,並對新的專利文摘進行預測。

這些函數都返回帶有格式化HTML的Python字符串。該字符串被髮送到另外一個模板以呈現爲網頁。例如,generate_random_start返回格式爲html,返回結果爲random.html

<!DOCTYPE html>
<html>

<header>
    <title>Random Starting Abstract
    </title>

    <link rel="stylesheet" href="/static/css/main.css">
    <link rel="shortcut icon" href="/static/images/lstm.ico">
    <ul>
        <li><a href="/">Home</a></li>
    </ul>
</header>

<body>
    <div class="container">
        {% block content %}
        {{input|safe}}
        {% endblock %}
    </div>
</body>

</html>

這裏咱們再次使用Jinja模板引擎來顯示格式化的HTML。由於Python字符串已經被格式化爲HTML,咱們所要作的就是使用{{input| safe}}(其中input是Python變量)來顯示它。而後咱們就能夠在main.css設計這個頁面的樣式了, 和其餘html模板同樣。

輸出量

generate_random_start選擇一個隨機的專利文摘做爲開始序列,並根據該摘要進行預測。而後顯示開始順序,RNN生成的輸出和實際輸出:

該函數generate_from_seed採用用戶提供的起始序列,而後使用通過訓練的RNN對其進行構建。輸出以下:

儘管結果並不老是徹底正確,但它們確實代表遞歸神經網絡已經學習了英語的基礎知識。通過訓練,能夠預測前50個單詞中的下一個單詞,並掌握瞭如何撰寫具備說服力的專利文摘!

根據預測的多樣性,輸出多是徹底隨機的或循環的。

運行應用

要本身運行該應用程序,你所須要作的就是下載存儲庫,導航到該deployment目錄並輸入python run_keras_server.py。這將當即使Web應用程序在localhost:10000可用。

根據家庭WiFi的配置方式,你應該可以使用IP地址從網絡上的任何計算機訪問該應用程序。

下一步

你的我的計算機上運行的Web應用程序很是適合與朋友和家人共享。我絕對不建議你向家庭網絡中的全部人開放此功能!爲此,咱們想要在AWS EC2實例上設置應用程序並將其提供給全世界(稍後發佈)。

爲了改善應用程序,咱們能夠(經過main.css)更改樣式,並可能添加更多選項,例如選擇通過預先訓練的網絡的功能。關於我的項目的偉大之處在於,你能夠根據須要擴展它們。若是你想使用該應用程序,請下載代碼並開始使用。

結論

在本文中,咱們看到了如何將訓練有素的Keras深度學習模型部署爲Web應用程序。這須要將多種不一樣的技術結合在一塊兒,包括遞歸神經網絡,Web應用程序,模板,HTML,CSS,固然還有Python。

雖然這只是一個基本的應用程序,但它代表你能夠開始使用深度學習來構建web應用程序,而不須要花費太多的精力。

submit = SubmitField("Enter")

在訓練模型中加載。

原文連接:https://towardsdatascience.com/stop-worrying-and-create-your-deep-learning-server-in-30-minutes-bb5bd956b8de

歡迎關注磐創AI博客站:
http://panchuang.net/

sklearn機器學習中文官方文檔:
http://sklearn123.com/

歡迎關注磐創博客資源彙總站:
http://docs.panchuang.net/

相關文章
相關標籤/搜索