1 Pendahuluan

Deep Learning merupakan topik yang sedang nge-trend dikalangan akademisi ataupun professional. Apa sih Deep Learning itu? Deep Learning adalah salah satu cabang Machine Learning yang menggunakan Deep Neural Network untuk menyelesaikan permasalahan pada domain Machine Learning

Neural network sendiri adalah model yang terinspirasi oleh bagaimana neuron dalam otak manusia bekerja. Tiap neuron pada otak manusia saling berhubungan dan informasi mengalir dari setiap neuron tersebut. Tiap neuron menerima input dan melakukan operasi dot dengan sebuah weight, menjumlahkannya (weighted sum) dan menambahkan bias. Hasil dari operasi ini akan dijadikan parameter dari activation function yang akan dijadikan output dari neuron tersebut.

Beberapa kegunaan dari Deep Learning adalah sebagai berikut:

  • Mengenali wajah atau Face Recognizition,
  • Mendeteksi pola tulisan tangan,
  • Mendeteksi suara dan kalimat,
  • Natural Language Processing,
  • Recommendation Systems, dan sebagainya.

Dalam analisis Deep Learning banyak sekali framework yang dapat digunakan dalam penganalisisan. Beberapa yang cukup populer di antaranya adalah: Tensorflow, Keras, MXNet, dan PyTorch. Berikut adalah grafik tingkat kepopuleran framework deep learning selama 2018.

2 Activation Function

Sesuai dengan namanya, activation function berfungsi untuk menentukan apakah neuron tersebut harus “aktif” atau tidak berdasarkan dari weighted sum dari input. Secara umum terdapat 2 jenis activation function, Linear dan Non-Linear Activation function.

2.1 Linear Function

Bisa dikatakan secara “default” activation function dari sebuah neuron adalah Linear. Jika sebuah neuron menggunakan linear function, maka keluaran dari neuron tersebut adalah weighted sum dari input + bias.

2.2 Sigmoid and Tanh Function (Non-Linear)

Sigmoid function mempunyai rentang antara 0 hingga 1 sedangkan rentang dari Tanh adalah -1 hingga 1. Kedua fungsi ini biasanya digunakan untuk klasifikasi 2 class atau kelompok data. Namun terdapat kelemahan dari kedua fungsi ini, nanti akan coba saya jelaskan di part berikutnya.

2.3 ReLU (Non-Linear)

Pada dasarnya ReLU melakukan “treshold” dari 0 hingga infinity. ReLU juga dapat menutupi kelemahan yang dimiliki oleh Sigmoid dan Tan

3 Eksplorasi Data

3.1 Garis Besar Data

Dataset yang digunakan untuk analisis neural network ini adalah dataset Fashion MNIST. Dataset ini merupakan sebuah kumpulan 60,000 buah gambar hitam-putih yang memiliki 10 kategori dan direpresentasikan dalam sebuah pixel berukuran 28x28. Hasil dari analisis ini adalah membuat sebuah model dalam memprediksi/mengklasifikasikan gambar berdasarkan data yang ada.

Supaya dapat direpresentasi sebagai kisaran nilai antara 0 sampai 1, maka masing-masing data train dan test terlebih dahulu dijadikan matriks, lalu dibagi dengan 255 (nilai terbesar sebuah piksel).

3.2 Load Library

library(keras)
use_condaenv("r-tensorflow")
## Warning in normalizePath(path.expand(path), winslash, mustWork):
## path[1]="C:\Users\hp\ANACON~1\envs\rstudio/python.exe": The system cannot
## find the file specified

3.4 Ekplorasi Dataset

table(fashion_train$label)
## 
##    0    1    2    3    4    5    6    7    8    9 
## 6000 6000 6000 6000 6000 6000 6000 6000 6000 6000
barplot(table(fashion_train$label))

#merubah data menjadi matrix
fashionmatrix<- matrix(fashion_train[2,2:ncol(fashion_train)], nrow = 28, ncol=28)
fashionmatrix <- apply(fashionmatrix, 2, as.numeric, byrow = T)
image(fashionmatrix)

fashionmatrix2 <- t(apply(fashionmatrix, 1, rev))
image(fashionmatrix2)

#visualisasi data yang akan digunakan
vizTrain <- function(input){
  
  dimmax <- sqrt(ncol(fashion_train[,-1]))
  
  dimn <- ceiling(sqrt(nrow(input)))
  par(mfrow=c(dimn, dimn), mar=c(.1, .1, .1, .1))
  
  for (i in 1:nrow(input)){
      m1 <- matrix(input[i,2:ncol(input)], nrow=dimmax, byrow=T)
      m1 <- apply(m1, 2, as.numeric)
      m1 <- t(apply(m1, 2, rev))
      
      image(1:dimmax, 1:dimmax, m1, col=grey.colors(255), xaxt = 'n', yaxt = 'n')
      text(2, 20, col="white", cex=1.2, fashion_train[i, 1])
  }
  
}

vizTrain(fashion_train[1:100,])

Setelah melihat secara umum data yang akan kita olah, selanjutkan adalah merubah data pixel menjadi data matrix.

train <- data.matrix(fashion_train)
test <- data.matrix(fashion_test)

train_x <- train[,-1]
train_y <- train[,1]

test_x <- test[,-1]
test_y <- test[,1]

train_x train_y dan test_x``test_y adalah sebuah label klasifikasi untuk 10 buah jenis gambar yang ada. Pada beberapa framework tipe data yang disyaratkan berbeda beda, jika pada NN harus berupa matrix, namun bila di keras harus arrayy

library(keras)
train_x_keras <- array_reshape(train_x, dim = c(nrow(train_x), ncol(train_x)))
## Warning in normalizePath(path.expand(path), winslash, mustWork):
## path[1]="C:\Users\hp\ANACON~1\envs\rstudio/python.exe": The system cannot
## find the file specified
test_x_keras <- array_reshape(test_x, c(nrow(test_x), ncol(test_x)))

Setelah merubah tipe data menjadi array, selanjutnya yang belum kita lakukan adalah menstandarisasinya. Berbeda dengan tipe/standarisasi pada data biasanya dengan menggunakan scale.

train_x_keras <- train_x_keras/255 #standarisasi pixel (scaling)
test_x_keras <- test_x_keras/255

Bila kita bekerja dalam bentuk foto maka R akan membacanya sebagai pixel oleh karena itu kita cukup membagi dengan total warna (untuk warna hitam putih sebanyak 255) semakin mendekati nol betarti semakin gelap. semakin mendekati 255 semakin putih.

train_y_keras <- to_categorical(train_y, 10)
test_y_keras <- to_categorical(train_y, 10)

head(train_y_keras)
##      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,]    0    0    1    0    0    0    0    0    0     0
## [2,]    0    0    0    0    0    0    0    0    0     1
## [3,]    0    0    0    0    0    0    1    0    0     0
## [4,]    1    0    0    0    0    0    0    0    0     0
## [5,]    0    0    0    1    0    0    0    0    0     0
## [6,]    0    0    0    0    1    0    0    0    0     0

Pembagian dengan 255 berguna untuk mempercepat perhitungan. Hal ini disebut normalisasi. Pembagian dengan nilai maksimum yang dimiliki data akan mempercepat penghitungan, sedangkan untuk label alias variabel train_y_keras dan test_y_keras, masing-masingnya diubah dengan to_categorical.

4 Modelling

Setelah data siap digunakan , kita bisa mulai membuat modelnya. Arsitektur yang akan kita coba beberapa model, yaitu dengan menggunakan 3 hidden layer, yang masing-masing hanya berbeda pada jumlah neuron pada tiap model gunak mendapatkan akurasi yang paling baik.

Di bawah, kita dapat melihat function keras_model_sequential() yang artinya semacam wadah dari arsitektur Deep Learning yang akan dibuat. Menandakan bahwa data masuk dari satu lapisan ke lapisan yang lain sesuai dengan urutan penambahannya.

Sedangkan Dense merupakan representasi lapisan MLP, atau yang biasa dikenal dengan Hidden Layer. Dense pertama memiliki 256 sel (neuron), dan memerlukan input sebesar 784, dengan layer_dropout pada pertama sebesar 0.3 dan layer_dropout kedua sebesar 0.2. Namun pada model ketiga kita akan mencoba untuk tidak memakainya, guna melihat perbedaan hasil pada akurasi model yang akan dihasilkan.

Kemudian Activation Function yang akan dipakai adalah ReLu, terdapat di layer setelah input layer (hidden layer dan output layer), kegunaannya untuk standarisasi/mencegah fitur fitur yang bernilai tinggi dan juga meminimalisir waktu pada train model setelah standarisasi.

Sedangkan pada layer_dense kedua, activation yang akan dipakai adalah softmaxdiakrena class yang akan diprediksi memiliki lebih dari 2 class- lebih ke probabilitas, untuk multiclass (rangenya dari 0 sampai 1).

Selanjutnya fungsi compile adalah untuk menambahkan metode optimisasi dan fungsi loss. Dalam analisis ini akan menggunakan ‘categorical_crossentropy‘ untuk multikategori, dan bisa gunakan ‘binary_crossentropy‘ untuk output dua kategori. Untukoptimize_adam sebagai optimizer yang akan digunakan karena performanya baik.

# model <- keras_model_sequential()
# model %>% layer_dense(units = 256, activation = "relu", 
#     input_shape = c(784)) %>% 
#   layer_dropout(rate = 0.3) %>% 
#     layer_dense(units = 128 , activation = "relu") %>% 
#   layer_dropout( rate = 0.2) %>% 
#     layer_dense(units = 10, 
#     activation = "softmax")
# 
# model %>% compile(loss = "categorical_crossentropy", 
#             optimizer = optimizer_adam(lr = 0.0001), metrics = c("accuracy"))



# model2 <- keras_model_sequential()
# model2 %>% layer_dense(units = 128, activation = "relu", 
#     input_shape = c(784)) %>% 
#   layer_dropout(rate = 0.3) %>% 
#     layer_dense(units = 64 , activation = "relu") %>% 
#   layer_dropout( rate = 0.2) %>% 
#     layer_dense(units = 10, 
#     activation = "softmax")
# 
# model2 %>% compile(loss = "categorical_crossentropy", 
#             optimizer = optimizer_adam(lr = 0.0001), metrics = c("accuracy"))



model3 <- keras_model_sequential()
model3 %>% layer_dense(units = 256, activation = "relu", 
    input_shape = c(784)) %>% 
  layer_dropout(rate=0.3) %>% 
    layer_dense(units = 128 , activation = "relu") %>% 
  layer_dropout(rate = 0.2) %>% 
    layer_dense(units = 10, 
    activation = "softmax")

model3 %>% compile(loss = "categorical_crossentropy", 
            optimizer = optimizer_adam(lr = 0.0001), metrics = c("accuracy"))

5 Training Model

Setelah model siap, kita bisa mulai melakukan training dengan data yang kita sudah buat diawal. Untuk melakukan training, kita harus memanggil method fit. Epoch, learning rate, batch_size, dll ini adalah hyperparameter yang bisa kita tentukan. Sedangkan nilai hyperparameter yang ideal, sampai saat ini masih belum ada riset yang bisa memecahkan masalah tersebut dalam hal penentuan epoch dan batch_size yang ideal dalam suatu pemodelan. Dalam analsis ini kita membuat perbedaan dari masing-masing model.

# fashmod <- model %>% fit(train_x_keras, train_y_keras, epoch = 100, 
#                          bacth_size = 256) #model 1
# fashmod <- model %>% fit(train_x_keras, train_y_keras, epoch = 100, 
#                          bacth_size = 128) #model 2
fashmod3 <- model3 %>% fit(train_x_keras, train_y_keras, epoch = 30, 
                           bacth_size = 256, validation_split = 0.1) #model 3
plot(fashmod3)

# fashmod$metric$loss[30]
# fashmod2$metrics$loss[30] 
# fashmod3$metrics$loss[30] 
# 
# Hasil :
# [1] 0.2696702
# [1] 0.2900571
# [1] 0.2296789
# fashmod$metrics$acc[30] 
# fashmod2$metrics$acc[30] 
# fashmod3$metrics$acc[30]
# 
# Hasil :
# [1] 0.90075
# [1] 0.8938
# [1] 0.9142037

Dari ketika model yang kita buat terdapat perbedaan nilai loss dan akurasi yang berbeda-beda. Dimana arsitektur deep network :

  • Model 1 : Acc = 90.00% Loss : 0.26
  • Model 2 : Acc = 89.38% Loss : 0.29
  • Model 3 : Acc = 91.42% Loss : 0.22

Berdasarkan hasil diatas, bisa kita lihat bahwa model ketiga merupakan model dengan tingkat akurasi tertinggi dan nilai loss terendah. Apakah ini berarti model ketiga sudah layak dikatakan model terbaik?? Jawabannya belum tentu.

Dengan melihat akurasi tersebut, kita perlu menentukan, apakah kita perlu lebih lanjut membuat arsitektur yang lebih baik atau tidak. Sedangkan, akurasi terhadap training ataupun validasi, gunanya adalah untuk mengevaluasi pada saat training terjadi. Karena biasanya training dilakukan dalam ribuan epoch, sehingga sangat lama baru bisa melakukan evaluasi terhadap data uji coba. Jika pada pengujian terhadap data training dan didapat nilai akurasi yang masih belum masuk kriteria baik, bisa dilakukan lagi dengan mencoba membuat model tambahan tergantung pada masing-masing individu dan kebutuhan untuk mengevaluasi model yang dibuat.

Pada analisis ini, pembuatan arsitektur deep learning hanya dilakukan pada tiga model saja. Dan selanjutnya kita akan bandingkan dengan pengujian model pada data test.

6 Evaluasi dan Prediksi

Setelah melakukan pengujian model terhadap data training, selanjutnya kita coba untuk menerapkan model pada data test. Dimana hasil dari ketiga model yang telah dibuat tadi berdasarkan Confusion Matrix menghasilkan nilai akurasi yang berbeda bila dibandingkan terhadap pengujianpada data training. Dimana bila kita lihat, bahwa terjadi penurunan nilai akurasi pada setiap model yang ada.

prediction_test3 <-  keras::predict_classes(object = model3, x = test_x_keras)
prediction_test3[1:10]
##  [1] 0 1 2 2 4 6 8 3 5 0
# caret::confusionMatrix(as.factor(prediction_test), as.factor(test_y)) #Model 1
# caret::confusionMatrix(as.factor(prediction_test2), as.factor(test_y)) #Model 2
caret::confusionMatrix(as.factor(prediction_test3), as.factor(test_y))
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   0   1   2   3   4   5   6   7   8   9
##          0 865   4  14  14   0   0 128   0   2   0
##          1   0 986   1  11   1   0   1   0   0   0
##          2   8   0 807   6  46   1  47   0   7   0
##          3  13   7  15 934  30   0  25   0   2   0
##          4   1   0  84  15 858   0  47   0   1   0
##          5   0   2   0   1   0 947   0  13   1   4
##          6 105   1  77  17  63   0 745   0   9   1
##          7   0   0   0   0   0  32   0 937   2  27
##          8   8   0   2   2   2   2   7   0 975   0
##          9   0   0   0   0   0  18   0  50   1 968
## 
## Overall Statistics
##                                          
##                Accuracy : 0.9022         
##                  95% CI : (0.8962, 0.908)
##     No Information Rate : 0.1            
##     P-Value [Acc > NIR] : < 2.2e-16      
##                                          
##                   Kappa : 0.8913         
##                                          
##  Mcnemar's Test P-Value : NA             
## 
## Statistics by Class:
## 
##                      Class: 0 Class: 1 Class: 2 Class: 3 Class: 4 Class: 5
## Sensitivity            0.8650   0.9860   0.8070   0.9340   0.8580   0.9470
## Specificity            0.9820   0.9984   0.9872   0.9898   0.9836   0.9977
## Pos Pred Value         0.8423   0.9860   0.8753   0.9103   0.8529   0.9783
## Neg Pred Value         0.9850   0.9984   0.9787   0.9926   0.9842   0.9941
## Prevalence             0.1000   0.1000   0.1000   0.1000   0.1000   0.1000
## Detection Rate         0.0865   0.0986   0.0807   0.0934   0.0858   0.0947
## Detection Prevalence   0.1027   0.1000   0.0922   0.1026   0.1006   0.0968
## Balanced Accuracy      0.9235   0.9922   0.8971   0.9619   0.9208   0.9723
##                      Class: 6 Class: 7 Class: 8 Class: 9
## Sensitivity            0.7450   0.9370   0.9750   0.9680
## Specificity            0.9697   0.9932   0.9974   0.9923
## Pos Pred Value         0.7318   0.9389   0.9770   0.9335
## Neg Pred Value         0.9716   0.9930   0.9972   0.9964
## Prevalence             0.1000   0.1000   0.1000   0.1000
## Detection Rate         0.0745   0.0937   0.0975   0.0968
## Detection Prevalence   0.1018   0.0998   0.0998   0.1037
## Balanced Accuracy      0.8573   0.9651   0.9862   0.9802
# Model : 1
 
    #            Accuracy : 0.8995          
    #              95% CI : (0.8934, 0.9053)
    # No Information Rate : 0.1             
    # P-Value [Acc > NIR] : < 2.2e-16 



# Model 2

    #            Accuracy : 0.9009          
    #              95% CI : (0.8949, 0.9067)
    # No Information Rate : 0.1             
    # P-Value [Acc > NIR] : < 2.2e-16

Dari masing-masing model yang telah dilakukan pengujian pada data test, nilai akurasinya menjadi turun. Penurunan keakurasian data ini merupakan salah satu contoh dari overfitting. Overfitting dapat terjadi ketika data yang kita uji sebelumnya memiliki nilai galat yang lebih jauh ketimbang data evaluasi. Sampai disini kita bisa kembali mengevaluasi model yang akan kita pilih, dengan membuat arsitektur yang lebih kompleks, misalnya merubah jumlah hidden layer maupun jumlah neuron, epoch ataupun nilai bacth_size nya. lalu kembali mengevaluasinya.

Berdasarkan hasil perbandingan penuruan nilai akurasi antara setiap model terhadap data training dan data uji, dapat kita simpulkan bahwa model pertama merupakan model yang terbaik diantara model lainnya. Ini dilihat dari kecilnya perbedaan penurunan nilai akurasi antara data training dan data test yaitu sebesar 0.17, berbeda dengan model ketiga yang mana sebelumnya pada data training memiliki nilai akurasi hingga 91% namun ketika dilakukan pengujian terhadap data test nilai akurasinya menurun cukup drastis sekitar 1.57, yang artinya terjadi overfitting pada model ketiga. Sedangkan pada model kedua walaupun memiliki akurasi 90% terhadap data test namun bila dibandingkan terhadapa penurunan akurasi pada datatraining tidak lebih baik dari model pertama yang memiliki akurasi lebih rendah pada datatest. Selanjutnya, kita akan mencoba untuk melakukan plot visualisasi data prediksi terhadap data test.

plotResults <- function(images, preds) {
    
    x <- ceiling(sqrt(length(images)))
    par(mfrow = c(x, x), mar = c(0.1, 0.1, 0.1, 0.1))
    
    for (i in images) {
        m <- matrix(test_x[i, ], nrow = 28, byrow = TRUE) 
        m <- apply(m, 2, rev)
        image(t(m), col = grey.colors(255), axes = FALSE)
        text(0.05, 0.1, col = "blue", cex = 1.2, preds[i])
    }
    
}
prediction_test3 <- sapply(as.character(prediction_test3), switch,
                       "0" = "Tshirt",
                       "1" = "Trouser",
                       "2" = "Pullover",
                       "3" = "Dress",
                       "4" = "Coat",
                       "5" = "Sandal",
                       "6" = "Shirt",
                       "7" = "Sneaker",
                       "8" = "Bag",
                      "9" = "Boot")
plotResults(1:64, prediction_test3)

7 Kesimpulan

Pengujian pada data test memang selamanya tidak menghasilkan 100 % benar, ada sebagian atau beberapa data yang terkadang hasil prediksi tidak sesuai dengan jenis gambarnya. Di sini, bisa disimpulkan bahwa, pemilihan arsitektur sangatlah krusial jika akurasi tidak kunjung membaik. Pada tahap evaluasi tadi, kita selalu melihat ukuran akurasi sebagai acuan dalam pemilihan suatu model. Ukuran akurasi dihitung dari total percobaan yang benar tebakannya, dibagi dengan total seluruh percobaan. Percobaan yang salah, disebut dengan error.

Di tahap proses training data, kita berharap agar nilai akurasi semakin besar, atau nilai error semakin kecil. Namun, tentu saja ada batasan, sekecil apa error bisa dianggap aman? Ukuran ini biasanya mengacu kepada manusia. Karena pada akhirnya, sistem Deep Learning digunakan untuk menggantikan peran manusia pada suatu tugas, acuannya pasti kemampuan manusia itu sendiri.

Jika akurasi pada data training rendah, alias errornya tinggi, maka model yang dibuat memiliki bias yang tinggi, atau sering disebut Underfitting. Sedangkan jika akurasi pada data training tinggi, errornya kecil, namun akurasi pada validasi jauh lebih rendah, maka model yang dibuat memiliki variance yang tinggi yang disebut Overfitting.

Ada istilah bias-variance-tradeoff. Yang artinya, jika kita berusaha mengecilkan bias maka variance akan membesar. Begitu juga sebaliknya. Jika kita berusaha mengecilkan variance, maka bias akan membesar.Hal tersebut sekarang sudah terpecahkan dengan banyaknya data yang digunakan pada metode Deep Learning. Solusinya, ortogonalisasi.

Secara sederhana jika bias tinggi (underfitting), maka ada 3 hal yang bisa dilakukan:

  • Membuat model yang lebih besar. Maksudnya adalah menambahkan jumlah unit pada satu layer. Atau membuatnya semakin dalam dengan menambah jumlah layer lagi.

  • Melakukan training lebih lama. Dengan kata lain, menambah jumlah epochs. Jika kamu perhatikan, semakin lama, nilai akurasi pada data training terus meningkat.

  • Menggunakan arsitektur lain yang lebih cocok. Misalnya CNN untuk gambar, atau RNN untuk teks. Akan tetapi, biasanya opsi 1 dan 2 sudah cukup untuk menyelesaikan masalah kamu.

Sedangkan, jika variance tinggi (overfitting), ada tiga hal pula yang bisa kamu lakukan:

  • Menambah data yang bisa kamu gunakan untuk training dan validasi. Semakin banyak jumlah data, semakin banyak referensi yang bisa digunakan oleh sistem dalam mencari korelasi antar fitur untuk mendapatkan hasil yang lebih baik.
  • Regularisasi. Hal ini digunakan untuk secara langsung mengurangi noise yang muncul ketika training sedang dilakukan. Teknik regularisasi yang cukup terkenal adalah Dropout, yaitu mematikan secara acak beberapa unit sehingga tidak menghasilkan keluaran apapun (0 untuk segala macam input). Seperi yang kita lakukan pada model yang dianalisis diatas.
  • Menggunakan arsitektur lain yang lebih cocok.

Namun, untuk mendapatkan model yang baik dan efisien dalam hal waktu (dikarenakan dalam setiap evaluasi memerlukan waktu yang tidak sedikit), ada beberapa hal penting yang bisa dijadikan panduan dalam pembuatan model Deep Learning, yaitu :

  1. Gunakan Hidden Layer dengan satu lapisan saja. Kemudian, uji coba pada data tes. Jika hasilnya memuaskan, cukup sampai di sini.
  2. Bisa kita tambahkan kompleksitas arsitektur yang dibuat, misalnya dengan menambahkan jumlah neuron dalam lapisan (hidden layer) tersebut. Atau dengan menambahkan jumlah hidden layernya. Jika hasilnya memuaskan, maka cukup sampai di sini dalam proses pembuatan model.
  3. Bila masih belum juga, ubah arsitektur yang dibuat menjadi yang lebih tepat. Gunakan CNN untuk mengolah gambar, dan RNN untuk mengolah deret.