Optimasi Inisiasi Bobot pada Multi Layer Perceptron menggunakan Particle Swarm Optimization

By | November 22, 2022
3,111 Views

Optimasi Inisiasi Bobot pada Multi Layer Perceptron menggunakan Particle Swarm Optimization. Pembahasan mengenai Multi Layer Perceptron telah banyak diulas di blog ini. Mulai dari menggunakan matlab, python, dan R. Namun jarang bgtyang membahas cara Inisiasi Bobot.

Inisiasi Bobot dan Bias selama ini yaitu hanya mengandalkan random by system. Pada tulisan ini, kita bisa menggunakan Particle Swarm Optimization (PSO) untuk mencari bobot yang optimal sebagai pengganti, yang semula inisialisasi bobot secara random.

Fungsi Objektif

Fungsi objektif pada PSO yaitu untuk maksimasisasi dan minimalisasi. Nah fungsi objektif yang akan dimasukan kedalam PSO yaitu proses forward()/perhitungan maju sehingga. Sebelum membahas lebih lanjut cara Inisiasi Bobot dan Bias alangkah baiknya kita sedikit mengulas PSO yang ada di buku https://softscients.com/2020/10/24/buku-belajar-mudah-pemrograman-gnu-octave/ Kalian bisa pelajari sendiri.

Disini hanya contoh penggunaanya saja, sebagai contoh  untuk menemukan titik minimal dari sebuah persamaan kuadraat dari

    \[ y(x) = 2x^2+15x+3 \]

Mari kita coba ploting saja menggunakan matplotlib

import numpy as np
from matplotlib import pyplot as plt

x = np.arange(-15,15,0.1)
y = 2*x**2+15*x+3


#kita akan plotkan
fig, ax = plt.subplots()
ax.plot(x, y, label = "Persamaan kuadrat")
ax.set(xlabel='x',
       ylabel='y',
       title='Persamaan Kuadrat y(x)')
ax.grid()
plt.legend()
plt.show()

Hasilnya yaitu mempunyai titik terendah/minimal  pada posisi x = -3.75 menghasilkan = -25.124

Kalian bisa cari sendiri caranya menggunakan perhitungan biasa. Sedangkan untuk mencari x pada persamaan diatas menggunakan PSO, terlebih dahulu kalian bisa membuat sebuah function

def fitness(x):
    return 2*x**2+15*x+3

Selanjutnya biarkan saja semua nilai argument default, kita akan menggunanakan package pyswam https://pythonhosted.org/pyswarm/

from pyswarm import pso
def fitness(x):
    return 2*x**2+15*x+3    

lowerbound= [-10]
upperbound = [+10]

xopt, fopt = pso(fitness, lowerbound, upperbound)

fungsi objektif diatas akan mempunyai nilai maksimal

xopt
Out[54]: array([-3.75009939])

fopt
Out[55]: array([-25.12499998])

Mari kita buktikan melalui grafik saja

fig, ax = plt.subplots()
ax.plot(x, y, label = "Persamaan kuadrat")
ax.scatter(xopt,fopt,s=10,c="red")
ax.set(xlabel='x',
       ylabel='y',
       title='Persamaan Kuadrat y(x)')
ax.grid()
plt.legend()
plt.show()

hasilnya yaitu

See also  Penjelasan Algoritma RNN dan Contoh Kasus

 

Lebih lanjut kalian bisa pelajari PSO bila sebuah fungsi objektif lebih dari 1 argument di https://pythonhosted.org/pyswarm/

Kita lanjutkan untuk fungsi objektif yang melibatkan 2 argument input. Perhatikan persamaan berikut ini yang bisa kita visualisakan dalam bentuk 3 dimensi

z(x,y) = \frac{x^2}{4} + \frac{y^2}{9}+20

Dengan batasan range sebagai berikut -15\leq x \leq 15 dan -15\leq y \leq 15. Kode untuk visualisasi dalam bentuk 3 dimensi

x = np.arange(-15,15,0.1)
y = np.arange(-15,15,0.1)
X, Y = np.meshgrid(x, y)

def fitness2(x, y):
 return (x**2)/4 + (y**2)/9+20

Z = fitness2(X,Y)
#%matplotlib widget
ax = plt.figure().add_subplot(projection='3d')
ax.plot_surface(X,Y,Z)
ax.set(xlabel='x',
        ylabel='y',
        zlabel= 'z',
        title='Persamaan z(x,y)')
ax.grid()
plt.legend()
plt.show()

Kita bisa melihat titik minimum Z berada di titik 20

 

Carilah x dan y agar nilai z agar minimum?

Hal yang pertama kali kita lakukan yaitu mengubah function berikut

def fitness2(x, y):   
return (x**2)/4 + (y**2)/9+20

menjadi function dengan argument tunggal

def fitness3(a):   
    x = a[0]
    y = a[1]
    return x**4 - 2*y*x**2 + y**2 + x**2 - 2*x + 5

Selanjutnya kita cari menggunakan PSO

lowerbound = [-15, -15]
upperbound = [15, 15]

xopt, fopt = pso(fitness3, lowerbound, upperbound)
xopt
fopt

hasilnya

xopt
Out[23]: array([0.00014709, 0.00013229])

fopt
Out[24]: 20.000000007353048

Nilai diatas adalah pendekatan, karena sebenarnya kita bisa hitung sendiri jika x dan y == 0, maka z = 20

Multi Layer Perceptron

MLP bisa kalian cara tahu di blog ini, saya akan bahas penerapan MLP pada kasus XOR. Berikut adalah kasus LOGIKA XOR yang merupakan kasus non linear dengan input yaitu X dan target berupa Y

Kita akan import dulu package yang diperlukan serta membuat X dan Y sebagai input dan target nya. Untuk library_nn.py nya bisa kalian download. Oiya sebagai gambaran kode tersebut hanya untuk 1 hidden layer saja.

Source code akan tampil dibawah ini, jika kalian telah login/regristrasi

Existing Users Log In




Enter Captcha Here :

   

Model arsitektur yang digunakan yaitu

  1. input layer terdiri dari 2 node
  2. hidden layer terdiri dari 3 node, dan
  3. output layer terdiri dari 1 node
See also  Deep Learning Machine

 

Sehingga nantinya ada bobot sebagai berikut

  1. W1 : 2 baris x 3 kolom
  2. W2 : 3 baris x 1 kolom

 

import numpy as np
from library_nn import Neural_Network


X = np.array((
                [1,1], 
                [1,0],
                [0,1],
                [0,0]
                ), dtype=float)
y = np.array(([1],
              [1],
              [1],
              [0]), dtype=float)

langsung kita gunakan

NN = Neural_Network()
NN.fit(X,y,epoch=500,mse=0.01,debug=False)
print("epoch :",NN.last_epoch,' dengan lost :',NN.lost)
NN.predict(X)
W1 = NN.W1
W2 = NN.W2
print('W1: ',W1)
print('W2: ',W2)

Hasilnya sebagai berikut dengan epoch 500 didapatkan nilai loss sebesar 0.057

epoch : 500 dengan lost : 0.05726335140748321
Predicted data based on trained weights: 
Input (scaled): 
 [[1. 1.]
 [1. 0.]
 [0. 1.]
 [0. 0.]]
Output: 
 [[0.97107994]
 [0.94882221]
 [0.9494473 ]
 [0.09810807]]
W1:  [[ 2.86493957 -2.83761111  1.14184193]
 [ 2.67420815 -2.96554648  1.04789882]]
W2:  [[ 3.56580486]
 [-7.98715381]
 [-0.01550117]]

Fungsi Objektif MLP untuk PSO

Untuk membuat fungsi objektif MLP yang akan dimasukan ke PSO berupa function forward nya

def forward(X,W1,W2):
    #forward propagation through our network
    z = np.dot(X,W1)  # dot product of X (input) and first set of 3x2 weights
    z2 = sigmoid(z)  # activation function
    z3 = np.dot(z2,W2)  # dot product of hidden layer (z2) and second set of 3x1 weights
    o = sigmoid(z3)  # final activation function
    return o
def sigmoid(s):s
    # activation function
    return 1 / (1 + np.exp(-s))
def score(a,b):
    return  np.linalg.norm(a-b)

perhatikan function score() diatas yang akan diminimalkan, semakin kecil semakin bagus nilainya. Kemudian kita akan split bobot/W menggunakan function berikut

def split(W):
    W = np.array(W)
    W1 = W[0:6]
    W1 = np.reshape(W1,[2,3])
    W2 = W[6:9]
    W2 = np.reshape(W2,[3,1])
    return W1,W2

artinya nanti W akan diisi dengan LowerBound dan UpperBound. Inilah yang akan dicari agar nilai score nya kecil. Berikut function fitness yang akan kita masukan ke PSO

def fitness(W,*args):
    W1,W2 = split(W)
    X,Y = args
    prediksi = forward(X,W1,W2)
    return (score(prediksi,Y))

argument input *args adalah argument input tambahan yaitu X dan Y sebagai input dan target pada MLP. Kita buat dulu X dan Y

X = np.array((
                [1,1], 
                [1,0],
                [0,1],
                [0,0]
                ), dtype=float)
Y = np.array(( [0], [1], [1],[0]), dtype=float)

Kemudian kita buat upperbound dan lowerbound serta setting X dan Y nya

#input dan target PSO nya
args =(X,Y)


#upper dan lower partikel
#index 0 sampai 5 sebagai W1
#index 6 sampai 8 sebagai W2
lb = [-10,-10,-10,-10,-10,-10,-10,-10,-10]
ub = [+10,+10,+10,+10,+10,+10,+10,+10,+10]

Ok dilanjutkan dengan PSO nya, saya kasih argument lengkap

xopt, fopt = pso(fitness, lb, ub,
                 swarmsize=100, 
                 omega=0.5, 
                 phip=0.5,
                 phig=0.5, 
                 maxiter=500, 
                 minstep=1e-8,
                 minfunc=1e-8, 
                 debug=False,
                 args=args)

Kita coba print saja xopt dan fopt nya

print('fopt: ',fopt)
W1,W2 = split(xopt)
print('Pencarian Bobot W1 dan W2 oleh PSO')
print('W1 :\n',W1)
print('W2 :\n',W2)

hasilnya yaitu

fopt:  0.7075122491989653
Pencarian Bobot W1 dan W2 oleh PSO
W1 :
 [[-10.          -1.25321416   4.68434161]
 [ -9.82741494  10.          10.        ]]
W2 :
 [[-9.71007943]
 [-5.67837647]
 [ 5.67834171]]

bobot tersebut kita masukan ke MLP dengan hanya memberikan maksimal iterasi == 10 saja

NN2 = Neural_Network()
NN2.W1 = W1
NN2.W2 = W2
NN2.fit(X,Y,epoch=10,mse=0.01,debug=False)
print('Hasil PSO :')
print("epoch :",NN2.last_epoch,' dengan lost :',NN2.lost)

dihasilkan sebagai berikut

epoch : 10  dengan lost : 0.02904214524236343

ternyata epoch maksimal 10 dengan lost 0.029. Bila dibandingkan dengan sebelumnya dengan epoch 500 didapatkan nilai loss sebesar 0.057 maka Optimasi Inisiasi Bobot pada Multi Layer Perceptron menggunakan Particle Swarm Optimization cukup efektif.

See also  Mengoptimalkan Performa Model Machine Learning: Panduan Praktis Split Dataset untuk Training, Testing, dan Validation

Referensi:

  1. https://visualstudiomagazine.com/articles/2013/12/01/neural-network-training-using-particle-swarm-optimization.aspx
  2. https://jamesmccaffrey.wordpress.com/2013/12/23/neural-network-training-using-particle-swarm-optimization/