Topeng Bali adalah salah satu warisan budaya yang kaya dan mendalam dari Indonesia, merepresentasikan berbagai karakter dan cerita dalam upacara dan pertunjukan tradisional. Dalam interval digital ini, teknologi machine learning dapat membantu kita untuk lebih memahami dan mengklasifikasikan jenis-jenis topeng tersebut dengan lebih efektif. Pada artikel ini, kita akan membahas bagaimana menggunakan model VGG16 yang telah dilatih dengan bobot dari ImageNet untuk mengklasifikasikan topeng Bali berdasarkan dataset yang tersedia di Kaggle.
Bali, dengan segala keindahan dan kekayaan budayanya, memiliki berbagai bentuk seni yang unik, salah satunya adalah topeng. Topeng-topeng ini tidak hanya digunakan dalam seni pertunjukan, tetapi juga memiliki makna spiritual dan ritual yang mendalam. Mengingat keragaman dan kompleksitas dari jenis-jenis topeng Bali, pengenalan otomatis menggunakan teknologi machine learning menjadi tantangan yang menarik sekaligus penting.
Pada proyek ini, saya menggunakan dataset dari Kaggle yang terdiri dari tujuh kelas topeng Bali: bujuh, dalem, keras, penasar, sidakarya, tua, dan wijil. Dengan menggunakan arsitektur jaringan syaraf konvolusional (Convolutional Neural Neighborhood — CNN) yang populer, VGG16, dan memanfaatkan bobot yang sudah dilatih sebelumnya dari ImageNet, kita akan membangun model klasifikasi yang mampu mengenali dan membedakan jenis-jenis topeng ini.
Proses yang akan dibahas dalam artikel ini mencakup persiapan dataset, preprocessing gambar, dan pelatihan model menggunakan VGG16. Dengan demikian, kita akan mendapatkan pemahaman yang lebih baik tentang bagaimana teknologi dapat digunakan untuk mendukung pelestarian dan pemahaman budaya kita.
Proses yang dilakukan dalam endeavor ini adalah untuk mempersiapkan dataset yang akan digunakan untuk pelatihan model klasifikasi topeng Bali menggunakan VGG16. Berikut adalah langkah-langkah yang diambil beserta penjelasannya:
- Import Library dan Definisi Path
import os
import matplotlib.pyplot as plt
import shutil
from sklearn.model_selection import train_test_split
import numpy as np
from PIL import Image
Pada langkah ini, kita mengimpor library yang diperlukan untuk manipulasi file, visualisasi information, dan pengelolaan gambar. Library yang digunakan antara lain adalah os
untuk operasi file, matplotlib.pyplot
untuk visualisasi grafis, shutil
untuk operasi file system, sklearn.model_selection.train_test_split
untuk membagi dataset menjadi put together set, validation set, dan check out set, numpy
untuk manipulasi information numerik, dan PIL.Image
untuk manipulasi gambar.
2. Visualisasi Jumlah Gambar dalam Setiap Kelas
# Baca nama folder (kelas) dan hitung jumlah gambar dalam setiap kelas
class_folders = os.listdir(image_path)
class_counts = []for class_folder in class_folders:
class_path = os.path.be part of(image_path, class_folder)
if os.path.isdir(class_path):
num_images = len(os.listdir(class_path))
class_counts.append((class_folder, num_images))
# Visualisasikan nama kelas beserta jumlah gambar dalam grafik
plt.decide(figsize=(10, 6))
bars = plt.bar([x[0] for x in class_counts], [x[1] for x in class_counts], shade='skyblue')
plt.xlabel('Kelas')
plt.ylabel('Jumlah Gambar')
plt.title('Jumlah Gambar dalam Setiap Kelas')
# Tambahkan label jumlah gambar pada setiap batang
for bar in bars:
yval = bar.get_height()
plt.textual content material(bar.get_x() + bar.get_width()/2, yval, int(yval), va='bottom')
plt.xticks(rotation=45, ha='correct')
plt.tight_layout()
plt.current()
Langkah ini bertujuan untuk menghitung dan memvisualisasikan jumlah gambar yang ada dalam setiap kelas (folder) di dataset awal. Grafik bar menunjukkan distribusi gambar per kelas, memberi pemahaman awal tentang seberapa seimbang atau tidaknya dataset.
3. Pembersihan dan Pembagian Dataset
def clean_folders():
for folder in [train_path, valid_path, test_path]:
if os.path.exists(folder):
shutil.rmtree(folder)clean_folders()
for path in [train_path, valid_path, test_path]:
os.makedirs(path, exist_ok=True)
for class_folder in class_folders:
class_path = os.path.be part of(image_path, class_folder)
if os.path.isdir(class_path):
recordsdata = os.listdir(class_path)
train_files, test_valid_files = train_test_split(recordsdata, test_size=0.4, random_state=42)
valid_files, test_files = train_test_split(test_valid_files, test_size=0.5, random_state=42)
for file in train_files:
src = os.path.be part of(class_path, file)
dest = os.path.be part of(train_path, class_folder)
os.makedirs(dest, exist_ok=True)
shutil.copy(src, dest)
for file in valid_files:
src = os.path.be part of(class_path, file)
dest = os.path.be part of(valid_path, class_folder)
os.makedirs(dest, exist_ok=True)
shutil.copy(src, dest)
for file in test_files:
src = os.path.be part of(class_path, file)
dest = os.path.be part of(test_path, class_folder)
os.makedirs(dest, exist_ok=True)
shutil.copy(src, dest)
Di sini, kita memastikan bahwa folder put together, respectable, dan check out dibersihkan terlebih dahulu sebelum membagi dataset. Kemudian, dataset dipecah menjadi put together set, validation set, dan check out set dengan mempertahankan proporsi jumlah gambar setiap kelas. Penggunaan train_test_split
dari sklearn.model_selection
memastikan bahwa proses pembagian dilakukan secara acak dengan mempertahankan distribusi yang seimbang antara setiap kelas.
4. Visualisasi Jumlah Gambar per Kelas di Setiap Folder
class_counts = {'put together': {}, 'respectable': {}, 'check out': {}}def count_images_per_class(folder_path, folder_name):
class_folders = os.listdir(folder_path)
for class_folder in class_folders:
class_path = os.path.be part of(folder_path, class_folder)
if os.path.isdir(class_path):
num_images = len(os.listdir(class_path))
class_counts[folder_name][class_folder] = num_images
count_images_per_class(train_path, 'put together')
count_images_per_class(valid_path, 'respectable')
count_images_per_class(test_path, 'check out')
Langkah ini bertujuan untuk menghitung kembali jumlah gambar per kelas setelah dibagi ke dalam put together set, validation set, dan check out set. Dengan melakukan ini, kita dapat memastikan bahwa dataset yang dibagi memiliki distribusi yang seimbang, yang penting untuk melatih model yang baik.
Berikut adalah langkah-langkah untuk melatih model klasifikasi topeng Bali menggunakan arsitektur VGG16 dan TensorFlow:
- Import Library dan Definisi Path
import os
import numpy as np
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.features import VGG16
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D
from tensorflow.keras.fashions import Model
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau, CSVLogger# Menonaktifkan verifikasi sertifikat SSL secara worldwide (hanya untuk tujuan demonstrasi, bukan praktek yang disarankan)
tf.keras.utils.get_file = lambda *args, **kwargs: get_file(*args, **kwargs, ssl_verify=False)
Di sini, kita mengimpor semua library yang dibutuhkan untuk membangun dan melatih model, termasuk TensorFlow, ImageDataGenerator untuk preprocessing gambar, arsitektur VGG16 dari keras.features, serta komponen-komponen lain seperti Dense layers untuk output, dan callbacks seperti EarlyStopping, ModelCheckpoint, ReduceLROnPlateau, dan CSVLogger untuk monitoring dan manajemen pelatihan.
2. Pengaturan ImageDataGenerator dan Mills untuk Dataset
# Definisikan path ke folder dataset
dataset_path = 'dataset'# Inisialisasi ImageDataGenerator untuk preprocessing gambar
datagen = ImageDataGenerator(
rescale=1./255, # Normalisasi information gambar
rotation_range=20, # Rentang rotasi gambar
width_shift_range=0.2, # Pergeseran lebar gambar
height_shift_range=0.2, # Pergeseran tinggi gambar
shear_range=0.2, # Pergeseran gambar
zoom_range=0.2, # Zoom gambar
horizontal_flip=True, # Putar gambar secara horizontal
fill_mode='nearest' # Mode pengisian untuk gambar yang diubah
)
# Membuat generator untuk setiap set information (put together, validation, check out)
train_generator = datagen.flow_from_directory(
os.path.be part of(dataset_path, 'put together'),
target_size=(224, 224),
batch_size=32,
class_mode='categorical',
shuffle=True
)
valid_generator = datagen.flow_from_directory(
os.path.be part of(dataset_path, 'respectable'),
target_size=(224, 224),
batch_size=32,
class_mode='categorical',
shuffle=False
)
test_generator = datagen.flow_from_directory(
os.path.be part of(dataset_path, 'check out'),
target_size=(224, 224),
batch_size=32,
class_mode='categorical',
shuffle=False
)
Pada langkah ini, kita menggunakan ImageDataGenerator untuk melakukan augmentasi information seperti rotasi, pergeseran, dan flip pada gambar. Generator-generator yang dibuat (train_generator
, valid_generator
, test_generator
) akan digunakan untuk memasukkan information gambar ke dalam model selama pelatihan, validasi, dan pengujian.
3. Membangun Model VGG16
# Membuat model VGG16
base_model = VGG16(weights='imagenet', include_top=False) # Mengambil output layer dari model
x = base_model.output
# Menambahkan worldwide frequent pooling layer
x = GlobalAveragePooling2D()(x)
# Menambahkan completely associated layer dengan 1024 neuron
x = Dense(1024, activation='relu')(x)
# Menambahkan output layer dengan 7 neuron (sesuaikan dengan jumlah kelas Anda)
predictions = Dense(7, activation='softmax')(x)
# Membuat model dengan enter dari base model dan output dari layer yang baru ditambahkan
model = Model(inputs=base_model.enter, outputs=predictions)
# Membekukan semua layer di model VGG16 agar tidak terlatih ulang
for layer in base_model.layers:
layer.trainable = False
# Kompilasi model dengan optimizer Adam dan loss carry out categorical crossentropy
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
Di sini, kita membangun arsitektur model dengan menggunakan VGG16 sebagai base model, mengambil output dari base model, menambahkan layer-layer tambahan seperti GlobalAveragePooling2D dan Dense layers untuk output, dan kemudian membuat model dengan Model API dari TensorFlow. Kita juga membekukan semua layer di VGG16 agar tidak terlatih ulang (swap learning).
4. Pelatihan Model
# Menambahkan EarlyStopping untuk menghentikan pelatihan jika tidak ada peningkatan dalam validasi loss
early_stopping = EarlyStopping(monitor='val_loss', verbose=1, endurance=3, restore_best_weights=True)# Menyimpan bobot terbaik selama pelatihan
checkpoint = ModelCheckpoint('best_model.h5', verbose=1, monitor='val_loss', save_best_only=True, mode='min')
# Menyimpan log pelatihan ke file CSV
csv_logger = CSVLogger('training_log.csv')
# Mengurangi learning charge jika tidak ada peningkatan dalam validasi loss
reduce_lr = ReduceLROnPlateau(monitor='val_loss', situation=0.2, endurance=5, min_lr=0.001)
# Melatih model dengan generator information, menyimpan callback untuk monitoring dan mengatur epochs
historic previous = model.match(
train_generator,
epochs=50,
validation_data=valid_generator,
callbacks=[early_stopping, checkpoint, csv_logger, reduce_lr]
)
Langkah ini melibatkan proses pelatihan model menggunakan generator information yang telah disiapkan sebelumnya. Kita menggunakan EarlyStopping
untuk menghentikan pelatihan jika tidak ada peningkatan dalam validasi loss, ModelCheckpoint
untuk menyimpan bobot model terbaik, CSVLogger
untuk mencatat log pelatihan ke file CSV, dan ReduceLROnPlateau
untuk mengurangi learning charge jika tidak ada peningkatan dalam validasi loss.
5. Evaluasi Model dan Visualisasi Performa
# Memuat bobot terbaik untuk evaluasi
model.load_weights('best_model.h5')# Evaluasi model pada information validasi
valid_predictions = model.predict(valid_generator)
valid_pred_classes = np.argmax(valid_predictions, axis=1)
valid_true_classes = valid_generator.classes
# Menghitung metrik-metrik evaluasi seperti accuracy, precision, recall, dan F1-score
accuracy = accuracy_score(valid_true_classes, valid_pred_classes)
precision = precision_score(valid_true_classes, valid_pred_classes, frequent='weighted')
recall = recall_score(valid_true_classes, valid_pred_classes, frequent='weighted')
f1 = f1_score(valid_true_classes, valid_pred_classes, frequent='weighted')
print("Accuracy:", accuracy)
print("Precision:", precision)
print("Recall:", recall)
print("F1 Ranking:", f1)
Output :
3/3 [==============================] — 13s 3s/step
Accuracy: 1.0
Precision: 1.0
Recall: 1.0 F1 Ranking: 1.0
Pada tahap ini, kita mengambil bobot terbaik dari model yang telah dilatih dan mengevaluasi performanya pada information validasi menggunakan metrik-metrik evaluasi seperti accuracy, precision, recall, dan F1-score.
6. Visualisasi Loss dan Accuracy selama Pelatihan
# Membaca log pelatihan dari file CSV
import pandas as pd
log_data = pd.read_csv('training_log.csv')# Membuat grafik untuk visualisasi loss dan accuracy selama pelatihan
plt.decide(figsize=(12, 6))
# Plot loss
plt.subplot(1, 2, 1)
plt.plot(log_data['epoch'], log_data['loss'], label='Teaching Loss')
plt.plot(log_data['epoch'], log_data['val_loss'], label='Validation Loss')
plt.title('Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
# Plot accuracy
plt.subplot(1, 2, 2)
plt.plot(log_data['epoch'], log_data['accuracy'], label='Teaching Accuracy')
plt.plot(log_data['epoch'], log_data['val_accuracy'], label='Validation Accuracy')
plt.title('Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()
plt.current()
Visualisasi ini membantu kita untuk melihat bagaimana loss dan accuracy model berubah selama proses pelatihan, baik pada information pelatihan maupun validasi.
7. Confusion Matrix dan Classification Report
from sklearn.metrics import classification_report, confusion_matrix
import seaborn as sns# Melakukan prediksi pada information uji
y_pred = model.predict(test_generator)
y_pred_classes = np.argmax(y_pred, axis=1)
# Mendapatkan label sebenarnya dari information uji
true_classes = test_generator.classes
class_labels = report(test_generator.class_indices.keys())
# Menampilkan laporan klasifikasi
print(classification_report(true_classes, y_pred_classes, target_names=class_labels))
# Membuat confusion matrix
conf_matrix = confusion_matrix(true_classes, y_pred_classes)
# Menampilkan confusion matrix menggunakan heatmap
plt.decide(figsize=(10, 8))
sns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues', xticklabels=class_labels, yticklabels=class_labels)
plt.xlabel('Predicted Labels')
plt.ylabel('True Labels')
plt.title('Confusion Matrix')
plt.current()
Output :
Langkah ini melibatkan evaluasi lebih lanjut dari performa model dengan melihat classification report yang mencakup precision, recall, dan F1-score untuk setiap kelas, serta confusion matrix untuk melihat seberapa baik model memprediksi setiap kelas.
Dengan langkah-langkah ini, Anda dapat membangun, melatih, dan mengevaluasi model klasifikasi menggunakan arsitektur VGG16 untuk dataset klasifikasi topeng Bali. Pastikan untuk menyesuaikan jumlah kelas, dataset, dan pengaturan lainnya sesuai kebutuhan proyek Anda.
Dalam proyek ini, saya berhasil mengembangkan dan melatih model klasifikasi menggunakan arsitektur VGG16 untuk mengidentifikasi tujuh jenis topeng Bali yang berbeda. Melalui langkah-langkah yang sistematis, dimulai dari persiapan dataset hingga evaluasi akhir, saya mencapai hasil yang sangat memuaskan.
Hasil evaluasi menunjukkan bahwa model saya mencapai tingkat akurasi, presisi, recall, dan F1-score sebesar 1.0 untuk setiap kelas, menandakan kemampuannya yang sangat baik dalam mengenali dan membedakan setiap jenis topeng. Keberhasilan ini tidak hanya menunjukkan kehandalan arsitektur deep learning VGG16, tetapi juga memvalidasi pendekatan saya dalam membagi dataset, melakukan augmentasi gambar, dan mengimplementasikan teknik-teknik pengelolaan model yang efektif.
Penerapan model ini dapat memberikan kontribusi signifikan dalam pelestarian dan pemahaman lebih lanjut terhadap budaya topeng Bali. Dengan kemampuannya untuk secara otomatis mengidentifikasi topeng berdasarkan gambar, model ini berpotensi menjadi alat yang berharga dalam studi seni, pendidikan budaya, serta dalam upaya pelestarian warisan budaya.
Kesimpulan ini menegaskan bahwa integrasi teknologi deep learning dengan budaya lokal bukan hanya berpotensi untuk mempertahankan identitas budaya, tetapi juga memperluas penggunaan teknologi modern dalam mendukung tujuan sosial dan kebudayaan yang lebih luas.