Istilah Deep Learning dan Neural Network rasanya tidak asing lagi di telinga kita yang sedang menggeluti bidang data science. Rasanya dua kata kunci tersebut amat canggih sekaligus menantang untuk dipelajari dan diaplikasikan ke dalam project data science kita.
Pada kesempatan kali ini kita akan coba bahas mengenai konsep-konsep dibalik Deep learning dan Neural Network dalam Memahami Deep Learning, dan ulik aplikasinya dalam Handwriting Recognition Huruf Hijaiyah.
Deep learning sejatinya adalah metode machine learning dengan tujuan yang sama dengan machine learning lainnya, untuk menciptakan suatu artificial intelligence atau kecerdasan buatan. Deep learning kini dianggap seperti puncak dari teknologi data science yang kini masih berkembang. Untuk memahami cara kerja deep learning tersebut mari kita telaah asal muasal dari teknologi tersebut yaitu neural network.
Neural network atau beberapa menyebutnya artificial neural network (ANN) adalah suatu metode machine learning yang terinspirasi dari cara kerja otak manusia. Otak bekerja dengan suatu sistem saraf atau yang disebut biological neural network. Tidak semua bagian dari sistem saraf manusia disalin menjadi artificial neural network. Terdapat beberapa prinsip yang diadopsi, yaitu sebagai berikut:
Sistem saraf yang dimiliki manusia terdiri dari sel saraf yang dinamakan neuron, dan neuron tersebut amat banyak hingga membentuk jaringan. Tiap stimulus/input dari luar akan diterima oleh panca indra kita sebagai signal kemudian akan dialirkan melalui sel saraf satu ke sel saraf lainnya. Jaringan sel saraf tersebut seperti membentuk lapisan-lapisan sel saraf yang saling mengalirkan informasi. Jaringan sel saraf tersebut tersebar dari ujung jari hingga otak dan berlanjut kembali ke seluruh tubuh kita.
Jaringan sel saraf tersebut seperti membentuk lapisan-lapisan sel saraf yang saling mengalirkan informasi.
Bila kita telaah, terdapat arsitektur khusus dari sistem saraf tubuh kita. Arsitektur tersebut terdiri dari stimulus/input yang diterima oleh panca indra, kemudian input tersebut dialirkan melalui sel-sel saraf ke otak, input tersebut diproses, kemudian hasil proses dialirkan kembali melalui sel-sel saraf ke bagian tubuh tertentu sebagai output atau respon yang kita berikan.
Arsitektur sel saraf ini lah yang menginspirasi arsitektur atau model artificial neural network. Arsitektur neural network terdiri dari jaringan sel atau node yang mengalirkan informasi dan mengolahnya, dari input hingga menghasilkan output. Kita akan membahas lebih dalam mengenai arsitektur neural network setelah ini. Berikut adalah contoh sederhana perbandingan biological neural network dan artifical neural network:
Selama manusia hidup dan berkembang, selama itu pula sistem saraf kita berkembang. Perkembangan tersebut menghasilkan sistem saraf yang “pintar”, yang mengerti sel-sel saraf mana saja yang perlu aktif/inaktif dalam mengalirkan stimulus. Hal ini agar output atau respon tubuh yang kita berikan sesuai dengan seharusnya. Sel saraf yang aktif tersebut dapat dianalogikan seperti memiliki bobot yang tinggi dalam menentukan output (layaknya faktor penting untuk menghasilkan prediksi yang tepat). Sementara itu sel yang inaktif dapat dianggap tidak penting atau mengganggu dalam proses pengolahan informasi. Pembobotan ini telah menghasilkan arsitektur aliran informasi yang amat baik, sehingga tubuh kita selalu menghasilkan output yang tepat atau optimal.
Bayangkan aliran informasi yang terjadi ketika kita tidak sengaja menyentuh panci yang panas, kemudian mengangkat jari kita. Atau ketika mata kita terkena debu, terasa sakit, sehingga mulai berair dan berkedip-kedip. Atau ketika kita berbicara. Semua respon instan dalam tubuh kita tidak terjadi begitu saja, namun melalui proses latihan. Melalui banyak kesalahan, berkali-kali rasa sakit, juga beribu pengalaman, tubuh kita akhirnya mengerti dengan sendirinya bahwa–misalnya–menyentuh lapisan yang panas itu berbahaya sehingga kita perlu mengangkat jari kita. Pembobotan sistem saraf pun terbentuk untuk memastikan tubuh memberikan respon yang tepat. Betapa hebatnya sistem dalam tubuh manusia yang belajar dengan sendirinya.
Bila kita coba mengartikan istilah intelegensi mungkin dapat diartikan sebagai berikut:
“Suatu kemampuan menerima informasi dan mengolah informasi untuk dijadikan perilaku yang sepatutnya pada suatu lingkungan.”
Konsep pembobotan ini lah yang akhirnya juga diadaptasikan dalam arsitektur artificial neural network. Agar suatu mesin dapat memiliki intelegensi manusia, mesin perlu bisa menentukan faktor apa saja yang mempengaruhi output atau mengetahui bobot yang dimiliki tiap node. Tidak hanya itu, mesin juga harus bisa “belajar”, mengadaptasikan bobot-bobot yang ia pelajari untuk menghasilkan output paling optimal. Contoh paling sederhana adalah suatu mesin/model yang menghasilkan error prediksi paling kecil. Proses adaptasi bobot ini memperhitungkan sesuatu yang disebut cost function untuk mendapatkan output yang paling optimal.
Sebagai analogi, bayangkan Anda yang sedang berbicara dengan teman Anda di suatu transportasi umum. Anda ingin agar ucapan Anda terdengar oleh teman Anda namun juga tidak ingin mengganggu penumpang lain. Input yang Anda berikan adalah volume suara Anda. Volume suara yang terlalu rendah akan membuat teman Anda sulit mendengar Anda, namun volume yang terlalu tinggi juga dapat mengganggu penumpang di sekitar Anda. Anda akhirnya mempelajari volume optimal dengan terus mencoba beberapa volume suara. Ketika suasana menjadi lebih bising/hening, Anda juga mengadaptasikan volume suara Anda. Anda terus melihat respon teman Anda dan penumpang di sekitar Anda hingga mendapatkan respon paling baik.
Pada analogi di atas, target Anda tidak lagi hanya ucapan Anda terdengar (yang mungkin akan dihasilkan dengan volume suara yang terlalu tinggi). Namun lebih dari itu, keberterimaan teman Anda dan penumpang lain menjadi hal yang penting dan dijadikan landasan untuk adaptasi volume suara Anda. Dalam contoh ini, keberterimaan teman Anda dan penumpang lain layaknya cost function. Anda menargetkan agar keberterimaan teman Anda dan penumpang lain memilik nilai yang paling tinggi.
Pada artificial neural network kita akan menentukan arsitektur neural network yang terbaik. Arsitektur tersebut berupa jaringan-jaringan node dan pembobotan untuk tiap node yang dioptimalkan berdasarkan cost function tertentu.
Setelah mengerti asal usul dari neural network, kita akan lebih mudah memahami arsitekturnya. Kita akan membuat contoh sederhana neural network dengan package neuralnet dan dummy data.
Kita akan membuat neural network dengan function neuralnet() dan memplotkan objek neural network tersebut dengan plot().
# membuat ANN
set.seed(417)
model_nn <- neuralnet(formula = y~Var1+Var2+Var3, # target ~ prediktor
data = dummy,
hidden = 3, # jumlah node pada hidden layer
rep = 5) # jumlah percobaan pembuatan model
# rep="best" untuk memplot percobaan yang menghasilkan error terkecil
plot(model_nn, rep="best")Arsitektur neural network terdiri dari:
input layer: layer yang terdiri dari node-node yang menerima input Var1, Var2, dan Var3. Pada contoh ini input layer berada di paling kiri dan terdiri dari 3 node.
output layer: layer yang terdiri dari node-node yang menghasilkan output (hasil prediksi). Pada contoh ini output layer berada paling kanan dengan simbol y.
hidden layer: layer diantara input dan output, dimana proses pengolahan informasi terjadi. Pada contoh ini hidden layer berada di tengah dan terdiri dari 3 node.
Nama hidden layer berasal dari konsep sederhana dimana kita tidak mengetahui tentang detail proses yang terjadi dalam layer tersebut (blackbox). Sama seperti kita yang masih amat buta tentang apa yang terjadi dalam otak manusia, suatu sistem kompleks yang menakjubkan karya Sang Pencipta.
Selama proses training model, neural network akan memberikan pembobotan secara random untuk tiap node nya. Bobot-bobot tersebut ditunjukkan dengan angka berwarna hitam di tiap panah antar node. Terdapat pula angka berwarna biru dan panahnya yang menunjukkan bias atau koefisien intercept untuk prediksi. Bobot tersebut akan terus dioptimasi hingga–pada kasus ini–mencapai error terkecil. Pada contoh ini, error (SSE) tersebut adalah cost function yang digunakan karena target prediksi kita adalah numerik atau merupakan kasus regresi.
Dibutuhkan 83 steps optimasi bobot hingga didapatkan error terkecil 0.001107. Steps juga seringkali disebut epoch. Kita akan lebih membahas bagaimana bobot dioptimasi ketika kita membahas tentang Backpropagation di bawah.
Pada pembuatan model menggunakan fungsi neuralnet(), kita juga dapat menentukan parameter rep = 5. Hal ini untuk membuat 5 buah (percobaan) arsitektur neural network, masing-masing dengan bobot awal yang berbeda. Sehingga pada tahap akhir kita bisa memplotkan atau memilih arsitektur yang menghasilkan error terkecil. Meskipun begitu, pada praktiknya (yang lebih sering menggunakan package Keras), umumnya kita hanya menggunakan 1 repetisi dan melakukan tuning model pada pengaturan epoch.
Hal lain yang khas untuk tiap arsitektur neural network juga adalah aliran informasinya. Terdapat 2 jenis aliran informasi yaitu:
Reccurent neural network (RNN) memperbolehkan adanya analisis sequences sehingga banyak digunakan dalam kasus time series atau text analysis.
Kita telah mengetahui tentang neural network. Namun apa hubungannya dengan Deep Learning? Deep learning ternyata adalah suatu neural network yang memiliki jumlah hidden layer yang lebih dari satu. Seperti contoh di bawah ini:
set.seed(417)
model_dl <- neuralnet(formula = y~Var1+Var2+Var3,
data = dummy,
hidden = c(3,4), # masing-masing angka untuk jumlah node di tiap hidden layer
rep = 5)
plot(model_dl, rep="best")Dengan menambahkan jumlah hidden layer di model neural network awal kita, kita telah mengubahnya menjadi model deep learning!
Kita telah mengetahui bahwa neural network akan mengadaptasikan bobot tiap nodenya untuk mendapatkan hasil terbaik, namun bagaimana adaptasi tersebut? Neural network melakukannya dengan proses backpropagation.
Untuk tiap tahapan training neural network akan dihasilkan nilai error dari cost function yang telah ditentukan. Nilai error yang ada di output akan dikembalikan ke node-node sebelumnya dengan proses backpropagation. Sementara itu, optimisasi nilai error dari proses backpropagaiton tersebut umum dilakukan menggunakan algoritma gradient descent.
Pembahasan algoritma tersebut akan membutuhkan sesi yang lebih dalam oleh karena itu tidak akan di bahas pada artikel ini. Untuk memahami lebih lanjut, video “Gradient Descent, Step-by-Step” oleh Josh Starmer (Stat Quest) dapat membantu Anda. Terdapat banyak algoritma lain untuk optimasi bobot namun tidak akan kita bahas satu per satu pada artikel ini.
Sebagai tambahan, terdapat satu istilah lagi yang umumnya ditemukan dalam pembuatan arsitektur neural network yaitu “epoch” atau yang pada plot neural net sebelumnya dinamakan “steps”. Epoch merupakan satu tahapan aliran informasi dari input layer ke output (feed-forward) kemudian dikembalikan lagi ke node sebelumnya (backpropagation) hingga bobot tiap node terupdate (terjadi optimasi bobot).
Pada contoh dibawah, digunakan epoch sebanyak 83.
Contoh kasus yang kita demonstrasikan sebelumnya adalah contoh kasus regresi. Terdapat beberapa perbedaan ketika kita menggunakan neural network untuk kasus klasifikasi:
Cross function: kasus yang berbeda akan menggunakan cross function yang berbeda. Cross function yang sering digunakan adalah sebagai berikut:
neuralnet(..., err.fct="sse")neuralnet(..., err.fct="ce"). Secara sederhana cross-entropy loss adalah kebaikan model dalam memprediksi label secara benar. Semakin kecil cross-entropy loss maka semakin baik model.Activation Function:
Activation function adalah suatu mekanisme untuk menentukan bagaimana sebuah informasi dialirkan ke node selanjutnya. Activation function ada pada setiap setelah input layer dan berfungsi untuk mentrasformasikan nilai/informasi yang ia terima ke bentuk lain sebelum dialirkan ke node selanjutnya.
Pada kasus klasifikasi, terdapat activation function yang sering digunakan yaitu sigmoid function. Sigmoid function ini digunakan pada output layer dan akan mengubah informasi hasil olahan node-node sebelumnya ke range nilai 0 - 1, cukup aplikatif untuk binary classification bukan? Beragam activation function lain juga berguna dalam proses penentuan hasil prediksi, diantaranya:
tanh()max(0, x)Sebagai contoh, Softmax function sering dipakai untuk kasus multiclass classification. Berbeda dari Sigmoid function yang digunakan untuk binary classification, Softmax akan menghasilkan nilai peluang 0-1 untuk tiap node atau kelasnya, namun peluang tersebut bila dijumlahkan dari tiap kelas maka akan menghasilkan nilai 1. Hasil klasifikasi akan ditentukan berdasarkan kelas yang memiliki peluang tertinggi.
Keunggulan dari Deep Learning adalah keberadaan hidden layer pada arsitekturnya. Keberadaan tersebut membolehkan model untuk menangkap informasi/pola abstrak yang sulit ditangkap oleh model machine learning lainnya. Oleh karena itu, berbeda dengan model machine learning lain yang umumnya mengambil input data dalam bentuk tabular, deep learning unggul dalam pemrosesan data-data abstrak:
Pada aplikasinya, sering kali kita akan melakukan model tuning di bagian arsitektur model. Terdapat banyak sekali hyperparameter tuning yang dapat dilakukan namun dua yang sering menjadi pembicaraan adalah:
Semakin “deep” atau “wide” arsitektur neural network, maka kompleksitas dari model tersebut akan semakin tinggi. Hal tersebut mungkin akan membantu dalam menangkap/mengolah informasi abstrak dari data. Namun ada hal yang perlu diwaspadai:
Kemudian bagaimanakah cara kita menentukan baik/tidaknya suatu arsitektur neural network? Sampai saat ini belum ada standar khusus untuk itu. Unsur abstrak atau “Black Box” dari neural network tersebut memang menjadi keunggulan dan tantangan sendiri dalam pembuatan model prediksi. Sebagai pertimbangan, pilihlah arsitektur yang paling sederhana namun dapat menghasilkan prediksi yang cukup mumpuni atau di atas ambang batas yang kita tentukan.
Handwriting recognition kini semakin berkembang dan tidak terkecuali untuk huruf hijaiyah atau bahasa arab. Pengembangan sistem handwriting recognition huruf hijaiyah menggunakan Deep Learning akan membuka jalan untuk kemudahan proses transfer bentuk literasi dari manuskrip-manuskrip kuno yang berbahasa arab menjadi bentuk digitalnya. Hal ini akan memudahkan proses penyimpanan literatur serta riset arkeologi, antropologi, serta sejarah Arab. Pengembangan ide dari handwriting recognition ini dapat membuka jalan untuk riset arkeologi dan sejarah secara umum untuk umat manusia.
Pembuatan model Deep Learning untuk Handwriting Recognition Huruf Hijaiyah akan menggunakan dataset “Arabic Handwritten Characters Dataset” yang tersedia secara online dan dipublikasikan oleh Mohamed Loey (2019).
Untuk pembuatan model, akan digunakan beberapa package sebagai berikut:
Dalam dataset, terdapat hasil scan 16800 karakter huruf hijaiyah (alif s.d. ya) oleh 60 individu dan telah diproses menjadi data gambar dalam bentuk pixel dan tersimpan dalam format CSV. Terlah dipisahkan antara data train dan data test untuk pembuatan model. Masing masing data juga telah dipisahkan antara kolom target (label) dengan kolom prediktornya (data gambar).
# data train
arabich_train_x <- read_csv("arabich/csvTrainImages 13440x1024.csv") # prediktor
arabich_train_y <- read_csv("arabich/csvTrainLabel 13440x1.csv") # target
# data test
arabich_test_x <- read_csv("arabich/csvTestImages 3360x1024.csv")
arabich_test_y <- read_csv("arabich/csvTestLabel 3360x1.csv")#> [1] 13439 1024
#> [1] 13439 1
#> [1] 3359 1024
#> [1] 3359 1
Dalam dataset terdapat 13439 observasi atau gambar 8 bit dengan ukuran 32 x 32 pixel yang dijadikan data train, berikut 3359 gambar dengan ukuran sama yang dijadikan data test. Dalam data, terdapat 28 label atau huruf hijaiyah:
#> [1] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15"
#> [16] "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28"
Sebelum dimasukkan kedalam model neural network, data train yang kini masih dalam bentuk data.frame perlu diubah menjadi bentuk matrix kemudian ke bentuk array. Hal ini karena model neural network menggunakan package keras membutuhkan data input berupa array.
# mengubah data.frame -> matrix
train_x <- data.matrix(arabich_train_x)
train_y <- arabich_train_y$`1` - 1 # karena integer di python dimulai dari `0`
test_x <- data.matrix(arabich_test_x)
test_y <- arabich_test_y$`1` - 1
# mengubah matrix -> array untuk data prediktor
train_x_keras <- array_reshape(train_x, c(nrow(train_x), 1024))
test_x_keras <- array_reshape(test_x, c(nrow(test_x), 1024))
# normalisasi data dengan min-max normalization
train_x_keras <- train_x_keras / 255 # gambar 8 bit akan memiliki range intiger warna 0 - 255 (2^8)
test_x_keras <- test_x_keras / 255
# mengubah label menjadi kategorik
train_y_keras <- to_categorical(train_y, 28) # untuk 28 huruf hijaiyahmodel <- keras_model_sequential()
model %>%
layer_dense(units = 224, activation = 'relu', input_shape = c(1024)) %>%
layer_dense(units = 112, activation = 'relu') %>%
layer_dense(units = 56, activation = 'relu') %>%
layer_dense(units = 28, activation = 'softmax')
model %>% compile(
loss = 'categorical_crossentropy', # cost function: cross-entropy
optimizer = optimizer_rmsprop(), # tipe optimizer untuk backpropagation: RMSProp
metrics = c('accuracy')
)#> Model: "sequential"
#> ________________________________________________________________________________
#> Layer (type) Output Shape Param #
#> ================================================================================
#> dense (Dense) (None, 224) 229600
#> ________________________________________________________________________________
#> dense_1 (Dense) (None, 112) 25200
#> ________________________________________________________________________________
#> dense_2 (Dense) (None, 56) 6328
#> ________________________________________________________________________________
#> dense_3 (Dense) (None, 28) 1596
#> ================================================================================
#> Total params: 262,724
#> Trainable params: 262,724
#> Non-trainable params: 0
#> ________________________________________________________________________________
Setelah membuat arsitektur model deep learning, kita dapat melatih model tersebut (model fitting) menggunakan data train. Kita dapat memplotkan proses fitting tersebut untuk melihat pada epoch ke berapa model kita mulai konvergen atau stabil (tidak memberikan penurunan error yang tinggi).
history <- model %>% fit(
train_x_keras, train_y_keras,
epochs = 30, batch_size = 128
)
plot(history)#> [1] 0.9334772
Berdasarkan hasil plot, kita dapat mengetahui bahwa model sudah mulai stabil pada epoch ke 15 dengan nilai accuracy 0.93.
Untuk itu kita akan mencoba tuning epoch kembali agar proses training dan prediksi akan lebih cepat. Ketika kita mengubah epoch (atau hyperparameter tuning lainnya), maka kita harus menjalankan ulang dari tahap pembuatan arsitektur deep learning.
model <- keras_model_sequential()
model %>%
layer_dense(units = 224, activation = 'relu', input_shape = c(1024)) %>%
layer_dense(units = 112, activation = 'relu') %>%
layer_dense(units = 56, activation = 'relu') %>%
layer_dense(units = 28, activation = 'softmax')
model %>% compile(
loss = 'categorical_crossentropy', # cost function: cross-entropy
optimizer = optimizer_rmsprop(), # tipe optimizer untuk backpropagation: RMSProp
metrics = c('accuracy')
)
history2 <- model %>% fit(
train_x_keras, train_y_keras,
epochs = 15, batch_size = 128
)
plot(history2)Setelah membuat model neural network kita dapat menggunakannya untuk memprediksi data test. Hal ini untuk melihat performa model dalam memprediksi data baru. Selanjutnya kita akan mengevaluasi model dengan confussion matrix.
# menyandingkan data aktual - hasil prediksi
result <- data.frame(actual = test_y, prediction = prediction_test) %>%
mutate_all(as.factor)
result %>%
conf_mat(actual, prediction) %>%
autoplot(type = "heatmap")#> [1] 0.7308723
Hasil pengujian pada data test memperlihatkan nilai akurasi yang lebih rendah yaitu 0.73 dibandingkan nilai akurasi di data train. Perbedaan akurasi yang cukup tinggi mengindikasikan adanya overfitting. Kita dapat melakukan tuning pada arsitektur neural network salah satunya dengan mengurangi jumlah node. Pada contoh di bawah, kita akan mengurangi jumlah node pada hidden layer pertama arsitektur neural network.
model2 <- keras_model_sequential()
model2 %>%
layer_dense(units = 112, activation = 'relu', input_shape = c(1024)) %>%
layer_dense(units = 112, activation = 'relu') %>%
layer_dense(units = 56, activation = 'relu') %>%
layer_dense(units = 28, activation = 'softmax')
model2 %>% compile(
loss = 'categorical_crossentropy', # cost function: cross-entropy
optimizer = optimizer_rmsprop(), # tipe optimizer untuk backpropagation: RMSProp
metrics = c('accuracy')
)
history3 <- model2 %>% fit(
train_x_keras, train_y_keras,
epochs = 15, batch_size = 128
)
plot(history3)#> [1] 0.8767021
Dari model tuning didapatkan akurasi 0.88. Akurasi ini cukup baik, sehingga model akan coba diujikan pada data test.
# menyandingkan data aktual - hasil prediksi
result <- data.frame(actual = test_y, prediction = prediction_test) %>%
mutate_all(as.factor)
result %>%
conf_mat(actual, prediction) %>%
autoplot(type = "heatmap")#> [1] 0.7174754
Hasil prediksi menunjukkan akurasi 0.72. Nilai tersebut dinilai tidak berbeda terlalu jauh dengan nilai akurasi pada data train, bila dibandingkan dengan percobaan sebelumnya. Oleh karena itu, model kedua ini dapat lebih diterima untuk dijadikan model prediksi untuk tujuan Handwriting Recognition Handwriting Recognition Huruf Hijaiyah.
Meskipun begitu, model ini masih amat jauh dari kesempurnaan. Masih banyak hyperparameter tuning lainnya yang dapat dilakukan seperti pengubahan jumlah layer dan node pada arsitektur neural network dan pemilihan optimizer. Pada bagian Memahami Deep Learning, Anda bisa telusuri lebih jauh mengenai konsep-konsep yang mendasari Deep Learning dan Neural Network. Pengetahuan tersebut akan menjadi basis yang baik untuk menelusuri ragam optimasi model deep learning dengan lebih mudah.
Selamat belajar dan semoga bermanfaat!