22.01.23 모델 서비스하기
2022. 1. 23. 19:26ㆍ카테고리 없음
학습된 모델 저장하고 불러오기
tensorflow 모델 구성요소
tensorflow 모델 저장 형식
SavedModel 활용방법
model.save().h5해야 h5는 가능, default는 savedmodel임
Checkpoint 불러오기 save_weights_only는 False가 좋다.
모델 서비스 하기 flask, javascript등 으로 웹에 서비스 가능
Tensorflow.js
flask에서 서비스하기
서버 안정화 처리
실행 가능한 작업 제한
-> 간단한 구현 가능하고, 가벼운 모델이면 서비스 다운을 방지할 수 있으나
-> 사용자가 작업을 예약하는 건 불가능, 대규모 서비스에서는 안됨
다른방법 (작업 큐를 이용한 비동기 처리)
큐 먼저 입력-> 먼저 출력
큐를 이용한 처리 (프로세스 분리)
메인프로세스는 절대 종료되면 안된다.
작업 큐를 이용한 비동기처리구현
작업 큐와 비동기처리의 장점
실습1 모델저장하기
from elice_utils import EliceUtils
elice_utils = EliceUtils()
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
from tensorflow.keras import layers, models, Sequential
from tensorflow.keras.datasets import mnist
import numpy as np
def load_data():
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train, X_test = X_train / 255.0, X_test / 255.0
X_train = np.expand_dims(X_train, axis=-1)
X_test = np.expand_dims(X_test, axis=-1)
return X_train, X_test, y_train, y_test
def build_model(input_shape, num_classes=10):
model = Sequential()
model.add(layers.Conv2D(16, kernel_size=(3, 3), padding="same", activation="relu", input_shape=input_shape))
model.add(layers.MaxPool2D(2))
model.add(layers.Conv2D(32, kernel_size=(3, 3), padding="same", activation="relu"))
model.add(layers.MaxPool2D(2))
model.add(layers.Flatten())
model.add(layers.Dense(num_classes, activation="softmax"))
return model
def main():
X_train, X_test, y_train, y_test = load_data()
model = build_model(X_train[0].shape)
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
model.fit(X_train, y_train, epochs=1, batch_size=64, shuffle=True, verbose=2)
# TODO: H5 형식으로 모델 저장
model.save('h5_model.h5')
# TODO: SavedModel 형식으로 모델 저장
model.save('saved_model')
if __name__ == "__main__":
main()
실습2 모델 불러오기
import os
import tensorflow as tf
import keras
# 모델에 대한 어떠한 정보도 정의하지 않습니다
# 오직 저장된 모델로부터 다양한 정보를 불러와 출력합니다.
print("학습하던 모델을 불러옵니다.")
# TODO: 지시사항을 보고 학습한 SavedModel 형식 모델을 불러오세요
loaded_model = keras.models.load_model('afterfit')
loaded_model.summary()
# TODO: 지시사항을 보고 5번째 체크 포인트를 불러오세요
loaded_ckpt = keras.models.load_model("./checkpoints/cp-0005.ckpt")
loaded_ckpt.summary()
실습3 checkpoint 이어서 모델 학습하기
import os
import tensorflow as tf
from tensorflow.keras import layers, models, Sequential
from tensorflow.keras.datasets import mnist
import numpy as np
def load_data(): # 학습에 사용할 데이터입니다.
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train, X_test = X_train / 255.0, X_test / 255.0
X_train = np.expand_dims(X_train, axis=-1)
X_test = np.expand_dims(X_test, axis=-1)
return X_train, X_test, y_train, y_test
def main():
X_train, X_test, y_train, y_test = load_data() # 빠른 실습을 위해 양이 적은 X_test, y_test 를 학습합니다.
# TODO: 10번째 체크포인트의 경로를 checkpnt_path에 저장하세요
checkpnt_path = './checkpoints/cp-0010.ckpt'
# TODO: 불러온 체크포인트를 불러와 model에 저장하세요
model = models.load_model(checkpnt_path)
# TODO: 10epoch까지 학습된 이 모델을 11번째 epoch부터 이어서 5 epoch 더 학습시키세요
hist = model.fit( x=X_test, y=y_test, batch_size=64, epochs=15,
shuffle=True, initial_epoch=10)
return hist, checkpnt_path
if __name__ == "__main__":
main()
실습4 모델 변환하기
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
from tensorflow.keras import layers, models, Sequential
from tensorflow.keras.datasets import mnist
import numpy as np
import tensorflowjs as tfjs
def load_data():
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train, X_test = X_train / 255.0, X_test / 255.0
X_train = np.expand_dims(X_train, axis=-1)
X_test = np.expand_dims(X_test, axis=-1)
return X_train, X_test, y_train, y_test
def build_model(input_shape, num_classes=10):
model = Sequential()
model.add(layers.Conv2D(8, kernel_size=(3, 3), padding="same", activation="relu", input_shape=input_shape))
model.add(layers.MaxPool2D(2))
model.add(layers.Conv2D(16, kernel_size=(3, 3), padding="same", activation="relu"))
model.add(layers.MaxPool2D(2))
model.add(layers.Flatten())
model.add(layers.Dense(num_classes, activation="softmax"))
return model
X_train, X_test, y_train, y_test = load_data()
model = build_model(X_train[0].shape)
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
model.fit(X_train, y_train, epochs=1, batch_size=64, shuffle=True, verbose=1)
# TODO: 학습한 모델을 바로 변환
model.save('JSModel1')
# TODO: 다른 SavedModel 형식의 모델인 "OtherSModel"을 불러오기
loaded_model = models.load_model('OtherSModel')
# TODO: loaded_model을 tensorflow js로 변환
tfjs.converters.save_keras_model(loaded_model, 'JSModel2')
실습5 Flask로 MNIST 서비스하기
from flask import Flask, jsonify, request
import tensorflow as tf
app = Flask(__name__)
import PIL.Image as image
def work(img, model): # 이미지를 입력하면 숫자를 출력하는 함수
pred = model.predict([img]) # TODO: 모델에 이미지를 넣고 결과를 pred에 저장
pred = pred[0] # TODO: batch 단위로 나온 결과에서 이미지 하나의 결과를 추출
idx = tf.math.argmax(pred) # TODO: 결과중 가장 확률이 높은 index 가져오기
return idx
@app.route("/", methods=["GET"]) # @app.route를 작성하고, GET Method만 사용합니다.
def predict():
imgurl = request.args.get("img") # img라는 이름으로 url을 받아옴
result_string="please input image url"
if imgurl != None: # imgurl을 제대로 받은 경우
imgurl=imgurl.split("?")[0]
img = image.open("img/"+imgurl) # 전달받은 url의 이미지 로드
img=tf.keras.utils.img_to_array(img) # 이미지를 행렬로 변환
img=tf.expand_dims(img, axis=0) # batch를 위해 한 차원 높게 변환
idx = work(img, model) # 모델을 work 함수를 통해 사용합니다.
result_string = "This number is %d"%(idx) #사용자에게 보여줄 문자열
return jsonify(result_string)
# Flask 서버를 실행하는 코드입니다.
if __name__ == "__main__":
model = tf.keras.models.load_model('mymodel') # TODO: 학습된 모델 "mymodel"을 불러오세요.
app.run(host="0.0.0.0", port=8080) # flask 서비스 시작