개인 개발 프로젝트/AI 숫자 판별 앱

[AI 숫자 판별 앱] 3. 숫자 판별 API 작성 및 테스트

종범2 2019. 12. 16. 23:25

이전 글에서는 숫자를 판별하는 딥러닝 모델을 구현하고 결과값을 반환하는 함수까지 작성하였다. 이 함수를 웹에서 사용하기 위해서는 이 함수를 API로 작성해야 한다. 이를 위해 python의 flask를 이용하였다. Flask란 python 웹 어플리케이션을 만드는 프레임워크이다. Django와 더불어 가장 많이 쓰이는 python 웹 애플리케이션 프레임워크이다. 심플한 기능만 구현하기에는 flask가 더 적합하므로 flask를 이용하였다.

 

아나콘다를 설치하면 많은 라이브러리들이 설치되지만 다 설치되지 않을 수도 있다. 시작메뉴에서 Anaconda Prompt를 실행하면 콘솔 창이 뜨는데 여기서 필요한 라이브러리들을 설치해준다.

 

Flask 설치

pip install flask

Flask Cors 설치

pip install -U flask-cors

추가적으로 설치가 필요한 라이브러리는 여기까지일 것이다.

 

Flask를 사용하여 API를 구현한 코드는 다음과 같다. 대부분 이전 글에서 설명한 딥러닝 관련 함수고 flask의 기능과 관련된 코드는 매우 짧다.

 

app.py

from flask import Flask, request
from flask_cors import CORS
app = Flask (__name__)
CORS(app)
import numpy as np
from PIL import Image
import glob
import pickle as pickle
from common.functions import sigmoid, softmax

def init_network():
    with open("sample_weight.pkl",'rb') as f:
        network = pickle.load(f)
    return network

def predict(network, x):
    W1, W2, W3 = network['W1'], network['W2'], network['W3']
    b1, b2, b3 = network['b1'], network['b2'], network['b3']
    
    a1 = np.dot(x, W1) + b1
    z1 = sigmoid(a1)
    a2 = np.dot(z1, W2) + b2
    z2 = sigmoid(a2)
    a3 = np.dot(z2,W3) + b3
    y = softmax(a3)
    
    return y

@app.route('/')
def hello_world():
    return 'Hello, Mnist App!'

@app.route('/number', methods=['POST'])
def number():
    # get file from request
    f = request.files['file']
    # save file
    fileName = 'tempImgFile.'+f.filename.rsplit('.', 1)[1]
    f.save(fileName)
    # predict
    network = init_network()
    global result
    for image_path in glob.glob(fileName):
        img = Image.open(image_path).convert("L")
        img = np.resize(img, (1,784))
        img = 255-(img)
        y = predict(network, img)
        result = np.argmax(y)
    return str(result)

if __name__ == "__main__":
    app.run()

 

우선 세 번째 줄의 app = Flask (__name__)와 맨 마지막 줄의 코드는 flask를 이용하여 api를 개발하기 위해서는 고정적으로 항상 사용해야 하는 코드이다. 웹 애플리케이션을 위한 인스턴스를 생성하고 실행하는 코드로 생각하면 된다 (아직 flask는 잘 몰라서 정확하게 이해는 못했다).

 

API를 작성하기 위해서는 URL과 함수를 이어야하는데 이를 위해 @app.route라는 데코레이션을 함수 위에 작성한다. route에는 첫 번째로 라우팅과 두 번째로 method를 전달한다. hello world는 테스트 용으로 작성하였고 number는 판별한 숫자를 반환하기 위해 작성하였다.

 

잘 작동하는지 확인하기 위해 시작메뉴에서 Anaconda Prompt를 실행하면 콘솔 창을 띄운다. 그리고 app.py가 위치한 경로로 이동하고 다음과 같이 실행한다.

 

Anaconda Prompt

다음으로 웹브라우저를 실행시키고 localhost:5000에 접속해 결과를 확인한다.

 

localhost:5000 결과

다음과 같이 작성한 문자열을 잘 반환함을 테스트하였다. 이제 본격적으로 숫자 판별 API를 테스트해야 하는데 웹 브라우저에서 테스트하기 위해서는 파일을 업로드하는 UI가 필요하므로 Postman에서 테스트를 진행하였다. Postman은 API 테스트 진행을 돕는 툴이다. Postman에 대한 상세 설명은 생략하겠다. Postman을 실행시켜 다음과 같이 API를 호출하였다.

 

Postman 작성1
Postman 작성 2

 

my0.png는 직접 그림판에서 작성한 28*28의 손 글씨 이미지로 다음과 같다.

 

그림으로 작성한 0 이미지

Send 버튼을 클릭하여 얻은 결과는 다음과 같다.

 

Postman 결과

예상대로 0으로 잘 판별하였다. 다른 숫자들도 잘 판별하는지 궁금하다면 다른 손글씨 이미지를 작성하여 넣으면 된다. 단 28*28 사이즈만 가능하다 (알아서 줄여주는 기능도 나중에 시간이 된다면 만들어 볼만 할 듯).

결과는 0, 1, 2, 3, 4, 3으로 숫자 5는 잘 판단하지 못하였다. 아마 mnist 데이터 손글씨랑 내 손글씨가 많이 다르기 때문일 것이다.

 

다음 글 바로가기

[AI 숫자 판별 앱] 4. API Heroku 배포 및 테스트