-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy path09-NN.Rmd
More file actions
294 lines (192 loc) · 13.1 KB
/
09-NN.Rmd
File metadata and controls
294 lines (192 loc) · 13.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
# Neural Network and Deep Learning
```{r setup, include=FALSE}
# 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)
```
```{r echo=FALSE, warning=FALSE, message=FALSE}
library(rsample)
library(recipes)
library(keras)
library(nnet)
```
## Neural Network and their Implementation
### **Apa perbedaan metode Machine Learning dengan Neural Network dan Deep Learning?**
- Neural network bukan merupakan metode yang berasal dari statistik melainkan lahir dari pemikiran dari peneliti dengan background Computer Science dan Mathematics.
- Neural network merupakan salah satu metode Machine Learning. Neural netwrok dengan arsitektur yang cukup rumit sering disebut sebagai Deep Learning. Neural network hanya memiliki satu hidden layer, sedangkan Deep Learning memiliki lebih dari satu hidden layer.
Berikut merupakan link eksternal yang dapat dijadikan sebagai bahan referensi [Deep learning & Machine learning: what’s the difference?](https://parsers.me/deep-learning-machine-learning-whats-the-difference/)
### **Implementasi/penggunaan deep learning di dunia nyata?**
Berikut beberapa contoh implementasi/penggunaan deep learning di dunia nyata:
- Data suara:[Speech emotions recognition](https://github.com/fafilia/speech-emotions-recognition/blob/master/Speech_Emotions_Recognition.ipynb)
- Data gambar: [Image recognation dengan model convolutional neural network](https://github.com/fafilia/cnn-intel_images/blob/master/CNN_IntelImages.ipynb)
Penggunaan deep learning saat ini:
- [Top 20 Applications of Deep Learning in 2021 Across Industries](https://www.mygreatlearning.com/blog/deep-learning-applications/)
## Pre-processing
### **Bagaimana cara mentransformasikan prediktor data kategorik menjadi variabel dummy?**
Kita akan menggunakan data `attrition` yang memiliki variabel kategorik untuk dilakukan dummy transformation sebelum menggunakan metode neural network.
```{r}
attrition <- read.csv("data/08-NN/attrition.csv")
str(attrition)
```
Kita akan melakukan cross validation, yaitu membagi data menjadi **training set** untuk proses pemodelan dan **testing set** untuk melakukan evaluasi. Namun, data train dan data test tidak langsung dimasukkan ke dalam sebuah objek melainkan dilakukan tahapan data preparation terlebih dahulu yang di dalamnya terdapat tahapan dummy transformation.
Cross validation akan dilakukan dengan menggunakan fungsi `initial_split()` dari library `rsample`. Fungsi tersebut akan melakukan proses sampling untuk cross validation dengan metode **stratified random sampling**, sehingga proporsi target variabel pada data awal, akan dipertahankan baik pada training set maupun testing set.
```{r}
set.seed(100)
splitted <- initial_split(attrition,
prop = 0.8,
strata = "attrition")
splitted
```
Proses yang dilakukan pada tahapan data preparation akan dilakukan dengan menggunakan fungsi dari library `recipes`, yaitu:
- `step_rm()`: menghapus variabel yang dianggap tidak berpengaruh
- `step_nzv()`: membuang variabel yang variansinya mendekati 0 (tidak informatif)
- `step_center()` dan `step_scale()`: melakukan scaling
- `step_dummy()`: melakukan dummy transformation
```{r}
rec <- recipe(attrition ~ ., data = training(splitted)) %>%
step_rm(employee_count, employee_number) %>%
step_nzv(all_predictors()) %>%
step_center(all_numeric()) %>%
step_scale(all_numeric()) %>%
step_dummy(all_nominal(), -attrition, one_hot = FALSE) %>%
prep()
```
Setelah mendefinisikan proses data preparation pada objek `rec`, selanjutnya proses tersebut diterapkan ke data train menggunakan fungsi `juice()` dan ke data test menggunakan fungsi `bake()` dari library `recipes`.
```{r}
data_train <- juice(rec)
data_test <- bake(rec, testing(splitted))
prop.table(table(data_train$attrition))
prop.table(table(data_test$attrition))
```
Setelah melakukan dummy transformation pada prediktor, data train dan test harus disesuaikan bentuknya untuk melalui proses building model dengan metode neural network. Target variabel yang bertipe kategorik akan dilakukan dummy transformation dengan menggunakan fungsi `to_categorical()` dari library `keras`, sementara semua prediktor akan diubah ke dalam bentuk matriks numerik.
```{r}
# menyiapkan data train
data_train_y <- to_categorical(as.numeric(data_train$attrition) - 1)
data_train_x <- data_train %>%
select(-attrition) %>%
data.matrix()
dim(data_train_x)
```
```{r}
# menyiapkan data test
data_test_y <- to_categorical(as.numeric(data_test$attrition) - 1)
data_test_x <- data_test %>%
select(attrition) %>%
data.matrix()
dim(data_train_y)
```
### **Ketika running model Neural Network, weight/bobot diinisialisasi secara random sehingga menyebabkan hasil yang berbeda jika dilakukan berulang kali. Bagaimana cara mengatur `set.seed()` pada Neural Network?**
Metode neural network selalu menginisialisasi bobot/weight secara random di awal, sehingga ketika metode tersebut di running berulang kali akan memperoleh hasil yang berbeda. Untuk mengatasi hal tersebut kita dapat menggunakan seed (state random). Kita dapat menentukan seed dengan menggunakan fungsi `use_session_with_seed()` dari library `keras`.
```{r eval=FALSE}
use_session_with_seed(seed)
```
Selain menggunakan cara di atas kita juga dapat menggunakan seed dengan fungsi `initializer_random_normal()`. Berikut cara menggunakan seed dengan fungsi tersebut:
```{r eval=FALSE}
# define seed
set.seed(100)
initializer <- initializer_random_normal(seed = 100)
# use the seed when building architecture
model <- keras_model_sequential() %>%
layer_dense(units = ...,
activation = "...",
input_shape = c(...),
kernel_initializer = initializer,
bias_initializer = initializer)
```
### **Bagaimana cara membagi data train, test, dan validation untuk keperluan deep learning analysis?**
Anda dapat menambahkan parameter `validation_split` saat melakukan fitting model dengan menggunakan fungsi `fit()` dari pacakge `keras`. Penjelasan lebih lengkap mengenai parameter dan fungsi dari pacakge `keras` dapat Anda lihat pada referensi berikut [`fit()` function](https://keras.rstudio.com/reference/fit.html)
## Architecture
### **Secara best practice, berapa jumlah hidden layer dan nodes yang digunakan dalam membangun arsitektur neural network (ANN)?**
- Kebanyakan peneliti menggunakan minimal 2 hidden layer, namun tidak menutup kemungkinan menggunakan lebih dari 2 ataupun kurang dari 2 hidden layer.
- Jumlah nodes biasanya semakin sedikit ketika hidden layers semakin dekat dengan output layer. Tujuannya adalah untuk melihat fitur dengan lebih spesifik.
- Kebanyakan peneliti menggunakan angka biner $2^{n}$ seperti 1, 2, 4, 8, 16, 32, 64, 128, 256, dst karena neural network merupakan metode yang berasal dari bidang IT dan Matematika yang biasa menggunakan angka biner.
### **Fungsi aktivasi apa yang sering digunakan ketika membuat arsitektur neural network?**
- Hidden layer: `relu` (Rectified Linear Unit), karena dapat mentransformasi data dengan mengubah nilai negatif menjadi 0 dan membiarkan nilai positif. Hal ini mengakibatkan semakin mendekati output layer, informasi yang dibawa tidak banyak berkurang.
- Output layer: tergantung case yang sedang dikerjakan:
- Regresi: `linear`
- Klasifikasi biner: `sigmoid`
- Klasifikasi multiclass: `softmax`
### **Bagaimana cara menentukan batch size dan jumlah epoch?**
- Batch size menggunakan angka yang dapat habis membagi jumlah data, agar data yang tersedia dapat digunakan secara keseluruhan (tidak ada yang tidak terpakai). Contoh: Jika data train terdiri dari 800 observasi, kita bisa menggunakan batch size 200 yang dapat habis membagi 800 observasi tersebut menjadi 4 batch.
- Jumlah epoch dimulai dari angka yang kecil terlebih dahulu untuk memastikan bahwa model dapat berjalan tanpa error sehingga tidak menunggu komputasi yang terlalu lama. Kemudian lihat apakah error dan accuracy yang dihasilkan sudah konvergen atau belum. Apabila belum, silahkan tambahkan jumlah epoch sedikit demi sedikit, dan sebaliknya.
### **Bagaimana menentukan learning rate yang tepat?**
Learning rate dapat mempercepat atau memperlambat besaran update error.
- Semakin besar learning rate, maka error/accuracy akan semakin cepat konvergen. Namun, bisa saja titik error paling minimum (global optimum) terlewat.
- Semakin kecil learning rate, maka terdapat kemungkinan yang lebih besar untuk sampai di titik error paling minimum (global optimum). Namun, error/accuracy akan membutuhkan waktu lebih lama untuk konvergen.
### **Optimizer apa yang paling sering digunakan?**
Optimizer merupakan fungsi yang digunakan untuk mengoptimumkan error (memperkecil error). Secara sederhana, untuk mengoptimumkan suatu fungsi bisa melalui fungsi turunan, pada neural network disebut `sgd` (Stochastic Gradient Descent). Namun, `sgd` memiliki beberapa kekurangan sehingga mulai banyak peneliti yang memperbaiki fungsi `sgd` tersebut.
Salah satu optimizer yang cukup terkenal adalah `adam` sebagai optimizer yang merupakan perbaikan dari `sgd` karena optimizer tersebut dapat mengupdate/menyesuaikan momentum ketika proses optimisasi. Berikut link eksternal yang dapat dijadikan sebagai bahan referensi [Adaptive Moment Estimation (Adam)](https://ruder.io/optimizing-gradient-descent/index.html#adam)
Selain tips di atas berikut link eksternal yang dapat dijadikan referensi dalam membangun arsitektur neural network [Rules-of-thumb for building a Neural Network](https://towardsdatascience.com/17-rules-of-thumb-for-building-a-neural-network-93356f9930af)
### **Adakah fungsi untuk memvisualisasikan arsitektur neural network?**
Anda dapat menggunakan fungsi `plot()` untuk memvisualisasikan arsitektur model neural network yang dibuat dengan fungsi `neuralnet()` dari pacakage `nnet` seperti berikut
```{r eval=FALSE}
set.seed(100)
nneu <- neuralnet(y ~ Var1 + Var2 + Var3, dat, hidden = 4, rep = 5)
plot(nneu, rep = "best")
```
## Framework
## Mathematics Formula
Aturan update weight:
1. Menghitung turunan parsial dari weight.
2. Berikut hal yang harus dilakukan jika:
- Hasil turunannya Positif, maka nilai weight dikurangi.
- Hasil turunannya negatif, maka nilai weight ditambah.
Keduanya dilakukan dengan tujuan untuk mencari weight yang menghasilkan error terkecil.
```{r echo=FALSE, out.width="60%"}
knitr::include_graphics("assets/08-NN/updaterule.png")
```
**Forward Propagation**
```{r echo=FALSE, out.width="60%"}
knitr::include_graphics("assets/08-NN/nn.png")
```
Diketahui:
- $w_{11}=0.5$
- $w_{12}=1$
- $b_{11}=1$
- $w_{21}=0.5$
- $b_{12}=1$
1. Forward pass dari input ke hidden layer 1.
```{r echo=FALSE, out.width="60%"}
knitr::include_graphics("assets/08-NN/input-hidden.png")
```
$$h_{in}=x_1*w_{11}+x_2*w_{12}+b_{11} \\ h_{in}= 2*0.5 + 3*1 + 1 \\ h_{in}= 5$$
2. Transformasi nilai dengan fungsi aktivasi `sigmoid`.
$$sigmoid=\frac{1}{1+e^{-x}}$$
$$h_{out}=\frac{1}{1+e^{-5}} \\ h_{out} = 0.9933071$$
3. Forward pass hidden layer ke output layer.
```{r echo=FALSE, out.width="60%"}
knitr::include_graphics("assets/08-NN/hidden-output.png")
```
$$Output_{in}=0.9933071*0.5+1 \\ Output_{in} = 1.496654$$
4. Transformasi nilai dengan fungsi aktivasi `linear`.
$$Output_{in} = Output_{out} = 1.496654$$
5. Hitung nilai error dengan cost function.
$$cost=\frac{1}{2}(output_{aktual} - output_{out})^2 \\ cost = \frac{1}{2}(4-1.496654)^2 \\ cost = 3.133371$$
**Backpropagation**
1. Backward pass dari output ke hidden layer 1
2. Mengitung turunan parsial cost ke $w_{21}$ menggunakan chain rule:
$$\frac{d_{cost}}{d_{w_{21}}}= \frac{d_{cost}}{d_{output_{out}}}* \frac{d_{output_{out}}}{d_{output_{in}}}*\frac{d_{output_{in}}}{d_{w_{21}}}$$
Hitung $\frac{d_{cost}}{d_{output_{out}}}$
$$\frac{d_{cost}}{d_{output_{out}}} = \frac{d(\frac{1}{2}(output_{actual}-output_{out})^2)}{d(output_{out})} \\ \frac{d_{cost}}{d_{output_{out}}} = -1 * 2 * \frac{1}{2}(4-1.496654) \\ \frac{d_{cost}}{d_{output_{out}}} = -2.503346$$
Hitung $\frac{d_{output_{out}}}{d_{output_{in}}}$
karena merupakan fungsi aktivasi `linear` maka:
$$\frac{d_{output_{out}}}{d_{output_{in}}} = 1$$
Hitung $\frac{d_{output_{in}}}{d_{w_{21}}}$
$$\frac{d_{output_{in}}}{d_{w_{21}}} = \frac{d(h_{out}*w_{21}+b_{12})}{d(w_{21})} \\ \frac{d_{output_{in}}}{d_{w_{21}}} = h_{out} \\ \frac{d_{output_{in}}}{d_{w_{21}}} = 0.9933071$$
Jadi turunan parsial $\frac{d_{cost}}{d_{output_{out}}}$:
$$\frac{d_{cost}}{d_{output_{out}}} = -2.503346 * 1 * 0.9933071 \\ \frac{d_{cost}}{d_{output_{out}}} = -2.486591$$
3. Mengitung turunan parsial cost ke $b_{12}$ menggunakan chain rule:
$$\frac{d_{cost}}{d_{b_{12}}}= \frac{d_{cost}}{d_{output_{out}}}* \frac{d_{output_{out}}}{d_{output_{in}}}*\frac{d_{output_{in}}}{d_{b_{12}}} \\ \frac{d_{cost}}{d_{b_{12}}} = -2.503346*1*1 \\ \frac{d_{cost}}{d_{b_{12}}} = -2.503346$$
4. Update $w_{21}$
Misal, learning rate ($\alpha$) = 0.1,
$$w_{21}^{'} = w_{21} - \alpha(\frac{d_{cost}}{d_{w_{21}}}) \\ w_{21}^{'} = 0.5 - (0.1*-2.486591) \\ w_{21}^{'} = 0.7486591$$
5. Update $b_{12}$
$$b_{12}^{'} = b_{12} - \alpha(\frac{d_{cost}}{d_{b_{12}}}) \\ b_{12}^{'} = 1 - (0.1*-2.503346) \\ w_{21}^{'} = 1.250335$$