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
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
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
Dengan batasan range sebagai berikut dan . 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
Model arsitektur yang digunakan yaitu
- input layer terdiri dari 2 node
- hidden layer terdiri dari 3 node, dan
- output layer terdiri dari 1 node
Sehingga nantinya ada bobot sebagai berikut
- W1 : 2 baris x 3 kolom
- 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.