ETC
🎓 졸업과제 - Flask Server, Mock Tensorflow Model
HaningYa
2020. 8. 7. 15:40
728x90
목표
- 질문을 입력받을 수 있는 웹페이지에서 질문을 입력한다.
- 해당 질문을 일단 서버로 보내 모델에서 prediction 했다고 가정하고 응답을 웹에 표시한다.
*파이썬 프로젝트에 Flask 를 추가 했었고 templates 패키지에 필요한 HTML 코드를 작성 해놓은 상태이다.
HTML 코드
더보기
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Table</title>
<script type="text/javascript">
window.onload = function() {
//제출하기 clickListener
document.getElementById("submit").onclick = function() { // on click
loadFileAsText()
}
}
//HTML File -> show table
function loadFileAsText(){
var fileToLoad = document.getElementById("fileToLoad").files[0];
var fileReader = new FileReader();
fileReader.onload = function(fileLoadedEvent){
//불러온 텍스트 파일
var textFromFileLoaded = fileLoadedEvent.target.result;
//html 형식
var html = new DOMParser().parseFromString(textFromFileLoaded, "text/html");
//table 추출
var table = html.querySelector("table");
//원문 html 문자열
var htmlString = html.documentElement.outerHTML
//테이블 표시
document.getElementById("disp").appendChild(table);
//원문 표시
document.getElementById("html").innerHTML = htmlString
<!-- post_to_url('/handle_data',html,POST)-->
};
fileReader.readAsText(fileToLoad, "UTF-8");
}
</script>
</head>
<body>
<hr>
<h1>Table</h1>
<!--<form action="/handle_data" method="POST">-->
<input type="file" id="file" accept="html/*" name="table"/>
<button id="submit">제출하기</button>
<!--</form>-->
<br>
<br>
<hr>
<div id="disp">표 출력</div>
<h2>Question</h2>
<form action="/post" method="post">
<p>질문입력해주세요 : <input type="text" name="test"></p>
<input type="submit" value="질문하기">
</form>
<br>
<br>
<hr>
<h2>Answer</h2>
<div id="html">원문 출력</div>
</body>
</html>
Flask 코드
더보기
from flask import Flask , render_template, request
app = Flask(__name__)
@app.route('/')
def index():
return render_template('tableView.html')
@app.route('/handle_data',methods = ['POST'])
def handle_data():
projectpath = request.form['table']
print(projectpath)
return projectpath
@app.route('/post', methods=['POST'])
def post():
value = request.form['test']
print(value)
return value
if __name__ == '__main__':
app.run(debug = True)
Flask 실행시 로컬호스트로 가면 아래 페이지가 뜬다.
여기서 질문입력을 받으면 서버에 출력을 먼저 해보겠다.
입력한 질문을 받을 수 있다.
이까지는 해놨었다.
그런데 나는 웹 페이지 전체를 다시 로드하지 않고 모델에서 prediction 후에 결과값만 기존 페이지에 update 해주고 싶다.
이상태로는 return value 라서 텍스트만 띡 하고 표시된다.
음 웹 하나도 모르겠는데
일단 python 코드에 있는 데이터를 html 로 표시해 줄땐
@app.route('/')
def index():
title = "이것은 타이틀이다."
return render_template('tableView.html', title=title)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{{ title }}</title>
이런식으로 하면 title 웹페이지에 표시된다.
이걸 기본으로 mock 웹페이지를 만들어 보겠다.
텐서플로우 예제 모델을 하나 들고와 붙이자
MNIST 모델 만드는 코드
더보기
## 출처: https://medium.com/@kiseon_twt/flask%EB%A1%9C-tf-2-0-mnist-%EB%AA%A8%EB%8D%B8-%EC%84%9C%EB%B9%99%ED%95%98%EA%B8%B0-6c9fb7cf3322
import tensorflow as tf
import numpy as np
# 학습 데이터 load
((train_data, train_label), (eval_data, eval_label)) = tf.keras.datasets.mnist.load_data()
# data를 정규화하여 28x28로 reshape
train_data = train_data / np.float32(255)
train_data = train_data.reshape(60000, 28, 28, 1)
train_data.shape
eval_data = eval_data / np.float32(255)
eval_data = eval_data.reshape(10000, 28, 28, 1)
eval_data.shape
from tensorflow.keras import models
# CNN으로 모델 생성
model = models.Sequential()
model.add(tf.keras.layers.Conv2D(32, (5, 5), padding='same', activation='relu', input_shape=(28, 28, 1)))
model.add(tf.keras.layers.MaxPooling2D((2, 2)))
model.add(tf.keras.layers.Conv2D(64, (5, 5), activation='relu'))
model.add(tf.keras.layers.MaxPooling2D((2, 2)))
model.add(tf.keras.layers.Conv2D(64, (5, 5), activation='relu'))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(64, activation='relu'))
model.add(tf.keras.layers.Dense(10, activation='softmax'))
model.summary()
# graph를 생성하고 training
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(train_data, train_label, epochs=5)
test_loss, test_acc = model.evaluate(eval_data, eval_label, verbose=2)
test_acc
# save the model. TF 2.0에서는 experimental 대신 save_model만 하면됨
model_dir = "/tmp/tfkeras_mnist"
tf.keras.experimental.export_saved_model(model, model_dir)
prediction 함수 부분
더보기
# 출처: https://medium.com/@kiseon_twt/flask%EB%A1%9C-tf-2-0-mnist-%EB%AA%A8%EB%8D%B8-%EC%84%9C%EB%B9%99%ED%95%98%EA%B8%B0-6c9fb7cf3322
def prediction(question):
# 데이터를 읽어들이고
((train_data, train_label), (eval_data, eval_label)) = tf.keras.datasets.mnist.load_data()
eval_data = eval_data / np.float32(255)
eval_data = eval_data.reshape(10000, 28, 28, 1)
# 저장해 두었던 모델을 읽어들인 후
model_dir = "/tmp/tfkeras_mnist"
new_model = tf.keras.experimental.load_from_saved_model(model_dir)
new_model.summary()
# 그래프를 생성하고
new_model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
answer = '예시 정답 텍스트'
random_idx = np.random.choice(eval_data.shape[0])
test_data = eval_data[random_idx].reshape(1, 28, 28, 1)
res = new_model.predict(test_data)
answer = "predict: {}, original: {}".format(np.argmax(res), eval_label[random_idx])
return answer
아무 질문이나 넣어서 제출하기 POST 누르면
MNIST Prediction 이 수행되고 결과값이 웹페이지에 리턴된다.
나중에 테이블 QA모델이 만들어 지면 모델만 바꿔치면 될 것 같다.
앞으로 할일
- 질의할 테이블 선택후 보여주는 화면 구성
- QA 에 대한 어텐션 테이블에 시각화
- BERT, TAPAS 코드분석
728x90