Basic Neural Network Menggunakan NumPy

[latexpage]

Pada lesson basic neural network menggunakan NumPy akan membahas membuat machine learning menggunakan library NumPy.

Tujuan dari lesson ini adalah untuk memberikan gambaran sederhana bagaimana machine learning bekerja di belakang layar jika menggunakan library seperti TensorFlow atau PyTorch. Karena sebagai gambaran saja, maka data observation dan target akan digenerate automatik menggunakan NumPy.

Untuk memudahkan proses belajar, gunakan jupyter notebook. Download file basic-neural-network-numpy.ipynb

#import library
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

#tentukan besar data
observations = 1000000

#generate data 
xs = np.random.uniform(low=-10, high=10, size=(observations,1))
zs = np.random.uniform(-10, 10, (observations,1))
inputs = np.column_stack((xs,zs))

#generate target
noise = np.random.uniform(-1, 1, (observations,1))
targets = 13*xs + 7*zs - 12 + noise

#inisialisasi weight dan bias awal
init_range = 0.1
weights = np.random.uniform(low=-init_range, high=init_range, size=(2, 1))
biases = np.random.uniform(low=-init_range, high=init_range, size=1)

#tentukan learning rate
learning_rate = 0.02

#model training
for i in range (100):
    outputs = np.dot(inputs,weights) + biases
    deltas = outputs - targets

    loss = np.sum(deltas ** 2) / 2 / observations
    print (loss)
    
    deltas_scaled = deltas / observations    

    weights = weights - learning_rate * np.dot(inputs.T,deltas_scaled)
    biases = biases - learning_rate * np.sum(deltas_scaled)

print(weights, biases)

#visualize data
plt.plot(outputs,targets)
plt.xlabel('outputs')
plt.ylabel('targets')
plt.show()

Pembahasan Code

Import library yang diperlukan untuk membuat model, yaitu NumPy. Sebetulnya cukup diperlukan NumPy saja, library lainnya digunakan untuk membuat visual graphic.

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

Disini data digenerate otomatis, pada prakteknya data akan diambil dari data real. Untuk generate kita gunakan NumPy untuk membuat random data observation.

Besar observation (n) adalah 1000. Anda bisa bereksperimen besarnya data, makin besar data makin lambat komputer melakukan proses.

Model yang akan dibuat adalah 2 input. Data akan digenerate di variable x dan z menggunakan fungsi random.uniform. Untuk dokumentasi silakan lihat di numpy.random.uniform.

Kedua variable x dan z kemudian digabung menjadi matrix n x k disimpan dalam variable inputs menggunakan perintah column_stack.

Perhatian, dimensi matrix sangat penting dalam Aljabar Linear. Karena kita hanya dapat mengkalikan matrix dengan dimensi yang kompatible. (lihat lesson Machine Learning Model pada bagian dimensi matrix multiple input).

observations = 1000000

xs = np.random.uniform(low=-10, high=10, size=(observations,1))
zs = np.random.uniform(-10, 10, (observations,1))
inputs = np.column_stack((xs,zs))

Seperti data observasi, data target pun kita generate otomatis. Dimensi matrix target adalah n x 1. Target akan dibuat dengan fungsi 13x + 7z 12 + noise. Anda bisa menggunakan fungsi lain, yang penting fungsi linear.

Jadi, kita mengharapkan model setelah ditraining dapat memprediksi nilai weight dan bias, yaitu w1=13, w2=7 dan b=-12.

Untuk noise, sengaja ditambahkan agar data lebih random. Karena pada prakteknya real data selalu mengandung noise.

noise = np.random.uniform(-1, 1, (observations,1))
targets = 13*xs + 7*zs - 12 + noise

Model akan mencari nilai w dan b agar output mendekati nilai target. Seperti yang sudah kita pelajari, untuk mengoptimalkan nilai w dan b, digunakan gradient descent.

Kita akan memilih nilai awal dari w dan b secara random. Walaupun random, kita gunakan nilai awal yang kecil.Variable init_range akan digunakan untuk memilih nilai awal weight dan bias pada range [-0.1, 0.1]

Inisialisasi weights akan dibuat menggunakan fungsi Numpy.random.uniform. Perhatikan dimensi matrix adalah 2×1.

Inisialisasi bias juga dibuat menggunakan fungsi Numpy.random.uniform. Perhatikan dimensi matrix adalah 1×1.

init_range = 0.1
weights = np.random.uniform(low=-init_range, high=init_range, size=(2, 1))
biases = np.random.uniform(low=-init_range, high=init_range, size=1)

Berikutnya adalah set learning rate dari model. Pada contoh adalah 0.02, silakan Anda bereksperimen mengubah nilai learning rate.

learning_rate = 0.02

Berikutnya adalah melakukan model training. Tujuannya adalah meminimumkan nilai cost/loss function. Karena ini adalah model linear, maka loss function yang digunakan adalah half L2-norm. L2-norm function adalah $\sum (y_i – t_i)^2$.

Proses learning adalah proses berulang, karena itu kita gunakan block for. Dengan step didalamnya adalah

  • Hitung outputs, menggunakan perintah numpy.dot.
  • Untuk kemudahan perhitungan los function buat variable deltas untuk menghitung perbedaan outputs dan targets.
  • Hitung loss function L2-norm menggunakan numpy.sum. Karena kita akan menggunakan half L2-norm, maka dibagi 2. Kemudian dibagi lagi dengan nilai observations, untuk mendapatkan nilai rata-rata loss per observasion (mean loss). Hal ini akan dibahas lebih detail pada akhir lesson.
  • Print loss setiap iterasi, untuk kepentingan observasi program.
  • Adjust weight dan bias menggunakan gradient descent logic yaitu $w_{i+1} = w_i – \eta \sum_i x_i\delta_i$ dan $b_{i+1} = b_i – \eta \sum_i \delta_i$

Perhatian, inputs adalah matrix 1000×2, sementara deltas_scaled adalah 1000×1, maka dari itu matrix inputs harus ditranpose dengan menggunakan metoda object.T dari numpy.

for i in range (100):
    outputs = np.dot(inputs,weights) + biases
    deltas = outputs - targets

    loss = np.sum(deltas ** 2) / 2 / observations
    print (loss)
    
    deltas_scaled = deltas / observations    

    weights = weights - learning_rate * np.dot(inputs.T,deltas_scaled)
    biases = biases - learning_rate * np.sum(deltas_scaled)

Setelah selesai menjalankan code diatas, maka kita bisa melihat nilai weigths dan biases terakhir. Bandingkan nilai tersebut dengan fungsi target yang kita definisikan, dalam lesson ini adalah 13x + 7z – 12 + noise (w1=13, w2=7, b=-12).

print(weights, biases)

#akan menampilkan nilai weights dan biases terakhir
[[12.9999195 ]
 [ 7.00020463]] [-11.7898171]

Mungkin hasil Jika nilainya masih jauh dari target, hal ini bisa disebabkan karena iterasi untuk mentraining model terlalu kecil atau learning rate yang kurang tepat. Coba lakukan for loop diatas sekali lagi, dan lihat lagi nilainya.

Terakhir adalah kita plot hasil perhitungan kita secara visual.

plt.plot(outputs,targets)
plt.xlabel('outputs')
plt.ylabel('targets')
plt.show()

Whats Next

Selanjutnya Anda bisa bereksperimen dengan mengubah parameter berikut:

  • Jumlah observasi
  • Larning rate
  • Jumlah iterasi for loop
  • Atau initial range (var init_range) dari weights dan biases

Selamat mencoba, semoga bermanfaat.

Sharing is caring: