LBB: Neural Network and Deep Learning


1. Pendahuluan

library(neuralnet)
library(dplyr)
library(keras)
library(caret)

options(scipen = 100, max.print = 1e+06)

Pada LBB (Learning by Building) ini akan dibuat model klasifikasi untuk mengklafisikasikan kategori dari gambar bahasa isyarat (sign language) menggunakan algoritma Neural Network menggunakan framework keras menggunakan data dari (https://www.kaggle.com/datamunge/sign-language-mnist).

2. Mengimport Data

Hal paling pertama yang harus dilakukan adalah pastikan lokasi folder dataset yang ingin diinput sama dengan Rmd ini. Kemudian, lanjut dengan read dataset.

# your code here
sign_train <- read.csv("sign_mnist_train.csv")
sign_test <- read.csv("sign_mnist_test.csv")

Dataset telah terbaca dan terinput dengan nama sign_train dan sign_test. Untuk mengetahui isi dataset tersebut, lakukan ke tahap selanjutnya yaitu dengan cara menginspeksi data.

3. Menginspeksi Data

head(sign_train,3)
head(sign_test,3)

Kemudian, cek missing value apakah ada atau tidak

anyNA(sign_train)
#> [1] FALSE
anyNA(sign_test)
#> [1] FALSE

Terlihat bahwa tidak ada missing value, sehingga data siap diolah ke tahap selanjutnya.

4. Mengolah Data

Cek label dari tiap data sign_train dan sign_test

table(sign_train$label)
#> 
#>    0    1    2    3    4    5    6    7    8   10   11   12   13   14   15   16 
#> 1126 1010 1144 1196  957 1204 1090 1013 1162 1114 1241 1055 1151 1196 1088 1279 
#>   17   18   19   20   21   22   23   24 
#> 1294 1199 1186 1161 1082 1225 1164 1118
table(sign_test$label)
#> 
#>   0   1   2   3   4   5   6   7   8  10  11  12  13  14  15  16  17  18  19  20 
#> 331 432 310 245 498 247 348 436 288 331 209 394 291 246 347 164 144 246 248 266 
#>  21  22  23  24 
#> 346 206 267 332

Karena label 9 dan 25 tidak ada, kita dapat mengurangkan dengan 1 semua label yang bernilai lebih besar dari 9. Dengan cara ini, label kita menjadi semua bilangan bulat dari 0 hingga 23. Anda dapat memanfaatkan fungsi mutate() dan ifelse() untuk memperbaiki kategori pada target variabel baik pada data sign_train dan sign_test.

Gunakan code di bawah ini untuk memperbaiki kategori target variabel pada data sign_train dan sign_test.

sign_train <- sign_train %>% 
  mutate(label = ifelse(label > 9, label-1, label))

sign_test <- sign_test %>% 
  mutate(label = ifelse(label > 9, label-1, label))

Cek kembali apakah sudah berubah

table(sign_train$label)
#> 
#>    0    1    2    3    4    5    6    7    8    9   10   11   12   13   14   15 
#> 1126 1010 1144 1196  957 1204 1090 1013 1162 1114 1241 1055 1151 1196 1088 1279 
#>   16   17   18   19   20   21   22   23 
#> 1294 1199 1186 1161 1082 1225 1164 1118
table(sign_test$label)
#> 
#>   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19 
#> 331 432 310 245 498 247 348 436 288 331 209 394 291 246 347 164 144 246 248 266 
#>  20  21  22  23 
#> 346 206 267 332

Dan ternyata sudah berubah, kemudian ke tahap selanjutnya.

Memisahkan prediktor dan target, mengubah data ke dalam matriks, dan features scaling

Data berisi nilai pixel yang disimpan dalam data frame, harus dipisahkan prediktor dan target untuk data sign_train dan sign_test dan menyimpannya ke dalam train_x, train_y, test_x, dan test_y. Digunakan fungsi select() untuk memisahkan prediktor dan target pada data sign_train dan sign_test.

Setelah itu, data train_x, train_y, test_x, dan test_y harus diubah menjadi matriks menggunakan fungsi data.matrix(). Khusus untuk prediktor variabel yang disimpan pada train_x dan test_x lakukan features scaling dengan cara membaginya dengan range.

range(sign_train[,-1])
#> [1]   0 255

Diperoleh range nya adalah 255

# Predictor variables in `sign_train`
train_x <- sign_train %>% 
  select(-label) %>% # untuk memisahkan target dengan prediktor
  as.matrix()/255 # untuk mengubah dalam bentuk matrix dan melakukan scaling dengan /255

# Predictor variables in `sign_test`
test_x <- sign_test %>% 
  select(-label) %>% 
  as.matrix()/255

# Target variable in `sign_train`
train_y <- sign_train$label

# Target variable in `sign_test`
test_y <- sign_test$label

Mengubah matriks menjai array

Selanjutnya, diubah matriks prediktor ke dalam bentuk array menggunakan fungsi array_reshape(data, dim(data)) untuk mengubah matriks prediktor menjadi array.

# Predictor variables in `train_x`
train_x_array <- array_reshape(train_x, dim=dim(train_x))

# Predictor variables in `test_x`
test_x_array <- array_reshape(test_x, dim=dim(test_x))

Kemudian dilakukan one-hot encoding terhadap target variabel pada data train (train_y) menggunakan fungsi to_categorical() dari library Keras, kemudian simpan sebagai objek train_y_dummy.

# Target variable in `train_y`
train_y_dummy <- to_categorical(train_y, num_classes = 24)

5. Membuat Model

Membuat sebuah model dasar menggunakan keras_model_sequential()

Untuk mengatur layer, dibuat model dasar, yaitu model sequential. Panggil fungsi keras_model_sequential(), dan gunakan operator pipe untuk membangun arsitektur model dari model dasar yang ada.

Membangun Arsitektur (menentukan layer, neuron, dan fungsi aktivasi)

Untuk membangun arsitektur tiap layer, dibuat beberapa model dengan mengatur beberapa parameter. Sebelum membangun arsitekturnya, atur initializer untuk memastikan hasil yang diperoleh tidak akan berubah.

RNGkind(sample.kind = "Rounding")
set.seed(100)
initializer <- initializer_random_normal(seed = 100)
input_dim <- ncol(train_x)
num_class <- n_distinct(sign_train$label)

Pertama, buat model (simpan dalam model_base) dengan mendefinisikan parameter-parameter di bawah ini: - layer pertama berisi 64 nodes, fungsi aktivasi relu, 784 input shape - layer kedua berisi 32 nodes, fungsi aktivasi relu - layer ketiga berisi 24 nodes, fungsi aktivasi softmax

# your code here
model_base <- keras_model_sequential(name="model_base") %>% 
  
  # input layer + hidden layer pertama
  layer_dense(units = 64, # jumlah nodes pada hidden 1,
              input_shape = 784,        # Input_shape hanya digunakan untuk layer pertama saja
              activation = "relu", # actvation function
              name = "hidden_1") %>% 
  
  # hidden layer kedua
  layer_dense(units = 32,
              activation = "relu",
              name = "hidden_2") %>% 
  
  # output layer
  layer_dense(units = 24, # jumlah kelas target, sesuai jumlah kategori
              activation = "softmax", # untuk multikelas
              name = "ouput")
model_base
#> Model: "model_base"
#> ________________________________________________________________________________
#>  Layer (type)                       Output Shape                    Param #     
#> ================================================================================
#>  hidden_1 (Dense)                   (None, 64)                      50240       
#>  hidden_2 (Dense)                   (None, 32)                      2080        
#>  ouput (Dense)                      (None, 24)                      792         
#> ================================================================================
#> Total params: 53,112
#> Trainable params: 53,112
#> Non-trainable params: 0
#> ________________________________________________________________________________

Kedua, buatlah sebuah model (simpan ke dalam model_bigger) dengan mendefinisikan parameter di bawah ini: - layer pertama berisi 256 node, fungsi aktivasi relu, 784 input shape - layer kedua berisi 128 node, fungsi aktivasi relu - layer ketiga berisi 64 node, fungsi aktivasi relu - layer keempat berisi 24 node, fungsi aktivasi softmax

# your code here
model_bigger <- keras_model_sequential(name="model_bigger") %>% 
  
  # input layer + hidden layer pertama
  layer_dense(units = 256, # jumlah nodes pada hidden 1,
              input_shape = 784,        # Input_shape hanya digunakan untuk layer pertama saja
              activation = "relu", # actvation function
              name = "hidden_1") %>% 
  
  # hidden layer kedua
  layer_dense(units = 128,
              activation = "relu",
              name = "hidden_2") %>% 
  
  # hidden layer ketiga
  layer_dense(units = 64,
              activation = "relu",
              name = "hidden_3") %>% 
  
  # output layer
  layer_dense(units = 24, # jumlah kelas target
              activation = "softmax", # untuk multikelas
              name = "ouput")
model_bigger
#> Model: "model_bigger"
#> ________________________________________________________________________________
#>  Layer (type)                       Output Shape                    Param #     
#> ================================================================================
#>  hidden_1 (Dense)                   (None, 256)                     200960      
#>  hidden_2 (Dense)                   (None, 128)                     32896       
#>  hidden_3 (Dense)                   (None, 64)                      8256        
#>  ouput (Dense)                      (None, 24)                      1560        
#> ================================================================================
#> Total params: 243,672
#> Trainable params: 243,672
#> Non-trainable params: 0
#> ________________________________________________________________________________

Membangun arsitektur (menentukan cost function dan optimizer)

Dilakukan compile model terhadap model_base dan model_bigger dengan menggunakan parameter berikut: - categorical_crossentropy sebagai loss function - optimizer_adam sebagai optimizer dengan learning rate 0.001 - gunakan accuracy sebagai metrik evaluasi

# your code here
model_base %>% 
  compile(loss = "sparse_categorical_crossentropy",
          optimizer = optimizer_adam(learning_rate = 0.001),
          metrics = "accuracy")
model_bigger %>% 
  compile(loss = "sparse_categorical_crossentropy",
          optimizer = optimizer_adam(learning_rate = 0.001),
          metrics = "accuracy")

Fitting model di data train (mengatur epoch dan ukuran batch)

Pada tahap ini, fit model menggunakan epoch = 10, batch_size = 150, dan menambahkan parameter shuffle = F agar sampel pada tiap batch tidak diambil secara random melainkan terurut (sequence) untuk model_base dan model_bigger.

# your code here
history_base <- model_base %>% 
   fit(x = train_x,
      y = train_y,
      epoch = 10,
      batch_size = 150,
      shuffle = F,
      validation_data = list(test_x, test_y),
      verbose = 1)

plot(history_base)

# your code here
history_bigger <- model_bigger %>% 
  fit(train_x, train_y,
      epoch = 10,
      batch_size = 150,
      shuffle = F,
      verbose = 1)

plot(history_bigger)

Prediksi ke data test

# your code here
pred_base <- predict(model_base, test_x_array) %>% 
  k_argmax() %>% 
  as.array() %>% 
  as.factor()
pred_bigger <- predict(model_bigger, test_x_array) %>% 
  k_argmax() %>% 
  as.array() %>% 
  as.factor()

6. Evaluasi model neural network

Confusion Matrix (klasifikasi)

library(caret)
confusionMatrix(data=pred_base, reference = as.factor(sign_test$label))
#> Confusion Matrix and Statistics
#> 
#>           Reference
#> Prediction   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16
#>         0  298   0   0   0  24   0   0   0   2   0   0   9  41   0   0   0   0
#>         1    0 324   0   1   9   0   0   0   0   0   0   0   0   0   0   0   0
#>         2    0   0 263   0   0   0   0   0   0   0   0   0   0   0   0   0   0
#>         3    0   0   0 197   0   0   0   0   0   0   0   0  26   0   0   0   0
#>         4    0   0   0   0 334   0   0  21   0   0   0  17  21   2   0   0   0
#>         5    0   0  21   0   0 176   2   0  16   0   0   0   0  45  21   0   0
#>         6    0   0   0   0   0   0 168  20   0   0   0   0   0  10   0   0   0
#>         7    0   0   0   0   0   0  43 384  21   0   0   0   0   4   0   0   0
#>         8    6   0   0   0   0   0  22   0 143   0   0   6  13   0   3   0   0
#>         9    0  61   0   0   0  38   0   0   0 205   0   0   0   0   0   0   6
#>         10   0   0   5   0   0   0  18   0   0   0 209   0   0   0   0   0  21
#>         11   0   0   0   0  62   0   0   4   0   0   0 157   0   0   0  21   0
#>         12   0   0   0   0   0   0   8   0   1   0   0 104 106   0   0   4   0
#>         13  22   0   0   0   0   0   3   4   0   0   0  21  26 141   0   0   0
#>         14   0   0   0   0   0   0   0   0   0   0   0   0   0   0 255   0   0
#>         15   0   0   0   0   0   0  25   0   0   0   0   4  20   7  26 139   0
#>         16   0   8   0   3   0   0   0   0  26  85   0   0   0   0   0   0  81
#>         17   0   0   0   0  69   0   0   0   3   0   0  72  22   0   0   0   0
#>         18   0   0   0   0   0  26  53   0   0   0   0   0  16  37   0   0   0
#>         19   0  39   0  22   0   0   0   1   0   0   0   0   0   0   0   0  17
#>         20   0   0   0   1   0   4   0   0   0   0   0   0   0   0   5   0   3
#>         21   0   0   0   0   0   3   0   0   0   0   0   0   0   0  22   0   0
#>         22   0   0  21  21   0   0   6   2   0   0   0   0   0   0  15   0   0
#>         23   5   0   0   0   0   0   0   0  76  41   0   4   0   0   0   0  16
#>           Reference
#> Prediction  17  18  19  20  21  22  23
#>         0    1   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  41   5  11   0   0
#>         4   21   0   0   0   0   0   0
#>         5    0   0   0  20   0   0   0
#>         6    0   0   0   0   0   0   0
#>         7   20   9   0   0  21   0   0
#>         8   32   0   0   0   0   2  10
#>         9    0   0  70  72  46   5  21
#>         10   0  60  30   0   0  21  39
#>         11  62   0   0   0   0   0   0
#>         12  16   0   0   0   0   0   0
#>         13   0   0   0   0   0   0   0
#>         14   0   2   0   0   0   0   0
#>         15   1   0   0   0   0   1   0
#>         16   0   0  58  46  44  16   3
#>         17  72   0   0   0   0  10   8
#>         18   0  57   0   0   0   0  21
#>         19   0  20  64   1   9   0   0
#>         20   0   0   0 159  17   0  21
#>         21   0   0   0   0  58  37   0
#>         22   0  79   0  18   0 164   0
#>         23  21  21   3  25   0  11 209
#> 
#> Overall Statistics
#>                                                
#>                Accuracy : 0.6083               
#>                  95% CI : (0.5969, 0.6197)     
#>     No Information Rate : 0.0694               
#>     P-Value [Acc > NIR] : < 0.00000000000000022
#>                                                
#>                   Kappa : 0.5906               
#>                                                
#>  Mcnemar's Test P-Value : NA                   
#> 
#> Statistics by Class:
#> 
#>                      Class: 0 Class: 1 Class: 2 Class: 3 Class: 4 Class: 5
#> Sensitivity           0.90030  0.75000  0.84839  0.80408  0.67068  0.71255
#> Specificity           0.98874  0.99852  1.00000  0.98802  0.98771  0.98195
#> Pos Pred Value        0.79467  0.97006  1.00000  0.70357  0.80288  0.58472
#> Neg Pred Value        0.99514  0.98421  0.99320  0.99304  0.97573  0.98967
#> Prevalence            0.04615  0.06023  0.04322  0.03416  0.06944  0.03444
#> Detection Rate        0.04155  0.04518  0.03667  0.02747  0.04657  0.02454
#> Detection Prevalence  0.05229  0.04657  0.03667  0.03904  0.05800  0.04197
#> Balanced Accuracy     0.94452  0.87426  0.92419  0.89605  0.82920  0.84725
#>                      Class: 6 Class: 7 Class: 8 Class: 9 Class: 10 Class: 11
#> Sensitivity           0.48276  0.88073  0.49653  0.61934   1.00000   0.39848
#> Specificity           0.99560  0.98248  0.98635  0.95337   0.97214   0.97802
#> Pos Pred Value        0.84848  0.76494  0.60338  0.39122   0.51861   0.51307
#> Neg Pred Value        0.97419  0.99220  0.97909  0.98105   1.00000   0.96548
#> Prevalence            0.04852  0.06079  0.04016  0.04615   0.02914   0.05494
#> Detection Rate        0.02342  0.05354  0.01994  0.02858   0.02914   0.02189
#> Detection Prevalence  0.02761  0.06999  0.03305  0.07306   0.05619   0.04267
#> Balanced Accuracy     0.73918  0.93161  0.74144  0.78635   0.98607   0.68825
#>                      Class: 12 Class: 13 Class: 14 Class: 15 Class: 16
#> Sensitivity            0.36426   0.57317   0.73487   0.84756   0.56250
#> Specificity            0.98067   0.98903   0.99971   0.98801   0.95888
#> Pos Pred Value         0.44351   0.64977   0.99222   0.62332   0.21892
#> Neg Pred Value         0.97332   0.98490   0.98670   0.99640   0.99074
#> Prevalence             0.04057   0.03430   0.04838   0.02287   0.02008
#> Detection Rate         0.01478   0.01966   0.03555   0.01938   0.01129
#> Detection Prevalence   0.03332   0.03026   0.03583   0.03109   0.05159
#> Balanced Accuracy      0.67247   0.78110   0.86729   0.91779   0.76069
#>                      Class: 17 Class: 18 Class: 19 Class: 20 Class: 21
#> Sensitivity            0.29268  0.229839  0.240602   0.45954  0.281553
#> Specificity            0.97343  0.977903  0.984217   0.99253  0.991100
#> Pos Pred Value         0.28125  0.271429  0.369942   0.75714  0.483333
#> Neg Pred Value         0.97484  0.972565  0.971139   0.97314  0.979013
#> Prevalence             0.03430  0.034579  0.037089   0.04824  0.028723
#> Detection Rate         0.01004  0.007948  0.008924   0.02217  0.008087
#> Detection Prevalence   0.03569  0.029281  0.024122   0.02928  0.016732
#> Balanced Accuracy      0.63306  0.603871  0.612409   0.72603  0.636327
#>                      Class: 22 Class: 23
#> Sensitivity            0.61423   0.62952
#> Specificity            0.97654   0.96740
#> Pos Pred Value         0.50307   0.48380
#> Neg Pred Value         0.98495   0.98175
#> Prevalence             0.03723   0.04629
#> Detection Rate         0.02287   0.02914
#> Detection Prevalence   0.04545   0.06023
#> Balanced Accuracy      0.79539   0.79846
confusionMatrix(data=pred_bigger, reference = as.factor(sign_test$label))
#> Confusion Matrix and Statistics
#> 
#>           Reference
#> Prediction   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16
#>         0  331   0   0   0  28   0   0   0  18   0   0  17  63   0   0   7   0
#>         1    0 297   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
#>         2    0   0 285   0   0   1   0   0   0   0   0   0   0   0   0   0   0
#>         3    0  20   0 202   0   0   0   0   0   0   0   0   0   0   0   0   0
#>         4    0   0   0   0 407   0   0   1   0   0   0   0  21   0   0   0   0
#>         5    0   0  23   0   0 226   8   0   2   5   0   0   0  21   0   6   0
#>         6    0   0   0   0   0   0 200  15   0   0   0   0   0   1   0   0   0
#>         7    0   0   0   0   0   0  42 413   0   0   0   0   0   0   0   0   0
#>         8    0   0   0   0   0   0   0   0 182  20   0   0   0   0   0   0   8
#>         9    0  41   0   0   0   0   0   0   0 177   0   0   0   0   0   0   0
#>         10   0   0   0   0   0   0   0   0  19   0 197   0   0   0   0   0  21
#>         11   0   0   0   0   9   0   0   0   0   0   0 187   0   0   0   0   0
#>         12   0   0   0  19   0   0   0   0   0   0   0  44 103   0   0   0   5
#>         13   0   0   0   0   0   0   0   0   0   0   0   0  21 163   0   0   0
#>         14   0   0   0   0   0   0  21   0   0  37   0   0   0   0 347   0   0
#>         15   0   0   0   0   0   0  35   1   0   0   0  13  20   4   0 150   0
#>         16   0   0   0   0   0   0   0   0   0  70   0   0   0   0   0   0  90
#>         17   0  21   0   0  54   0   0   0  20   0   0 133  41  21   0   1   5
#>         18   0   0   2   2   0  20  42   6   0   0   5   0  22  36   0   0  11
#>         19   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   2
#>         20   0   1   0   0   0   0   0   0   0   1   0   0   0   0   0   0   0
#>         21   0  52   0   0   0   0   0   0   0   0   0   0   0   0   0   0   2
#>         22   0   0   0  22   0   0   0   0   5   0   7   0   0   0   0   0   0
#>         23   0   0   0   0   0   0   0   0  42  21   0   0   0   0   0   0   0
#>           Reference
#> Prediction  17  18  19  20  21  22  23
#>         0    0   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  20   0   0   0   0
#>         4   23   0   0   0   0   0   0
#>         5    0   4   0  41   0   0   0
#>         6    0   0   0   0   0   0   0
#>         7    0   0   0   0   0   0   0
#>         8   27   0   3   0   0   0   3
#>         9    0   0 102  13  19   0   0
#>         10   0   2   0   0   0   6  41
#>         11  41   0   0   0   0   0   0
#>         12   0   0   0   0   0   0   0
#>         13   1   0   0   0   0   0   0
#>         14   0   0   0  22   0   2   0
#>         15   0   0   0   0   0   6   0
#>         16   0   0  40   0  13   0   2
#>         17 133   0   0   0   0  22  20
#>         18   0 184   0  39   4   3  21
#>         19   0   0  25   0   8   0   0
#>         20   0   0  49 187  53   0  19
#>         21   0   0   0  22 108  39   0
#>         22   0  56   0   0   1 189   0
#>         23  21   2  27  22   0   0 226
#> 
#> Overall Statistics
#>                                                
#>                Accuracy : 0.6984               
#>                  95% CI : (0.6876, 0.709)      
#>     No Information Rate : 0.0694               
#>     P-Value [Acc > NIR] : < 0.00000000000000022
#>                                                
#>                   Kappa : 0.6847               
#>                                                
#>  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.68750  0.91935  0.82449  0.81727  0.91498
#> Specificity           0.98056  1.00000  0.99985  0.99423  0.99326  0.98412
#> Pos Pred Value        0.71336  1.00000  0.99650  0.83471  0.90044  0.67262
#> Neg Pred Value        1.00000  0.98036  0.99637  0.99380  0.98646  0.99693
#> Prevalence            0.04615  0.06023  0.04322  0.03416  0.06944  0.03444
#> Detection Rate        0.04615  0.04141  0.03974  0.02817  0.05675  0.03151
#> Detection Prevalence  0.06470  0.04141  0.03988  0.03374  0.06302  0.04685
#> Balanced Accuracy     0.99028  0.84375  0.95960  0.90936  0.90526  0.94955
#>                      Class: 6 Class: 7 Class: 8 Class: 9 Class: 10 Class: 11
#> Sensitivity           0.57471  0.94725  0.63194  0.53474   0.94258   0.47462
#> Specificity           0.99766  0.99376  0.99114  0.97442   0.98722   0.99262
#> Pos Pred Value        0.92593  0.90769  0.74897  0.50284   0.68881   0.78903
#> Neg Pred Value        0.97872  0.99658  0.98470  0.97742   0.99826   0.97015
#> Prevalence            0.04852  0.06079  0.04016  0.04615   0.02914   0.05494
#> Detection Rate        0.02789  0.05759  0.02538  0.02468   0.02747   0.02607
#> Detection Prevalence  0.03012  0.06344  0.03388  0.04908   0.03988   0.03305
#> Balanced Accuracy     0.78618  0.97051  0.81154  0.75458   0.96490   0.73362
#>                      Class: 12 Class: 13 Class: 14 Class: 15 Class: 16
#> Sensitivity            0.35395   0.66260   1.00000   0.91463   0.62500
#> Specificity            0.99012   0.99682   0.98799   0.98873   0.98221
#> Pos Pred Value         0.60234   0.88108   0.80886   0.65502   0.41860
#> Neg Pred Value         0.97315   0.98812   1.00000   0.99798   0.99224
#> Prevalence             0.04057   0.03430   0.04838   0.02287   0.02008
#> Detection Rate         0.01436   0.02273   0.04838   0.02091   0.01255
#> Detection Prevalence   0.02384   0.02579   0.05982   0.03193   0.02998
#> Balanced Accuracy      0.67203   0.82971   0.99399   0.95168   0.80361
#>                      Class: 17 Class: 18 Class: 19 Class: 20 Class: 21
#> Sensitivity            0.54065   0.74194  0.093985   0.54046   0.52427
#> Specificity            0.95120   0.96924  0.998552   0.98198   0.98349
#> Pos Pred Value         0.28238   0.46348  0.714286   0.60323   0.48430
#> Neg Pred Value         0.98314   0.99055  0.966232   0.97683   0.98590
#> Prevalence             0.03430   0.03458  0.037089   0.04824   0.02872
#> Detection Rate         0.01854   0.02566  0.003486   0.02607   0.01506
#> Detection Prevalence   0.06567   0.05535  0.004880   0.04322   0.03109
#> Balanced Accuracy      0.74592   0.85559  0.546268   0.76122   0.75388
#>                      Class: 22 Class: 23
#> Sensitivity            0.70787   0.68072
#> Specificity            0.98682   0.98026
#> Pos Pred Value         0.67500   0.62604
#> Neg Pred Value         0.98868   0.98444
#> Prevalence             0.03723   0.04629
#> Detection Rate         0.02635   0.03151
#> Detection Prevalence   0.03904   0.05033
#> Balanced Accuracy      0.84734   0.83049

Model Tuning

Karena kedua model belum memberikan performa yang cukup baik (best fit) dimana model_base cenderung underfitting dan model_bigger cenderung overfitting, maka akan dilakukan perbaikan pada model_bigger. Sekarang, akan dicoba membangun model_tuning dengan mengatur parameter sebagai berikut: - layer pertama berisi 128 nodes, fungsi aktivasi relu, 784 input shape - layer kedua berisi 64 nodes, fungsi aktivasi relu - layer ketiga berisi 24 nodes, fungsi aktivasi softmax

# your code here
model_tuning <- keras_model_sequential(name="model_tuning") %>% 
  
  # input layer + hidden layer pertama
  layer_dense(units = 128, # jumlah nodes pada hidden 1,
              input_shape = 784,        # Input_shape hanya digunakan untuk layer pertama saja
              activation = "relu", # actvation function
              name = "hidden_1") %>% 
  
  # hidden layer kedua
  layer_dense(units = 64,
              activation = "relu",
              name = "hidden_2") %>% 
  
  # output layer
  layer_dense(units = 24, # jumlah kelas target, sesuai jumlah kategori
              activation = "softmax", # untuk multikelas
              name = "ouput")
model_tuning
#> Model: "model_tuning"
#> ________________________________________________________________________________
#>  Layer (type)                       Output Shape                    Param #     
#> ================================================================================
#>  hidden_1 (Dense)                   (None, 128)                     100480      
#>  hidden_2 (Dense)                   (None, 64)                      8256        
#>  ouput (Dense)                      (None, 24)                      1560        
#> ================================================================================
#> Total params: 110,296
#> Trainable params: 110,296
#> Non-trainable params: 0
#> ________________________________________________________________________________

Kemudian, akan dilakukan compile model dengan menggunakan parameter berikut: - categorical_crossentropy sebagai loss function - optimizer_adam sebagai optimizer dengan learning rate 0.001 - gunakan accuracy sebagai metrik evaluasi

# your code here
model_tuning %>% 
  compile(loss = "sparse_categorical_crossentropy",
          optimizer = optimizer_adam(learning_rate = 0.001),
          metrics = "accuracy")

Terakhir, fit model menggunakan epoch = 10, batch_size = 150, dan menambahkan parameter shuffle = F agar sampel pada tiap batch tidak diambil secara random melainkan terurut (sequence)

# your code here
history_tuning <- model_tuning %>% 
   fit(x = train_x,
      y = train_y,
      epoch = 10,
      batch_size = 150,
      shuffle = F,
      validation_data = list(test_x, test_y),
      verbose = 1)

plot(history_tuning)

prediksi test_x_array menggunakan model_tuning.

# your code here
pred_tuning <- predict(model_tuning, test_x_array) %>% 
  k_argmax() %>% 
  as.array() %>% 
  as.factor()

Evaluasi performa model

# your code here
confusionMatrix(data=pred_tuning, reference = as.factor(sign_test$label))
#> Confusion Matrix and Statistics
#> 
#>           Reference
#> Prediction   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16
#>         0  310   0   0   0   0   0   0   0   0   0   0   0  56   0   0   0   0
#>         1    0 390   0  10   0   0   0   2   0   0   0   0   0   0   0   0   0
#>         2    0   0 270   0   0  21   0   0   0   0   0   0   0   0   0   0   0
#>         3    0   1   0 191   0   0   0   0   0   0   0   0   5   0   0   0   0
#>         4    0   0   0   0 416   0   0  19   0   0   0  21   0  21   0   0   0
#>         5    0   0  21   0   0 204   0   0   0  21   0   0   0  18   0   2   0
#>         6    0   0   0   0   0   0 247  20   0   0   0   0   0  21   0   0   0
#>         7    0   0   0   0   0   0  42 376   0   0   0   0   0   0   0   0   0
#>         8    0   0   0   0   0   1   0  17 193   0   0  11   0   0   1   0   1
#>         9    0  17   0   0   0   0   0   0   0 164   0   0   0   0   0   0   5
#>         10   0   0   0   0   0   0   0   0   0   0 209   0   0   0   0   0  21
#>         11   0   0   0   0  19   0   0   2   0   0   0 249  36   0   0  20   0
#>         12  18   0   0   0   0   0   0   0   3   0   0  42 136  15   0   0   0
#>         13   3   0   0   0   0   0   0   0   0   0   0   0  22 145   0   0   0
#>         14   0   0   0   0   0   0   0   0   0   0   0   0   0   0 340   0   0
#>         15   0   0   0   0   0   0  39   0   0   0   0  20  16   8   4 142   0
#>         16   0   0   0   3   0   0   0   0  35  84   0   0   0   0   0   0  77
#>         17   0   0   0   0  63   0   0   0  17  14   0  51   0   0   0   0  20
#>         18   0   0   0   0   0   0  17   0   2   0   0   0  20  18   2   0   0
#>         19   0  24   0   0   0   0   0   0   0  21   0   0   0   0   0   0  20
#>         20   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
#>         21   0   0   0   0   0  21   0   0   0   0   0   0   0   0   0   0   0
#>         22   0   0  19  41   0   0   3   0   0   0   0   0   0   0   0   0   0
#>         23   0   0   0   0   0   0   0   0  38  27   0   0   0   0   0   0   0
#>           Reference
#> Prediction  17  18  19  20  21  22  23
#>         0    0   0   0   0   0   0   0
#>         1    0   0   0   0   0   0  15
#>         2    0   0   0   0   0   0   0
#>         3    0   0   2  15   0   0   0
#>         4   22   0   0   0   0   0   0
#>         5    0   0   0  20   0   6   0
#>         6    0   0   0   0   0   0   0
#>         7   19   0   0   0  21   0   0
#>         8   23  21   0   0   0   0  20
#>         9    0   0  77  82   3   0  18
#>         10   0  30   0   0   0   2  41
#>         11  62   0   0   0   0   0   0
#>         12  18   0   0   0   0   0   0
#>         13   0   0   0   0   0   0   0
#>         14   0   0   0   4   0   0   0
#>         15   2   0   0   0   0   3   0
#>         16   0   0  12   0  20  18   3
#>         17  79   0   0   0   0  21  20
#>         18   0  91   0  19   0   0  21
#>         19   0  20 136   1  40   0   0
#>         20   0   0  33 161   0   0  19
#>         21   0   0   0  28 122  35   0
#>         22   0  86   0  16   0 182   0
#>         23  21   0   6   0   0   0 175
#> 
#> Overall Statistics
#>                                                
#>                Accuracy : 0.6979               
#>                  95% CI : (0.6871, 0.7085)     
#>     No Information Rate : 0.0694               
#>     P-Value [Acc > NIR] : < 0.00000000000000022
#>                                                
#>                   Kappa : 0.6839               
#>                                                
#>  Mcnemar's Test P-Value : NA                   
#> 
#> Statistics by Class:
#> 
#>                      Class: 0 Class: 1 Class: 2 Class: 3 Class: 4 Class: 5
#> Sensitivity           0.93656  0.90278  0.87097  0.77959  0.83534  0.82591
#> Specificity           0.99181  0.99599  0.99694  0.99668  0.98756  0.98729
#> Pos Pred Value        0.84699  0.93525  0.92784  0.89252  0.83367  0.69863
#> Neg Pred Value        0.99691  0.99378  0.99419  0.99224  0.98771  0.99375
#> Prevalence            0.04615  0.06023  0.04322  0.03416  0.06944  0.03444
#> Detection Rate        0.04322  0.05438  0.03765  0.02663  0.05800  0.02844
#> Detection Prevalence  0.05103  0.05814  0.04057  0.02984  0.06958  0.04071
#> Balanced Accuracy     0.96418  0.94939  0.93395  0.88814  0.91145  0.90660
#>                      Class: 6 Class: 7 Class: 8 Class: 9 Class: 10 Class: 11
#> Sensitivity           0.70977  0.86239  0.67014  0.49547   1.00000   0.63198
#> Specificity           0.99399  0.98783  0.98620  0.97047   0.98650   0.97949
#> Pos Pred Value        0.85764  0.82096  0.67014  0.44809   0.68977   0.64175
#> Neg Pred Value        0.98533  0.99106  0.98620  0.97546   1.00000   0.97863
#> Prevalence            0.04852  0.06079  0.04016  0.04615   0.02914   0.05494
#> Detection Rate        0.03444  0.05243  0.02691  0.02287   0.02914   0.03472
#> Detection Prevalence  0.04016  0.06386  0.04016  0.05103   0.04225   0.05410
#> Balanced Accuracy     0.85188  0.92511  0.82817  0.73297   0.99325   0.80574
#>                      Class: 12 Class: 13 Class: 14 Class: 15 Class: 16
#> Sensitivity            0.46735   0.58943   0.97983   0.86585   0.53472
#> Specificity            0.98605   0.99639   0.99941   0.98687   0.97510
#> Pos Pred Value         0.58621   0.85294   0.98837   0.60684   0.30556
#> Neg Pred Value         0.97767   0.98558   0.99897   0.99683   0.99032
#> Prevalence             0.04057   0.03430   0.04838   0.02287   0.02008
#> Detection Rate         0.01896   0.02022   0.04741   0.01980   0.01074
#> Detection Prevalence   0.03235   0.02370   0.04796   0.03263   0.03514
#> Balanced Accuracy      0.72670   0.79291   0.98962   0.92636   0.75491
#>                      Class: 17 Class: 18 Class: 19 Class: 20 Class: 21
#> Sensitivity            0.32114   0.36694   0.51128   0.46532   0.59223
#> Specificity            0.97026   0.98570   0.98175   0.99238   0.98794
#> Pos Pred Value         0.27719   0.47895   0.51908   0.75587   0.59223
#> Neg Pred Value         0.97575   0.97751   0.98119   0.97342   0.98794
#> Prevalence             0.03430   0.03458   0.03709   0.04824   0.02872
#> Detection Rate         0.01102   0.01269   0.01896   0.02245   0.01701
#> Detection Prevalence   0.03974   0.02649   0.03653   0.02970   0.02872
#> Balanced Accuracy      0.64570   0.67632   0.74652   0.72885   0.79009
#>                      Class: 22 Class: 23
#> Sensitivity            0.68165   0.52711
#> Specificity            0.97610   0.98655
#> Pos Pred Value         0.52450   0.65543
#> Neg Pred Value         0.98755   0.97726
#> Prevalence             0.03723   0.04629
#> Detection Rate         0.02538   0.02440
#> Detection Prevalence   0.04838   0.03723
#> Balanced Accuracy      0.82888   0.75683

7. Kesimpulan

Dari 3 model yang telah dibuat (model_base, model_bigger dan model_tuning), model yang paling baik adalah model_tuning, karena akurasinya cukup tinggi dan selisih akurasi antara data train dan data test paling kecil.