Machine Learning dengan Torch – Framework machine learning digunakan untuk mempermudah kita dalam melakukan pekerjaan dasar. Mengapa butuh framework? Yup urusan machine learning saat ini banyak menggunakan Python dengan pytorch dan tensorflow nya, namun begitu ke bahasa R, pilihannya belum ada. Membuat code sendiri untuk machine learning butuh effort yang besar, oleh sebab itu dengan adanya framework maka membuat arsitektur dan tunning parameternya menjadi lebih mudah. Itulah mengapa kita butuh framework.
Pada pembahasan sebelumnya Neural Network MLP dengan package Neuralnet yang merupakan package untuk machine learning MLP secara sederhana telah kita pelajari, kemudian kita mengenal framework machine learning yaitu Torch versi R telah tersedia Framework Machine Learning. 2 Postingan tersebut sebaiknya kalian baca terlebih dahulu.
Bila sudah, maka kita akan membahas cara membuat model Torch di R. Model yang akan kita buat nanti seperti model MLP yang terdiri dari beberapa layer saja. Seperti biasanya untuk contoh sederhana MLP, saya lebih suka menggunakan contoh kasus logika XOR. Alasan dibaliknya adalah kasus XOR merupakan tipe non linear sehingga sangat cocok sebagai contoh dasar. Belajar Algoritma Multi Layer Percepton. Non Linear adalah kasus yang tidak bisa dipecahkan oleh perceptron sehingga munculah Multi Layer Perceptron / MLP.
Nanti dilanjut kan dengan dataset iris yang terdiri dari 4 input dan 1 target dengan menggunakan function aktifasi relu.
Logika XOR
Contents
Yuk kita buat terlebih dahulu datasetnya menggunakan data frame yang terdiri dari 2 atribut input dan 1 target.
library(torch) df = data.frame(x1=c(1,1,0,0),x2=c(1,0,1,0),y=c(1,0,0,1))
mengingat masih dalam bentuk data frame, kita perlu ubah ke matrix
x_train = as.matrix(df[,-3]) y_train = as.matrix(df[,3])
Machine Learning dengan Torch membutuhkan operasi tensor, oleh sebab itu harus di convert ke tensor dengan type float
x_train = torch_tensor(x_train, dtype = torch_float()) y_train = torch_tensor(y_train, dtype = torch_float())
Model Torch Machine Learning
Cara membuat model Torch di R sangat mudah kok, Kita harus menentukan layer dan fungsi aktifasinya. Layer bisa bertipe linear/dense dengan beberapa layer yang saling dihubungkan dengan fungsi aktifasi sigmoid. Karena Model Torch Machine Learning mempunyai rentang nilai 0 sampai dengan 1.
net <- nn_module( "Model-Logika-XOR", initialize = function(){ self$layer1 = nn_linear(in_features = 2, out_features = 4) self$layer2 = nn_linear(in_features = 4, out_features = 3) self$layer3 = nn_linear(in_features = 3, out_features = 1) self$sigmoid = nn_sigmoid() }, forward = function(x){ x %>% self$layer1() %>% self$sigmoid() %>% self$layer2() %>% self$sigmoid() %>% self$layer3() %>% self$sigmoid() } )
dari contoh kode diatas, kita jadi teringat konsep object oriented programming di Python ya! Langkah selanjutnya menentukan metode optimasi serta loss function (pakai MSE saja)
model <- net() #model$to(device = "cuda") optimizer = optim_adam(model$parameters,lr=0.01) criterion = nn_mse_loss()
kita lakukan iterasi dan perbaikan bobot
l = c() #loss tiap epoch for (epoch in c(1:1000)){ optimizer$zero_grad() output = model(x_train) loss = criterion(output,y_train) loss$backward() optimizer$step() l = c(l,loss$item()) if(epoch %% 100==0) cat(" Epoch:", epoch,"Loss: ", loss$item(),"\n") }
Hemm. kalian bisa melihat loss yang semakin turun setiap epoch
Epoch: 100 Loss: 0.2493794 Epoch: 200 Loss: 0.2335983 Epoch: 300 Loss: 0.05096761 Epoch: 400 Loss: 0.007002922 Epoch: 500 Loss: 0.00306071 Epoch: 600 Loss: 0.001811262 Epoch: 700 Loss: 0.001227058 Epoch: 800 Loss: 0.0008979964 Epoch: 900 Loss: 0.0006909413 Epoch: 1000 Loss: 0.0005506711
Agar lebih menarik, kita plot kan saja
library(ggplot2) library(dplyr) df2 = data.frame(error = l) df2$iterasi = c(1:nrow(df2)) ggplot(data = df2, aes(x=iterasi,y=error))+ geom_line()+ labs(title = "Logika XOR Torch R", subtitle = "Loss di tiap iterasi", caption = "Data source: https://softscients.com", x = "Iterasi", y = "Loss")
hasilnya sebagai berikut
Kita cek hasilnya antar target dan prediksi yang dihasilkan
prediksi = model(x_train) hasil = data.frame(target=as.matrix(y_train),prediksi = as.matrix(prediksi)) hasil
hasil bisa kalian round() kan bila perlu
target prediksi 1 1 0.97308481 2 0 0.02729683 3 0 0.02402997 4 1 0.98771101
Dataset IRIS
Machine Learning dengan Torch bagaimana dengan data iris? Konsep membuat persiapan datasetnya sama seperti pembahasan sebelumnya yaitu input dinormalisasikan terlebih dahulu / jika tidak mau nanti pakai fungsi relu diawal sedangkan untuk target bisa dengan teknik one hot encoding.
Yuk kita loading datasetnya sekalian berikan target dalam bentuk angka
library(dplyr) library(torch) df = iris df spc = df %>% distinct(Species) spc$id = c(1:nrow(spc)) spc for(i in c(1:nrow(spc))){ df = df %>% mutate(Target=ifelse(Species==spc$Species[i],spc$id[i],Species)) }
datasetnya menjadi seperti berikut
Sepal.Length Sepal.Width Petal.Length Petal.Width Species Target 1 5.1 3.5 1.4 0.2 setosa 1 2 4.9 3.0 1.4 0.2 setosa 1 3 4.7 3.2 1.3 0.2 setosa 1 4 4.6 3.1 1.5 0.2 setosa 1 5 5.0 3.6 1.4 0.2 setosa 1
kita pakai kolom 1 sd 4 sebagai input dan kolom 6 sebagai target.
x_train = as.matrix(df[,1:4]) y_train = as.matrix(df[,6]) x_train = torch_tensor(x_train, dtype = torch_float()) y_train = torch_tensor(y_train, dtype = torch_float())
Model Torch Machine Learning
Mengingat nilai input dan target lebih dari 1, maka nanti pakai relu dan sigmoid ditengah nya. Jadi kita nggak usah pakai teknik normalisasi dan one hot encoding targetnya. Berikut cara membuat model Torch di R dengan fungsi relu.
Model Torch Machine Learning ini menggunakan fungsi relu? Yup karena input dan target yang digunakan mempunyai rentang nilai diatas 0 sampai tak hingga. Agar lebih efektif, maka ditengah2 layer tetap menggunakan fungsi sigmoid.
net <- nn_module( "Model-iris data ", initialize = function(){ self$layer1 = nn_linear(in_features = 4, out_features = 18) self$layer2 = nn_linear(in_features = 18, out_features = 6) self$layer3 = nn_linear(in_features = 6, out_features = 1) self$relu = nn_relu() self$sigmoid = nn_sigmoid() }, forward = function(x){ x %>% self$layer1() %>% self$relu() %>% self$layer2() %>% self$sigmoid() %>% self$layer3() %>% self$relu() } )
untuk Loss function dan optimizernya sama dengan sebelumnya
model <- net() #model$to(device = "cuda") optimizer = optim_adam(model$parameters,lr=0.01)#optim_sgd(model$parameters, lr = 0.01) criterion = nn_mse_loss()
bila sudah siap, lakukan iterasi Model Torch Machine Learning agar nilai loss nya semakin mengecil.
l = c() #loss per epoch for (epoch in c(1:1000)){ optimizer$zero_grad() output = model(x_train) loss = criterion(output,y_train) loss$backward() optimizer$step() l = c(l,loss$item()) if(epoch %% 100==0){ hasil = data.frame(target=as.matrix(y_train),prediksi = round(as.matrix(output))) hasil = hasil %>% mutate(keterangan=ifelse(prediksi==target,"benar","salah")) akurasi = ((nrow(hasil %>% filter(keterangan=="benar")))/nrow(hasil)*100) cat(" Epoch:", epoch,"Loss: ", loss$item()," akurasi: ",akurasi,"\n") } }
Ploting loss tiap epoch biar tampak keren
hasil tiap epoch yaitu
Epoch: 100 Loss: 0.3852514 akurasi: 60.66667 Epoch: 200 Loss: 0.03256994 akurasi: 98 Epoch: 300 Loss: 0.02988581 akurasi: 98 Epoch: 400 Loss: 0.02870255 akurasi: 98 Epoch: 500 Loss: 0.02761709 akurasi: 98 Epoch: 600 Loss: 0.0264603 akurasi: 98 Epoch: 700 Loss: 0.02512933 akurasi: 98 Epoch: 800 Loss: 0.02356768 akurasi: 97.33333 Epoch: 900 Loss: 0.02185466 akurasi: 97.33333 Epoch: 1000 Loss: 0.02012367 akurasi: 98
hemmm sangat lumayan dengan hasil sebesar 98%. Bagaimana menurut kalian Machine Learning dengan Torch?
Membuat Model tanpa konsep OOP/Class
Sebenarnya untuk membuat model tidak harus seperti diatas, bisa menggunakan cara berikut
model = nn_sequential( # Layer 1 nn_linear(2, 10), nn_relu(), # Layer 2 nn_linear(10, 5), nn_relu(), # Layee 3 nn_linear(5,1), nn_sigmoid() )