Make prediction API using your models with PyTorch

ในยุคที่ Machine Learning เฟื่องฟูนี้ ถ้าไม่ลองเขียนอะไรเกี่ยวกับ ML เลยก็จะดูบาปไปสักนิด วันนี้ก็เลยอยากเขียน blog เกี่ยวกับ Deep Learning Framework ที่เคยแชรฺไปวันก่อนสักนิดนึง โดยอยากโฟกัสไปที่การเอา model ที่ได้จากการ train ของ Data Scientistแล้วมาใช้งาน เพราะเมื่อวาน Varokas Panusuwan เมาท์ว่าถ้า PyTorch ทำไม่ได้จะเทใจไปใช้ฝั่ง TeamFortress วันนี้ก็เลยจะมาลองทำ Prediction API จากภาพว่าเป็นน้องหมาพันธ์อะไร โดยเราจะใช้ Algorithm Resnet 50 (สนใจอ่านต่อที่บทความนี้ครับ อธิบายดีมากๆ) ซึ่งวันนี้เราจะติ๊งต่างว่าเรามี Data Scientist ทำการ train model นี้ให้เราแล้ว และเรากำลังจะเอามา deploy เพื่อให้บริการบน Prediction API ตัวนี้

1_LLVL8xUiUOBE8WHgzAuY-Q

หลักๆแล้ว เราจะใช้ Flask เป็น Framework สำหรับให้บริการ REST โดยผมยืม​แนวคิดและ code บางส่วนมาจาก Keras เพื่อความรวดเร็ว และเปลี่ยนเป็นใช้ PyTorch สำหรับประมวลผลภาพและทำการทำนายจาก model ที่มี DS เตรียมไว้ให้เรา ส่วนที่สำคัญของเราในตอนนี้ก็คือ การ load model ที่มีคนเตรียมไว้ให้เรา อย่างที่เกริ่นไปข้างต้น เราจะใช้ resnet เพราะว่าตอนนี้ผมมีโมเดล PyTorch vision แค่อันเดียว lol ซึ่งขั้นตอนการ load ก็เริ่มจากสร้าง object ของ model ขึ้นมาโดยกำหนดให้ไม่ต้อง load pretrain ที่ให้มากับ PyTorch แต่เราจะทำการโหลดขึ้นมาเองด้วย torch.load และ ให้โมเดลเรียกใช้งานจาก checkpoint ที่เราเก็บเอาไว้ (ไฟล์นี้ผมดาวน์โหลดมาเอง แล้วติ๊งต่างว่ามีคนเตรียมให้นะครับ)

import torch
from torch import nn
from torchvision.models import resnet50

def load_model():
    global model
    model = resnet50(pretrained=False)
    model_path = "./models/resnet50-19c8e357.pth"
    checkpoint = torch.load(model_path)
    model.load_state_dict(checkpoint)
    model.eval()

ซึ่งหลังจากนั้นเราก็จะเอา image ที่ API รับมาจาก request และมาทำนายด้วย model ที่ได้โหลดขึ้นมา โดยก่อนหน้านั้น เราก็มีการทำ preprocessing image เช่น ทำการ resize image และ ทำการแปลงเป็น Tensor ก่อนที่จะนำไปทำนาย โดยวิธีการขั้นต้นก็เป็นไปตาม listing ด้านล่างนี้

# Resize the input image nad preprocess it.
image = T.Resize(target_size=(224, 224))(image)
image = T.ToTensor()(image)

# Convert to Torch.Tensor and normalize.
image = T.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])(image)

with torch.no_grad():
    image = torch.autograd.Variable(image[None])
      
# Get prediction results
preds = F.softmax(model(image), dim=1)
# Prepare first k items, from preditions result
results = torch.topk(preds.cpu().data, k=4, dim=1)

ซึ่งเมื่อประกอบชิน่วนทั้งหมดเข้าด้วยกันเป็น api_server.py (source code ฉบับเต็มเข้าไปดูได้ที่ https://github.com/mahasak/pytorch-deploy-model นะครับ และเมื่อได้ประกอบร่างเสร็จแล้วก็สามารถรัน Prediction Server ได้ดังภาพครับ

1_EEK7gO1ezbXtoVumwC0lCA

รัน Server ขึ้นมาสิครับ จะรออะไร
และแล้วก็ถึงเวลาที่เราจะเพลิดเพลินกับการทำนายสายพันธ์น้องหมาจาก Prediction API ที่เราทำไว้ :D โดยผมก็ได้ทดสอบดูตามภาพ เท่านี้เราก็สามารถเอาโมเดลที่ได้มีการพัฒนาและเทรนไว้เอาไปให้บริการผ่าน REST API ได้โดยไม่ต้องถูกตราหน้าว่างานวิจัยขึ้นหิ้งแล้วนะครับ #น้องหมาน่ารักจริงๆ

1_lehu6eYYA4Lx5yUka1Nz_A1_THsgQz5KMbjjNsZRboMr-Q

ภาพทดสอบน้องหมาฮัสกี้ และผลจาก prediction API
Happy Coding Krub :)

References: