Siri Belajar AI: Jaringan Neural Berlingkar (Convolutional Neural Network), Bahagian 1

Dalam siri yang lepas kita ada belajar membuat satu jaringan neural yang mampu untuk mengenal tulisan tangan. Untuk pengetahuan pembaca, jaringan neural merupakan bentuk pembelajaran mendalam (deep learning) yang paling asas sekali. Semua model AI yang canggih ketika ini, tak kiralah dari OpenAI seperti GPT, mahupun dari Meta, seperti Llama, kesemuanya menggunakan jaringan neural sebagai asasnya. Tapi model-model AI ini menggunakan bentuk jaringan neural yang lebih kompleks, lebih sofistikated dan lebih gempak arkitekturnya. Model ini diperkembangankan sedikit demi sedikit dari model asas sehingga membentuk model AI yang kita kenal hari ini.
Untuk bahagian kali ini, kita akan belajar antara bentuk penambahbaikan yang terawal pada jaringan neural. Penambahbaikan yang membolehkan ia memproses saiz imej dengan piksel yang tinggi jumlahnya, dipanggil sebagai jaringan neural berlingkar ataupun convolutional neural network.
Kenapa perlu ada Jaringan Neural Berlingkar?
Sebelum kita pergi lebih jauh, perlulah kita faham terlebih dahulu kenapa perlu wujudnya jaringan neural berlingkar ini? Dalam siri yang lepas, kita tahu yang jaringan neural belajar melalui nilai pemberat dan bias yang diperkemaskini melalui proses latihan. Nilai pemberat dan bias inilah yang perlu disimpan oleh setiap jaringan neural ketika ia sudah ‘belajar’. Dan jumlah pemberat dan bias yang perlu disimpan ini dipanggil sebagai jumlah parameter dan ia menentukan kuasa komputasi dan memori yang diperlukan oleh setiap model AI.
Dalam siri yang lepas, kita tahu yang kita mengambil setiap imej tulisan tangan yang mempunyai 28 x 28 pixel, menghasilkan 784 jumlah pixel. Kesemua 784 pixel ini akan mempunyai 10 label, mewaklili 10 digit. Kerana itulah, jaringan neural kita dibentuk untuk mengambil kesemua 784 data pixel ini dan melatihnya untuk mengenal tulisan tangan. Dengan maklumat yang ada di atas, kita boleh mengenalpasti jumlah parameter yang ada pada jaringan neural kita.
Lapisan input mempunyai 784 nod, yang sepadan dengan 784 pixel gambar input.
Lapisan Tersembunyi Pertama
Pemberat (w): Setiap nod dalam lapisan tersembunyi pertama disambungkan kepada semua nod dalam lapisan input. Kita mempunyai 784 pemberat bagi setiap 10 nod maka keseluruhannya, kita mempunyai (784 X 10 =7840), 7840 pemberat.
Bias (b): Setiap nod dalam lapisan tersembunyi pertama mempunyai satu bias. Maka kita mempunyai 10 bias
Jumlah parameter dalam lapisan tersembunyi pertama:
7840 (pemberat)+ 10 (bias) = 7850 parameter
Lapisan Tersembunyi Kedua
Pemberat (w): Setiap nod dalam lapisan tersembunyi kedua disambungkan kepada semua nod dalam lapisan tersembunyi pertama. Jadi keseluruhannya kita ada (10 X 10 =100), 100 pemberat untuk lapisan kedua.
Bias (v): Setiap nod dalam lapisan tersembunyi kedua mempunyai satu bias. Jadi kita perlu tambah lagi 10 bias.
Jumlah parameter dalam lapisan tersembunyi kedua:
100 (pemberat) + 10 (bias) = 110 parameter
Jumlah Keseluruhan Parameter dalam Jaringan
Menjumlahkan parameter dari kedua-dua lapisan:
7850 + 110 = 7960
Jadi, jumlah keseluruhan parameter dalam jaringan neural asal anda adalah 7960, yang kebanyakannya dipacu oleh 784 pixel input.
Untuk lebih memahami perspektif nombor parameter ini, mari kita cuba gantikan nombor tersebut kepada saiz byte komputer. Kita anggap setiap satu parameter diwakili oleh nombor float32. Setiap nombor float32 mempunyai 4 byte. Jadi secara keseluruhannya jaringan neural kita mempunyai saiz 31.1 kb.
Kecil, tapi perlu diingatkan yang jaringan neural kita ini hanyalah memproses imej tulisan tangan yang mempunyai 784 pixel. Ianya sudah dikecilkan untuk tujuan pembelajaran. Tapi secara realitinya, mana ada lagi imej yang mempunyai saiz pixel sekecil seperti ini? Kebanyakan imej yang ada dalam telefon pintar kita sekarang mempunyai saiz resolusi antara (4000*3000) dan ada yang boleh pergi sehingga ke (8000X6000) pixel. Bila berhadapan dengan saiz imej yang lebih besar, sudah tentulah jaringan neural yang diperlukan lebih besar. Kemungkinan boleh pergi sehingga ke satu ataupun 2GB. Maka ia bukanlah sesuatu yang bijak untuk terus menggunakan bentuk asas jaringan neural dalam melatih imej yang lebih besar.
Kerana itulah kita perlukan jaringan neural berlingkar
Masalah ini wujud kerana ketika itu kebanyakan penyelidik AI mengambil perspektif mesin dalam menangani masalah. Imej yang diproses diambil dalam bentuk piksel. Tetapi secara hakikatnya, dalam meniru kepintaran/kecerdasan (intelligence) manusia, kita perlulah mengikut cara manusia. Jadi, bagaimana sebenarnya cara manusia memproses imej? Adakah dengan mengambil satu demi satu piksel?
Untuk itu, mari kita kembali ke salah satu eksperimen yang pernah dilakukan oleh Hubel dan Weisel. Eksperimen mereka pada tahun 1960-an membolehkan mereka memahami bagaimana makhluk hidup memproses imej. Ia dilakukan pada beberapa ekor anak kucing. Ketika eksperimen, mereka mendapati bahawa makhluk hidup memproses imej melalui corak yang mereka lihat. Ia bermula daripada corak yang ringkas seperti rangka, garis tepi imej(edges), sebelum bergerak ke corak yang lebih kompleks seperti keseluruhan imej. Jadi neuron yang ada pada makhluk hidup seperti kucing dan juga manusia tidak memproses imej mengikut piksel, tapi mengikut corak (pattern) yang dikenali. Dari corak itu, ia digabungkan satu persatu bagi membentuk imej yang lengkap.
Menyedari hakikat itu, penyelidik AI mula membentuk satu arkitekture jaringan neural yang baru. Imej yang dimasukkan perlulah diproses terlebih dahulu bagi mengeluarkan pola ataupun corak yang mudah supaya ia boleh digunakan untuk melatih jaringan neural. Proses mengekstrak pola ataupun corak ini dipanggil sebagai “feature extraction” dan diletakkan diawal jaringan neural (rujuk pada gambar).
Keseluruhan arkiekture ini dipanggil sebagai jaringan neural berlingkar (convoluted neural network) dan hari ini kita akan cuba untuk melakukan sedikit demonstrasi bagaimana ia berfungsi. Untuk memudahkan tutorial, kita akan menggunakan dataset MNIST yang sama yang kita sudah proses dalam siri yang lepas.
Apa itu perlingkaran (convolution)?
Dalam jaringan neural berlingkar, penyelidik AI menambahkan dua operasi awal bagi membolehkan “feature extraction” berlaku. Operasi pertama dipanggil sebagai perlingkaran (convolution). Dalam proses perlingkaran, garis tepi (edges) imej yang dimasukkan akan dikesan melalui penapis yang melalui matriks imej yang diproses. Kita bagi contoh seperti di bawah:
Perlingkaran dengan Pemprosesan Imej MNIST
Gambar Input:
Gambar input MNIST adalah matriks dua dimensi berukuran 28x28 yang mengandungi 784 pixel.
Contohnya, gambar digit “3” dalam skala kelabu 28x28:
(Nilai pixel sebenar pastinya lebih kompleks, tapi ni hanya sekadar contoh yang ringkas)
2. Penapis (Kernel):
Penapis atau kernel adalah matriks kecil, contohnya 3x3, yang melalui seluruh imej input untuk melakukan operasi perlingkaran.
Contohnya, kernel 3x3:
Penapis yang dipilih perlulah bersesuaian dengan keadaan dan operasi yang ingin dilakukan. Dalam kes ini kita ingin mengenalpasti garis tepi imej tersebut (edges), maka penapis yang dipilih adalah seperti di atas, penapis dari Sobel
3. Operasi Perlingkaran:
Penapis diaplikasikan pada gambar input dengan melalui setiap pixel dalam matriks.
Di setiap posisi, nilai pixel gambar dikalikan dengan nilai penapis dan dijumlahkan untuk memberikan satu nilai pada gambar output.
Contoh:
Operasi perlingkaran:
(0×1+0×0+0×−1)+(0×1+0×0+255×−1)+(0×1+0×0+0×−1)=0−255+0=−255
Hasilnya seperti di bawah:
Operasi perlingkaran ini akan diteruskan pada setiap nilai matriks dari kiri ke kanan, dan atas ke bawah.
Mari kita buat dalam bentuk kod
import numpy as np
import matplotlib.pyplot as plt
from keras.datasets import mnist
# Memuatkan data MNIST
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
# Memilih imej pertama dari set data
image = train_images[0]
# Memaparkan imej asal
plt.title('Imej Asal')
plt.imshow(image, cmap='gray')
plt.show()
# Mendefinisikan kernel (contoh kernel untuk pengesanan garis tepi(edges))
kernel = np.array([
[1, 0, -1],
[1, 0, -1],
[1, 0, -1]
])
# Fungsi untuk melaksanakan operasi perlingkaran
def convolve2d(image, kernel):
kernel_height, kernel_width = kernel.shape
image_height, image_width = image.shape
output = np.zeros((image_height - kernel_height + 1, image_width - kernel_width + 1))
for i in range(output.shape[0]):
for j in range(output.shape[1]):
output[i, j] = np.sum(image[i:i+kernel_height, j:j+kernel_width] * kernel)
return output
# Melaksanakan operasi perlingkaran
convolved_image = convolve2d(image, kernel)
# Memaparkan hasil perlingkaran
plt.title('Imej Selepas Perlingkaran')
plt.imshow(convolved_image, cmap='gray')
plt.show()Meletakkan kod di atas akan membolehkan proses perlingkaran berlaku pada dataset MNIST, menghasilkan imej seperit di bawah:
Boleh perhatikan dalam gambar di atas, imej yang dimasukkan sudahpun dikenalpasti garis tepinya, memudahkan proses latihan jaringan neural kelak.
Proses Pooling
Perlingkaran sahaja tidak cukup. Sebelum dimasukkan ke dalam jaringan neural, ia perlulah melalui proses pooling.Pooling adalah teknik yang digunakan dalam Rangkaian Neural Perlingkaran (CNN) untuk mengurangkan dimensi data sambil mengekalkan ciri-ciri penting. Ini membantu dalam mengurangkan jumlah parameter dan mengurangkan risiko overfitting.
Jenis-Jenis Pooling
Terdapat beberapa jenis pooling yang biasa digunakan dalam CNN, antaranya ialah:
Max Pooling:
Penjelasan:Max pooling mengambil nilai maksimum dari setiap jendela (window) kecil dalam matriks input.
Tujuan: Menangkap ciri-ciri yang paling menonjol dalam jendela kecil tersebut.
Contoh:
Average Pooling:
Penjelasan: Average pooling mengambil nilai purata dari setiap jendela kecil dalam matriks input.
Tujuan: Mengurangkan noise dan mengekalkan informasi penting dalam jendela kecil.
Contoh:
Mari kita buat pooling dengan kod:
import numpy as np
import matplotlib.pyplot as plt
from keras.datasets import mnist
# Memuatkan data MNIST
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
# Memilih imej pertama dari set data
image = train_images[0]
# Memaparkan imej asal
plt.title('Imej Asal')
plt.imshow(image, cmap='gray')
plt.show()
# Fungsi untuk melaksanakan operasi max pooling
def max_pooling(image, size=2, stride=2):
image_height, image_width = image.shape
output_height = (image_height - size) // stride + 1
output_width = (image_width - size) // stride + 1
output = np.zeros((output_height, output_width))
for i in range(0, image_height - size + 1, stride):
for j in range(0, image_width - size + 1, stride):
output[i // stride, j // stride] = np.max(image[i:i + size, j:j + size])
return output
# Melaksanakan operasi max pooling
pooled_image = max_pooling(image)
# Memaparkan hasil max pooling
plt.title('Imej Selepas Max Pooling')
plt.imshow(pooled_image, cmap='gray')
plt.show()Memasukkan kod di atas membolehkan proses pooling berlaku pada dataset MNIST menghasilkan imej di bawah:
Boleh dilihat di sini yang gambar yang diproses ini sudahpun dikurangkan nilai pikselnya sekaligus bakal mengurangkan jumlah parameter yang bakal diproses nanti.
Baiklah, itu sahaja untuk kali ini. Dalam bahagian yang akan datang, kita akan tengok pula bagaimana untuk menggabungkan perlingkaran dan pooling ini dalam jaringan neural bagi membentuk satu jaringan neural perlingkaran yang lengkap.
Jumpa nanti dalam bahagian 2!












No problem tuan. Subscribe free pun takda masalah 😄
Terima kasih tuan atas perkongsian yang bermanfaat! Jemput singgah di blog saya berkenaan Infrastruktur IT di https://blog.inframesia.com