
Dalam bidang computer vision, dataset memainkan peran yang sangat penting dalam melatih model pembelajaran mesin. Namun, pengumpulan dataset yang besar dan berkualitas tinggi bisa menjadi tantangan, terutama dalam situasi di mana data yang tersedia terbatas. Untuk mengatasi masalah ini, augmentasi data (data augmentation) menjadi salah satu teknik yang paling efektif. Augmentasi data memungkinkan kita untuk memperluas jumlah data pelatihan tanpa perlu mengumpulkan data baru secara fisik. Teknik ini membantu meningkatkan kinerja model, mengurangi overfitting, dan memperkaya variasi data.
Apa itu Augmentasi Data?
Contents
Augmentasi data adalah proses di mana transformasi tertentu diterapkan pada data pelatihan asli untuk menghasilkan data baru yang berbeda tetapi tetap relevan. Dalam konteks computer vision, augmentasi data sering diterapkan pada gambar, di mana berbagai transformasi visual digunakan untuk membuat variasi dari gambar asli.
Contoh-contoh transformasi yang umum digunakan dalam augmentasi data untuk gambar meliputi:
- Rotasi (Rotation): Gambar diputar pada sudut tertentu untuk menciptakan perspektif baru.
- Skalasi (Scaling): Gambar diperbesar atau diperkecil untuk mengubah ukuran objek.
- Translasi (Translation): Gambar dipindahkan ke arah tertentu (misalnya, ke atas, bawah, kiri, atau kanan).
- Pemotongan (Cropping): Bagian tertentu dari gambar dipotong untuk fokus pada area spesifik.
- Pembalikan (Flipping): Gambar dibalik secara horizontal atau vertikal.
- Pengubahan Warna (Color Jittering): Perubahan pada kecerahan, kontras, saturasi, atau warna untuk meningkatkan variasi visual.
- Gaussian Noise: Menambahkan noise acak pada gambar untuk mensimulasikan gangguan lingkungan.
Manfaat Augmentasi Data
- Meningkatkan Generalisasi Model: Dengan augmentasi data, model menjadi lebih mampu menangani variasi dalam data yang belum pernah dilihat sebelumnya. Ini karena model dilatih dengan data yang lebih beragam, sehingga lebih mampu mengenali pola yang lebih umum.
- Mengurangi Overfitting: Overfitting terjadi ketika model terlalu cocok dengan data pelatihan dan gagal menggeneralisasi dengan baik ke data baru. Augmentasi data membantu mengurangi risiko ini dengan meningkatkan variasi data yang dilihat oleh model selama pelatihan.
- Mengatasi Keterbatasan Data: Dalam banyak kasus, data yang tersedia untuk pelatihan mungkin terbatas. Augmentasi data memungkinkan penggunaan kembali data yang sama dalam berbagai bentuk, sehingga secara efektif memperluas dataset tanpa perlu menambah data baru.
- Meningkatkan Kinerja Model: Studi telah menunjukkan bahwa augmentasi data dapat meningkatkan akurasi model dalam tugas-tugas computer vision. Dengan memaparkan model pada variasi data yang lebih luas, kinerja model dalam pengenalan gambar, deteksi objek, dan segmentasi gambar dapat meningkat secara signifikan.
Albumentation
Albumentations adalah library open-source yang dirancang untuk augmentasi data pada tugas-tugas computer vision seperti klasifikasi gambar, segmentasi, dan deteksi objek. Dibuat dengan fokus pada kecepatan dan fleksibilitas, Albumentations memungkinkan pengguna untuk menerapkan berbagai transformasi augmentasi yang kompleks dengan sedikit kode. Library ini mendukung berbagai format gambar dan sangat cocok digunakan dengan framework deep learning seperti PyTorch, TensorFlow, dan Keras.
Fitur Utama Albumentations
- Kecepatan: Albumentations dioptimalkan untuk kinerja tinggi. Ia mampu menerapkan berbagai augmentasi pada dataset besar dengan cepat, berkat implementasinya yang efisien.
- Beragam Transformasi: Albumentations menyediakan lebih dari 70 jenis transformasi augmentasi, mulai dari yang sederhana seperti rotasi dan pemotongan, hingga yang lebih kompleks seperti augmentasi berbasis mask untuk segmentasi gambar.
- Kompatibilitas Luas: Library ini mendukung format gambar umum seperti JPEG, PNG, dan TIFF. Selain itu, Albumentations kompatibel dengan berbagai framework deep learning, memudahkan integrasi dengan alur kerja yang sudah ada.
- Augmentasi Khusus untuk Segmentasi dan Deteksi Objek: Albumentations menyediakan alat khusus untuk tugas segmentasi dan deteksi objek, termasuk augmentasi yang mempertimbangkan bounding box dan mask.
- Custom Transformations: Pengguna juga bisa membuat transformasi kustom mereka sendiri jika transformasi yang tersedia tidak memenuhi kebutuhan spesifik mereka.
Perhatikan gambar berikut ini (saya menggunakan tools labelImg)
dataset diatas menggunakan format pascal VOC.
Pascal VOC adalah salah satu format anotasi yang digunakan secara luas dalam computer vision, terutama untuk tugas deteksi objek. Format ini pertama kali diperkenalkan oleh Pascal Visual Object Classes (VOC) Challenge, sebuah kompetisi yang dirancang untuk mengevaluasi model dalam tugas-tugas seperti deteksi objek, segmentasi gambar, dan klasifikasi.
Dalam deteksi objek, format Pascal VOC menyimpan informasi tentang lokasi objek dalam gambar melalui anotasi bounding box serta kategori objek. Format ini menggunakan file XML untuk menyimpan informasi anotasi.
Struktur File Pascal VOC
Setiap file XML Pascal VOC biasanya memiliki struktur dasar sebagai berikut:
<annotation> <folder>nama_folder</folder> <filename>nama_gambar.jpg</filename> <path>path/ke/nama_gambar.jpg</path> <source> <database>Unknown</database> </source> <size> <width>640</width> <height>480</height> <depth>3</depth> </size> <segmented>0</segmented> <object> <name>kategori_objek</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin>50</xmin> <ymin>50</ymin> <xmax>400</xmax> <ymax>300</ymax> </bndbox> </object> </annotation>
Kalian bisa menggunakan contoh berikut
dengan format XML pascal VOC nya yaitu
<annotation> <folder></folder> <filename>000090623_jpg.rf.f0956cd698e13eeb4614b8bbf89df3de.jpg</filename> <path>000090623_jpg.rf.f0956cd698e13eeb4614b8bbf89df3de.jpg</path> <source> <database>roboflow.ai</database> </source> <size> <width>416</width> <height>416</height> <depth>3</depth> </size> <segmented>0</segmented> <object> <name>1</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <occluded>0</occluded> <bndbox> <xmin>154</xmin> <xmax>173</xmax> <ymin>116</ymin> <ymax>139</ymax> </bndbox> </object> <object> <name>0</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <occluded>0</occluded> <bndbox> <xmin>174</xmin> <xmax>195</xmax> <ymin>116</ymin> <ymax>139</ymax> </bndbox> </object> <object> <name>9</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <occluded>0</occluded> <bndbox> <xmin>209</xmin> <xmax>230</xmax> <ymin>124</ymin> <ymax>148</ymax> </bndbox> </object> </annotation>
Kita bisa lho menggunakan albumentation dengan rotasi input dan target nya juga!
import os import numpy as np import cv2 import torch from torch.utils.data import Dataset, DataLoader import torchvision.transforms as transforms import torchvision import glob import pandas as pd import warnings import albumentations as A from albumentations.pytorch import ToTensorV2 from PIL import Image, ImageFont, ImageDraw from xml.etree import ElementTree as et from matplotlib import pyplot as plt warnings.filterwarnings("ignore") class MyDataset(Dataset): def __init__(self,classes,transform = None): self.all_images = glob.glob('*.jpg') self.dir_path = '.' self.classes = classes self.transforms = transform def __len__(self): return len(self.all_images) def __getitem__(self,idx): # capture the image name and the full image path image_name = self.all_images[idx] # read the image image = cv2.imread(image_name,0) # convert BGR to RGB color format image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32) image /= 255.0 height = image.shape[0] width = image.shape[1] # capture the corresponding XML file for getting the annotations annot_filename = image_name[:-4] + '.xml' annot_file_path = os.path.join(self.dir_path, annot_filename) boxes = [] labels = [] tree = et.parse(annot_file_path) root = tree.getroot() # box coordinates for xml files are extracted and corrected for image size given for member in root.findall('object'): # map the current object name to `classes` list to get... # ... the label index and append to `labels` list labels.append(int(member.find('name').text)) # xmin = left corner x-coordinates xmin = int(member.find('bndbox').find('xmin').text) # xmax = right corner x-coordinates xmax = int(member.find('bndbox').find('xmax').text) # ymin = left corner y-coordinates ymin = int(member.find('bndbox').find('ymin').text) # ymax = right corner y-coordinates ymax = int(member.find('bndbox').find('ymax').text) boxes.append([xmin, ymin, xmax, ymax]) # bounding box to tensor boxes = torch.as_tensor(boxes, dtype=torch.float32) # area of the bounding boxes # luas area area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0]) # no crowd instances ''' AS far as I know, the iscrowd label is used in the cocoapi to determine the target type. I.e. iscrowd = 0 uses polygons for the object instances, while iscrowd = 1 uses run-length encoding (RLE). ''' iscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64) # labels to tensor labels = torch.as_tensor(labels, dtype=torch.int64) # prepare the final `target` dictionary target = {} target["boxes"] = boxes target["labels"] = labels target["area"] = area target["iscrowd"] = iscrowd image_id = torch.tensor([idx]) target["image_id"] = image_id # apply the image transforms if self.transforms: T = self.transforms(image = image, bboxes = target['boxes'], labels = labels) image = T['image'] target['boxes'] = torch.Tensor(T['bboxes']) return image, target # define the training tranforms def mytransform(): return A.Compose([ A.Flip(0.5), A.RandomRotate90(0.5), A.MotionBlur(p=0.2), A.MedianBlur(blur_limit=3, p=0.1), A.Blur(blur_limit=3, p=0.1), ToTensorV2(p=1.0), ], bbox_params={ 'format': 'pascal_voc', 'label_fields': ['labels'] }) transform = mytransform() CLASSES = [ '__background__', '11', '9', '13', '10', '6', '7', '0', '5', '4', '2', '14', '8', '12', '1', '3' ] dataset = MyDataset(classes = CLASSES,transform =transform)
mari kita panggil record 0 (karena emang datanya 1 saja) dan 3 kali dipanggil, apakah setiap kali diload, ada perubahan?
for i in range(0,3): a,b = dataset.__getitem__(0) img = transforms.ToPILImage()(a) draw = ImageDraw.Draw(img) for bb in b['boxes']: draw.rectangle(((bb[0],bb[1]), (bb[2],bb[3]))) plt.figure() plt.imshow(img) plt.show()
Bounding box nya juga ikut berubah!
Kesimpulan
Augmentasi data adalah teknik yang sangat berguna dalam computer vision, terutama ketika dataset terbatas. Dengan memanfaatkan transformasi yang sederhana namun efektif, augmentasi data dapat memperluas dan memperkaya dataset, meningkatkan kinerja model, dan membantu mengatasi tantangan yang terkait dengan overfitting. Dengan demikian, augmentasi data adalah alat yang sangat penting bagi para praktisi machine learning yang ingin mengembangkan model yang kuat dan handal dalam tugas-tugas computer vision.