스터디/AI

[Imple] Flask를 이용한 api 샘플

_leezoee_ 2023. 2. 13. 14:34

 

Flask는 Python의 웹 프레임 워크로 다양한 웹 엔진과 호환성이 좋고, 가벼워서 널리 이용되는 프레임워크다.

(특히 API를 만들기 매우 편리!)

 

샘플 소스는 다음과 같다.

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

 

이러한 Flask를 이용해 api를 만들고 모델 학습 결과로 이미지를 분류하는 간단한 소스를 구현해보고자 한다.

 

데이터는 import fashion_mnist 로 구글, 깃허브를 통해 쉽게 볼 수 있는 옷 종류 이미지 데이터를 사용하였다.

작성한 IDE는 Spyder(Python 3.9)로 Anaconda를 다운로드 받을때 함께 설치되었다.

 

① pre.py

 

app.py를 구현하기 전에 train, test 데이터를 나누고 이미지 다섯개 정도만 추출하여 따로 uploads 라는 폴더에 저장해두는 pre 소스를 구현 하였다.

# 파이프라인 테스트 코드 
from tensorflow.keras.datasets import fashion_mnist
from imageio  import imsave

(X_train, y_train), (X_test, y_test) = fashion_mnist.load_data()

for i in range(5) : 
    # 이미지를 로컬에 저장, 테스트로 다섯장
    imsave(uri="C:/Users/user/FlaskAPI/uploads/{}.png".format(i), im=X_test[i])

 

 

이미지를 불러와 저장하는 imsave 는 scipy(1.2.0 이전 버전에서 제공) 혹은 imageio 모듈을 통해 사용할 수 있다.

로컬에 scipy는 1.2.0 이후 버전이므로 imageio 모듈을 사용하였다.

 

 

+ Spyder 사용 시 자주 사용한 단축키

행 선택 ctrl + 1 : 주석

메소드 ctrl + i : 해당 메소드 설명 확인 가능

행 선택  ctrl + enter : 행 실행

 

 

해당 파일을 실행하면 지정한 경로에 for range 개수인 다섯개의 이미지가 저장되어있음을 볼 수 있다.

fashion_mnist 파일 저장

 

 

② app.py

 

전체 소스이고, 소스에 대한 설명은 최대한 주석으로 남겨두었다.

 

대략 순서는 이렇게 보면 될 듯 하다.

 

1) 모델 구조, 학습된 모델을 가져와서 모델 만들기

2) flask api 만들기

3) /api/image/이미지이름 으로 post api 만들기 (이미지 이름을 건네면 지정 경로에 있는 이미지를 보고 클래스 분류 실행)

4) 결과(가장 근접한 분류확률 argmax(prediction[0])) 리턴.

5) 앱 실행 

6) api 호출하고 결과보기

import os #경로와 파일을 다뤄 위치를 지정하거나 삭제함
import requests #경로를 생성하거나 서버로 오는 요청을 수신
import numpy as np #수학연산, 행렬 작업
import tensorflow as tf

from imageio import imsave, imread
from flask import Flask, request, jsonify

#모델 구조 가져오기
# 모델 망구성방식(토폴로지)에 대한 정보가 담긴 json 파일, 가중치를 저장하는 .h5 파일 

with open("C:/Users/user/FlaskAPI/fashion_model_flask.json", "r") as f: #파일읽기 r
    model_json = f.read() #모델구조읽기
    
# 읽은 파일 토대로 모델 만들기    
model = tf.keras.models.model_from_json(model_json) #하나의 인자로 전체모델구조를 포함한 변수를 사용   

#모델을 위한 모든 사전학습 가중치 불러오기
model.load_weights("C:/Users/user/FlaskAPI/fashion_model_flask.h5")

#flask api 만들기
app = Flask(__name__)

#이미지 분류 함수 만들기, 데코레이터사용
@app.route("/api/image/<string:img_name>", methods=["POST"])
def classify_image(img_name):
    
    upload_dir = "C:/Users/user/FlaskAPI/uploads/"    
    
    image = imread(uri=upload_dir + img_name)
    
    classes = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot'] #Fashion MNIST classes 가져옴
    
    prediction = model.predict([image.reshape(1, 28*28)]) #예측값
    
    return jsonify({" result ":classes[np.argmax(prediction[0])]})

#flask 실행
app.run(port=5000, debug=False)

 

* 당연히 소스 실행 전에 모델 망 구성방식을 정의한 fashion_model_flask.json 과 학습 시킨 모델 fashion_model_flask.h5 파일이 준비되어있어야 실행할 수 있다.*

fashion_model_flask.json 미리보기

 

 

 

소스를 실행하면 app.run을 통해 flask 앱이 실행이 되고, 콘솔 결과는 다음과 같다.

127.0.0.1:5000 번으로 실행

 

postman 을 이용해서 api를 호출하면

postman 으로 api 호출

 

요렇게 0.png 가 Ankle boot 라는 결과가 돌아온다

 

실제로 0.png를 확인해보면 신발모양의 이미지임을 확인할 수 있었다!

0.png