第6回は、LSTMを用いた時系列処理を取り扱う。
また、総合演習に向けて、Flaskを用いたPythonサーバーの構築と機械学習アプリの基礎についても説明する。
ここでは、Google ColabをPythonサーバーにする方法について説明する。
ngrokは、ローカルマシン上で稼働しているサーバーをインターネットを経由して外部に公開するためのトンネルサービス。
これを使うことで、Google Colab上で稼働しているFlaskサーバーを外部に公開してアクセス可能になる。
まず、以下の手順でngrokにサインアップする。
次に、Google Colabに入り、以下のコマンドを入力してngrokをインストールする。
!wget https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-amd64.tgz !tar xvzf ngrok-v3-stable-linux-amd64.tgz
!./ngrok config add-authtoken [Your Authtoken]
次にFlaskのサーバー用プログラムとコンテンツを準備する。 フォルダtemplatesを作成する。
# /server.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index():
return render_template( "index.html" )
if __name__ == '__main__':
app.run(port=6006,debug=True)<!doctype html>
<html>
<body>
<h1>Flask Server!</h1>
<p>This is test.</p>
</body>
</html>これが準備できたら、ngrokを起動してURLを取得し、サーバーを起動する。
get_ipython().system_raw('./ngrok http 6006 &')
!curl -s http://localhost:4040/api/tunnels | python3 -c "import sys, json; print(json.load(sys.stdin)['tunnels'][0]['public_url'])"!python server.py
このプロセスはずっと起動しっぱなしになる。
四則演算を行う簡単なウェブアプリをFlaskを使って作成する。
from flask import Flask,render_template,request
app = Flask(__name__)
@app.route("/")
def index():
return render_template( "calc.html" )
@app.route("/calc",methods={"GET","POST"})
def calc():
inp1=float(request.form.get("inp1"))
inp2=float(request.form.get("inp2"))
op=request.form.get("op")
if op=="+": ans=inp1+inp2
if op=="-": ans=inp1-inp2
if op=="*": ans=inp1*inp2
if op=="/": ans=inp1/inp2
return "<p>{}{}{}={}</p>".format(inp1,op,inp2,ans)
if __name__ == '__main__':
app.run(port=6006,debug=True)<!doctype html>
<html>
<head>
<meta charset='utf-8'>
<title>TinyCalc</title>
<script src="https://code.jquery.com/jquery-latest.js"></script>
<script src="static/my.js"></script>
<link rel="stylesheet" href="static/my.css">
</head>
<body>
<h1>簡易電卓</h1>
<form action="/calc" method="post">
<input name="inp1" size=5>
<select name="op">
<option>+</option>
<option>-</option>
<option>*</option>
<option>/</option>
</select>
<input name="inp2" size=5>
<input type="submit" value="=">
</form>
</body>
</html>!python server_calc.py
from tensorflow import keras
from tensorflow.keras.datasets import mnist
(tr_img,tr_lbl),(tt_img,tt_lbl)=mnist.load_data()
from tensorflow.keras import layers
inputs=keras.Input(shape=(28,28,1))
x=layers.Conv2D(32,3,activation='relu')(inputs)
x=layers.Conv2D(64,3,activation='relu')(x)
x=layers.MaxPooling2D(2)(x)
x=layers.Conv2D(64,3,activation='relu')(x)
x=layers.Conv2D(128,3,activation='relu')(x)
x=layers.MaxPooling2D(2)(x)
x=layers.Conv2D(128,3,activation='relu')(x)
x=layers.Flatten()(x)
outputs=layers.Dense(10,activation='softmax')(x)
model=keras.Model(inputs,outputs)
callbacks=[
keras.callbacks.ModelCheckpoint("mnist.keras",
save_bset_only=True)
]
model.compile(optimizer="rmsprop",
loss="sparse_categorical_crossentropy",
metrics=['accuracy'])
hist=model.fit(tr_img,tr_lbl,epochs=5,batch_size=64,
validation_data=(tt_img,tt_lbl),
callbacks=callbacks)<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>MNist画像判定</title>
</head>
<body>
<h1>MNist画像判定</h1>
<p>手書き数字が描かれた画像をアップすると、その画像が何の数字かを判定します。</p>
<form method="POST" action="/upload" enctype="multipart/form-data">
<input type="file" name="datafile">
<input type="submit" value="アップロード">
</form>
<form method="post" action="/judge">
<input type="submit" value="判定">
</form>
</body>
</html>from flask import Flask,render_template,request
from tensorflow import keras
import cv2
import numpy as np
import datetime
app = Flask(__name__)
@app.route("/upload", methods=["POST"])
def upload():
t_delta = datetime.timedelta(hours=9)
JST=datetime.timezone(t_delta,'JST')
now=datetime.datetime.now(JST)
d=now.strftime('%Y%m%d%H%M%S')
file=request.files["datafile"]
name="static/datafile-{}.png".format(d)
file.save(name)
with open("pngname.txt","wt") as f:
f.write(name)
return "Received: "+file.filename
@app.route("/judge",methods={"GET","POST"})
def judge():
with open("pngname.txt") as f:
name=f.read()
img=cv2.imread(name,cv2.IMREAD_GRAYSCALE)
img=cv2.resize(img,(28,28))
model=keras.models.load_model('mnist.keras')
data=img.reshape(1,28,28,1)
res=model.predict(data)
judge=np.argmax(res[0])
return "<p>画像:<img src='{}'></p><p>判定:{}</p>".format(name,judge)
if __name__ == '__main__':
app.run(port=6006,debug=True)