Membuat Demo Deep Learning dengan web based application

By | September 6, 2023
Print Friendly, PDF & Email
218 Views

Membuat demo aplikasi saat ini sudah sangat dipermudah dan sudah banyak bergeser ke ranah mobile application. Walaupun begitu tidak mudah membuat / porting ulang aplikasi yang mengandalkan deep learning, karena membutuhkan daya komputasi yang besar.

Solusinya yaitu menyediakan API atau web based application. Biasanya untuk proses uji coba algoritma/model
lebih kepada console based application seperti menggunakan notepad/jupyter-notebook, editor Spyder. Kalian jangan bingung bisa kok menggunakan Shiny App yang berbasis web di Python.

Postingan ini sudah kami bahas sebelumnya disini Build WebApp Streamlit dan Shiny. Nah disini akan menguji cobakan model HRNet – High Resolution Network untuk melakukan tugas klasifikasi objek – https://raw.githubusercontent.com/pytorch/hub/master/imagenet_classes.txt. Secara garis besar kita bisa melihat versi demo nya berbasis jupyter-notebook disini https://huggingface.co/docs/timm/models/hrnet dan https://github.com/HRNet/HRNet-Image-Classification/tree/master. Oiya kalian install dulu model yang sudah jadi di https://timm.fast.ai/model_architectures

Kita pakai timm yang merupakan repositori buat model beragam deep learning

import timm
model = timm.create_model('hrnet_w18', pretrained=True)
model.eval()

Misalkan kita ingin mengklasifikasi/recognition gambar dari internet

import urllib
from PIL import Image
from timm.data import resolve_data_config
from timm.data.transforms_factory import create_transform

config = resolve_data_config({}, model=model)
transform = create_transform(**config)

url, filename = ("https://github.com/pytorch/hub/raw/master/images/dog.jpg", "tmp.jpg")
urllib.request.urlretrieve(url, filename)
img = Image.open(filename).convert('RGB')
tensor = transform(img).unsqueeze(0) # transform and add batch dimension

Langsung kita panggil modelnya

import torch
with torch.no_grad():
    out = model(tensor)
probabilities = torch.nn.functional.softmax(out[0], dim=0)

Kita akan rangking sebanyak 5 teratas

# Get imagenet class mappings
url, filename = ("https://raw.githubusercontent.com/pytorch/hub/master/imagenet_classes.txt", "imagenet_classes.txt")
urllib.request.urlretrieve(url, filename) 
with open("imagenet_classes.txt", "r") as f:
    categories = [s.strip() for s in f.readlines()]

# Print top categories per image
top5_prob, top5_catid = torch.topk(probabilities, 5)
for i in range(top5_prob.size(0)):
    print(categories[top5_catid[i]], top5_prob[i].item())
# prints class names and probabilities like:
# [('Samoyed', 0.6425196528434753), ('Pomeranian', 0.04062102362513542), ('keeshond', 0.03186424449086189), ('white wolf', 0.01739676296710968), ('Eskimo dog', 0.011717947199940681)]

 

Tapi kan tidak praktis juga menggunakan cara tersebut bila digunakan sebagai demo, nah berikut kode yang
gunakan untuk membuat aplikasi berbasis Shiny nanti diberikan pilihan mau upload file atau URL. Kita simpan dengan nama App.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Apr  5 00:22:03 2023

@author: mulkansyarif
"""

from matplotlib.image import imread
import matplotlib.pyplot as plt
import numpy as np
from shiny import *
from shiny.types import FileInfo
from shiny import App, Inputs, Outputs, Session, reactive, ui

from PIL import Image
from io import BytesIO
import base64
import PIL
import pywt.data
import numpy as np


import torch.nn as nn
import torch
import torchvision
import torchvision.transforms as transforms
from torch.utils.data import Dataset
from PIL import Image
import glob
from torch.utils.data.dataloader import DataLoader
import numpy as np
from matplotlib import pyplot as plt
import torch.optim as optim
import cv2
import os
import urllib

import timm
from timm.data import resolve_data_config
from timm.data.transforms_factory import create_transform



os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"
model = timm.create_model('hrnet_w18', pretrained=True)
model.eval()

config = resolve_data_config({}, model=model)
transform = create_transform(**config)


# Get imagenet class mappings
#url, filename = ("https://raw.githubusercontent.com/pytorch/hub/master/imagenet_classes.txt", "imagenet_classes.txt")
#urllib.request.urlretrieve(url, filename) 
# tidak perlu download lagi nama class karena sudah pernah di download
with open("imagenet_classes.txt", "r") as f:
    categories = [s.strip() for s in f.readlines()]


app_ui = ui.page_fluid(
    ui.panel_title('Image Recognition dengan HRNet'),
    ui.layout_sidebar(
        ui.panel_sidebar(
            ui.input_checkbox('cek_url','Input URL?'),
            ui.input_file('file1','Pilih file gambar',accept=[".jpg",".jpeg",".png"],multiple=False),
            ui.output_text(id="text"),
            ui.input_text("url", "Url", ""),
            ui.input_action_button("go", "Go!", class_="btn-success"),
            ui.output_ui("result")
            
        ),
        ui.panel_main(
            ui.row(
                #ui.column(6,ui.output_image("image1")),
                ui.column(6,ui.output_plot("p_kiri"))     
                
            )        
            
            
        )
    )
)



def server(input:Inputs,output:Outputs,session:Session):
    
    val = reactive.Value('hasil....')
    
    def localfile(path):
        f: list[FileInfo] = path
        return f[0]["datapath"]
           
    @output
    @render.ui
    def result():
        return val.get()
    
    @output
    @render.text
    def text():
        if input.file1() is None:
            return "..."
        else:
            return "Lokasi File "+localfile(input.file1())    
        
    @output
    @render.plot
    @reactive.event(input.go, ignore_none=False)
    def p_kiri():        
        #cek dulu apakah checkbox dicentang?
        
        if input.cek_url():
            #maka yang akan di proses adalah URL
            if input.url() is None:
                print("tidak ada URL")
                return None
            try:
                if input.url()!="":
                    url, filename = (input.url(), "tmp.jpg")
                    urllib.request.urlretrieve(url, filename)
                    original = imread(filename)
                    img = Image.open(filename).convert('RGB')
                    tensor = transform(img).unsqueeze(0) # transform and add batch dimension

                    with torch.no_grad():
                        out = model(tensor)
                    probabilities = torch.nn.functional.softmax(out[0], dim=0)

                    top5_prob, top5_catid = torch.topk(probabilities, 5)

                    fig, ax = plt.subplots()
                    ax.imshow(original, cmap=plt.cm.gray)
                    ax.set_xticks([])
                    ax.set_yticks([])
                    ax.set_title('hasil '+categories[top5_catid[0]])

                    val.set(categories[top5_catid[0]])
                    ui.notification_show("Selesai...", duration=5)
                    return fig

            except:
                print("ada keesalahan!")
                ui.notification_show("Ada kesalahan, alamat URL salah atau tidak bisa di download!", duration=None)
        else:
            if input.file1()is None:
                return None            
            else:
                original = imread(localfile(input.file1()))
                #uji coba dengan gambar offline
                img = Image.open(localfile(input.file1())).convert('RGB')
                tensor = transform(img).unsqueeze(0) # transform and add batch dimension

                with torch.no_grad():
                    out = model(tensor)
                probabilities = torch.nn.functional.softmax(out[0], dim=0)

                top5_prob, top5_catid = torch.topk(probabilities, 5)

                fig, ax = plt.subplots()
                ax.imshow(original, cmap=plt.cm.gray)
                ax.set_xticks([])
                ax.set_yticks([])
                ax.set_title('hasil '+categories[top5_catid[0]])

                val.set(categories[top5_catid[0]])
                ui.notification_show("Selesai...", duration=5)
                return fig
        
    
                
app = App(app_ui,server)

Buka command promp ketikan shiny run App.py Tunggu sampai keluar message

INFO:     Started server process [3532]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

Buka browser ketikan localhost:8000

See also  Backend Deep Learning dengan MPS GPU Apple M1

 

 

 

Leave a Reply