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