Stochastic Gradient Descent
Stochastic Gradient Descent (SGD) เป็นวิธีการหลักในการ Train Neural Network Model โดยใช้ Gradient หรือ ความชัน เป็นตัวบอกขนาดและทิศทางในการปรับ Parameters ที่จะทำให้ Loss Value เคลื่อนที่ไปยัง จุดต่ำสุดของพื้นผิว (Minima) การทำความเข้าใจแนวคิดของ SGD จึงเป็นสิ่งสำคัญในการที่จะทำให้สามารถปรับจูน Neural Network โดยเฉพาะ Deep Learning Model ให้มีประสิทธิภาพมากยิ่งขึ้น
โดยในบทนี้ได้ทำความเข้าใจพฤติกรรมการเคลื่อนที่ของ Loss Value ในแต่ละรอบของการ Train Model แบบ Linear Regression โดยใช้ Tensorflow และ Keras Framework ซึ่งจะมีวิธีการ 2 แบบ ได้แก่
- Gradient Descent
- Stochastic Gradient Descent
Gradient Descent Method
Two Dimensional Parabola Graph
เพื่อให้เห็นภาพมากขึ้น ขอยกตัวอย่างกราฟพาราโบลา y=x²-2x+3 ซึ่งมีจุดต่ำสุดที่จุด x เท่ากับ 1 ดังภาพด้านบน จุดมุ่งหมายของ Gradient Descent Method คือการหาค่าของ x (Weight หรือ Bias) ที่ทำให้ y (Loss Value) มีค่าต่ำสุด โดยการปรับค่า x ให้ค่อยๆ เคลื่อนที่ไปตามทางลาด (Descending) ของพื้นผิวนั้นๆ
สมมติว่าหากผูกผ้าปิดตาแล้วนำไปวางไว้ที่จุด x เท่ากับ -4 การที่จะไปยังจุดต่ำสุดได้ เราต้องอาศัยสัมผัสของเท้าทั้ง 2 ข้างเพื่อประเมินว่าจะเดินไปทางซ้ายหรือทางขวา โดยในการประเมิน เราจะหาอนุพันธ์ของฟังก์ชัน y เทียบกับ x (หา Gradient)
ดังนั้นที่จุด x เท่ากับ -4 ความชันของกราฟพาราโบลาจะมีค่าเท่ากับ -10
Gradient = 2x-2
= (2)(-4)-(2)
= -10
ซึ่งเมื่อความชันเป็นลบ เราจึงรู้ได้ว่าพื้นผิวที่ยืนอยู่นั้น มีการลาดเอียงมาทางขวามือ เราจึงเดินไป 10 ก้าว ยังจุดที่ x เท่ากับ 6
Update x = x-(-10)
= (-4)-(-10)
= 6
อย่างไรก็ตามการเดินถึง 10 ก้าว ทำให้เราเคลื่อนที่ไปยังอีกฝั่งของหลุมที่ความชันเป็นบวก แทนที่จะค่อยๆ เดินลงหลุมไปยังจุดต่ำสุด ดังนั้นในการ Train Model จริง จึงต้องมีการ Update ค่า x ด้วยจำนวนก้าวที่ไม่มากนัก โดยการทำให้ Gradient มีขนาดเล็กลง ด้วยการคูณด้วย Learning Rate ที่มีค่าอยู่ระหว่าง 0–1 ตามสมการด้านล่าง
Learning_Rate = 0.01
Update x = x - Learning_Rate*Gradient
= (-4)-(0.01)(-10)
= -3.9
Linear Regression with Tensorflow
เริ่มต้นด้วยการ Implement Neural Network Model แบบ Linear Regression ด้วย Tensorflow Framework เพื่อศึกษาการเคลื่อนที่ของ Loss Value โดยใช้ Gradient Descent Method จาก Fish market ดังตัวอย่างตามขั้นตอนต่อไปนี้
Import Library
import tensorflow.compat.v1 as tf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as seabornInstance
from sklearn.model_selection import train_test_split
from sklearn import metricsfrom tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.layers import Dense
from keras import backend as K
import plotly
import plotly.graph_objs as go
import plotly.io as piopio.renderers.default = 'colab'
%matplotlib inline
กำหนด Random Seed และจำนวน Epoch ที่จะ Train
np.random.seed(seed=13)
EPOCH = 500
Load ไฟล์ Fish.csv ซึ่งพบว่ามีทั้งหมด 159 Row โดยจะนำข้อมูลใน Column Height มาทำเป็น Input Data หรือตัวแปรอิสระ (Predictor) และ Width มาทำเป็นผลเฉลย หรือตัวแปรตาม (Response)
Plot Heightและ Width เพื่อดูลักษณะของข้อมูล
ดูการกระจายตัวของ Height
แยก Dataset เป็น Input Data (x) และผลเฉลย (y)
X = dataset['Height'].values.reshape(-1,1)
y = dataset['Width'].values.reshape(-1,1)
สุ่มแบ่งข้อมูลเป็น 2 ชุด สำหรับ Train 80% และ Test 20%
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle= True)
นิยาม Model ด้วย Tensorflow โดยจะมีการนำ X_train เข้า Model ทั้งก้อนขนาด 127 Row
W = tf.Variable(tf.random.uniform([1], -1.0, 1.0))
b = tf.Variable(tf.random.uniform([1], -1.0, 1.0))
y = W * X_train + b
นิยาม Loss Function แบบ Mean Squared Error (MSE)
loss = tf.reduce_mean(tf.square(y - y_train))
กำหนด Optimizer และ Learning Rate
optimizer = tf.train.GradientDescentOptimizer(0.0001)
train = optimizer.minimize(loss)
โดย Optimizer จะมีการทำ Back-propagation Algorithm เพื่อปรับค่า Weight (W) และ Bias (b) ให้อัตโนมัติ
เคลียร์ Tensorflow Variable
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
Train Model
his=[]
wb = []
for step in range(EPOCH):
sess.run(train)
his.append(sess.run(loss))
print(step, sess.run(W), sess.run(b), sess.run(loss))
wb.append([sess.run(W)[0], sess.run(b)[0], sess.run(loss)])
ดึง Weight (W) และ Bias (b) มาสร้าง Linear Regression Model
M = sess.run(W)
C = sess.run(b)
นิยาม Function Predict
def predict(X, M, C):
y = M*X+C
return y[0]
แปลง Loss Value List เป็น DataFrame
df = pd.DataFrame(his, columns=['loss'])
Plot Loss
Predict Height
แสดงผลการ Predict 10 แถวแรก
Plot กราฟเปรียบเทียบผลการทำนายกับค่าจริง
แสดง Model ที่สร้างจากการ Train ใน Epoch ที่ 1
M = [i[0] for i in wb]
L = [i[2] for i in wb]
C = [i[1] for i in wb]
แสดง Model ที่สร้างจากการ Train ใน Epoch ที่ 5
แสดง Model ที่สร้างจากการ Train ใน Epoch ที่ 10
แสดง Model ที่สร้างจากการ Train ใน Epoch ที่ 500
ดู Loss Value เทียบกับค่า Weight
ดู Loss Value เทียบกับค่า Bias
ดู Loss Value เทียบกับค่า Weight และ Bias
จะเห็นว่าค่า Loss Value จะค่อยๆ เคลื่อนที่ไปยังจุดต่ำสุดของพื้นผิว (Minima) แบบ 3 มิติ ด้วย Learning Rate เท่ากับ 0.0001 ครับ
วัดประสิทธิภาพของ Model ด้วย Mean Absolute Error, Mean Squared Error และ Root Mean Squared Error
Stochastic Gradient Descent Method
Linear Regression with Keras
ต่อไปจะทดลอง Train Neural Network Model แบบ Linear Regression โดยใช้ Keras Framework ซึ่งในการ Train Model ด้วย Keras นั้นจะใช้เวลาค่อนข้างมาก การจะนำ Dataset เข้า Train Model เป็นก้อนใหญ่ๆ จึงไม่เหมาะสม
ดังนั้นเราจะใช้การสุ่มแบ่ง Dataset เป็นก้อนเล็กๆ ขนาด 64 Row (Batch Size เท่ากับ 64) เพื่อนำไป Train Model ซึ่งเราจะเรียก Gradient Descent แบบที่มีการสุ่มแบ่ง Dataset เป็นก้อนขนาดเล็กว่า Stochastic Gradient Descent
นิยาม Root Mean Squared Error
def rmse(y_true, y_pred):
return K.sqrt(K.mean(K.square(y_pred - y_true), axis=-1))
นิยาม Model
model = Sequential()
model.add(Dense(1, input_dim=1, kernel_initializer='random_uniform', activation='linear'))
model.summary()
Compile Model
model.compile(loss='mse', optimizer='adam', metrics=['mae', 'mse', rmse])
Train Model ด้วยการสุ่มแบ่งข้อมูลสำหรับ Train 80% และ Validate อีก 20% โดยกำหนด Batch Size เท่ากับ 64
history = model.fit(X_train, y_train, epochs=EPOCH, batch_size=64, verbose=1, validation_split=0.2, shuffle=True)
Plot Loss และ Validate Loss
Predict
y_pred = model.predict(X_test)
แปลงเป็น DataFrame
y_pred = y_pred.flatten()
df = pd.DataFrame({'Actual': y_test, 'Predicted': y_pred})
df.head(10)
Plot กราฟเปรียบเทียบผลการทำนายกับค่าจริง
แสดง Model ที่สร้างจากการ Train 500 Epoch
วัดประสิทธิภาพของ Model ด้วย Mean Absolute Error, Mean Squared Error และ Root Mean Squared Error
Reference
https://blog.pjjop.org/introduction-to-stochastic-gradient-descent-with-tensorflow-and-keras
Colab
https://colab.research.google.com/drive/1lH0PLUIgjTPJkb5BkJ0_ZTTBEe50jATn?usp=sharing
บทความนี้เป็นส่วนหนึ่งของรายวิชา AI จัดทำขึ้นเพื่อทดลองทำ Lab ซึ่งหากมีข้อผิดพลาดใดๆ ขออภัยไว้ ณ ที่นี้