timm: Gudang 1000+ Model Computer Vision Siap Pakai di PyTorch

# timm: Gudang 1000+ Model Computer Vision Siap Pakai di PyTorch Halo temen-temen, di tutorial kali ini aku mau ngajak kalian kenalan sama library yang menurutku wajib ada di toolbox siapa pun yang n...

By Ruby Abdullah · · tutorial
timmpytorchcomputer-visiontransfer-learningimage-classification

timm: Gudang 1000+ Model Computer Vision Siap Pakai di PyTorch

Halo temen-temen, di tutorial kali ini aku mau ngajak kalian kenalan sama library yang menurutku wajib ada di toolbox siapa pun yang ngerjain computer vision pakai PyTorch, namanya timm, kependekan dari PyTorch Image Models. Kalau kalian pernah bingung mau pakai backbone apa buat proyek klasifikasi gambar, atau pernah copy-paste kode ResNet dari blog orang terus bingung kenapa akurasinya jelek, timm ini jawabannya.

Singkatnya, timm itu koleksi lebih dari seribu arsitektur model vision yang udah dilatih (pretrained), lengkap sama preprocessing yang benar, augmentasi modern, optimizer, scheduler, dan utilitas training. Semuanya dengan API yang konsisten. Ganti dari ResNet ke ConvNeXt ke EfficientNet ke Vision Transformer cuma ganti satu string nama model. Serius, satu string.

Di tutorial ini kita bakal bahas instalasi, cara nyari dan milih model, inference sederhana, ambil fitur buat transfer learning, fine-tuning model buat dataset sendiri, sampai tips memilih model yang pas antara akurasi dan kecepatan. Yuk mulai.

Introduction

Sebelum ngoding aku mau jelasin dulu kenapa timm beda dari sekadar torchvision.models.

Apa Itu timm

timm dibuat oleh Ross Wightman dan sekarang jadi bagian dari ekosistem HuggingFace. Isinya implementasi arsitektur vision paling lengkap yang pernah ada dalam satu library: ResNet dan semua variannya, EfficientNet, RegNet, ConvNeXt, Vision Transformer (ViT), Swin Transformer, DeiT, BEiT, MaxViT, EVA, MobileNet, dan masih banyak lagi.

Yang bikin dia spesial bukan cuma jumlah modelnya, tapi tiga hal ini.

Pertama, bobot pretrained-nya berkualitas tinggi dan sering kali lebih bagus dari bobot resmi paper aslinya, karena Ross melatih ulang banyak model dengan resep training modern.

Kedua, setiap model bawa konfigurasi preprocessing sendiri. Ini penting banget dan sering diremehkan orang. ViT dilatih dengan normalisasi berbeda dari ResNet. Kalau kalian pakai mean dan std yang salah, akurasi bisa anjlok belasan persen tanpa kalian sadari. timm ngurus ini otomatis.

Ketiga, API-nya konsisten. Semua model dibuat lewat timm.createmodel(), semua punya method forwardfeatures(), dan semua punya cara yang sama buat ganti jumlah kelas output.

Kapan Pakai timm

Pakai timm kalau kalian butuh backbone kuat untuk klasifikasi gambar, butuh feature extractor untuk task lain (deteksi, segmentasi, retrieval, similarity search), atau lagi benchmarking beberapa arsitektur untuk dataset kalian dan pengen ganti-ganti model tanpa nulis ulang kode.

Kalau kalian butuh model deteksi objek siap pakai, itu ranahnya Ultralytics atau Detectron2. timm fokus di backbone dan klasifikasi, tapi backbone-nya sering dipakai di dalam library-library itu juga.

Instalasi

Butuh Python 3.8 ke atas dan PyTorch. Bikin virtual environment dulu ya.

python -m venv venv

source venv/bin/activate # Linux / Mac

venv\Scripts\activate # Windows

pip install torch torchvision

pip install timm pillow matplotlib

Cek versinya:

import timm

import torch

print("timm:", timm.version)

print("torch:", torch.version)

print("cuda tersedia:", torch.cuda.isavailable())

Mencari Model yang Tersedia

Karena modelnya ribuan, hal pertama yang perlu kalian bisa adalah nyari.

import timm

Berapa banyak model dengan bobot pretrained?

semua = timm.listmodels(pretrained=True)

print("total model pretrained:", len(semua))

Cari model ConvNeXt

print(timm.listmodels("convnext", pretrained=True)[:10])

Cari model efficientnet ukuran kecil

print(timm.listmodels("efficientnetb0", pretrained=True))

Cari ViT

print(timm.listmodels("vitbase", pretrained=True)[:10])

Pola penamaan timm biasanya arsitekturukuran.resepdataset. Contohnya convnexttiny.fbin22kftin1k artinya ConvNeXt ukuran tiny, bobot dari Facebook, dilatih di ImageNet-22k lalu di-fine-tune ke ImageNet-1k. Semakin banyak kalian baca nama model, semakin gampang nebak kualitasnya.

Inference Pertama

Ayo langsung coba klasifikasi satu gambar.

import timm

import torch

from PIL import Image

import urllib.request

1. Buat model dengan bobot pretrained

model = timm.createmodel("convnexttiny.fbin1k", pretrained=True)

model.eval()

2. Ambil transform yang BENAR untuk model ini

config = timm.data.resolvemodeldataconfig(model)

transform = timm.data.createtransform(config, istraining=False)

print(config)

3. Siapkan gambar

urllib.request.urlretrieve(

"https://raw.githubusercontent.com/pytorch/hub/master/images/dog.jpg", "dog.jpg"

)

img = Image.open("dog.jpg").convert("RGB")

4. Prediksi

x = transform(img).unsqueeze(0) # tambah dimensi batch

with torch.nograd():

logits = model(x)

probs = logits.softmax(dim=-1)[0]

top5 = probs.topk(5)

5. Ambil nama kelas ImageNet

url = "https://raw.githubusercontent.com/pytorch/hub/master/imagenetclasses.txt"

urllib.request.urlretrieve(url, "imagenetclasses.txt")

labels = open("imagenetclasses.txt").read().splitlines()

for skor, idx in zip(top5.values, top5.indices):

print(f"{labels[idx]:30s} {skor.item():.4f}")

Perhatikan langkah nomor dua. resolvemodeldataconfig itu kunci yang sering dilewatin orang. Dia ngasih tau ukuran input, mean, std, dan metode interpolasi yang dipakai waktu model ini dilatih. Jangan pernah asal pakai normalisasi ImageNet standar buat semua model.

Mengganti Jumlah Kelas

Buat dataset sendiri, kalian pasti butuh output layer yang beda. Di timm ini cuma satu argumen.

# Dataset saya punya 7 kelas

model = timm.createmodel("resnet50.a1in1k", pretrained=True, numclasses=7)

x = torch.randn(2, 3, 224, 224)

print(model(x).shape) # torch.Size([2, 7])

Kalau kalian set numclasses=0, timm bakal ngilangin classifier head-nya dan langsung ngeluarin fitur. Ini berguna banget buat feature extraction.

backbone = timm.createmodel("resnet50.a1in1k", pretrained=True, numclasses=0)

fitur = backbone(torch.randn(2, 3, 224, 224))

print(fitur.shape) # torch.Size([2, 2048])

Vektor 2048 dimensi itu bisa kalian pakai buat image similarity search, clustering, atau input ke classifier klasik kayak SVM.

Mengambil Feature Map Multi-Skala

Untuk task seperti segmentasi atau deteksi, kalian butuh feature map dari beberapa level kedalaman, bukan cuma vektor akhir.

import timm

import torch

model = timm.createmodel(

"resnet50.a1in1k",

pretrained=True,

featuresonly=True,

outindices=(1, 2, 3, 4),

)

out = model(torch.randn(1, 3, 224, 224))

for i, f in enumerate(out):

print(i, f.shape)

print(model.featureinfo.channels()) # jumlah channel tiap level

print(model.featureinfo.reduction()) # faktor downsampling tiap level

Ini yang bikin timm sering dipakai sebagai encoder di library segmentasi seperti segmentationmodelspytorch. Kalian bisa tukar backbone-nya semudah ganti string.

Fine-Tuning untuk Dataset Sendiri

Sekarang bagian utamanya. Aku bakal tunjukin loop training sederhana tapi lengkap, pakai struktur folder standar ImageFolder.

Struktur datasetnya begini:

data/

train/

kucing/ gambar1.jpg ...

anjing/ gambar1.jpg ...

val/

kucing/ ...

anjing/ ...

Kodenya:

import timm

import torch

import torch.nn as nn

from torch.utils.data import DataLoader

from torchvision.datasets import ImageFolder

DEVICE = "cuda" if torch.cuda.isavailable() else "cpu"

NAMAMODEL = "convnexttiny.fbin1k"

1. Model

model = timm.createmodel(NAMAMODEL, pretrained=True, numclasses=2)

model.to(DEVICE)

2. Transform sesuai model, versi train dan eval

cfg = timm.data.resolvemodeldataconfig(model)

tftrain = timm.data.createtransform(cfg, istraining=True, autoaugment="rand-m9-mstd0.5")

tfval = timm.data.createtransform(*cfg, istraining=False)

3. Dataset dan loader

dstrain = ImageFolder("data/train", transform=tftrain)

dsval = ImageFolder("data/val", transform=tfval)

dltrain = DataLoader(dstrain, batchsize=32, shuffle=True, numworkers=4, pinmemory=True)

dlval = DataLoader(dsval, batchsize=64, shuffle=False, numworkers=4)

print("kelas:", dstrain.classes)

4. Optimizer, scheduler, loss

optimizer = timm.optim.createoptimizerv2(model, opt="adamw", lr=3e-4, weightdecay=0.05)

criterion = nn.CrossEntropyLoss(labelsmoothing=0.1)

EPOCHS = 10

scheduler = torch.optim.lrscheduler.CosineAnnealingLR(optimizer, Tmax=EPOCHS)

5. Loop training

for epoch in range(EPOCHS):

model.train()

totalloss = 0.0

for x, y in dltrain:

x, y = x.to(DEVICE), y.to(DEVICE)

optimizer.zerograd()

loss = criterion(model(x), y)

loss.backward()

optimizer.step()

totalloss += loss.item() x.size(0)

scheduler.step()

model.eval()

benar = 0

total = 0

with torch.nograd():

for x, y in dlval:

x, y = x.to(DEVICE), y.to(DEVICE)

pred = model(x).argmax(dim=1)

benar += (pred == y).sum().item()

total += y.size(0)

print(f"epoch {epoch+1}/{EPOCHS} "

f"loss {totalloss/len(dstrain):.4f} "

f"valacc {benar/total:.4f}")

torch.save(model.statedict(), "modelfinetuned.pth")

Beberapa hal yang perlu kalian catat dari kode di atas.

auto
augment="rand-m9-mstd0.5" mengaktifkan RandAugment, augmentasi modern yang biasanya ngasih kenaikan akurasi gratis di dataset kecil sampai menengah. labelsmoothing=0.1 bikin model nggak terlalu pede berlebihan dan biasanya sedikit meningkatkan generalisasi.

AdamW dengan weight decay 0.05 adalah resep standar buat model modern seperti ConvNeXt dan ViT. Untuk ResNet klasik, SGD dengan momentum kadang masih lebih bagus.

Membekukan Backbone

Kalau dataset kalian kecil banget (di bawah beberapa ratus gambar per kelas), sering lebih aman melatih head-nya saja dulu.

model = timm.createmodel("convnexttiny.fbin1k", pretrained=True, numclasses=2)

for p in model.parameters():

p.requiresgrad = False

Buka hanya classifier head

for p in model.getclassifier().parameters():

p.requiresgrad = True

optimizer = torch.optim.AdamW(

[p for p in model.parameters() if p.requiresgrad], lr=1e-3

)

Setelah beberapa epoch dan loss-nya stabil, buka semua parameter dan lanjutkan training dengan learning rate kecil, misalnya 1e-5 sampai 5e-5. Teknik ini namanya gradual unfreezing dan sering menyelamatkan dataset kecil dari overfitting.

Memuat Kembali Model

import timm

import torch

model = timm.createmodel("convnexttiny.fbin1k", pretrained=False, numclasses=2)

model.loadstatedict(torch.load("modelfinetuned.pth", maplocation="cpu"))

model.eval()

Perhatikan pretrained=False di sini, karena bobotnya kita ambil dari file kita sendiri, bukan dari internet.

Memilih Model yang Tepat

Ini pertanyaan yang paling sering aku terima, jadi aku kasih panduan praktis.

Kalau kalian butuh cepat dan ringan buat deploy di CPU atau perangkat mobile, coba mobilenetv3large100, efficientnetb0, atau efficientvitb0. Ukurannya kecil, inferensinya cepat, akurasinya masih respectable.

Kalau kalian butuh keseimbangan bagus antara akurasi dan biaya di GPU, convnexttiny, resnet50, dan efficientnetb3 adalah titik manis yang jarang mengecewakan.

Kalau kalian mengejar akurasi maksimal dan punya GPU besar plus data banyak, lihat convnextbase, swinbasepatch4window7224, atau model keluarga eva02 yang sering menempati posisi teratas benchmark.

Kalau data kalian sedikit sekali, pilih model yang dilatih di dataset besar seperti ImageNet-22k (perhatikan in22k di nama modelnya), karena fiturnya lebih general dan transfer learning-nya lebih kuat.

Satu tips terakhir: selalu benchmark dua sampai tiga kandidat di data kalian sendiri. Peringkat di ImageNet nggak selalu berlaku di dataset spesifik kalian, apalagi kalau domainnya jauh seperti citra medis atau citra satelit.

Tips dan Best Practice

Selalu pakai resolvemodeldataconfig dan createtransform, jangan hardcode normalisasi. Ini kesalahan nomor satu yang aku lihat di kode orang.

Perhatikan ukuran input. Beberapa model dilatih di 224x224, ada yang 288, 384, bahkan 512. Kalau kalian paksa ukuran yang salah ke ViT, kadang error atau akurasinya turun karena posisi embedding-nya nggak cocok.

Gunakan mixed precision buat hemat memori dan mempercepat training di GPU modern, cukup bungkus forward pass dengan torch.autocast.

Simpan nama model dan versi timm di file konfigurasi eksperimen kalian. Nama bobot di timm kadang berubah antar versi, dan ini bisa bikin hasil kalian nggak reproducible.

Manfaatkan timm.utils.ModelEmaV2 kalau kalian training lama. Exponential moving average dari bobot sering ngasih akurasi validasi lebih stabil dan sedikit lebih tinggi secara gratis.

Kesimpulan

timm adalah salah satu library yang paling meningkatkan produktivitas kalau kalian kerja di computer vision. Yang perlu kalian ingat: timm.createmodel() adalah satu pintu masuk ke lebih dari seribu arsitektur dengan bobot pretrained berkualitas.

Selalu ambil transform lewat resolvemodeldataconfig supaya preprocessing kalian persis sama dengan waktu model dilatih.

numclasses mengganti head untuk dataset sendiri, numclasses=0 mengubah model jadi feature extractor, dan features_only=True memberi feature map multi-skala untuk deteksi dan segmentasi.

Fine-tuning cukup dengan loop PyTorch biasa, ditambah augmentasi modern dan optimizer AdamW dari timm.

Pemilihan model harus mempertimbangkan target deployment, ukuran data, dan domain, bukan cuma peringkat akurasi ImageNet.

Coba ambil dataset kecil kalian sendiri, misalnya klasifikasi produk atau kualitas hasil produksi, lalu bandingkan tiga arsitektur berbeda cuma dengan mengganti satu string. Kalian bakal langsung ngerasain kenapa library ini jadi standar de facto di dunia computer vision PyTorch. Selamat mencoba.

Artikel Terkait

Depth Anything V2: Prediksi Kedalaman dari Satu Gambar dengan Python

Depth Anything V2: Prediksi Kedalaman dari Satu Gambar dengan Python Halo temen-temen, di tutorial kali ini aku mau ngaj...

DINOv2: Panduan Lengkap Vision Foundation Model dari Meta AI untuk Embedding Gambar Tanpa Label

DINOv2: Panduan Lengkap Vision Foundation Model dari Meta AI untuk Embedding Gambar Tanpa Label Halo temen-temen, di tut...

PaddleOCR: Ekstraksi Teks dari Gambar dan Dokumen dengan Akurasi Tinggi

PaddleOCR: Ekstraksi Teks dari Gambar dan Dokumen dengan Akurasi Tinggi Halo temen-temen, kali ini kita bahas salah satu...

DeepSpeed: Melatih Model Raksasa di GPU Terbatas dengan ZeRO dan Offload

DeepSpeed: Melatih Model Raksasa di GPU Terbatas dengan ZeRO dan Offload Halo temen-temen, kali ini kita masuk ke topik ...