모델 저장하고 불러오기
모델의 구성 요소
- 모델의 구조
레이어의 종류와 형태
입력값의 형태
- 가중치 값
- Compile 정보
Optimizer의 종류, Lr, 사용한 Loss Function 등의 정보
모델의 저장 형식
- H5 Format
- 과거 Keras에서 사용하던 저장 방식
- 모델의 구조와 가중치를 포함한 정보들을 저장
- 사용자 정의 레이어와 손실함수는 저장하지 않음
- SavedModel
- 최근에 사용하는 Tensorflow 표준 저장 형식
- 모델의 구조와 가중치를 포함한 정보들을 저장
- 사용자 정의 레이어와 손실함수까지 모두 저장
▮모델 저장
model.fit(x,y)
...
model.save("my_model")
▮저장된 모델 사용
loaded_model = kersas.models.load_model("my_model")
▮불러온 모델을 이어서 학습을 진행하려면
loaded_model = keras.models.load_model("my_model")
# 다시 compile 하지 않아도 바로 이어서 학습 가능
loaded_model.fit(x,y, initial_epoch=20, epochs=40)
▮Checkpoint 불러오기
Checkpoint 콜백함수의 인수 중 save_weights_only=False로 설정하는 것을 추천
# 모델을 학습하면서 Checkpoint를 저장
# 20epoch 이후 저장된 체크포인트 로드
loaded_model = keras.models.load_model("checkpoints/cp-0020.ckpt")
# 21 epoch부터 40 epoch까지 학습
loaded_model.fit(x, y, initial_epoch = 20, epochs=40)
모델 서비스
자바스크립트를 이용한 모델 서비스
Tensorflow.js
- 자바스크립트 Tensorflow 라이브러리
- 브라우저 또는 Node.js에서 학습된 모델을 사용 가능
Tensorflow.js에서 사용하는 과정
- 모델의 학습을 Tensorflow에서 진행
- Python에서 학습된 모델을 Tensorflow.js에 맞는 형식으로 변환
- Tensorflow.js에서 모델의 동작을 js로 작성하여 서비스
Tensorflow.js 형식으로 변환
- tensorflowjs를 이용
- target_dir에 json 파일을 포함된 모델 저장
# pip install tensorflowjs
import tensorflowjs as tfjs
def train(...):
model = keras.models.Sequential()
...
model.compile(...)
model.fit(...)
tfjs.converters.save_keras_model(model, target_dir)
Tensorflow.js 형식으로 변환한 모델 사용 방법
- model.json 파일의 URL을 제공하여 TensorFlow.js에 모델을 로드
javascript
import * as tf from "@tensorflow/tfjs";
const model = await;
tf.loadLayersModel("model.json파일의 URL");
- 모델 학습, 추론
javascript
const example = tf.fromPixels(webcamElement); //웹캠 Element를 사용한다고 가정
const prediction = model.predict(example)
Flask를 이용한 모델 서비스
학습한 모델 불러오기
- SavedModel 형식의 모델 로드
if __name__ == "__main__":
model = tf.keras.models.load_model("my_model")
# flask 서비스 시작
app.run(host="localhost", port=8080)
모델의 사용은 가대로 predict 사용
res = model.predict([inputdata])
example)
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) # 모델에 이미지를 넣고 결과를 pred에 저장
pred = pred[0] # batch 단위로 나온 결과에서 이미지 하나의 결과를 추출
idx = tf.math.argmax(pred) # 결과중 가장 확률이 높은 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") # 학습된 모델 "mymodel" 로드
app.run(host="0.0.0.0", port=8080) # flask 서비스 시작
서버 안정화 처리
서버 안정화 처리의 필요성
딥러닝 모델 서비스
- 모델의 추론과정은 일반적인 연산에 비해 처리 시간이 길고 자원도 많이 소모
- GPU자원을 사용하는 경우 GPU를 병렬적으로 사용하기 위한 처리 필요
- 사용자의 요청에 따라 계속 연산을 처리하면 서비스가 종료될 수 있음
서비스 안정화
- 사용자의 요청을 거절하더라도 서비스가 종료되지 않도록 자원 관리가 필요
- 서버의 연산 성능, 처리적인 작업의 수를 고려한 설계가 요구
서버 안정화 처리 방법
1. 서버에서 동시에 진행가능한 작업의 수를 제한하여 안정화
- 동시에 처리 가능한 최대 작업의 수를 상수로 정의 (max_works)
- 전역변수를 이용하여 진행중인 작업의 수를 저장 (num_works)
- 사용자의 요청이 왔을 때, 진행중인 작업의 수 비교 (max_works > num_works)
- 작업의 수가 최대일 때: 사용자에게 잠시 후 시도해달라는 안내 메세지를 출력하고 거절
- 작업의 수가 최대가 아닐 때: 작업을 수락하고 num_works += 1
- 작업이 완료되면 num_works을 1 감소
장점: 비교적 간단하게 구현이 가능 / 가벼운 모델만 사용할 때 서비스가 다운되는 현상 방지
단점: 대규모 서비스에 적용하기는 부적절함
2. 작업 큐를 이용한 비동기 처리
- 사용자와 상호작용을 관리하는 프로세스와 작업을 처리하는 Worker 프로세스를 분리
- 각 프로세스는 큐를 이용하여 상호작용함
메인 프로세스가 사용자의 요청을 받아오고 큐에 입력
Worker 프로세스는 큐에서 하나 빼오고 처리하고 큐에서 하나 빼오고 처리하고... 계속 반복
메인 프로세스
- 사용자의 요청을 처리하는 프로세스
- 처리 시간이 짧은 처리만 담당하여 빠르게 사용자의 요청에 반응
- 이 프로세스는 절대로 종료되지 않도록 주의하며 처리
- 사용자의 요청이 들어오면 큐에 작업을 추가하고 사용자에게 응답
Worker 프로세스
- 시간이 오래걸리거나 복잡한 작업을 단순하게 계속 처리
- 큐에 있는 작업을 불러와 처리하는 과정만 계속 반복
- 연산에 필요한 자원은 미리 할당한 상태로 작업
- 이 프로세서가 종료되더라도 메인 서비스는 계속 동작