flask 서버 구축
flask에 ML 모델 구현
sklearn의 모델 저장, 불러오기
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
import pickle
iris = load_iris()
X = iris.data
y = iris.target
dt_model = DecisionTreeClassifier(max_depth=3)
dt_model.fit(X, y)
DecisionTreeClassifier(max_depth=3)In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
DecisionTreeClassifier(max_depth=3)
iris.target_names
array(['setosa', 'versicolor', 'virginica'], dtype='<U10')
test = [X[10], X[60], X[120]]
test
[array([5.4, 3.7, 1.5, 0.2]),
array([5. , 2. , 3.5, 1. ]),
array([6.9, 3.2, 5.7, 2.3])]
dt_model.predict(test)
array([0, 1, 2])
with open("pickled_model_iris.bin", "wb") as f:
pickle.dump(dt_model, f)
Kernel Restart
import pickle
with open("pickled_model_iris.bin", "rb") as f:
dt_model_loaded = pickle.load(f)
dt_model_loaded.predict([[6.9, 3.2, 5.7, 2.3]])
array([2])
tensorflow의 모델 저장, 불러오기
import tensorflow as tf
fashion_mnist = tf.keras.datasets.fashion_mnist
(X_train, y_train), (X_test, y_test) = fashion_mnist.load_data()
X_train = X_train[:5000, :]
y_train = y_train[:5000]
X_test = X_test[:1000, :]
y_test = y_test[:1000]
X_train = X_train/255.0
X_test = X_test/255.0
model = tf.keras.Sequential([
tf.keras.layers.Conv2D(32, (3, 3), input_shape=(28, 28, 1), padding='same'),
tf.keras.layers.MaxPooling2D((2, 2)),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['acc'])
model.fit(X_train, y_train, validation_split=0.2, epochs=10)
Epoch 1/10
125/125 [==============================] - 4s 22ms/step - loss: 0.8404 - acc: 0.7145 - val_loss: 0.4930 - val_acc: 0.8210
Epoch 2/10
125/125 [==============================] - 2s 17ms/step - loss: 0.5320 - acc: 0.8173 - val_loss: 0.4192 - val_acc: 0.8590
Epoch 3/10
125/125 [==============================] - 2s 17ms/step - loss: 0.4681 - acc: 0.8385 - val_loss: 0.3925 - val_acc: 0.8650
Epoch 4/10
125/125 [==============================] - 2s 17ms/step - loss: 0.4193 - acc: 0.8590 - val_loss: 0.3503 - val_acc: 0.8780
Epoch 5/10
125/125 [==============================] - 2s 17ms/step - loss: 0.3918 - acc: 0.8680 - val_loss: 0.3398 - val_acc: 0.8840
Epoch 6/10
125/125 [==============================] - 2s 17ms/step - loss: 0.3695 - acc: 0.8750 - val_loss: 0.3502 - val_acc: 0.8760
Epoch 7/10
125/125 [==============================] - 2s 17ms/step - loss: 0.3407 - acc: 0.8845 - val_loss: 0.3329 - val_acc: 0.8810
Epoch 8/10
125/125 [==============================] - 2s 17ms/step - loss: 0.3207 - acc: 0.8955 - val_loss: 0.3354 - val_acc: 0.8800
Epoch 9/10
125/125 [==============================] - 2s 17ms/step - loss: 0.2960 - acc: 0.9030 - val_loss: 0.3151 - val_acc: 0.8850
Epoch 10/10
125/125 [==============================] - 2s 17ms/step - loss: 0.2807 - acc: 0.9065 - val_loss: 0.3187 - val_acc: 0.8770
<keras.callbacks.History at 0x22cb0b333a0>
model.evaluate(X_test, y_test)
32/32 [==============================] - 0s 8ms/step - loss: 0.4271 - acc: 0.8590
[0.42713961005210876, 0.859000027179718]
model.save("my_fashion_model.h5")
model_loaded = tf.keras.models.load_model("my_fashion_model.h5")
model_loaded.evaluate(X_test, y_test)
32/32 [==============================] - 1s 8ms/step - loss: 0.4271 - acc: 0.8590
[0.42713961005210876, 0.859000027179718]
모델을 업데이트! 여러서버가 필요하다.
flask 서버
#!pip install flask
from flask import Flask
app = Flask(__name__)
@app.route("/") # 데코레이터
def anyname():
return "안녕하세요."
@app.route("/app1")
def app1():
return "app1입니다"
@app.route("/app2")
def app2():
return "app2입니다"
app.run(host="localhost", port=5000)
페이지 하나를 app 하나에 연결
유저상대 UI는 짜기 어렵다.
flask with ml_model
from flask import Flask
import pickle
with open("pickled_model_iris.bin", "rb") as f:
dt_model_loaded = pickle.load(f)
app = Flask(__name__)
@app.route("/") # 데코레이터
def anyname():
return "안녕하세요."
@app.route("/MLtest")
def app2():
label_name = ['setosa', 'versicolor', 'virginica']
idx = dt_model_loaded.predict([[6.9, 3.2, 5.7, 2.3]])
return f"꽃은 {label_name[int(idx)]}입니다."
app.run(host="localhost", port=5000)
변수의 사용
from flask import Flask
my_count = 0
app = Flask(__name__)
@app.route("/")
def anyname():
global my_count
my_count+= 1
return f"""
<html>
<head>
<title>안녕하세요.</title>
</head>
<body>
<p>{my_count} 번째 방문입니다.</p>
</body>
</html>
"""
app.run(host="localhost", port=5000)
controller와 view 분리
from flask import Flask
my_count = 0
# view
def build_input_page(my_count):
page = f"""
<html>
<head>
<title>안녕하세요.</title>
</head>
<body>
<p>{my_count} 번째 방문입니다.</p>
</body>
</html>
"""
return page
app = Flask(__name__)
# controller
@app.route("/input")
def app_input():
global my_count
my_count+= 1
page = build_input_page(my_count)
return page
app.run(host="localhost", port=5000)
=> MVC 패턴
머신러닝 모델 제공 웹페이지
from flask import Flask, request
import pickle
with open("pickled_model_iris.bin", "rb") as f:
dt_model_loaded = pickle.load(f)
def build_home_page():
page = f"""
<html>
<body>
<h1>Iris 분류기</h1>
<p>Iris 분류 시스템 입니다.</p>
<a href="/input">새로 입고된 꽃의 치수 입력하기</a>
</body>
</html>
"""
return page
def build_input_page():
page = f"""
<html>
<body>
꽃 측정원 님 안녕하세요<br>
지금 입고된 꽃의 치수를 cm 단위로 입력해 주세요<br>
저희 [나만돈벌어tm] 회사의 머신러닝 분류기가 꽃의 종류를 판단해 줍니다<br>
그러면 그 결과에 맞추어 창고에 넣어 주세요<br>
<form action="/result", method="get">
<input type="text" placeholder="꽃받침 길이" name="sepal_length"></input>cm<br>
<input type="text" placeholder="꽃받침 너비" name="sepal_width"></input>cm<br>
<input type="text" placeholder="꽃잎 길이" name="petal_length"></input>cm<br>
<input type="text" placeholder="꽃잎 너비" name="petal_width"></input>cm<br>
<input type="submit"></input><br>
</form>
</body>
</html>
"""
return page
def build_result_page():
sepal_length = request.args.get("sepal_length")
sepal_width = request.args.get("sepal_width")
petal_length = request.args.get("petal_length")
petal_width = request.args.get("petal_width")
values = [sepal_length, sepal_width, petal_length, petal_width]
values = list(map(float, values))
global dt_model_loaded
res = dt_model_loaded.predict([values])
label_name = ['setosa', 'versicolor', 'virginica']
page = f"""
수신결과: {sepal_length}, {sepal_width}, {petal_length}, {petal_width}<br>
판단결과: 꽃은 {label_name[int(res)]}입니다. 창고에 넣어주세요.<br>
<a href="/input">다른 꽃의 치수 입력하기</a>
"""
return page
app = Flask(__name__)
@app.route("/")
def home():
page = build_home_page()
return page
@app.route("/input")
def app_input():
page = build_input_page()
return page
@app.route("/result", methods=["POST", "GET"])
def app_result():
page = build_result_page()
return page
app.run(host="localhost", port=5000)
템플릿
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def home():
return render_template("flask_index.html", var1="이불밖은", var2="위험해요") # jinja 언어
app.run(host="localhost", port=5000)
flask_index.html
test.css
- template: html 파일들을 모아둔다.
- static: 그림, 음악, js, css 파일들을 모아둔다. => 귀찮으니 flask는 기능구현으로만 하자. (동시접속이 많다면 java로)
- python 서버는 java와 다르게 security기능이 없다. 동시접속이 어렵다.
댓글남기기