Downloads · 30 days
0
bima2026/beefresearch-bima
beefresearch-bima is a machine learning model from bima2026. Use it for the machine learning task on the model card, and read the license before you ship it in a product. It is set up for scikit-learn. The card lists the license as mit.
1. Latar Belakang 2. Tujuan Penelitian 3. Dataset 4. Metodologi 5. Arsitektur Pipeline 6. Tahapan Pipeline (Detail Teknis) 7. Hasil dan Evaluasi 8. Struktur Output
Downloads · 30 days
0
Access
Public
Updated Aug 23, 2026
Repo size
—
Likes
0
Public
Click a slice to open those files.
.lock1.5 MB · 61%
From the Hugging Face model README
Penilaian mutu dan kesegaran daging sapi secara konvensional masih mengandalkan inspeksi visual oleh tenaga ahli—sebuah proses yang tidak skalabel, subjektif, dan rentan terhadap inkonsistensi antar penilai. Di sisi lain, pendekatan machine learning supervised (SVM, KNN, CNN) membutuhkan dataset berlabel dalam jumlah besar yang mahal dan memakan waktu untuk dikumpulkan, terutama di konteks penelitian lapangan (RPH dan UMKM).
Proyek ini menawarkan pendekatan alternatif: pipeline sepenuhnya unsupervised berbasis computer vision yang mampu memisahkan citra daging sapi ke dalam dua klaster mutu (Segar / Tidak Segar) tanpa memerlukan label training satu pun. Sistem ini dirancang untuk berjalan lintas domain (multi-domain), yaitu dapat menangani dataset dari kondisi pengambilan gambar yang berbeda (latar belakang hitam dari RPH Day-1 dan karton biru dari UMKM Day-2) tanpa memerlukan penyesuaian aturan warna yang berbeda per domain.
Dataset terdiri dari citra daging sapi yang dikumpulkan dari dua domain berbeda:
| Domain | Kondisi Pengambilan | Latar Belakang | Label Temporal |
|---|---|---|---|
| DAY-1 | RPH (Rumah Potong Hewan), hari pertama pasca penyembelihan | Kain hitam | Segar |
| DAY-2 | UMKM/pasar, hari berikutnya | Karton biru muda | Mendekati tidak segar |
[HARI]_[DOMAIN]_[KODE]_[NOMOR].JPG
Contoh: DAY-1_RPH_SIR_001.JPG
HARI: DAY-1 atau DAY-2DOMAIN: kode lokasi pengambilan gambarKODE: jenis potongan daging (misal SIR untuk sirloin)NOMOR: nomor urut citraFile data/labels.csv dengan kolom filename,label (nilai: segar / tidak_segar) bersifat opsional dan tidak digunakan untuk training. Label ini hanya dipakai untuk validasi eksternal pasca-hoc (menghitung ARI, NMI, dan Purity) guna mengukur seberapa baik klaster otomatis bersesuaian dengan penilaian pakar.
Pipeline ini tidak menggunakan label apapun dalam proses pelatihan. Seluruh pemisahan mutu dilakukan secara otonom berdasarkan struktur visual inheren dari citra daging. Pendekatan ini dipilih karena:
Citra Mentah
│
▼
Preprocessing & Segmentasi ROI
(Resize → Denoising → HSV Thresholding → Morfologi → Bounding Box Crop)
│
▼
Ekstraksi Fitur Lokal
(SIFT / SURF, dibatasi pada area mask daging)
│
├── Descriptor lokal (128-dim SIFT / 64-dim SURF)
└── Momen HSV (Mean, Std, Skewness per channel H/S/V → 9-dim)
│
▼
Bags of Visual Words (BoVW)
(MiniBatchKMeans codebook → Histogram Hellinger → Fusi HSV)
│
▼
Reduksi Dimensi (PCA)
│
▼
Clustering Unsupervised
(K-Means / GMM, k=2)
│
▼
Evaluasi & Komparasi
(Metrik internal + eksternal opsional + visualisasi PCA/t-SNE)
Segmentasi menggunakan Strict HSV Thresholding pada rentang pigmen mioglobin (H: 0–30 dan 160–180, S > 30, V > 25), diikuti Margin Annihilation (menghapus 12% tepi citra untuk mengeliminasi sisa label/stiker), lalu morfologi ellips (close + open) untuk menutup porositas tanpa mendistorsi batas. Pendekatan ini bekerja untuk kedua domain (hitam dan biru) tanpa aturan warna yang berbeda per domain.
Histogram BoVW dinormalisasi menggunakan transformasi Hellinger (√(histogram/total)) bukan L2 biasa. Ini menghasilkan vektor dengan norma L2 = 1 dan mengurangi sensitivitas terhadap frekuensi kata visual yang sangat dominan—ekuivalen dengan menggunakan kernel Hellinger pada SVM, namun bekerja langsung di ruang Euclidean sehingga K-Means dan GMM dapat diterapkan secara efektif.
Momen warna HSV (mean, std, skewness untuk channel H, S, dan V = 9 dimensi) difusikan ke histogram BoVW setelah dua tahap normalisasi:
Dengan demikian, parameter HSV_FUSION_WEIGHT benar-benar merepresentasikan "bobot proporsi" yang terkendali: nilai 3.0 berarti kontribusi warna diberi bobot 3× lipat kontribusi tekstur.
Semua algoritma clustering (K-Means dan GMM) dijalankan di ruang fitur yang sama setelah PCA (bukan K-Means di data mentah sementara GMM di PCA). Ini memastikan perbandingan murni pada level algoritma, bukan perbandingan ruang fitur yang tercampur.
Untuk menghindari metric-chasing (melaporkan Silhouette dari satu kali fit yang berpotensi terlalu optimis), pipeline menjalankan 10 kali subsample 80% data dan melaporkan Silhouette mean ± std serta ARI vs klaster data penuh. ARI mendekati 1 berarti klaster stabil terhadap perturbasi subsampling.
Pipeline terdiri dari 8 tahap yang dapat dijalankan secara terpisah (dengan cache pickle antar tahap) atau sekaligus:
┌─────────────────────────────────────────────────────────────┐
│ run_pipeline.py │
│ │
│ step_preprocess → step_extract → step_bovw │
│ │ │ │ │
│ manifest.pkl descriptors_*.pkl histograms_*.pkl │
│ masks/*.npz timing_*.pkl codebooks_*.pkl │
│ processed/*.npz hsv_*.pkl │
│ │
│ step_cluster → step_evaluate → step_export │
│ │ │ │ │
│ cluster_labels.pkl figures/ Laporan_Prediksi.csv │
│ cluster_metrics.csv tables/ │
│ │
│ step_tune → step_build_production_model │
│ │ │ │
│ tuning_results.csv meat_grading_model.joblib │
│ │
│ step_batch_experiment │
│ │ │
│ archives/ (14 skenario + Master_Log.csv) │
└─────────────────────────────────────────────────────────────┘
src/preprocessing.py, src/segmentation.py)Alur per citra:
RESIZE_MAX_SIDE).fastNlMeansDenoisingColored (opsional, diaktifkan jika DENOISE_H bukan None).area / (dist_dari_pusat + 1).outputs/visualized_segments/.Output: outputs/interim/processed/*.npz (gray, hsv, mask per citra), manifest.pkl.
src/feature_extraction.py)cv2.xfeatures2d.SIFT_create, descriptor 128-dimensi.cv2.xfeatures2d.SURF_create, Hessian threshold = 500 (hasil tuning), descriptor 64-dimensi.mask di detectAndCompute.Output: descriptors_sift.pkl, descriptors_surf.pkl, hsv_sift.pkl, hsv_surf.pkl, timing_*.pkl.
src/bovw.py)MiniBatchKMeans dengan batch size 2000, n_init=10, max_iter=200, untuk ukuran k ∈ {50, 100, 200}.codebook.predict(descriptors), lalu dinormalisasi dengan transformasi Hellinger.USE_COLOR_FUSION=True, vektor HSV dinormalisasi (MinMax → L2-norm) lalu dikali HSV_FUSION_WEIGHT dan di-concatenate ke histogram BoVW.Output: codebooks_*.pkl (dict k → MiniBatchKMeans), histograms_*.pkl (dict k → matrix N×(k+9)).
src/clustering.py)4a. Sensitivitas Ukuran Codebook (ruang fitur mentah, K-Means saja):
feature_space="raw" agar tidak tercampur dengan analisis perbandingan algoritma.4b. Perbandingan Algoritma Clustering (ruang fitur PCA, codebook k=200):
n_init=20) dan GMM (covariance_type="full", n_init=10) dibandingkan di ruang PCA yang sama.4c. Uji Stabilitas Klaster:
Output: cluster_labels.pkl, cluster_metrics_all.csv, cluster_stability.csv.
src/evaluation.py, src/visualization.py)Metrik Validasi Internal (tanpa label):
| Metrik | Interpretasi | Arah Optimal |
|---|---|---|
| Silhouette Score | Kerapatan intra-klaster vs. separasi antar-klaster, rentang [-1, 1] | ↑ Lebih tinggi lebih baik |
| Davies-Bouldin Index | Rata-rata similaritas tiap klaster dengan klaster paling mirip | ↓ Lebih rendah lebih baik |
| Calinski-Harabasz Index | Rasio dispersi antar-klaster / intra-klaster | ↑ Lebih tinggi lebih baik |
Metrik Validasi Eksternal (bila labels.csv tersedia):
| Metrik | Interpretasi |
|---|---|
| ARI (Adjusted Rand Index) | Kesesuaian klaster dengan ground truth, dikoreksi untuk chance, rentang [-1, 1] |
| NMI (Normalized Mutual Info) | Informasi mutual antara klaster dan ground truth, rentang [0, 1] |
| Purity | Proporsi anggota klaster yang berasal dari kelas mayoritas |
Visualisasi yang dihasilkan:
step_tune)Grid search terhadap:
Total 75 kombinasi diuji, diurutkan berdasarkan Silhouette Score tertinggi lalu Davies-Bouldin terendah. Konfigurasi terbaik kemudian diuji stabilitasnya (10× subsample) dan hasilnya dilaporkan sebagai mean ± std, bukan nilai mentah dari pencarian, untuk menghindari bias optimistis.
Peringatan metodologis: Silhouette Score hasil grid search tidak boleh dilaporkan langsung sebagai bukti separabilitas karena merupakan target optimisasi itu sendiri. Selalu gunakan angka stabilitas (mean ± std dari subsample berulang).
step_export)Menghasilkan tabel prediksi per citra dari model terbaik (SIFT + K-Means) dalam format CSV yang siap dibuka di Excel, mencakup: nama file, domain asal, hari ke-, jenis potongan, ID klaster, dan asumsi kondisi (Klaster A / Klaster B).
step_build_production_model)Merakit dan menyimpan seluruh komponen pipeline ke dalam satu file .joblib:
model_package = {
"codebook": MiniBatchKMeans, # Kamus visual BoVW
"scaler": MinMaxScaler, # Normalisasi HSV
"pca": PCA, # Reduksi dimensi
"gmm": GaussianMixture, # Classifier akhir
"hsv_weight": float, # Bobot fusi warna
"metadata": dict # Konfigurasi eksperimen
}
Model ini dapat dimuat dan digunakan untuk klasifikasi citra daging baru tanpa menjalankan ulang seluruh pipeline.
| Aspek | SIFT | SURF |
|---|---|---|
| Dimensi Descriptor | 128-dim | 64-dim |
| Kecepatan Ekstraksi | Lebih lambat | ~2–3× lebih cepat |
| Jumlah Keypoint | Lebih banyak (threshold berbasis DoG) | Bergantung Hessian threshold (500 optimal) |
| Separabilitas Klaster | Silhouette umumnya lebih tinggi di ruang PCA | Silhouette kompetitif setelah fusi HSV |
| Keunggulan | Akurasi separasi tekstur | Efisiensi komputasi |
| Komponen | Dampak pada Silhouette |
|---|---|
| Raw BoVW tanpa PCA | Baseline (rendah akibat curse of dimensionality) |
| + PCA (30 komponen) | Peningkatan signifikan |
| + Fusi HSV (weight=3.0) | Peningkatan tambahan — warna permukaan merupakan indikator kesegaran yang kuat |
| + Normalisasi L2 HSV | Memastikan bobot HSV terkendali dan dapat diinterpretasi |
Kualitas klaster dilaporkan sebagai:
Ukuran codebook k ∈ {50, 100, 200} diuji. Secara umum, k=200 memberikan representasi yang lebih granular dan Silhouette Score yang lebih baik. Perbedaan antara k=100 dan k=200 biasanya tidak dramatis, menunjukkan saturasi representasi.
outputs/
├── interim/ # Cache pickle antar tahap (dapat dihapus & diulang)
│ ├── manifest.pkl # Metadata seluruh citra (hari/domain/kode/label)
│ ├── processed/ # *.npz per citra (gray, hsv, mask)
│ ├── masks/ # Mask ROI terpisah (*.npz)
│ ├── descriptors_sift.pkl
│ ├── descriptors_surf.pkl
│ ├── hsv_sift.pkl
│ ├── hsv_surf.pkl
│ ├── codebooks_sift.pkl
│ ├── codebooks_surf.pkl
│ ├── histograms_sift.pkl
│ ├── histograms_surf.pkl
│ ├── timing_sift.pkl
│ ├── timing_surf.pkl
│ └── cluster_labels.pkl
├── figures/ # Seluruh grafik (PCA, t-SNE, radar, boxplot, dsb.)
├── tables/ # Seluruh tabel hasil (CSV)
│ ├── manifest_summary.csv
│ ├── efficiency_raw.csv
│ ├── efficiency_summary.csv
│ ├── cluster_metrics_all.csv
│ ├── cluster_stability.csv
│ ├── tuning_results_deep_search.csv
│ ├── Laporan_Prediksi_SIFT_KMEANS.csv
│ └── final_summary.json
├── visualized_segments/ # Hasil QA segmentasi (asli | tersegmentasi)
├── meat_grading_model.joblib # Model produksi siap pakai
└── logs/
└── pipeline.log
archives/
└── DATA-BIMA_EXP-YYYYMMDD-XX/ # Satu folder per skenario eksperimen batch
├── code_snapshot/ # Snapshot kode saat eksperimen berjalan
└── results/
└── evaluation_metrics.json
Master_Log_DATA-BIMA_YYYYMMDD_HHMMSS.csv # Rekapitulasi 14 skenario
# Install Python 3.7 lewat uv (jika belum ada di mesin)
uv python install 3.7
# Buat & sync environment sesuai pyproject.toml
uv sync
# Verifikasi SIFT & SURF tersedia (harus mencetak True True)
uv run python -c "import cv2; s=cv2.xfeatures2d.SIFT_create(); f=cv2.xfeatures2d.SURF_create(); print(True, True)"
Catatan: Jika
uv python install 3.7gagal karena python-build-standalone tidak lagi menyediakan build 3.7 di platform Anda, gunakan pyenv/conda untuk menyediakan interpreter 3.7, lalu arahkan uv ke sana:uv venv --python /path/to/python3.7 uv sync
| Paket | Versi | Fungsi |
|---|---|---|
opencv-contrib-python | 3.4.2.16 | SIFT, SURF (xfeatures2d) |
scikit-learn | ≥1.0.2 | KMeans, GMM, PCA, metrik |
numpy | ≥1.21.6 | Operasi matriks |
pandas | ≥1.1.5 | Tabel hasil |
matplotlib | ≥3.5.3 | Visualisasi |
seaborn | ≥0.12.2 | Visualisasi statistik |
DAY-1_[DOMAIN]_[KODE]_[NOMOR].JPG).data/dataset_root/ atau ubah RAW_DATA_DIR di config.py.data/labels.csv dengan kolom filename,label untuk validasi eksternal.Edit config.py sesuai kebutuhan:
DATASET_DOMAIN = "DATA-BIMA" # Nama domain untuk penamaan arsip
RAW_DATA_DIR = "data/dataset_root"
USE_COLOR_FUSION = True # Aktifkan fusi momen HSV
HSV_FUSION_WEIGHT = 3.0 # Bobot kontribusi warna vs. tekstur
DEFAULT_CODEBOOK_SIZE = 200 # Ukuran codebook utama
SURF_HESSIAN_THRESHOLD = 500 # Threshold detektor SURF
uv run python run_pipeline.py --step preprocess
uv run python run_pipeline.py --step extract
uv run python run_pipeline.py --step bovw
uv run python run_pipeline.py --step cluster
uv run python run_pipeline.py --step evaluate
uv run python run_pipeline.py --step export
uv run python run_pipeline.py --step build_model
uv run python run_pipeline.py --step all
Perintah
--step allmenjalankan semua tahap kecualitune(untuk menghindari grid search yang lama secara tidak sengaja).
# Grid search hyperparameter (lama, ~75 kombinasi × step_bovw)
uv run python run_pipeline.py --step tune
# 14 skenario eksperimen batch dengan arsip otomatis
uv run python run_pipeline.py --step batch_log
beefresearch-bima/
├── config.py # Konfigurasi sentral pipeline
├── run_pipeline.py # Orkestrator utama (semua step ada di sini)
├── pyproject.toml # Dependensi & metadata proyek
├── data/
│ ├── dataset_root/ # Dataset mentah (diatur di config.py)
│ └── labels.csv # Ground truth opsional
├── src/
│ ├── preprocessing.py # Resize, denoising, konversi, crop
│ ├── segmentation.py # HSV thresholding & morfologi ROI
│ ├── feature_extraction.py # SIFT/SURF + momen HSV
│ ├── bovw.py # Codebook & histogram Hellinger
│ ├── clustering.py # K-Means, GMM, metrik validasi
│ ├── evaluation.py # Tabel efisiensi & komparasi fitur
│ ├── visualization.py # Semua fungsi plot
│ └── utils.py # Logger, I/O pickle/JSON, utils umum
├── outputs/ # Semua hasil pipeline (di-generate otomatis)
└── archives/ # Arsip eksperimen batch