Kali ini kita akan melakukan image classification menggunakan deep learning dengan framework keras. Kita akan gunakan data Sign Language MNIST yang berisi data image tentang gambar bahasa isyarat yang di tampilkan dalam bentuk csv. Adapun data telah diunduh sebelumnya dari https://www.kaggle.com/datamunge/sign-language-mnist. Kita akan coba klasifikasikan setiap gambar bahasa isyarat ke label huruf yang sesuai.

1 Persiapan Data

Kita siapkan dataset sebagai langkah pertama. Kita akan menggunakan data Sign Language MNIST. Data tersebut terdiri dari data train dan datatest. Dari data tersebut, mewakili label dari 0 - 25 dengan ukuran 28 x 28 pixel. Sebelumnya kita akan gunakan daftar istilah berikut ini untuk melabelkan variabel target kita :

categories <- c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
                "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
                "U","V", "W", "X", "Y", "Z")

1.1 Load Library & Read Data

Load library yang digunakan

# library yang digunakan
library(readr)
library(keras)
library(caret)
library(dplyr)
# read data
sign_mnist_train <- read_csv("sign_mnist_train.csv")
sign_mnist_test <- read_csv("sign_mnist_test.csv")

Periksa mnist_train data dengan menggunakan function head().

# periksa data
head(sign_mnist_train)

Cek Dimensi

# cek dimensi
dim(sign_mnist_train)
## [1] 27455   785

Cek nilai unik dari kategori (label) gambar yang ingin ditebak

# cek unik
unique(sign_mnist_train$label)
##  [1]  3  6  2 13 16  8 22 18 10 20 17 19 21 23 24  1 12 11 15  4  0  5  7 14

Data sign_mnist_train data terdiri dari 27455 observations (baris) dan 785 variabel (1 target and 784 prediktor). Setiap prediktor merepresentasikan pixel dari gambar.

1.2 Konversi ke Dalam Matriks

Data berisi nilai pixel yang disimpan dalam data frame. Namun, kita harus mengkonversi data menjadi matriks sebelum kita membuat sebuah model. Lakukan konversi data menjadi format matrix menggunakan fungsi data.matrix().

# ubah data frame ke dalam matrix
train_m <- data.matrix(sign_mnist_train)
test_m <- data.matrix(sign_mnist_test)

1.3 Pisahkan Prediktor & Target

Setelah itu, kita harus memisahkan prediktor dan target di data train_m dan test_m

# Predictor variables in `train_m`
train_x <-  train_m[,-1]

# Predictor variables in `test_m`
test_x <- test_m[,-1]

# Target variables in `train_m`
train_y <- train_m[,1]

# Target variables in `test_m`
test_y <- test_m[,1]

1.4 Ubah Menjadi Array

Selanjutnya, kita harus mengkonversi prediktor matriks ke dalam bentuk array. Silahkan gunakan array_reshape(data, dim(data)) untuk mengkonversi data.

train_x_array <- array_reshape(train_x, dim(train_x))
test_x_array <- array_reshape(test_x, dim(test_x))

1.5 Scaling

Tahap selanjutnya adalah menskalakan nilai array (train_x_array dan test_x_array) dengan membaginya dengan 255.

train_x.keras <- train_x_array/255
test_x.keras <- test_x_array/255

Untuk mempersiapkan data train model, kita menerapkan one-hot encoding ke target variabel (train_y) menggunakan fungsi to_categorical() dari library keras dan simpan sebagai obyek train_y.keras.

train_y.keras <- to_categorical(train_y)

2 Model Neural Network

2.1 Membuat Model Dasar

Untuk mengatur layer, kita harus membuat model dasar, yaitu model Sequential. Panggil fungsi keras_model_sequential(), dan pipe model dasar dengan arsitektur model.

2.2 Membangun Arsitektur

Menentukan layer, Neuron, dan fungsi aktivasi.

Untuk mendefinisikan arsitektur tiap layer, kita akan membuat beberapa model dengan mengatur beberapa parameter. Sebelum membangun arsitekturnya, kita atur initializer untuk memastikan hasil yang kita dapat tidak akan berubah.

set.seed(100)
initializer <- initializer_random_normal(seed = 100)

Buat model dan simpan dalam model_sign_mnist dengan mendefinisikan parameter-parameter di bawah ini: - layer pertama berisi 32 nodes, fungsi aktivasi relu, 784 input shape - layer kedua berisi 32 nodes, fungsi aktivasi relu - layer ketiga berisi 25 nodes, fungsi aktivasi softmax

model_sign_mnist <- keras_model_sequential() %>% 
  layer_dense(units = 32, activation = "relu", input_shape = c(784),
              kernel_initializer = initializer, bias_initializer = initializer) %>% 
  layer_dense(units = 32, activation = "relu",
              kernel_initializer = initializer, bias_initializer = initializer) %>% 
  layer_dense(units = 25, activation = "softmax", 
              kernel_initializer = initializer, bias_initializer = initializer)

2.3 Membangun Arsitektur

Mendefinisikan cost function dan optimizer.

Kita masih perlu melakukan beberapa pengaturan sebelum melatih model yang telah kita buat sebelumnya. Kita harus menyusun model dengan mendefinisikan loss function, jenis optimizer, dan metrik evaluasi. Gunakan compile model dengan menyetel parameter berikut:

  • categorical crossentropy sebagai loss function
  • adam sebagai pengoptimal dengan learning rate 0.001
  • gunakan accuracy sebagai metrik evaluasi
model_sign_mnist %>% 
  compile(loss = "categorical_crossentropy", 
          optimizer = optimizer_adam(lr = 0.001),   
          metrics = "accuracy")

2.4 Fitting model di Data Train

Mendefinisikan epoch dan ukuran batch

Pada tahap ini, kita fit model menggunakan epoch = 25 dan batch_size = 100 untuk model. Lalu simpan model ke dalam obyek history_sign_mnist.

history_sign_mnist <- model_sign_mnist %>%
  fit(train_x.keras, train_y.keras, epoch = 25, batch_size = 100)

3 Prediksi ke Data Test

Untuk mengevaluasi performa model terhadap data yang belum dilihat, kita akan memprediksi data test (test_x.keras) menggunakan model yang sudah dilatih. Kita prediksi menggunakan fungsi predict_classes() dari package keras dan simpan sebagai pred_sign_mnist.

pred_sign_mnist <- keras::predict_classes(object = model_sign_mnist, x= test_x.keras)

4 Evaluasi Model Neural Network

Karena label masih bertipe dbl, maka kita lakukan decode label tersebut berdasarkan kategorinya.

decode <- function(data){
  sapply(as.character(data), switch,
       "0" = "A",
       "1" = "B",
       "2" = "C",
       "3" = "D",
       "4" = "E",
       "5" = "F",
       "6" = "G",
       "7" = "H",
       "8" = "I",
       "9" = "J",
       "10" = "K",
       "11" = "L",
       "12" = "M",
       "13" = "N",
       "14" = "O",
       "15" = "P",
       "16" = "Q",
       "17" = "R",
       "18" = "S",
       "19" = "T",
       "20" = "U",
       "21" = "V",
       "22" = "W",
       "23" = "X",
       "24" = "Y",
       "25" = "Z")
}

Dekode pred_sign_mnist sebelum kita mengevaluasi performa model menggunakan confusion matrix. Kita juga perlu mendekode vektor test_y untuk mendapatkan label yang sebenarnya atau bernilai true yang didekode dari variabel target.

reference <- decode(test_y)
pred_decode <- decode(pred_sign_mnist)

4.1 Confusion Matrix

# confusion matrix
confusionMatrix(as.factor(pred_sign_mnist), as.factor(test_y))
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   0   1   2   3   4   5   6   7   8  10  11  12  13  14  15  16  17
##         0  331   0   0   0  36   0   0   0  33   0   0   0  56   0   1  21   0
##         1    0 362   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
##         2    0   0 282   0   0   2   0   0   0   0   0   0   0  20   0   0   0
##         3    0   0   0 130   0   2   0   0   3   0   0   0   0   0   0   0   0
##         4    0   0   0   0 382   0   0   0   0   0   0  55  21  19   0   0   0
##         5    0   0   5   0   0 121   0   0   0   0   0   0   0   1   0   0   0
##         6    0   0   0   0   0   0 168  21   0   0  21   0   0   2   5   0   0
##         7    0   0   0   0   0   0  66 304   5   0   0  14   0   5   5   0   0
##         8    0  10   0  16   0  18  12  58 141  21   0   6   4   0  17   0  37
##         10   0  22   0   0   0   2   0   0   0  81   0   0   0   0   0   0  21
##         11   0   0   0   0   0  28   0   0   0  21 172   0   0   0   0   0  17
##         12   0   0   0   0  24   0   0   0   0   0   0  75   1   0   0   2   0
##         13   0   0   0   0  12   0   0   0   0   0   0 100 107   0   0   0   0
##         14   0   0   2   0   0   0  28  42   0   0   0  18  40 159   0   0   0
##         15   0   0   0   0   0   0  13   0   0  21   0   0   0   0 277   2   0
##         16   0   0   0   0   0   0  43   2   5   0   0  18   6  34  13 139   0
##         17   0  16   0  25   0   0   0   0  19  45   0   0   0   0   0   0   1
##         18   0   0   0  19  44   0   0   0  23   3   0 108  39   0   3   0   0
##         19   0   0  21   0   0  41  16   9   0   0  16   0  17   6   0   0   4
##         20   0   3   0   9   0   0   0   0  21   0   0   0   0   0   0   0   0
##         21   0   0   0  19   0  19   2   0   1  60   0   0   0   0   5   0   7
##         22   0  19   0   0   0  13   0   0   0  22   0   0   0   0  20   0  54
##         23   0   0   0  27   0   0   0   0   0   0   0   0   0   0   1   0   0
##         24   0   0   0   0   0   1   0   0  37  57   0   0   0   0   0   0   3
##           Reference
## Prediction  18  19  20  21  22  23  24
##         0    4   0   0   0   0   0   0
##         1    0   0   0   0   0   0   0
##         2    0   0   0   0   0   0   0
##         3    0   0   2   0   0   0   0
##         4   35   0   0   0   0   0   0
##         5    0   0   0  20   0   0   0
##         6    0  40   0   2   0   0   0
##         7    0  25   0   0   0   0   5
##         8   77  57   8   1  15   9  79
##         10   0   0   5  34  17   0   0
##         11   0   0   3   1   0   8  41
##         12  42   0   0   0   0   0   0
##         13   6   4   0   0   0  12   0
##         14   0   0   0   0   0   0   0
##         15   0   0   0  32   0   0   0
##         16   6   2   0   0   0   3   0
##         17   0   0  73  60  14   0   0
##         18  76   0   0   0   0  21   1
##         19   0  98   0  37   6  13  16
##         20   0   0  74   0  29   0   0
##         21   0   4  57 147  20   2  23
##         22   0   0   0  12 105  52   0
##         23   0  18   0   0   0 147   0
##         24   0   0  44   0   0   0 167
## 
## Overall Statistics
##                                           
##                Accuracy : 0.5641          
##                  95% CI : (0.5526, 0.5757)
##     No Information Rate : 0.0694          
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.5443          
##                                           
##  Mcnemar's Test P-Value : NA              
## 
## Statistics by Class:
## 
##                      Class: 0 Class: 1 Class: 2 Class: 3 Class: 4 Class: 5
## Sensitivity           1.00000  0.83796  0.90968  0.53061  0.76707  0.48988
## Specificity           0.97793  1.00000  0.99679  0.99899  0.98052  0.99625
## Pos Pred Value        0.68672  1.00000  0.92763  0.94891  0.74609  0.82313
## Neg Pred Value        1.00000  0.98972  0.99592  0.98365  0.98258  0.98206
## Prevalence            0.04615  0.06023  0.04322  0.03416  0.06944  0.03444
## Detection Rate        0.04615  0.05047  0.03932  0.01813  0.05326  0.01687
## Detection Prevalence  0.06721  0.05047  0.04239  0.01910  0.07139  0.02050
## Balanced Accuracy     0.98896  0.91898  0.95324  0.76480  0.87379  0.74306
##                      Class: 6 Class: 7 Class: 8 Class: 10 Class: 11 Class: 12
## Sensitivity           0.48276  0.69725  0.48958   0.24471   0.82297   0.19036
## Specificity           0.98666  0.98144  0.93536   0.98524   0.98291   0.98982
## Pos Pred Value        0.64865  0.70862  0.24061   0.44505   0.59107   0.52083
## Neg Pred Value        0.97396  0.98042  0.97768   0.96423   0.99462   0.95461
## Prevalence            0.04852  0.06079  0.04016   0.04615   0.02914   0.05494
## Detection Rate        0.02342  0.04239  0.01966   0.01129   0.02398   0.01046
## Detection Prevalence  0.03611  0.05982  0.08171   0.02538   0.04057   0.02008
## Balanced Accuracy     0.73471  0.83935  0.71247   0.61497   0.90294   0.59009
##                      Class: 13 Class: 14 Class: 15 Class: 16 Class: 17
## Sensitivity            0.36770   0.64634   0.79827   0.84756 0.0069444
## Specificity            0.98053   0.98123   0.99004   0.98116 0.9641434
## Pos Pred Value         0.44398   0.55017   0.80290   0.51292 0.0039526
## Neg Pred Value         0.97345   0.98736   0.98975   0.99638 0.9793323
## Prevalence             0.04057   0.03430   0.04838   0.02287 0.0200781
## Detection Rate         0.01492   0.02217   0.03862   0.01938 0.0001394
## Detection Prevalence   0.03360   0.04030   0.04810   0.03779 0.0352761
## Balanced Accuracy      0.67411   0.81379   0.89415   0.91436 0.4855439
##                      Class: 18 Class: 19 Class: 20 Class: 21 Class: 22
## Sensitivity            0.30894   0.39516   0.27820   0.42486   0.50971
## Specificity            0.96232   0.97083   0.99102   0.96792   0.97244
## Pos Pred Value         0.22552   0.32667   0.54412   0.40164   0.35354
## Neg Pred Value         0.97513   0.97817   0.97271   0.97076   0.98531
## Prevalence             0.03430   0.03458   0.03709   0.04824   0.02872
## Detection Rate         0.01060   0.01366   0.01032   0.02050   0.01464
## Detection Prevalence   0.04699   0.04183   0.01896   0.05103   0.04141
## Balanced Accuracy      0.63563   0.68299   0.63461   0.69639   0.74107
##                      Class: 23 Class: 24
## Sensitivity            0.55056   0.50301
## Specificity            0.99334   0.97924
## Pos Pred Value         0.76166   0.54045
## Neg Pred Value         0.98281   0.97596
## Prevalence             0.03723   0.04629
## Detection Rate         0.02050   0.02328
## Detection Prevalence   0.02691   0.04308
## Balanced Accuracy      0.77195   0.74113

DAri hasil model model_sign_mnist :

Accuracy di data train : 0.8803 (88%) Accuracy di data test : 0.6274 (62%)

Karena terdapat perbedaan selisih antara data train dan data test maka bisa di katakan model kita overvitting (karena accuracy di data test lebih kecil dari accuracy di data train). Untuk itu kita perlu melakukan Tuning Model.

4.2 Tuning Model

Kita ingin mendapatkan model terbaik, jadi kita dapat membandingkan satu model dengan model lainnya (simpan sebagai model_tuning). Sekarang, mari kita coba membangun model_tuning dengan menyesuaikannya saat compile model: - Menggunakan adam sebagai optimizer dengan learning rate 0,001 - Yang lainnya sama dengan model_sign_mnist

Dan dengan mendefinisikan parameter-parameter di bawah ini: - layer pertama berisi 64 nodes, fungsi aktivasi relu, 784 input shape - layer kedua berisi 64 nodes, fungsi aktivasi relu - layer ketiga berisi 25 nodes, fungsi aktivasi softmax

model_tuning <- keras_model_sequential() %>% 
  layer_dense(units = 64, activation = "relu", input_shape = c(784)) %>% 
  layer_dense(units = 64, activation = "relu") %>% 
  layer_dense(units = 25, activation = "softmax")

model_tuning %>% 
  compile(loss = "categorical_crossentropy", 
          optimizer = optimizer_adam(lr = 0.001), 
          metrics = "accuracy")

history_tuning <- model_tuning %>%
  fit(train_x.keras, train_y.keras, epochs = 25, batch_size = 100)

Setelah tuning model, kemudian prediksi test_x.keras.

pred_tuning <- keras::predict_classes(object = model_tuning, x= test_x.keras)

Kemudian, dekode pred_tuning dan periksa performa model menggunakan confusionMatrix().

pred_decode_tun <- decode(pred_tuning)
confusionMatrix(as.factor(pred_tuning), as.factor(test_y))
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   0   1   2   3   4   5   6   7   8  10  11  12  13  14  15  16  17
##         0  302   0   0   0   0   0   0   0   0   0   0   7  42   0   0   0   0
##         1    0 391   0   1   0   0   0   4   0   0   0   0   0   0   0   0   0
##         2    0   0 288   0   0   0   0   0   0   0   0   0   0  21   0   0   0
##         3    0   0   0 220   0   0   0   0   0   0   0   0   0   0   0   0   0
##         4    0   0   0   0 455   0   0   0   0   0   0  37   3  21   0   0   0
##         5    0   1  21   0   0 220   0   0   0  46   0   0   0   0   0   6   0
##         6    0   0   0   0   0   2 296  24   0   0   0   0  21  24  16   0   0
##         7    0   0   0   0   0   0  18 349   0   0   0  13   0   0   0   0   0
##         8    0   0   0   0   0   0   0   0 235   0   0   0  15   0   8   0   0
##         10   0   0   0   0   0   7   0   0   0 134   0   0   0   0   0   0   0
##         11   0   0   0   0   0   3   0   0  18   0 179   0   0   0   0   0   1
##         12   0   0   0   0   0   0   0  21   0  20   0 216   1   0   0  16   0
##         13  17   0   0   0   0   0   0   0   0   0   0  25 166   0   0   0   0
##         14  12   0   0   0   0   0   0   0   0   0   0   0  21 158   0   0   0
##         15   0   0   0   0   0   0   3   0   0   0   9   0   0   0 317   0   0
##         16   0   0   0   0   0   0  31   0   0   0   0   4  22   5   6 142   0
##         17   0   7   0   1   0   0   0   0   3  20   0   0   0   0   0   0  87
##         18   0   0   0   0  43   0   0  19  11  21   0  92   0   0   0   0   0
##         19   0   0   1   0   0  15   0   3   0   0  21   0   0  17   0   0   0
##         20   0  33   0   0   0   0   0  16   0  50   0   0   0   0   0   0  36
##         21   0   0   0   3   0   0   0   0   0   2   0   0   0   0   0   0  20
##         22   0   0   0   0   0   0   0   0   0  17   0   0   0   0   0   0   0
##         23   0   0   0  20   0   0   0   0   0   4   0   0   0   0   0   0   0
##         24   0   0   0   0   0   0   0   0  21  17   0   0   0   0   0   0   0
##           Reference
## Prediction  18  19  20  21  22  23  24
##         0    0   0   0   0   0   0   0
##         1    0   0   0   0   0   0   9
##         2    0   0   0   0  12   0   0
##         3    2   0   9   1   0   0   0
##         4   21   0   0   0   0   0   0
##         5    0   0   0  20   0   3   0
##         6    0   4   0   0   9   0   0
##         7   20  19   0   0   0   0   0
##         8   21   0   0   0   0   0  12
##         10   0   0  55  24   0   0  13
##         11   0   0   0   0   0   4  41
##         12  41   0   0   0   0   0   0
##         13  20   0   0   0   0   0  19
##         14   1  20   0   0   0   0   0
##         15   0   0   0  20   0   4   0
##         16   0   0   0   0   0   0   0
##         17   0   0   1   0  19   0   0
##         18 120   0   0   0   0  17  20
##         19   0 139   0   0   0   0  21
##         20   0   0 170  34  21   0   0
##         21   0   0  22 214  21   0  19
##         22   0   4   0  33 124  37   0
##         23   0  62   0   0   0 202   0
##         24   0   0   9   0   0   0 178
## 
## Overall Statistics
##                                           
##                Accuracy : 0.7393          
##                  95% CI : (0.7289, 0.7494)
##     No Information Rate : 0.0694          
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.7271          
##                                           
##  Mcnemar's Test P-Value : NA              
## 
## Statistics by Class:
## 
##                      Class: 0 Class: 1 Class: 2 Class: 3 Class: 4 Class: 5
## Sensitivity           0.91239  0.90509  0.92903  0.89796  0.91365  0.89069
## Specificity           0.99284  0.99792  0.99519  0.99827  0.98771  0.98599
## Pos Pred Value        0.86040  0.96543  0.89720  0.94828  0.84730  0.69401
## Neg Pred Value        0.99575  0.99394  0.99679  0.99640  0.99352  0.99606
## Prevalence            0.04615  0.06023  0.04322  0.03416  0.06944  0.03444
## Detection Rate        0.04211  0.05452  0.04016  0.03067  0.06344  0.03067
## Detection Prevalence  0.04894  0.05647  0.04476  0.03235  0.07487  0.04420
## Balanced Accuracy     0.95261  0.95151  0.96211  0.94811  0.95068  0.93834
##                      Class: 6 Class: 7 Class: 8 Class: 10 Class: 11 Class: 12
## Sensitivity           0.85057  0.80046  0.81597   0.40483   0.85646   0.54822
## Specificity           0.98535  0.98961  0.99187   0.98553   0.99038   0.98539
## Pos Pred Value        0.74747  0.83294  0.80756   0.57511   0.72764   0.68571
## Neg Pred Value        0.99233  0.98712  0.99230   0.97161   0.99567   0.97404
## Prevalence            0.04852  0.06079  0.04016   0.04615   0.02914   0.05494
## Detection Rate        0.04127  0.04866  0.03277   0.01868   0.02496   0.03012
## Detection Prevalence  0.05521  0.05842  0.04057   0.03249   0.03430   0.04392
## Balanced Accuracy     0.91796  0.89503  0.90392   0.69518   0.92342   0.76681
##                      Class: 13 Class: 14 Class: 15 Class: 16 Class: 17
## Sensitivity            0.57045   0.64228   0.91354   0.86585   0.60417
## Specificity            0.98823   0.99220   0.99473   0.99030   0.99274
## Pos Pred Value         0.67206   0.74528   0.89802   0.67619   0.63043
## Neg Pred Value         0.98195   0.98736   0.99560   0.99684   0.99190
## Prevalence             0.04057   0.03430   0.04838   0.02287   0.02008
## Detection Rate         0.02315   0.02203   0.04420   0.01980   0.01213
## Detection Prevalence   0.03444   0.02956   0.04922   0.02928   0.01924
## Balanced Accuracy      0.77934   0.81724   0.95413   0.92808   0.79845
##                      Class: 18 Class: 19 Class: 20 Class: 21 Class: 22
## Sensitivity            0.48780   0.56048   0.63910   0.61850   0.60194
## Specificity            0.96780   0.98873   0.97249   0.98725   0.98694
## Pos Pred Value         0.34985   0.64055   0.47222   0.71096   0.57674
## Neg Pred Value         0.98155   0.98433   0.98591   0.98079   0.98821
## Prevalence             0.03430   0.03458   0.03709   0.04824   0.02872
## Detection Rate         0.01673   0.01938   0.02370   0.02984   0.01729
## Detection Prevalence   0.04782   0.03026   0.05020   0.04197   0.02998
## Balanced Accuracy      0.72780   0.77461   0.80579   0.80288   0.79444
##                      Class: 23 Class: 24
## Sensitivity            0.75655   0.53614
## Specificity            0.98755   0.99313
## Pos Pred Value         0.70139   0.79111
## Neg Pred Value         0.99056   0.97783
## Prevalence             0.03723   0.04629
## Detection Rate         0.02817   0.02482
## Detection Prevalence   0.04016   0.03137
## Balanced Accuracy      0.87205   0.76464

Setelah dilakukan tunning model, maka di dapatkan :

Accuracy di data train : 0.9988 (99%) Accuracy di data test : 0.7137 (71%)

5 Kesimpulan

Dari 2 model yang telah kita buat model_sign_mnist dan model_tuning didapatkan kesimpulan bahwa model_tuning dapat di katakan lebih baik di bandingkan model_sign_mnist baik dari nilai Accuracy di data train maupun nilai Accuracy di data test.