Implementasi Deep Learning Menggunakan Convolutional Neural Network untuk Klasifikasi Gambar (Mata Juling dan Mata Normal) dengan R

QOLBIYATUL LINA
13 min readDec 15, 2018

--

Assalamu’alaikum kawan-kawan…

Untuk kamu yang pernah menggunakan Facebook, pasti pernah mempertanyakan, bagaimanakah caranya mengenali wajah seseorang dan melakukan tagging secara otomatis.

Jawabannya, Convolutional Neural Network.

Pertanyaan nya, apa sih Convolutional Neural Network itu? Kenapa bisa melakukan hal secanggih itu?

Convolutional Neural Network (CNN) adalah salah satu algoritma dari Deep Learning yang merupakan pengembangan dari Multi Layer Perceptron (MLP) yang dirancang untuk mengolah data dalam bentuk grid, salah satunya citra dua dimensi, misalnya gambar atau suara. Convolutional Neural Network digunkaan untuk mengklasifikasikan data yang terlabel dengan menggunakan metode supervised learning, yang mana cara kerja dari supervised learning adalah terdapat data yang dilatih dan terdapat variabel yang ditargetkan sehingga tujuan dari metode ini adalah mengelompokan suatu data ke data yang sudah ada. CNN sering digunakan untuk mengenali benda atau pemandangan, dan melakukan deteksi dan segmentasi objek.

Arsitektur CNN

Arsitektur dari CNN dibagi menjadi 2 bagian besar, Feature Learning dan Classification (MLP). Adapun tahap dari CNN adalah sebagai berikut :

  1. Input : Memasukkan data gambar kedalam CNN

Dasar dari segala teknik pengolahan gambar adalah Pengenalan Gambar. Yaitu sebuah teknik untuk membuat mesin “mengenal” apa yang ada di dalam gambar tersebut. Misalkan gambar ini.

Tentu, komputer tidak bisa seperti manusia yang sejak awal bisa melihat objek. Komputer hanya bisa membaca data yang direpresentasikan oleh gambar tersebut.

Seperti gambar di atas, yang dilihat oleh komputer adalah angka RGB (Red, Green, dan Blue) dari sebuah gambar. Nilainya antara 0 sampai 255 untuk setiap warna pada tiap pixel gambar.

2. Feature Learning meliputi, Convolution (konvolusi) ReLu (fungsi aktivasi layer) dan pooling layer. Namun kadang ada beberapa riset/paper yang tidak menggunakan pooling. Proses ini diulang beberapa kali sampai didapatkan peta fitur yang cukup untuk dilanjutkan ke tahap Classification (klasifikasi).

Convolutional layer

Convolutional layer terdiri dari neuron yang tersusun sedemikian rupa sehingga membentuk sebuah filter dengan panjang dan tinggi (pixels).

Gambar tersebut menunjukkan RGB (Red, Green, Blue) gambar berukuran 32x32 pixel yang sebenarnya adalah multidimensional array dengan ukuran 32x32 pixel (3 adalah jumlah channel). Convolutional layer terdiri dari neuron yang tersusun sedemikian rupa sehingga membentuk sebuah filter dengan panjang dan tinggi (pixel). Sebagai contoh , layer pertama pada feature extraction layer adalah conv. layer dengan ukuran 5x5x3. Panjang 5 pixel, tinggi 5 pixel, dan tebal/jumlah 3 buah sesuai dengan channel dari gambar tersebut.

Ketiga filter ini akan digeser keseluruhan bagian dari gambar. Setiap pergeseran akan dilakukan operasi “dot” antara input dan nilai dari filter tersebut sehinga menghasilkan sebuah output atau biasa disebut sebagai activation map atau feature map. Proses dari feature map seperti pada gambar berikut.

Ilustrasi proses konvolusi dengan dua filter (W0 dan W1). Image by CS231n[1]

Untuk menghitung dimensi dari feature map kita bisa gunakan rumus sebagai berikut.

Keterangan :

W = Panjang/Tinggi Input

N = Panjang/Tinggi Filter

P = Zero Padding

S = Stride

Stride

Stride adalah parameter yang menentukan berapa jumlah pergeseran filter. Jika nilai stride adalah 1, maka conv. filter akan bergeser sebanyak 1 pixel secara horizontal lalu vertical. Pada ilustrasi diatas, stride yang digunakan adalah 2. Semakin kecil stride maka akan semakin detail informasi yang kita dapatkan dari sebuah input, namun membutuhkan komputasi yang lebih jika dibandingkan dengan stride yang besar. Namun perlu diperhatikan bahwa dengan menggunakan stride yang kecil kita tidak selalu akan mendapatkan performa yang bagus.

Padding

Padding atau zero padding adalah parameter menentukan jumlah pixel (berisi nilai 0) yang akan ditambhakan di setiap sisi dari input. Hal ini digunakan dengan tujuan untuk memanipulasi dimensi output dari conv. layer (feature map).

Dengan menggunakan padding, kita akan dapat mengukur dimensi output agar tetap sama seperti dimensi input atau setidaknya tidak berkurang secara drastis. Sehingga kita bisa menggunakan conv. layer yang lebih dalam sehingga lebih banyak feature yang berhasil di-extract. Meningkatkan performa model karena conv. layer akan fokus pada informasi yang sebenarnya yaitu yang berada diantara zero padding tersebut. Pada ilustrasi diatas, dimensi dari input sebenarnya adalah 5x5, jika dilakukan convolution dengan filter 3x3 dan stride sebesar 2, maka akan didaptkan feature map dengan ukuran 2x2. Namun jika ditambahkan zero padding sebanyak 1, maka feature map yang dihasilkan berukuran 3x3 (lebih banyak informasi yang dihasilkan).

Fungsi Aktivasi

Fungsi aktivasi berada pada tahap sebelum melakukan pooling layer dan setelah melakukan proses konvolusi. Pada tahap ini, nilai hasil konvolusi dikenakan fungsi aktivasi atau activation function. Terdapat beberapa fungsi aktivasi yang sering digunakan pada convolutional network, di antaranya tanh() atau reLU. Aktivasi reLU menjadi pilihan bagi beberapa peneliti karena sifatnya yang lebih berfungsi dengan baik.

Fungsi yang digunakan untuk aktivasi pada reLU, fungsi reLU adalah nilai output dari neuron bisa dinyatakan sebagai 0 jika inputnya adalah negatif. Jika nilai input dari fungsi aktivasi adalah positif, maka output dari neuron adalah nilai input aktivasi itu sendiri.

Pooling Layer

Polling layer biasanya berada setelah conv. layer. Pada prinsipnya pooling layer terdiri dari sebuah filter dengan ukuran dan stride tertentu yang bergeser pada seluruh area feature map. Pooling yang biasa digunakan adalah Max Pooling dan Average Pooling. Tujuan dari penggunaan pooling layer adalah mengurangi dimensi dari feature map (downsampling), sehingga mempercepat komputasi karena parameter yang harus di update semakin sedikit dan mengatasi overfitting.

3. Classification (MLP) : akan didapatkan hasil klasifikasi nya.

Feature map yang dihasilkan dari Feature Learning masih berbentuk multidimensional array, sehingga harus melakukan “flatten” atau reshape feature map mejadi sebuah vector agar bisa digunakan sebagai input dari fully-connected layer.

Lapisan Fully-connected adalah lapisan dimana semua neuron aktivitas dari lapisan sebelumnya terhubung semua dengan neuron di lapisan selanjutnya seperti hal nya jaringan syaraf tiruan bisa. Setiap aktivitas dari lapisan sebelumnya perlu diubah menjadi data satu dimensi sebelum dapat dihubungkan ke semua neuron di lapisan Fully-Connected.

Lapisan Fully-Connected biasanya digunakan pada metode Multi lapisan Perceptron dan bertujuan untuk mengolah data sehingga bisa diklasifikasikan. Perbedaan anatar lapisan Fully-Connected dan lapisan konvolusi biasa dalah neuron di lapisan konvolusi terhubung hanya ke daerah tertentu pada input. Sementara lapisan Fully-Connected memiliki neuron yang secara keseluruhan terhubung. Namun, kedua lapisan tersebut masih mengoprasikan produk dot, sehinga fungsinya tidak begitu berbeda.

Pada tahap ini, hasil klasifikasi terbagi menjadi 2 yakni mata juling dan mata normal.

Pembelajaran Backpropagation

Salah satu sifat neural network yang menyerupai dengan otak manusia adalah bahwa neural network membutuhkan proses pembelajaran. Pembelajaran dilakukan untuk menentukan nilai bobot yang tepat untuk masing-masing input. Bobot bertambah jika informasi yang diberikan oleh neuron yang bersangkutan tersampaikan. Sebaliknya jika informasi tidak disampaikan maka nilai bobot berubah secara dinamis sehingga dicapai suatu nilai yang seimbang. Apabila nilai ini telah mampu mengindikasikan hubungan yang diharapkan antara input dan output, proses pembelajaran bisa dihentikan.

Ilustrasi Jaringan Backpropagation

Memulai Klasifikasi Gambar Mata (Mata Normal Vs Mata Juling) Menggunakan CNN

Sebelum melakukan klasifikasi gambar, yuk kenali dulu apa itu mata juling, mata normal itu?

Mata normal atau emmetropia berasal ari kata Yunani, emmetros yang berarti ukuran normal atau dalam keseimbangan wajar, sedangkan arti opsis adalah penglihatan. (Sumber: Mister Kacamata)

Gambar Mata Normal (Sumber: Google)

Mata juling alias strabismus adalah kondisi di mana posisi kedua mata tidak sejajar, yang menyebabkan tatapan orang tersebut tidak tertuju pada satu obyek di waktu bersamaan. Salah satu sisi mata dapat terbalik ke arah luar, dalam, atas, atau ke bawah seperti terdistraksi untuk melihat ke arah lain.(Sumber: hello sehat)

Gambar Mata Juling (Sumber: Google)

Dalam pembuatan model tersebut maka diperlukan data-data dalam bentuk gambar dari mata yang akan diklasfikasikan. Pada kasus kali ini mata yang akan diklasifikasikan adalah mata normal dan mata juling.

Langkah-langkah yang dilakukan terdiri dari pengumpulan data gambar, preprocessing, pelatihan model klasifikasi dan pengujian model.

Pengumpulan Data

Hal pertama yang dilakukan adalah melakukan pengumpulan data. Data gambar mata diperoleh dari situs Google Image. Data gambar mata terdiri dari 20 gambar mata normal dan 20 gambar pula pada mata juling. Data gambar tersebut adalah gambar yang berwarna dengan ukuran yang bervariasi. Gambar-gambar mata yang telah tersimpan tersebut akan digunakan untuk melakukan proses training dan testing.

Preprocessing Data

Sebelum menginputkan data adalah menginstal package yang akan digunakan dalam pengolahan data. Ada tiga package yang akan digunakan yaitu package keras, package tensorflow dan package EBImage. Package Keras merupakan library Deep Learning yang digunakan untuk klasifikasi data, package tensorflow adalah library untuk deep learning (neural net dengan banyak layer dan bermacam topologi), sedangkan EBImage merupakan sebuah library yang menyediakan fungsi untuk memproses dan analisis gambar. Setelah package terinstal maka load package atau aktifkan package tersebut.

library(keras)
library(tensorflow)
library(EBImage)

Setelah mengaktifkan package, maka selanjutnya inputkan gambar yang telah disimpan sebelumnya dengan menggunakan syntax seperti berikut.

#misalkan
setwd("D://data/")

Data yang digunakan yaitu 40 gambar mata yang terdiri dari 20 gambar mata normal dan 20 gambar mata juling. Gambar-gambar tersebut dijadikan satu dan dimasukan kedalam folder data. Input gambar dilakukan menggunakan “setwd” yang diikuti dengan lokasi gambar disimpan.

Lalu,membuat satu folder lagi yang digunakan untuk menyimpan hasil gambar tersebut.

#misalkan
save_in<-("D://dataresize/")

Setelah itu dilanjutkan dengan identifikasi gambar. Lalu, kita ingin menangkap atau memanggil dari gambar-gambar yang telah kita simpan dalam folder tersebut, lalu mengatur lebar(width) dan tinggi (height) sesuai yang kita inginkan dan hasil perubahan tersebut akan tersimpan di save_in tersebut. List.files merupakan struktur data yang mampu menyimpan lebih dari satu data, sedangkan readImage digunakan sebagai perintah untuk membaca sebuah gambar

gambar<-list.files()
w<-100
h<-100
for (i in 1:length(gambar))
{result<-tryCatch({
imgname<-gambar[i]
img<-readImage(imgname)
img_resized<-resize(img, w=w, h=h)
path<-paste(save_in,imgname,sep = " ")
writeImage(img_resized,path,quality = 70)
print(paste("done",i,sep = ""))
},
error=function(e){print(e)}
)}

Setelah menjalankan syntax tersebut, maka data gambar akan terbaca yang ditandai dengan perubahan data gambar akan tersimpan di folder dataresize.

setwd("D://dataresize/")
gambar2<-list.files()
gambar2
gambar2<-lapply(gambar2,readImage)
str(gambar2)

Selanjutnya, membagi masing-masing dari gambar mata menjadi data train dan data test. Pembagian data menjadi data train dan data test beracuan terhadap penelitian terdahulu dimana pembagiannya menjadi 80% untuk data train dan 20% untuk data test. Karena data dari masing-masing gambar mata berjumlah 20 gambar, maka dibagi menjadi 16 gambar untuk data train dan 4 gambar untuk data test.

train<-gambar2[c(1:16,21:36)]
test<-gambar2[c(17:20,37:40)]

Selanjutnya, jika ingin melihat gambar yang terurut maka tulislah syntax dibawah ini.

par(mfrow=c(2,10))

Kemudian akan dilakukan resize kembali menjadi ukuran 32x32 pixel agar proses pengenalan gambar lebih cepat dilakukan oleh komputer.

for (i in 1:32) plot(train[[i]])for (i in 1:32){train[[i]]<-resize(train[[i]],32,32)}
for(i in 1:8){test[[i]]<-resize(test[[i]],32,32)}

Setelah dimensi gambar-gambar jamur tersebut sama, maka selanjutnya yaitu combine atau menyatukan gambar-gambar yang menjadi data train.

train<-combine(train)
x<-tile(train,32)
display(x,title='gambar')
dim(train)

Gambar dibawah ini menunjukan hasil dari penyatuan gambar untuk data train.

Sama seperti pada data train diatas, lakukan juga pada data test nya.

test<-combine(test)
y<-tile(test,8)
display(y,title='gambar2')
dim(test)
#dirubah letak dim nya
train<-aperm(train,c(4,1,2,3))
test<-aperm(test,c(4,1,2,3))
dim(train)
dim(test)

Maka, hasil penyatuan gambar data test akan terlihat seperti ini.

Selanjutnya yaitu memberi label pada data train. Pelabelan menggunakan angka 0 (nol) untuk mata juling dan angka 1 (satu) untuk mata normal. Angka 16 pada syntax menunjukan bahwa data yang akan diberi label pada setiap kategori ada sebanyak 16 gambar.

Sama seperti pada data train, dilakukan juga pemberian label untuk data testing. Pelabelan menggunakan angka 0 (nol) untuk mata juling dan angka 1 (satu) untuk mata normal. Angka 4 pada syntax menunjukan bahwa data yang akan diberi label pada setiap kategori ada sebanyak 4 gambar.

trainy<-c(rep(0,16),rep(1,16))
testy<-c(rep(0,4),rep(1,4))
trainy
testy

Sebelum membuat model, agar data dapat diinputkan ke dalam library Keras, data perlu diubah ke dalam skema one hot encoding. Fungsi dari one hot encoding adalah untuk mengubah fitur kategori ke format yang berfungsi lebih baik dengan pengklasifikasian.

#one hot encoding
trainLabels<-to_categorical(trainy)
testLabels<-to_categorical(testy)
trainLabels
testLabels

Pembuatan Model

Dalam keras terdapat dua cara dalam membangun model yaitu model sequential dan function API. Function API digunakan untuk menentukan model kompleks. Sedangkan sequential model lebih seperti tumpukan linier dari layer. Model yang akan digunakan adalah model Multi Layer Perceptron (MLP) sederhana, oleh karena itu yang digunakan adalah model Sequential. Model ini merupakan model yang paling sederhana. Model CNN mempunyai beberapa layer diantaranya convolution, pooling dropout.

model=keras_model_sequential()
model%>%
layer_conv_2d(filters=32,
kernel_size = c(3,3),
activation = "relu",
input_shape = c(32,32,3))%>%
layer_conv_2d(filters = 32,
kernel_size = c(3,3),
activation = "relu")%>%
layer_max_pooling_2d(pool_size = c(2,2))%>%
layer_dropout(rate=0.01) %>%
layer_conv_2d(filters = 64,
kernel_size = c(3,3),
activation = "relu")%>%
layer_max_pooling_2d(pool_size = c(2,2))%>%
layer_dropout(rate=0.01) %>%
layer_flatten()%>% #merubah menjadi vektor
layer_dense(units=256, activation = "relu")%>%
layer_dropout(rate=0.01) %>%
layer_dense(units=2,activation = "softmax")%>%
compile(loss="categorical_crossentropy",
optimizer = optimizer_sgd(lr=0.01,
decay = 1e-06,
momentum = 0.9,
nesterov=T),
metrics=c('accuracy'))
summary(model)

Kemudian didapatkan model seperti dibawah ini.

Angka 2.304 pada flatten layer merupakan angka yang didapatkan dari perkalian dari dimensi sebelumnya yaitu 6×6×64=2.304 dan pada dense layer 256 merupakan angka yang menunjukan banyaknya neuron yang digunakan. Parameter sebesar 590.080 didapatkan dari 2.304×256=590.080. Pada dense layer kedua, 2 menunjukan banyaknya kategori gambar yang digunakan yaitu mata juling dan mata normal, sehingga parameter yang didapatkan yaitu 2×256+2=514. Total parameter yang didapatkan dari model yang dibuat adalah sebanyak 619.234.

Selanjutnya yaitu melakukan pelatihan data gambar-gambar mata kedalam model dengan fit model. Dalam melakukan fit model digunakan epoch = 50, batch_size = 32 dan validation_split = 0,2. Epoch berarti berapa kali jaringan akan melihat seluruh kumpulan data, sedangkan batch_size adalah jumlah contoh pelatihan dalam satu forward/backward pass. Semakin tinggi nilai batch_size maka akan semakin banyak memori yang dibutuhkan.

proses=model%>%
fit(train,
trainLabels,
epoch=50,
batch_size = 32,
validation_split = 0.2)
plot(proses)

Kemudian didapatkan hasil fit model seperti dibawah ini.

Gambar diatas merupakan hasil dari pelatihan data train dan data test menggunakan iterasi (epoch) sebanyak 50. Berdasarkan gambar diatas dapat diketahui bahwa itersi menghasilkan nilai akurasi dan nilai loss untuk data train dan data test. Nilai akurasi adalah suatu nilai yang digunakan untuk mengetahui tingkat keberhasilan model yang telah dibuat. Sedangkan nilai loss merupakan suatu ukuran dari sebuah error yang dibuat oleh network, dan tujuannya adalah untuk meminimalisirnya.

Jika kita arahkan kursor di salah satu titik pada gambar diatas akan nilai val_loss dan loss pada iterasi(epoch) pertama sampai dengan iterasi terakhir (ke-50).

Selain itu, terdapat tampilan dari grafik hasil iterasi seperti berikut.

Gambar diatas menunjukan grafik pergerakan nilai akurasi (acc) dan nilai loss (loss) untuk data train dan data test yang dihasilkan pada setiap iterasi (epoch). Berdasarkan gambar, garis berwarna merah menunjukan pergerakan untuk data train, sedangkan garis berwarna biru menunjukan pergerakan nilai akurasi dan nilai loss untuk data test. Grafik atas menunjukan nilai loss untuk kedua data, dapat dilihat bahwa untuk data train, nilai loss yang didapatkan terus turun hingga epoch ke-50, dan nilai loss untuk data test awalnya turun kemudian pada sebuah titik nilai loss naik hingga epoch ke-50.

Sedangkan grafik bawah menunjukan nilai akurasi dari kedua data. Berdasarkan gambar diatas dapat dilihat bahwa nilai akurasi hasil iterasi yang dihasilkan baik untuk data train naik hingga epoch ke-50, sedangkan untuk data test mengalami naik turun sampai ke epoch ke-50. Untuk data train, pada akhir iterasi didapatkan nilai akurasi sebesar 0,8125. Sedangkan untuk data test nilai akurasi pada epoch terakhir yang didapatkan yaitu sebesar 0,625.

Uji Coba dan Evaluasi

Dalam melakukan uji coba dan evaluasi, saya menggunakan Confusion Matrix seperti gambar dibawah ini.

Contoh Confusion Matrix

Pada gambar tersebut ditunjukkan, nilai True Positive didefinisikan sebagai positive tupple yang diklasifikasikan dengan benar oleh model. True Negative adalah negative tupple yang diklasifikasikan dengan benar oleh model. Sementara itu, False Positive adalah negative tupple yang diklasifikasikan sebagai kelas positif oleh model. False Negative adalah positive tupple yang diklasifikasikan sebagai kelas negatif oleh model klasifikasi. Berdasar confusion matrix pada gambar tersebut, kinerja model klasifikasi dapat dihitung.

Selanjutnya untuk menghitung nilai akurasi dapat dinyatakan dalam persamaan berikut.

Menghitung Akurasi

Selanjutnya adalah melakukan uji coba dan evaluasi terhadap data train.

model%>%evaluate(train, trainLabels)
pred=model%>%predict_classes(train)
pred
table(predicted=pred, actual=trainy)
prob=model%>%predict_proba(train)
cbind(prob,predict_classes=pred,actual=trainy)

Pada penelitian ini uji coba dilakukan terhadap gambar mata yang dibagi menjadi 2 kategori berdasarkan jenisnya, yaitu mata normal dan mata juling. Gambar untuk data train yang akan diuji coba terdapat 16 gambar pada masing-masing jenis dengan total 32 gambar. Berikut ini adalah rincian perhitungan akurasi model pada kedua jenis gambar tersebut.

Dari gambar diatas dapat kita lihat bahwa tingkat akurasi yang cukup tinggi sebesar 81.25%. Secara manual, perhitungan akurasi nya sebagai berikut,

Akurasi data train

Prediksi mata juling yang benar ada 15 gambar, sedangkan 1 gambar salah diprediksi. Sedangkan untuk mata normal ada 11 gambar yang diprediksi benar dan 5 gambar diprediksi salah. Kesalahan tersebut dapat disebabkan karena adanya kemiripan pola antara kedua jenis mata tersebut.

Selanjutnya uji coba dan evaluasi pada data test. Uji coba pada data test dilakukan terhadap 8 gambar yang dibagi menjadi 4 gambar untuk mata juling dan 4 gambar untuk mata normal.

model%>%evaluate(test,testLabels)
pred=model%>%predict_classes(test)
pred
table(predicted=pred, actual=testy)
prob=model%>%predict_proba(test)
cbind(prob,predict_classes=pred,actual=testy)

Kemudian didapatkan output sebagai berikut.

Dari gambar diatas dapat kita lihat bahwa tingkat akurasi yang cukup tinggi sebesar 62.5%. Secara manual, perhitungan akurasi nya sebagai berikut,

Akurasi data test

Prediksi mata juling yang benar ada 4 gambar dan tidak ada salah gambar yang diprediksi. Sedangkan untuk mata normal ada 1 gambar yang diprediksi benar dan 3 gambar diprediksi salah. Kesalahan tersebut dapat disebabkan karena adanya kemiripan pola antara kedua jenis mata tersebut.

Untuk meningkatkan keakuratan hasil klasifikasi bisa dilakukan dengan cara seperti:

  1. Menambah gambar pada dataset yang mana bisa mengunduh di google atau melakukan pemotretan sendiri.
  2. Fokuskan gambar pada bagian yang akan di klasifikasin, misalnya dalam artikel ini hanya fokus pada gambar mata saja, nah apabila menjumpai atau menemukan gambar full wajah, maka bisa di crop di bagian matanya saja.
  3. Beberapa parameter yang dapat digunakan dalam memperbaiki keakuratan hasil akurasi dalam penelitian ini diantaranya ialah ukuran gambar (pixel), nilai dropout, fungsi aktivasi, dan penggunaan optimizer.

Sekian dari saya, semoga bermanfaat yaa ^^

--

--