Siri Belajar AI: Mari Kenali GAN (Generative Adversarial Network)-Bahagian 1
Hujung minggu telahpun tiba. Mari kita isi hujung minggu kita dengan siri belajar AI yang seterusnya. Setelah meneliti semua siri-siri belajar AI sebelum ini, saya ingat yang saya sudahpun bersedia untuk meneroka dan membicarakan tentang Transformer. Tapi atas nasihat seorang rakan, adalah lebih baik jika kita meneroka terlebih dahulu pada arkitekture GAN. Kerana ia merupakan antara arkitekture deep learning pertama yang membawa konsep generative pada AI.
Jika anda ingin membaca lebih lanjut tentang GAN, boleh merujuk pada kertas kajiannya di sini: https://arxiv.org/pdf/1406.2661
Kalau baca kertas kajian GAN ni, tak nampak dengan jelas sangat apakah arkitekture rangkaian neural yang dicadangkan. Kertas kajian ini hanya menyebut tentang kelebihan yang ada pada jaringan neural yang ada pada ketika itu (tahun 2014), dan bagaimana ia mampu melakukan kerja-kerja klasifikasi dan identifikasi dengan baik. Namun, pada masa tu, pada tahun 2014, jaringan neurla ni masih lagi mempunyai kelemahan yang besar jika ia ditugaskan untuk menghasilkan sesuatu yang baru (generation). Maka, penulis kertas kajian ini mencadangkan satu arkitektur yang boleh menggunakan segala kelebihan yang ada pada jaringan neural, bagi menutup kelemahannya dalam generation.
Kita lawankan dia

GAN ni hanya terdiri dari dua jaringan neural yang dilawankan antara satu sama lain.Penulis kertas kajian berharap yang jika ia dilawankan antara satu sama lain, maka ia boleh digunakan untuk menghasilkan sesuatu. Macam mana pulak tu?
Ok..dalam GAN ni ada generative dan ada discriminative. Discriminative ni terdiri daripada jaringan neural yang biasa, yang memang hebat dalam bidang-bidang pengkelasan ni. Tugas jaringan discriminative adalah untuk melihat pada output generative dan menentukan sama ada output dia itu tulen ataupun tidak. Tugas Generative pula adalah untuk menghasilkan output yang akan diadili oleh model discriminative tadi.
Seperti yang diterangkan dalam kertas kajian GAN, mereka membayang model generative ni sebagai seorang penjenayah (seperti Leonardo DiCaprio cerita Catch me if You Can), yang berusaha sebaik mungkin untuk menghasilkan cek palsu yang tak boleh dikesan oleh polis mahupun FBI. Dan model discriminative ni pula adalah Tom Hanks, FBI yang sedang cuba sedaya upaya untuk mengesan kepalsuan cek yang dihasilkan oleh Leonardo DiCaprio. Kedua-dua model ini akan bersaing di antara satu sama lain, dengan harapan yang model Generative akan menghasilkan output ynag lansung tak dapat dikesan kepalsuannya oleh model Discriminative. Tapi ini hanyalah satu gambaran sisi pandang helikopter. Kita kena terjun ke dasar, menyelam lebih dalam untuk faham betul-betul bagaimana arkitektur ini berfungsi
Kita fahamkan dulu pasal Generative
Ok, sebelum kita pergi jauh dulu, para pembaca perlu faham dulu, bahawa GAN ini sebenarnya digunakan untuk menghasilkan/menjana imej. Jadi merujuk kembali kepada kertas kajian GAN, contoh yang diberikan lebih kepada penjanaan dan penghasilan imej. Maka model Generativenya juga perlulah direka untuk memproses dan menjana imej.
Sekitar tahun 2010-an, proses penghasilan imej dihasilkan melalui pemahaman jaringan neural kepada noise/kekaburan yang ada pada data imej tersebut. Untuk tugas pengkelasan, jaringan neural memang mengambil terus data dari imej. Data yang saya maksudkan ini adalah setiap piksel imej tersebut, yang diterjemahkan kepada nombor mengikut saluran (channel) RGB (Red, Green, Blue). Siapa yang selalu main photoshop akan fahamlah sedikit sebanyak apa dia saluran RGB tu. Tapi berbeza pula untuk tugas penjanaan/penghasilan, ia memerlukan imej tersebut dikaburkan terlebih dahulu melalui proses gaussian noise.
Dalam nak menghasikan gaussian noise di atas imej tersebut, satu persamaan matematik perlu dilakukan ke atas imej tersebut. Dan persamaan ini berkait dengan teori taburan kebarangkalian (probability distribution). Boleh tengok persamaan matematiknya di bawah:
Proses menambahkan gaussian noise ke atas imej pula boleh digambarkan melalui persamaan di bawah:
Kenapa nak kaburkan?
Jadi persoalan yang mungkin sedang terngiang-ngiang di kepala para pembaca sekarang adalah kenapa nak kena kaburkan? Kenapa nak kena tambah noise? Kalau para pembaca fahamkan di atas, proses menambah noise ni secara tak lansung menambahkan data kebarangkalian secara seragam ke atas imej kita. Jadi, secara tak lansung ia membolehkan jaringan neural memproses data tersebut dengan lebih baik berbanding jika kita berikan ia sekadar data dari piksel. Data dengan kebarangkalian membolehkan jaringan tersebut mempelajari konteks dan perhubungan satu piksel dengan piksel yang lain sekaligus membolehkan ia menghasilkan imej dari data noise.
Tapi ada isu yang datang dari proses ini. Imej yang dihasilkan kurang menyengat. Dan kadangkala, masih lagi kabur. Oleh kerana itulah, GAN mencadangkan pendekatan yang berbeza.
Model Generative yang dicadangkan dalam GAN mengambil data gaussian noise terus tanpa imej. Input yang diberikan hanyalah data gaussian noise yang rambang, yang tidak bersandarkan pada sebarang imej. Data imej itu datang terus dari model discriminative.
Ok, mungkin kita kena tunjukkan sedikit bagaimana untuk membina model Generative GAN ini menggunakan kod. Dan seperti biasa kita akan bina model Generative ini tanpa menggunakan sebarang library. Untuk membina model Generatif ini, kita perlu:
Input untuk model GAN adalah nilai noise rawak, yang diambil daripada taburan normal N(0,1). Kita tak perlu menggunakan proses matematik Gaussian secara manual, sebaliknya kita boleh terus menjana satu tensor rawak, yang kita panggil sebagai dim_input.
dim_input ini kita tetapkan sebagai tensor bersaiz (1, 100), yang bermaksud 1 vektor dengan 100 elemen yang diambil daripada taburan normal.
Kita bina kelas Generator, yang mengambil nilai dim_input tadi dan menukarkannya kepada dim_output, bersaiz (28x28), mengikut saiz dataset MNIST.
Generator akan mempunyai 3 lapisan jaringan neural, dengan pemberat dan bias.
Lapisan pertama menerima input bersaiz (100,128).
Lapisan kedua menerima input bersaiz (128,256).
Lapisan terakhir sepatutnya mengambil input bersaiz (256, 784).
Antara lapisan pertama dan kedua, kita gunakan fungsi pengaktifan ReLU untuk memastikan proses pembelajaran dan latihan lebih stabil.
Lapisan terakhir akan menggunakan fungsi aktivasi Tanh untuk menghasilkan output dalam julat [-1,1].Kenapa Tanh? Sebab: -MNIST dataset sudah dinormalisasi ke dalam julat [-1,1]. -Tanh memastikan output lebih stabil dalam skala tertentu dan boleh menghasilkan butiran yang lebih realistik.
Dari situ, kita sudah berjaya menjana satu imej rawak, tetapi ia masih tidak bermakna kerana Generator belum dilatih.
#jadi mari kita bina kelas Generator kita
import numpy
class Generator:
def __init__(self, dim_input = 100, dim_output = 28*28):
self.dim_input = dim_input
self.dim_output = dim_output
#0k, sekarang kita letak nilai awal untuk pemberat dan bias
self.pemberat1 = np.randn(dim_input, 128) * 0.02 #darab 0.02 untuk pastikan nilai awal yang stabil
self.bias1 = np.zeros(128) #bias akan mengikut pemberat
self.pemberat1 = np.randn(128, 256)
self.bias2 = np.zeros(256)
self.pemberat3 = np.randn(256,output_dim)
self.bias3 = np.zeros(output_dim)
def forward(self,z):
x = np.dot(z, self.pemberat1) + self.bias1
x = np.maximum(0, x) # fungsi pengaktifan RelU
x = np.dot(x, self.pemberat2) + self.bias2
x = np.maximum(0, x)
x = np.dot(x, self.pemberat3) + self.bias3
return np.tanh(x) #fungsi pengaktifan TanhKali ni kita fahamkan Discriminative pulak
Ok…discriminative ni berbeza dengan generative. Ia mengambil terus data imej tersebut dari setiap piksel dan saluran RGB. Dalam siri belajar AI yang lepas, saya sudahpun menceritakan tentang jaringan neural berlingkar (CNN), yang memproses data imej yang banyak itu melalui proses convolution. Dengan cara itu, ia boleh mengurangkan jumlah piksel yang perlu diproses. Tapi, disebabkan kita hanya mempunyai saiz piksel yang kecil, maka kita tak memerlukan lapisan perlingkaran di depan. Kita hanya boleh terus membina Discriminative kita dengan menggunakan jaringan neural yang ringkas, kita boleh binanya seperti di bawah:
Kita ambil input dari data tersebut, dengan saiz 28x28
Sama seperti generator, kita ada 3 lapisan jaringan neural.
Lapisan pertama bersaiz (784,256)
Lpisan kedua bersaiz (256,128)
Dan lapisan terakhir bersaiz (128,1)
Untuk discriminator kita akan menggunakan LeakyReLU. LeakyRelu tidaklah terlalu linear.Ia membenarkan sedikit nilai negatif
Dan pada lapisan terakhir kita akan menggunakan fungsi pengaktifan sigmoid. Ini bagi membolehkan kita menukarkan output kita kepada nilai kebarangkalian (0–1).
import numpy as np
class SimpleDiscriminator:
def __init__(self, input_dim=28*28):
self.input_dim = input_dim
self.pemberat1 = np.random.randn(input_dim, 256) * 0.02
self.bias1 = np.zeros(256)
self.pemberat2 = np.random.randn(256, 128) * 0.02
self.bias2 = np.zeros(128)
self.pemberat3 = np.random.randn(128, 1) * 0.02
self.bias3 = np.zeros(1)
def leaky_relu(self, x, alpha=0.2):
#fungsi pengaktifan leaky relu
return np.where(x > 0, x, alpha * x)
def sigmoid(self, x):
#fungsi pengaktifan sigmoid
return 1 / (1 + np.exp(-x))
def forward(self, x):
x = np.dot(x, self.pemberat1) + self.bias1
x = self.leaky_relu(x)
x = np.dot(x, self.pemberat2) + self.bias2
x = self.leaky_relu(x)
x = np.dot(x, self.pemberat3) + self.bias3
return self.sigmoid(x) Ok, selesai sudah….
Kita dah pun belajar dengan ringkas tentang bagaimana untuk membentuk GAN. Kita dah kenal Generator dan Discriminator, dan dah pun mebina kedua-duanya di dalam python. Langkah seterusnya adalah untuk melatih jaringan neural ini. Dan kita akan lakukan semua ini dalam bahagian yang akan datang.






