# clear-up the environment
rm(list = ls())
# chunk options
knitr::opts_chunk$set(
message = FALSE,
warning = FALSE,
fig.align = "center",
comment = "#>"
)
# scientific notation
options(scipen = 9999)
Ada banyak frameworks (template) yang bisa kita gunakan untuk membangun neural network/deep learning model:
Untuk selanjutnya, kita akan menggunakan Keras
dalam
membuat arsitektur dan melakukan training model. Keras
adalah package yang membantu kita mengimplementasikan model Deep
Learning dengan cepat. Keras
memanfaatkan
tensorflow
, sebuah tools open source yang dikembangkan oleh
Google untuk implementasi Deep Learning.
keras
installationlibrary(keras)
library(tensorflow)
model <- keras_model_sequential()
Seperti yang sudah disampaikan di awal, deep learning merupakan
sebuah framework yang sering digunakan ketika menghadapi data
unstructured. Maka dari itu mari kita lakukan image
classification menggunakan deep learning dengan framework
keras
. Kita akan gunakan data MNIST yang berisi data image
tentang tulisan tangan untuk beragam angka. Kita akan coba
klasifikasikan setiap tulisan tangan ke label angka yang sesuai.
Gambar itu terdiri dari kumpulan pixel-pixel. Dimana nantinya dari setiap gabungan pixel yang ada, nantinya akan mewakili sebuah element yang jika digabungkan akan membuat sebuah gambar.
Data Source: kaggle
Data MNIST ada pada folder data_input/mnist
:
# Read mnist train
mnist_train <- read.csv("data_input/mnist/train.csv")
# Read mnist train
mnist_test <- read.csv("data_input/mnist/test.csv")
Pada data yang kita miliki, data yang sudah kita miliki sudah dalam bentuk pixel dan nantinya dari data tersebut kita akan mencoba untuk memprediksi apakah tulisan dari data tersebut.
Lalu bagaimana jika data yang kita miliki adalah gambar asli. Nantinya kita perlu memecahnya menjadi bentuk pixel terelbih dahulu. Intuisinya kenapa kita perlu mengubah nya menjadi pixel itu sama seperti ketika kita megubah data text menjadi nilai corpus yang hanya 1 & 0 saja
Pada tahapan eksplorasi data kali ini, mari coba jawab beberapa pertanyaan di bawah ini.
library(tidyverse)
# Please type your answer
mnist_train %>%
dim()
#> [1] 42000 785
Dimensi data kita:
Row: 42000
Column: 785 (Include 1 kolom buat target variable)
Berapa banyak category yang ada pada kelas target? dan bagaimana proporsinya?
# Please type your answer
mnist_train$label %>%
unique()
#> [1] 1 0 4 7 3 5 8 9 2 6
Terdapat 10 kategori pada kolom kelas target kita
mnist_train$label %>%
table() %>%
prop.table()
#> .
#> 0 1 2 3 4 5 6
#> 0.09838095 0.11152381 0.09945238 0.10359524 0.09695238 0.09035714 0.09850000
#> 7 8 9
#> 0.10478571 0.09673810 0.09971429
Jika kita lihat, proporsi target variable kita cukup seimbang
# Please type your answer
mnist_train %>%
ncol() - 1
#> [1] 784
# Please type your answer
mnist_train %>%
select(-label) %>%
range()
#> [1] 0 255
Jika kita ingat, gambar yang akan kita coba prediksi berbentuk kotak.
Untuk mengetahui berapa ukuran sisi dari gambar tersebut kita bisa
menghitugnnya dengan rumus sqrt()
# Please type your answer
sqrt(784)
#> [1] 28
Jadinya gambar kita memiliki ukuran 28 x 28 pixel
Apa yang anda ketahui terkait pixel?
resolusi gambar
bagian terkecil dari suatu gambar
range dari pixel adalah 0 - 255
Visualisasi gambar
vizTrain <- function(input) {
dimmax <- sqrt(ncol(mnist_train[, -1]))
dimn <- ceiling(sqrt(nrow(input)))
par(mfrow = c(dimn, dimn), mar = c(0.1, 0.1, 0.1,
0.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, mnist_train[i,
1])
}
}
# visualisasi
vizTrain(mnist_train[1:25, ])
Lakukan cross validation menggunakan initial_split dengan proporsi 80% data untuk data training.
library(rsample)
set.seed(100)
# Spliting
mnist_split <- initial_split(data = mnist_train,
prop = 0.8,
strata = "label")
# Data train
mnist_train <- training(mnist_split)
# Data validation
mnist_validation <- testing(mnist_split)
Sebelum membuat model dengan Keras
, ada beberapa hal
yang perlu dilakukan untuk mempersiapkan data:
Scalling dengan membagi data dengan angka 255 agar range data yang dimiliki menjadi 0 hingga 1.
Tujuan dari dilakukannya scalling adalah untuk meringankan komputasi, karena perhitungannya hanya menjadi 0-1 saja
# ambil prediktor dan lakukan scaling
#prediktor
train_x <- mnist_train %>%
select(-label) %>%
as.matrix()/255
validation_x <- mnist_validation %>%
select(-label) %>%
as.matrix()/255
#target
train_y <- mnist_train %>%
select(label)
validation_y <- mnist_validation %>%
select(label)
Framework keras menerima data dalam bentuk array. Sehingga
data prediktor dalam bentuk matrix perlu diubah ke dalam bentuk array
menggunakan array_reshape()
.
Keras : mengenal tipe data yang ada di python (array)
# prediktor
train_x_keras <- train_x %>%
array_reshape(dim = dim(train_x))
validation_x_keras <- validation_x %>%
array_reshape(dim = dim(validation_x))
Ubah target (data kategorik) menjadi variable One Hot
Encoding menggunakan fungsi to_categorical()
:
Jika kita langsung mengubahnya dalam bentuk categorical tidak bisa,
karena fungsi to_categorical()
hanya bisa menerima sebuah
bentuk matrix
# Please type your answer
train_y_keras <- train_y %>%
as.matrix() %>%
to_categorical()
validation_y_keras <-validation_y %>%
as.matrix() %>%
to_categorical()
Tahapan pembuatan model neural network/deep learning di Keras:
Tahapan yang pertama kali kita lakukan adalah membangun arsitektur dari model deep learning kita. Berikut, ada beberapa ketentuan dalam membantu arsitektur model deep learning dengan menggunakan Keras.
Step 1 Selalu diawali
keras_model_sequential()
# keras initialization
model <- keras_model_sequential()
Note: - keras_model_sequential()
adalah inisialisasi
awal pembuatan model - Ketika ingin mengubah sedikit saja parameter dari
model, maka harus di run ulang dari
keras_model_sequential()
Step 2 Membangun setiap layer (Input, Hidden & Output)
Dalam membangun setiap layer yang ada, Keras akan mengimplementasikan sistem layer by layer. Dimana, layer pertama yang dibuat akan menjadi hidden layer pertama dan layer terakhir yang dibuat akan menjadi output layer.
Fungsi yang dapat kita gunakan dalam membangun setiap layer adalah
layer_dense()
, pada fungsi tersebut nantinya akan kita isi
dengan beberapa parameter berikut ini.
input_shape
: mendefinisikan jumlah input nodes.
layer_dense()
yang paling pertama.units
: mendefinisikan jumlah nodes dalam layer
tersebut.activation
: mendefinisikan Activation Function yang
digunakan.
name
: untuk penamaan layer (demi kemudahan
visualisasi/summary).# Untuk mengunci random
tensorflow::tf$random$set_seed(123)
# Please type your answer
model %>%
layer_dense(input_shape = 784,
units = 128,
activation = "relu",
name = "Hidden_1") %>%
layer_dense(units = 64,
activation = "relu",
name = "Hidden_2") %>%
layer_dense(units = 32,
activation = "relu",
name = "Hidden_3") %>%
layer_dense(units = 10,
activation = "softmax",
name = "Output")
# Untuk melihat hasil arsitektur yang sudah dibuat
summary(model)
#> Model: "sequential_1"
#> ________________________________________________________________________________
#> Layer (type) Output Shape Param #
#> ================================================================================
#> Hidden_1 (Dense) (None, 128) 100480
#> Hidden_2 (Dense) (None, 64) 8256
#> Hidden_3 (Dense) (None, 32) 2080
#> Output (Dense) (None, 10) 330
#> ================================================================================
#> Total params: 111,146
#> Trainable params: 111,146
#> Non-trainable params: 0
#> ________________________________________________________________________________
Keterangan:
Total params
= Jumlah bobot yang dimiliki oleh
modelTrainable param
= parameter/koneksi yang bobotnya bisa
berubah sesuai dengan proses trainingNon-trainable param
= nilai bobot/parameter tidak
berubah atau dikunci nilainyaPada tahapan membangun arsitektur, kita belum memberikan perhitungan
error yang akan digunakan. Pada tahapan inilah kita akan memberikan cara
perhitungan error, dengan menggunakan fungsi compile()
.
Jenis perhitungan error dapat kita definisikan dengan menggunakan
parameter loss =
. Pada parameter tersebut dapat kita isi
dengan 3 value, seperti di bawah ini.
categorical_crossentropy
binary_crossentropy
.mean_square_error
Akan tetapi, setelah kita mendapatkan hasil dari perhitungan error
yang terjadi, model kita perlu untuk melakukan back propagation
untuk memperbaiki bobo agar errornya berkurang. Untuk melakukan hal
tersebut kita juga dapat menambahkan parameter optimizer =
.
Pada parameter optimizer terdapat 2 fungsi yang dapat kita isi, yaitu
optimizer_sgd()
dan optimizer_adam()
.
optimizer_sgd()
: Merupakan pembaharuaan
dari cara perhitungan Gradient Decent yang sudah di-implementasikan pada
fungsi neuralnet()
.optimizer_adam()
: Merupakan pembaharuaan
dari metode Optimizer SGD.
learning_rate =
untuk mengatur
seberapa cepat penurunan bobotnya.Parameter terakhir yang dapat kita tambahkan juga ke fungsi
compile()
adalah parameter metric =
. Parameter
tersebut dapat kita isi denagn accuracy
untuk melihat nilai
accuracy-nya yang dihasilkan.
# Please type your answer
model %>%
compile(loss = "categorical_crossentropy",
optimizer = optimizer_adam(learning_rate = 0.001),
metrics = "accuracy")
Setelah arsitektur dari model Deep Learning kita sudah siap, kita
akan memulai tahapan trainingnya. Untuk melakukan training model, kita
akan memnggunakan fungsi fit()
. Pada fungsi tersebut dapat
kita isi dengan beberapa parameter berikut ini,
x
: Prediktory
: Target variabelepochs
: Jumlah epoch atau jumlah iterasi yang dilakukan
untuk model belajar
neuralnet()
validation_data
: Data testing/unseen data untuk dilihat
metrik evaluasinyaverbose
: Apakah ingin menampilkan visualisasi selama
training berlangsungbatch_size
: Model akan mengupdate bobot setiap
n dataApa itu batch size?
Terminologi pada neuralnet yang kita pelajari sebelumnya & keras agak berbeda. Pada keras, model yang dibuat hanya 1 buah, namun proses trainingnya dapat dilakukan beberapa kali. Pada tiap proses training, dilakukan pembagian data ke beberapa batch melalui random sampling. Model akan ditraining menggunakan data pada batch 1 terlebih dahulu, kemudian batch selanjutnya, hingga digunakan seluruh data (1 epoch).
Model dapat ditraining lebih dari 1 epoch (berarti melakukan pembagian batch dengan random sampling yang berbeda dari sebelumnya). Pada tiap epoch, error dan accuracy (metrics) model dapat di track. Bila ditinjau, semakin bertambah epoch, model akan memiliki error semakin kecil dan accuracy yang semakin tinggi.
knitr::include_graphics("assets/batch.png")
Hal yang perlu di HIGHLIGHT:
# JANGAN RUN 2X! Karena akan melanjutkan proses training. Bila ingin run lagi, ulang dari `keras_model_sequential()`
history <- model %>%
fit(x = train_x_keras,
y = train_y_keras,
epoch = 10,
validation_data = list(validation_x_keras, validation_y_keras),
verbose = 1,
batch_size = 100
)
Batch(1): 100 Batch(2): 100 Batch(3): 100 Batch(4): 100 Batch(5): 100 Batch(336): 100 Total = 336 * 100
Plotting Model:
plot(history)
Melakukan prediksi pada data test test_x_keras
dengan
menggunakan fungsi predict()
# Please type your answer
predict_class <- predict(model, validation_x_keras) %>%
k_argmax() %>%
as.array() %>%
as.factor()
# melihat hasil prediksi
predict_class %>%
head()
#> [1] 1 3 9 3 7 6
#> Levels: 0 1 2 3 4 5 6 7 8 9
Evaluasi kebaikan model dalam memprediksi menggunakan
confusionMatrix()
:
# Please type your answer
caret::confusionMatrix(data = predict_class, reference = as.factor(mnist_validation$label))
#> Confusion Matrix and Statistics
#>
#> Reference
#> Prediction 0 1 2 3 4 5 6 7 8 9
#> 0 814 0 7 3 0 2 1 0 4 1
#> 1 0 913 0 0 2 1 2 0 2 0
#> 2 1 4 829 1 4 0 1 5 6 2
#> 3 0 0 0 844 0 8 0 1 7 7
#> 4 0 0 2 0 767 0 1 2 2 6
#> 5 2 0 1 8 1 735 4 2 9 3
#> 6 4 0 1 1 6 4 803 0 5 0
#> 7 2 1 6 7 7 1 0 884 4 14
#> 8 3 3 1 4 0 1 1 0 752 1
#> 9 2 1 2 4 26 2 0 6 11 815
#>
#> Overall Statistics
#>
#> Accuracy : 0.9707
#> 95% CI : (0.9669, 0.9742)
#> No Information Rate : 0.1097
#> P-Value [Acc > NIR] : < 0.00000000000000022
#>
#> Kappa : 0.9675
#>
#> Mcnemar's Test P-Value : NA
#>
#> Statistics by Class:
#>
#> Class: 0 Class: 1 Class: 2 Class: 3 Class: 4 Class: 5
#> Sensitivity 0.98309 0.9902 0.97644 0.9679 0.94342 0.97480
#> Specificity 0.99762 0.9991 0.99682 0.9969 0.99829 0.99608
#> Pos Pred Value 0.97837 0.9924 0.97186 0.9735 0.98333 0.96078
#> Neg Pred Value 0.99815 0.9988 0.99735 0.9963 0.99396 0.99751
#> Prevalence 0.09855 0.1097 0.10105 0.1038 0.09676 0.08974
#> Detection Rate 0.09688 0.1087 0.09867 0.1005 0.09129 0.08748
#> Detection Prevalence 0.09902 0.1095 0.10152 0.1032 0.09284 0.09105
#> Balanced Accuracy 0.99036 0.9947 0.98663 0.9824 0.97085 0.98544
#> Class: 6 Class: 7 Class: 8 Class: 9
#> Sensitivity 0.98770 0.9822 0.93766 0.9600
#> Specificity 0.99723 0.9944 0.99816 0.9929
#> Pos Pred Value 0.97451 0.9546 0.98172 0.9379
#> Neg Pred Value 0.99868 0.9979 0.99345 0.9955
#> Prevalence 0.09676 0.1071 0.09545 0.1010
#> Detection Rate 0.09557 0.1052 0.08950 0.0970
#> Detection Prevalence 0.09807 0.1102 0.09117 0.1034
#> Balanced Accuracy 0.99247 0.9883 0.96791 0.9764
NOTE: Bila hasil metrics masih ingin ditingkatkan, kita dapat melakukan model tuning kembali pada pembuatan model nn maupun tahap pre-processing lainnya.
Dikarenakan dalam proses training model memerlukan waktu yang tidak
sebentar, kita akan menyimpan terlebih dahulu model yang sudah semmpat
kita buat dengan menggunakan fungsi save_model_tf()
# save
model %>%
save_model_tf(filepath = "model_nn_rhea")
Untuk memanggil hasil model yang disimpan dengan menggunakan fungsi
save_model_tf()
, kita dapat menggunakan funsi
load_model_tf()
model_loaded <- load_model_tf(filepath = "model_nn_rhea")
summary(model_loaded)
#> Model: "sequential_2"
#> ________________________________________________________________________________
#> Layer (type) Output Shape Param #
#> ================================================================================
#> Hidden_1 (Dense) (None, 128) 100480
#> Hidden_2 (Dense) (None, 64) 8256
#> Hidden_3 (Dense) (None, 32) 2080
#> Output (Dense) (None, 10) 330
#> ================================================================================
#> Total params: 111,146
#> Trainable params: 111,146
#> Non-trainable params: 0
#> ________________________________________________________________________________
Buat model deep learning baru menggunakan data train yang sama dan
simpan ke dalam objek model_nama-anda
.
Step 1: Build architecture
Step 2: Compile model
Step 3: Fit (training) model
Step 4: Plot model
Step 5: Lakukan prediksi ke data test:
Step 6: Evaluasi
Data Pre-processing untuk Keras
data.frame
diubah terlebih dahulu
menjadi array
karena keras menerima input dalam bentuk
array. Tahapan: data.frame -> matrix -> array.array_reshape()
to_categorical()
Tahapan Model Building di Keras:
Panduan Model Building & Tuning:
optimizer_sgd()
di
Keras)optimizer_adam()
)