ニューラルネットワークをウェブサイトにすばやく接続する方法





この資料では、少しの努力で、python 3.7+フラスコ+ tensorflow 2.0 + keras + jsの小さなインクルージョンを接続し、Webページに特定の対話性を表示することを提案しています。キャンバス上に描画しているユーザーは、認識のために番号を送信し、CNNアーキテクチャを使用して以前にトレーニングされたモデルは、結果の描画を認識し、結果を出力します。このモデルは、よく知られている手書き数字MNISTのセットでトレーニングされているため、0から9までの数字のみを認識します。Windows 7は、これらすべてが回転するシステムとして使用されます。



簡単な紹介



機械学習の本の悲しい点は、本自体が公開されるとすぐにコードが古くなることです。そして、出版物の作者が彼の子供をサポートし、コードを維持および更新するのは良いことですが、多くの場合、すべてが彼らが書いたものに制限されています-これがrequirements.txtであり、古いパッケージをインストールし、すべてが機能します。



今回もそうだった。 Anubhav Singh、SayakPaulによるWeb用のハンズオンPythonDeep Learningを読んで、最初はすべてうまくいきました。しかし、最初の章の後、休日は終わりました。最も不快なことは、要件に記載されている要件が一般的に遵守されていることでした。



tensorflowおよびkerasパッケージの開発者自身が、火に燃料を追加しました。 1つのパッケージは、特定の他のパッケージと、それらの1つのダウングレードまたはシャーマンのタンバリンのいずれかでのみ機能します。

しかし、それだけではありません。一部のパッケージもアーキテクチャに依存していることがわかりました。



そのため、アイロンに代わるものがない場合、Tensorflow2.0はCeleronj1900を搭載したプラットフォームにインストールされ、AVX2命令はありませんでした。





そして、pip installtensorflowを介したオプション 機能しませんでした。



しかし、すべてが欲望とインターネットでそれほど悲しいわけではありません!



tensorflow 2.0のバリアントは、ホイールを介して実装されました -github.com/fo40225/tensorflow-windows-wheel/tree/master/2.0.0/py37/CPU/sse2およびx86のインストール:vc_redist.x86.exe、x64:vc_redist.x64 .exe(https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads)。



Kerasは、tensorflowと「互換性を持つようになった」最小バージョンでインストールされました-Keras == 2.3.0。



したがって、



pip install tensorflow-2.0.0-cp37-cp37m-win_amd64.whl
      
      





そして



pip install keras==2.3.0
      
      





主な用途



メインプログラムのコードを考えてみましょう。



フラスコ_app.py

#code work with scipy==1.6.1, tensorflow @ file:///D:/python64/tensorflow-2.0.0-cp37-cp37m-win_amd64.whl,
#Keras==2.3.0

from flask import Flask, render_template, request
import imageio
#https://imageio.readthedocs.io/en/stable/examples.html
#from scipy.misc import imread, imresize
#from matplotlib.pyplot import imread
import numpy as np
import tensorflow as tf
from tensorflow.keras.models import model_from_json
from skimage import transform,io

json_file = open('model.json','r')
model_json = json_file.read()
json_file.close()
model = model_from_json(model_json)
model.load_weights("weights.h5")
model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
#graph = tf.get_default_graph()
graph = tf.compat.v1.get_default_graph()

app = Flask(__name__)

@app.route('/')
def index():
    return render_template("index.html")
import re
import base64

def convertImage(imgData1):
    imgstr = re.search(r'base64,(.*)', str(imgData1)).group(1)
    with open('output.png', 'wb') as output:
        output.write(base64.b64decode(imgstr))

@app.route('/predict/', methods=['GET', 'POST'])
def predict():
    global model, graph
    
    imgData = request.get_data()
    convertImage(imgData)
    #print(imgData)
   
    #x = imread('output.png', mode='L')
    #x.shape
    #(280, 280)
    x = imageio.imread('output.png',pilmode='L')
    #x = imresize(x, (28, 28))
    #x = x.resize(x, (28, 28))
    x = transform.resize(x, (28,28), mode='symmetric', preserve_range=True)
    #(28, 28)
    #type(x)
    #<class 'numpy.ndarray'>

    x = x.reshape(1, 28, 28, 1)
    #(1, 28, 28, 1) 
    x = tf.cast(x, tf.float32)
    
    # perform the prediction
    out = model.predict(x)        
    #print(np.argmax(out, axis=1))
    # convert the response to a string
    response = np.argmax(out, axis=1)
    return str(response[0])

if __name__ == "__main__":
    # run the app locally on the given port
    app.run(host='0.0.0.0', port=80)
# optional if we want to run in debugging mode
    app.run(debug=True)

      
      









アップロードされたパッケージ:


from flask import Flask, render_template, request
import imageio
#https://imageio.readthedocs.io/en/stable/examples.html
#from scipy.misc import imread, imresize
#from matplotlib.pyplot import imread
import numpy as np
import tensorflow as tf
from tensorflow.keras.models import model_from_json
from skimage import transform,io

      
      





imreadが発見したように、imresizeはscipy == 1.0以降非推奨になっています。この本が比較的新しい(2019)ことを考えると、すべてが著者にとってどのように機能したかは不明です。最新のscipy == 1.6.1では、本っぽいバージョンのコードは機能しませんでした。



ディスクからロードし、ニューラルネットワークモデルをコンパイルします。




json_file = open('model.json','r')
model_json = json_file.read()
json_file.close()
model = model_from_json(model_json)
model.load_weights("weights.h5")
model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
#graph = tf.get_default_graph()
graph = tf.compat.v1.get_default_graph()

      
      





ここでは、互換性がないため、tf.compat.v1.get_default_graph()に置き換えました。



次はフラスコサーバー部分です。ページテンプレートの「描画」:




@app.route('/')
def index():
    return render_template("index.html")

      
      





画像を数値配列に変換する部分:




import re
import base64

def convertImage(imgData1):
    imgstr = re.search(r'base64,(.*)', str(imgData1)).group(1)
    with open('output.png', 'wb') as output:
        output.write(base64.b64decode(imgstr))

      
      





主な予測機能:




def predict():
    global model, graph
    
    imgData = request.get_data()
    convertImage(imgData)
    #print(imgData)
   
    #x = imread('output.png', mode='L')
    #x.shape
    #(280, 280)
    x = imageio.imread('output.png',pilmode='L')
    #x = imresize(x, (28, 28))
    #x = x.resize(x, (28, 28))
    x = transform.resize(x, (28,28), mode='symmetric', preserve_range=True)
    #(28, 28)
    #type(x)
    #<class 'numpy.ndarray'>

    x = x.reshape(1, 28, 28, 1)
    #(1, 28, 28, 1) 
    x = tf.cast(x, tf.float32)
    
    # perform the prediction
    out = model.predict(x)        
    #print(np.argmax(out, axis=1))
    # convert the response to a string
    response = np.argmax(out, axis=1)
    return str(response[0])

      
      





行はコメントアウトされ、作業行に置き換えられました。また、明確にするために、個別の行の結論も残されています。



使い方



Pythonのflask_app.pyコマンド起動すると、 ローカルのフラスコサーバーが起動し、jsが散在するindex.htmlが表示されます。



ユーザーはキャンバスに数字を描き、「予測」をクリックします。画像はサーバーに「飛んで」、そこで保存されてデジタル配列に変換されます。次に、CNNは数字を認識し、数字の形式で答えを返すことで、戦いに参加します。



ネットワークは常に正しい答えを与えるとは限りません。たった10年間勉強しました。これは、さまざまな方法で解釈できる「物議を醸す」図を描く場合に観察できます。



*スライダーを回して、認識のために数字の輪郭の太さを増減できます。



プログラムの2番目のバージョンは、API、curlを介したものです。



ユーザーは、認識用の番号が付いた画像をサーバーにアップロードし、[送信]をクリックします







。index.jsを次のように置き換えましょう。



index.js:
$("form").submit(function(evt){
	evt.preventDefault();
	var formData = new FormData($(this)[0]);
	$.ajax({
		url: '/predict/',
		type: 'POST',
		data: formData,
		async: false,
		cache: false,
		contentType: false,
		enctype: 'multipart/form-data',
		processData: false,
		success: function (response) {
			$('#result').empty().append(response);
		}
	});
	return false;
});

      
      







ページテンプレートも変更されます。



index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>MNIST CNN</title>
</head>
<body>
<h1>MNIST Handwritten Digits Prediction</h1>
<form>
<input type="file" name="img"></input>
<input type="submit"></input>
</form>
<hr>
<h3>Prediction: <span id="result"></span></h3>
<script
src='https://code.jquery.com/jquery-3.6.0.min.js'></script>
<script src="{{ url_for('static',filename='index.js') }}"></script>
</body>
</html>

      
      







メインプログラムもわずかに変更されます。



フラスコ_app2.py

#code work with scipy==1.6.1, tensorflow @ file:///D:/python64/tensorflow-2.0.0-cp37-cp37m-win_amd64.whl,
#Keras==2.3.0

from flask import Flask, render_template, request
import imageio
#https://imageio.readthedocs.io/en/stable/examples.html
#from scipy.misc import imread, imresize
#from matplotlib.pyplot import imread
import numpy as np
import tensorflow as tf
from tensorflow.keras.models import model_from_json
from skimage import transform,io


json_file = open('model.json','r')
model_json = json_file.read()
json_file.close()
model = model_from_json(model_json)
model.load_weights("weights.h5")
model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
#graph = tf.get_default_graph()
graph = tf.compat.v1.get_default_graph()

app = Flask(__name__)

@app.route('/')
def index():
    return render_template("index.html")

import re
import base64

def convertImage(imgData1):
    imgstr = re.search(r'base64,(.*)', str(imgData1)).group(1)
    with open('output.png', 'wb') as output:
        output.write(base64.b64decode(imgstr))

@app.route('/predict/', methods=['POST'])
def predict():
    global model, graph
    
    imgData = request.get_data()
    try:
        stringToImage(imgData)
    except:
        f = request.files['img']
        f.save('image.png')
       
    #x = imread('output.png', mode='L')
    #x.shape
    #(280, 280)
    x = imageio.imread('image.png',pilmode='L')
    #x = imresize(x, (28, 28))
    #x = x.resize(x, (28, 28))
    x = transform.resize(x, (28,28), mode='symmetric', preserve_range=True)
    #(28, 28)
    #type(x)
    #<class 'numpy.ndarray'>

    x = x.reshape(1, 28, 28, 1)
    #(1, 28, 28, 1) 
    x = tf.cast(x, tf.float32)
    
    # perform the prediction
    out = model.predict(x)        
    #print(np.argmax(out, axis=1))
    # convert the response to a string
    response = np.argmax(out, axis=1)
    return str(response[0])

if __name__ == "__main__":

    # run the app locally on the given port
    app.run(host='0.0.0.0', port=80)
# optional if we want to run in debugging mode
    app.run(debug=True)


      
      







すべてが同じように始まります-pythonflask_app2.py



カールオプション(Windows用)



curlの ダウンロード



Windowsのコマンドラインで、次のコマンドを送信します。




curl -X POST -F img=@1.png http://localhost/predict/

      
      





ここで、1.pngは番号付きの画像です(または番号付きの画像です)。

認識された数字がそれに応じて到着します。



ダウンロード用のファイル- ダウンロード



All Articles