Machine Learning #1 – Hello World!

Jika ada nilai input: x = [-1 0 1 2 3 4] ternyata menghasilkan nilai ouput: y = [-3 -1 1 3 5 7]

Jadi, apa rumus dari y ? apakah y=2x+1 atau y=x-2 atau yang lainnya?

Mari kita ajarkan nilai input dan ouput ini ke “MESIN”, agar si MESIN ini bisa belajar mencari model matematikanya. Dalam hal ini kita sebut saja dengan Machine Learning.

MESIN kita berikan petunjuk bahwa rumus dari y adalah linier, (y = wx + b) dimana w dan b adalah bilangan yang harus dicari oleh mesin.

Anggap saja Mesin menebak, w=3 dan b=-1, (y = 3x – 1) namun ternyata dari hasil perhitungan rumus itu adalah y = [-4 -1 2 5 8 11]

Hijau => Tebakan Mesin, Biru => Nilai seharusnya
Selisih dari setiap elemen perhitungan adalah, gap = [-1 0 1 2 3 4]
Jika setiap selisih dikuadratkan, maka gap = [1 0 1 4 9 16]

Jumlah dari kesalahan gap adalah, err = 1 + 0 + 1 + 4 +9 +16 = 31. OK, bagaimana kalau diakarkan saja? gap-nya kan dikuadratkan, jadi agar sebanding maka err adalah akar dari 31. Ini disebut dengan Mean Square Error, MSE = 5,57 (atau akar dari 31).

Ok, mesin coba jika y = 2x – 2. Maka hasil perhitungannya, y = [-4 -2 0 2 4 6], kalau dihitung MSE-nya maka hasilnya adalah 1 (MSE= 2,23) Wow, MSE sudah mulai berkurang. Proses ini dilakukan berulang ualng.

Mesin mencoba lagi, y = 2x – 1. Maka hasil perhitungannya y = [-3 -1 1 3 5 7] nah… ini baru tepat!

Mesin berhasil menebak, rumus matematikanya adalah y = 2x – 1

Menerapkan analogi di atas pada Machine Learning lewat Colabs (Atau jupyter notebook)

import tensorflow as tf
import numpy as np
from tensorflow import keras

model = tf.keras.Sequential([keras.layers.Dense(units=1, input_shape=[1])])
model.compile(optimizer='sgd', loss='mean_squared_error')

x = np.array([-1.0,  0.0, 1.0, 2.0, 3.0, 4.0], dtype=float)
y = np.array([-3.0, -1.0, 1.0, 3.0, 5.0, 7.0], dtype=float)

model.fit(x, y, epochs=50)

Baris 1 – 3 adalah penggunaan library tensonflow, numpy dan keras.

Baris 5, kita membuat model 1 input dan 1 output.

Baris 6, kita gunakan optimizer SGD (Stochastic Gradient Descent), sedangkan lost function-nya (untuk mengurangi kesalahannannya) menggunakan metode Mean Square Error (MSE) seperti yang dianalogikan di atas.

Baris 8 adalah nilai masukan, sedangkan baris 9 adalah hasil ouputnya.

Baris 10, kita minta MESIN untuk mencari model matematikanya dengan mencobanya sebanyak 50 kali.

Pertama tama, w=3 dan b = 1, namun error (loss) nya adalah 15,1. Karena gradien dari loss sudah ditemukan, maka MESIN mulai mengubah w dan b sesuai arah gradien, dalam hal ini percebaan kedua w=1,53 dan b = 0,37. Proses berulang-ulang hingga mencapi perulangan (epoch) yang kita tentukan. Contoh dalam kode ini adalah 50 epoch.

Pada akhirnya di-epoch ke 50, ditemukan w=2 dan b = -0.99 dimana loss-nya mendekati 0 (0,00009)

Perkiraan w dan b oleh MESIN dari epoch 1 hingga 50

Saat ini MESIN yakin bahwa rumus matematika yang didapatkan adalah y = 2x – 0,99 selanjutnya mari kita coba jika x adalah 4.

print(model.predict([4]))

Kode diatas adalah untuk memeriksa, memprediksikan, jika x = 4 maka berapakah nilai y nya

Hasilnya adalah 6.8087044, walaupun seharusnya hasilnya adalah 7
hasil perhitungan MESIN mendekati benar, dari setiap elemen nilai x

Kode untuk menampilkan plot

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

# Tebakan awal
INITIAL_W = 3.0
INITIAL_B = 1.0

# Fungsi menghitung loss
def loss(predicted_y, target_y):
  return tf.reduce_mean(tf.square(predicted_y - target_y))

# Proses training
def train(model, inputs, outputs, learning_rate):
  with tf.GradientTape() as t:
    current_loss = loss(model(inputs), outputs)
  # mencari arah gradien loss
  dw, db = t.gradient(current_loss, [model.w, model.b])
  # perbaiki model untuk epoch berikutnya dengan mengubah w dan b berdasarkan learning_rate
  model.w.assign_sub(learning_rate * dw)
  model.b.assign_sub(learning_rate * db)
  return current_loss

# Mendefinisikan model regresi linier
class Model(object):
  def __init__(self):
    # Inisialisasi w dan b
    self.w = tf.Variable(INITIAL_W)
    self.b = tf.Variable(INITIAL_B)

  def __call__(self, x):
    return self.w * x + self.b

"""Proses Training"""

# tentukan input, output dan learning rate
xs = [-1.0, 0.0, 1.0, 2.0, 3.0, 4.0]
ys = [-3.0, -1.0, 1.0, 3.0, 5.0, 7.0]
LEARNING_RATE=0.09

# Instantiate model
model = Model()

# Menampilkan w, b dan loss di setiap epoch
list_w, list_b = [], []
epochs = range(50)
losses = []
for epoch in epochs:
  list_w.append(model.w.numpy())
  list_b.append(model.b.numpy())
  current_loss = train(model, xs, ys, learning_rate=LEARNING_RATE)
  losses.append(current_loss)
  print('Epoch %2d: w=%1.2f b=%1.2f, loss=%2.5f' %
        (epoch, list_w[-1], list_b[-1], current_loss))

"""### Plot hasil training"""

# Plot nilai w dan b perkiraan dari hasil training terhadap w dan b seharusnya
TRUE_w = 2.0
TRUE_b = -1.0
plt.plot(epochs, list_w, 'r', epochs, list_b, 'b')
plt.plot([TRUE_w] * len(epochs), 'r--', [TRUE_b] * len(epochs), 'b--')
plt.legend(['w perkiraan', 'b perkiraan', 'w seharusnya', 'b seharusnya'])
plt.show()