Tensorflow 2.0 – Gradient-based Optimization bagian 2

By | October 23, 2021
1,579 Views

Tensor Gradient-based Optimization (Gradient Descent)

Pada bab sebelumya telah dibahas gradient descent serta belajar dasar-dasar tensor yuk kita bahas ulang lagi saja, kalian bisa lihat berikut. Mari kita mulai dengan eksperimen sederhana dengan melakukan perhitungan langsung di balik penurunan gradien , perhatikan persamaan kuadrat berikut

    \[y(x) = x^{2}+x-6\]

atau dalam persamaan turunan terhadap x yaitu

(1)   \begin{equation*}  \begin{split} \frac{df}{dx} & = x^{2}+x-6 \\ & =2 x+1 \end{split} \end{equation*}

untuk mencari x ketika y=0 atau mencapai y minimum yaitu

(2)   \begin{equation*}  \begin{split} 2x+1 & =0 \\ 2x & =-1 \\ x & =-\frac{1}{2} \end{split} \end{equation*}

Sekarang nilai x = -\frac{1}{2} akan kita masukan ke persamaan

    \[y(x) = x^{2}+x-6\]

menghasilkan nilai y=-6.25. Yuk kita gambar langsung saja, kalian bisa melihat nilai global minimum nya

Kita mencoba melakukan beberapa kali iterasi untuk melakukan untuk mencari nilai y minimal, maka saya menggunakan rumus berikut

    \[x_{i+1} = x_{i} - \alpha \frac{df}{dx}\]

Dengan menggunakan persamaan diatas dimana:

  • x_{i} adalah nilai tebakan awal /starting point dalam hal ini kita pakai angka x_{i}=1
  • \alpha adalah nilai  kecepatan pemelajaran (membuat “peluruhan lambat”)
  • \frac{df}{dx} adalah turunan dari fungsi  (berlawanan arah dengan turunan)
  • x_{i+1} adalah nilai tebakan berikutnya

Persamaan rumus diatas tidak perlu kita sebutkan lagi secara eksplisit didalam tensor, karena sudah ditangani secara khusus oleh optimizer = tf.compat.v1.train.GradientDescentOptimizer(learning_rate) tidak seperti sebelumnya yang harus kita buat didalam sebuah function tersendiri. Kalau persamaan matematikanya njlimet, mabok juga kita buat fungsi turunan / derivatifnya!

Yuk lanjutkan saja, pertama-tama, kita import terlebih dahulu Numpy dan Tensorflow (ingat ya, saya pakai tensorflow versi 2.0 keatas)

import tensorflow as tf
import numpy as np

tf.compat.v1.disable_eager_execution()

Langkah pertama: membuat variabel dan fungsi yang akan dioptimasi

Misalkan saya buat nilai awal x=2

#### langkah 1 : buat fungsi yang mau di-optimasi ####
# x adalah trainable parameter/variable
x = tf.Variable(2,name="scalar",dtype=tf.float32)

f = (x*x) + (x) - (6)

Langkah kedua: membuat fungsi optimitizer

Kita akan gunakan gradient descent sesuai dengan case diatas serta penetapan learning rate serta penepatan fungsi yang akan dioptimasi

learning_rate = 0.001
optimizer = tf.compat.v1.train.GradientDescentOptimizer(learning_rate)

Berikut kode untuk memangil fungsi yang akan dioptimasi yang akan diarahkan oleh gradient

train_onestep = optimizer.minimize(f)

Langkah ketiga: membuat fungsi training

Kita buat fungsi training (tanpa perlu melibatkan nilai return), didalam fungsi tersebut harus ada initial tensor

def train(sess, epoch=50):

    # inisialisasi variabel 
    init = tf.compat.v1.global_variables_initializer()
    sess.run(init)

    #mulai epoch
    for i in range(epoch):

        # update 1 langkah menuju local optima!
        _, curr_f_x, curr_x = sess.run([train_onestep, f, x])

        #cetak progress untuk setiap 'step' epoch
        print ("\r Epoch-{}, F(x): {}, x: {}".format(i+1, curr_f_x, curr_x))

Langkah keempat: membuat session untuk memanggil tensor

with tf.compat.v1.Session() as sess:    
    ### training ###
    train(sess)
    
    ### tampilkan siapa x itu; X yang terakhir setelah training! ###
    print ("nilai x optimal yaitu ",sess.run(x))

Hasil fungsi dari y(x) = x^{2}+x-6  nilai x  optimal yaitu -0.48711556

 Epoch-1, F(x): 0.0, x: 2.0
 Epoch-2, F(x): -1.1875, x: 1.75
 Epoch-3, F(x): -2.1493749618530273, x: 1.524999976158142
 Epoch-4, F(x): -2.9284934997558594, x: 1.3224999904632568
 Epoch-5, F(x): -3.559579849243164, x: 1.1402499675750732
 Epoch-6, F(x): -4.0707597732543945, x: 0.976224958896637
 Epoch-7, F(x): -4.48481559753418, x: 0.8286024332046509
 Epoch-8, F(x): -4.8202009201049805, x: 0.6957421898841858
 Epoch-9, F(x): -5.091862201690674, x: 0.5761680006980896
 Epoch-10, F(x): -5.311908721923828, x: 0.4685511887073517
 Epoch-11, F(x): -5.490146160125732, x: 0.3716960549354553
 Epoch-12, F(x): -5.634518146514893, x: 0.2845264673233032
 Epoch-13, F(x): -5.75145959854126, x: 0.2060738205909729
 Epoch-14, F(x): -5.846182346343994, x: 0.13546644151210785
 Epoch-15, F(x): -5.922907829284668, x: 0.07191979140043259
 Epoch-16, F(x): -5.985055446624756, x: 0.014727812260389328
 Epoch-17, F(x): -6.035394668579102, x: -0.036744970828294754
 Epoch-18, F(x): -6.076169490814209, x: -0.08307047188282013
 Epoch-19, F(x): -6.109197616577148, x: -0.12476342916488647
 Epoch-20, F(x): -6.135950088500977, x: -0.16228708624839783
 Epoch-21, F(x): -6.157619476318359, x: -0.19605837762355804
 Epoch-22, F(x): -6.175171375274658, x: -0.2264525443315506
 Epoch-23, F(x): -6.189388751983643, x: -0.25380730628967285
 Epoch-24, F(x): -6.2009053230285645, x: -0.2784265875816345
 Epoch-25, F(x): -6.210233211517334, x: -0.30058392882347107
 Epoch-26, F(x): -6.217789173126221, x: -0.32052552700042725
 Epoch-27, F(x): -6.2239089012146, x: -0.33847296237945557
 Epoch-28, F(x): -6.2288665771484375, x: -0.3546256721019745
 Epoch-29, F(x): -6.232881546020508, x: -0.3691630959510803
 Epoch-30, F(x): -6.2361345291137695, x: -0.38224679231643677
 Epoch-31, F(x): -6.238768577575684, x: -0.3940221071243286
 Epoch-32, F(x): -6.240902423858643, x: -0.40461990237236023
 Epoch-33, F(x): -6.242630958557129, x: -0.414157897233963
 Epoch-34, F(x): -6.244030952453613, x: -0.42274209856987
 Epoch-35, F(x): -6.2451653480529785, x: -0.4304678738117218
 Epoch-36, F(x): -6.246083736419678, x: -0.4374210834503174
 Epoch-37, F(x): -6.246827602386475, x: -0.44367897510528564
 Epoch-38, F(x): -6.247430801391602, x: -0.4493110775947571
 Epoch-39, F(x): -6.247919082641602, x: -0.45437997579574585
 Epoch-40, F(x): -6.248314380645752, x: -0.4589419662952423
 Epoch-41, F(x): -6.2486348152160645, x: -0.4630477726459503
 Epoch-42, F(x): -6.252220153808594, x: -0.47006869316101074
 Epoch-43, F(x): -6.2491044998168945, x: -0.47006869316101074
 Epoch-44, F(x): -6.249274730682373, x: -0.47306182980537415
 Epoch-45, F(x): -6.2494120597839355, x: -0.4757556617259979
 Epoch-46, F(x): -6.249523639678955, x: -0.47818008065223694
 Epoch-47, F(x): -6.249614238739014, x: -0.48036208748817444
 Epoch-48, F(x): -6.249687671661377, x: -0.48232588171958923
 Epoch-49, F(x): -6.249746799468994, x: -0.4840932786464691
 Epoch-50, F(x): -6.249794960021973, x: -0.48568394780158997
nilai x optimal yaitu  -0.48711556

 

See also  Pytorch - Apa itu Operasi Linear, Bobot, dan Bias pada Algoritma CNN