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).
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.
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.
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$labelMengubah 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)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()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
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.