%pip install -q torch torchvision scikit-image librosa transformers
import numpy as np
import torch
import torchvision
from torchvision import transforms, models
from skimage.feature import hog
from skimage.color import rgb2gray
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
device = 'cuda' if torch.cuda.is_available() else 'cpu'
print('Device:', device)Notebook Bab 12 - Citra & Audio
Notebook Bab 12 ini punya dua bagian. Bagian Demo tinggal Anda jalankan lalu amati keluarannya; bagian Mini Project berisi soal dan data yang Anda kerjakan sendiri.
Karena memakai pretrained model, notebook ini paling praktis dijalankan di Google Colab dengan GPU. Kita bandingkan fitur rancangan tangan (HOG, MFCC) dengan representasi yang dipelajari mesin (CNN, wav2vec2).
Persiapan
Section 1 - Demo: Fitur Rancangan Tangan vs. Representasi Mendalam
Citra: HOG vs fitur CNN pretrained
Dua kelas CIFAR-10 (pesawat vs mobil), 400 citra per kelas.
data = torchvision.datasets.CIFAR10(root='./data', train=True, download=True)
X_img, y_img, count, per = [], [], {0: 0, 1: 0}, 400
for img, label in zip(data.data, data.targets):
if label in (0, 1) and count[label] < per:
X_img.append(img); y_img.append(label); count[label] += 1
if count[0] >= per and count[1] >= per:
break
X_img, y_img = np.array(X_img), np.array(y_img)
print('Citra:', X_img.shape, '| label:', np.bincount(y_img))# Fitur rancangan tangan: HOG.
Xhog = np.array([hog(rgb2gray(im), pixels_per_cell=(8, 8), cells_per_block=(2, 2)) for im in X_img])
# Fitur dipelajari mesin: ResNet18 pretrained sebagai feature extractor beku.
resnet = models.resnet18(weights=models.ResNet18_Weights.DEFAULT)
resnet.fc = torch.nn.Identity()
resnet = resnet.eval().to(device)
prep = transforms.Compose([
transforms.ToPILImage(), transforms.Resize((224, 224)), transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),
])
feats = []
with torch.no_grad():
for i in range(0, len(X_img), 64):
batch = torch.stack([prep(im) for im in X_img[i:i + 64]]).to(device)
feats.append(resnet(batch).cpu().numpy())
Xcnn = np.vstack(feats)
print('Dimensi HOG:', Xhog.shape[1], '| dimensi CNN:', Xcnn.shape[1])def eval_rep(Xf):
Xtr, Xte, ytr, yte = train_test_split(Xf, y_img, test_size=0.3, random_state=42, stratify=y_img)
clf = LogisticRegression(max_iter=2000).fit(Xtr, ytr)
return accuracy_score(yte, clf.predict(Xte))
print('HOG (rancangan tangan) akurasi =', round(eval_rep(Xhog), 3))
print('ResNet18 (dipelajari mesin) akurasi =', round(eval_rep(Xcnn), 3))Audio: MFCC vs embedding wav2vec2
Pada satu klip contoh, kita bandingkan bentuk representasi rancangan tangan (MFCC) dengan embedding dari model raw-waveform pretrained.
import librosa
from transformers import Wav2Vec2Processor, Wav2Vec2Model
wav, sr = librosa.load(librosa.example('trumpet'), sr=16000)
mfcc = librosa.feature.mfcc(y=wav, sr=sr, n_mfcc=13)
print('MFCC (rancangan tangan) shape :', mfcc.shape)
proc = Wav2Vec2Processor.from_pretrained('facebook/wav2vec2-base-960h')
w2v = Wav2Vec2Model.from_pretrained('facebook/wav2vec2-base-960h').eval()
inp = proc(wav, sampling_rate=sr, return_tensors='pt')
with torch.no_grad():
emb = w2v(**inp).last_hidden_state.mean(dim=1)
print('Embedding wav2vec2 (dipelajari mesin) shape :', tuple(emb.shape))🔎 Amati. Untuk citra, fitur CNN pretrained biasanya jauh mengungguli HOG karena menangkap pola semantik berlapis, sementara HOG hanya merekam gradien tepi. Untuk audio, MFCC memampatkan spektrum menjadi matriks kecil rancangan tangan, sedangkan wav2vec2 menghasilkan embedding padat dari sinyal mentah yang membawa lebih banyak makna. Untuk mencegah kebocoran, partisi data harus di tingkat sumber rekaman, bukan potongan klip.
Section 2 - Mini Project
Soal
Ulangi perbandingan citra pada dua kelas CIFAR-10 yang berbeda (misalnya kucing kelas 3 vs anjing kelas 5).
Tugas:
- Ambil ~400 citra per kelas, ekstrak fitur HOG dan fitur ResNet18.
- Latih regresi logistik pada masing-masing representasi, bandingkan akurasi.
- Diskusikan kapan fitur rancangan tangan masih memadai (mis. data sangat kecil, kelas berbeda tekstur).
Luaran: kode ekstraksi + perbandingan akurasi, plus 3-4 kalimat analisis.
Kriteria penilaian: (a) pengklasifikasi sama untuk kedua representasi; (b) split yang benar; (c) analisis trade-off rancangan tangan vs deep.
# DATA AWAL: kelas 3 (kucing) dan 5 (anjing) dari CIFAR-10.
kelas = (3, 5)
Xm, ym, cnt = [], [], {kelas[0]: 0, kelas[1]: 0}
for img, label in zip(data.data, data.targets):
if label in kelas and cnt[label] < 400:
Xm.append(img); ym.append(0 if label == kelas[0] else 1); cnt[label] += 1
if cnt[kelas[0]] >= 400 and cnt[kelas[1]] >= 400:
break
Xm, ym = np.array(Xm), np.array(ym)
print('Citra:', Xm.shape, '| label:', np.bincount(ym))# Kerjakan di sini.
# Petunjuk: pakai kembali fungsi hog(...) dan ekstraktor resnet di atas untuk Xm.