The Effects of the Learning Rate on Model Performance

Pattharadet Vachirapuchai
5 min readSep 21, 2020

Learning Rate

เป็น Hyperparameter ที่สำคัญตัวหนึ่ง ที่มีหน้าที่ในการปรับขนาดของ Error ในแต่ครั้งของการปรับปรุง Weight และ Bias ด้วย Back-propagation Algorithm ดังสมการต่อไปนี้

Update w = w — Learning_Rate*Error_at_w

Impact of Learning Rate

เราจะใช้ Mnist Dataset ที่เป็นรูปภาพตัวเลข 0–9

import library ก่อนเลย

from tensorflow.keras.datasets import mnist

from tensorflow.keras.layers import Dense, Dropout, Flatten

from tensorflow.keras.models import Sequential

from tensorflow.keras.optimizers import SGD

from tensorflow.keras.utils import to_categorical

from sklearn.datasets import make_blobs

from matplotlib import pyplot

from numpy import where

from sklearn.model_selection import train_test_split

import pandas as pd

import plotly.express as px

import matplotlib.pyplot as plt

import numpy as np

Download และจัดขนาดของภาพ

(X_train, y_train), (X_test, y_test) = mnist.load_data()

X_train, X_test = X_train / 255.0, X_test / 255.0

X_train = np.array([X.flatten() for X in X_train])

X_test = np.array([X.flatten() for X in X_test])

X_train.shape, y_train.shape, X_test.shape, y_test.shape

นำ Dataset ส่วนที่ Train มาแปลงเป็น DataFrame

X_train_pd = pd.DataFrame(X_train)

y_train_pd = pd.DataFrame(y_train, columns=[‘class’])

df = pd.concat([X_train_pd, y_train_pd], axis=1)

df[‘class’] = df[‘class’].astype(str)

y_train = to_categorical(y_train)

y_test = to_categorical(y_test)

Model, Complie Model และ Plot Accuracy

def fit_model(trainX, trainy, testX, testy, lrate):

model = Sequential()

model.add(Flatten(input_shape=(28,28)))

model.add(Dense(units = 50, activation = ‘relu’, kernel_initializer=’he_uniform’))

model.add(Dense(units = 10, activation=’softmax’))

opt = SGD(lr=lrate)

model.compile(loss=’categorical_crossentropy’, optimizer=opt, metrics=[‘accuracy’])

history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=50, verbose=0)

pyplot.plot(history.history[‘accuracy’], label=’train’)

pyplot.plot(history.history[‘val_accuracy’], label=’test’)

pyplot.title(‘lr=’+str(lrate), pad=-35)

learning_rates = [1E-0, 1E-1, 1E-2, 1E-3, 1E-4, 1E-5, 1E-6, 1E-7]

for i in range(len(learning_rates)):

plot_no = 420 + (i+1)

pyplot.subplot(plot_no)

fit_model(X_train, y_train, X_test, y_test, learning_rates[i])

pyplot.tight_layout()

pyplot.savefig(‘lr1.jpeg’, dpi=300)

pyplot.show()

จะเห็นได้ว่า Ir = 0.01,0.001,0.0001, Model ประสบความสำเร็จในการเรียนรู้มากกว่าที่ lr ค่าอื่นๆ โดยที่ lr = 0.01, Model มีอัตราการเรียนรู้สูงที่สุด

Momentum

เป็นเทคนิคในการลดการแกว่งของ Learning Curves พร้อมกับเร่งอัตราการเรียนรู้ของ Model ให้เร็วขึ้น โดยใช้ Velocity (ความเร็ว)

นิยาม Model, กำหนด lr = 0.01, Complie Model และ Plot Accuracy

def fit_model(trainX, trainy, testX, testy, momentum):

model = Sequential()

model.add(Flatten(input_shape=(28,28)))

model.add(Dense(units = 50, activation = ‘relu’, kernel_initializer=’he_uniform’))

model.add(Dense(units = 10, activation=’softmax’))

opt = SGD(lr=0.01, momentum=momentum)

model.compile(loss=’categorical_crossentropy’, optimizer=opt, metrics=[‘accuracy’])

history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=200, verbose=0)

pyplot.plot(history.history[‘accuracy’], label=’train’)

pyplot.plot(history.history[‘val_accuracy’], label=’test’)

pyplot.title(‘momentum=’+str(momentum), pad=-80)

momentums = [0.0, 0.5, 0.9, 0.99]

for i in range(len(momentums)):

plot_no = 220 + (i+1)

pyplot.subplot(plot_no)

fit_model(X_train, y_train, X_test, y_test, momentums[i])

pyplot.tight_layout()

pyplot.savefig(‘momentum.jpeg’, dpi=300)

pyplot.show()

อัตราการเรียนรู้เร็วขึ้นกว่าตอนที่ไม่ได้ใช้ momentum

Learning Rate Decay

เพิ่มประสิทธิภาพของ Model ได้โดยการค่อย ๆ ลด Learning Rate (Learning Rate Decay) ในแต่ละ Epoch ในอัตราที่เหมาะสม

นิยาม Model, กำหนด lr = 0.01, Complie Model และ Plot Accuracy

def fit_model(trainX, trainy, testX, testy, decay):

model = Sequential()

model.add(Flatten(input_shape=(28,28)))

model.add(Dense(units = 50, activation = ‘relu’, kernel_initializer=’he_uniform’))

model.add(Dense(units = 10, activation=’softmax’))

opt = SGD(lr=0.01, decay=decay)

model.compile(loss=’categorical_crossentropy’, optimizer=opt, metrics=[‘accuracy’])

history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=200, verbose=0)

pyplot.plot(history.history[‘accuracy’], label=’train’)

pyplot.plot(history.history[‘val_accuracy’], label=’test’)

pyplot.title(‘decay=’+str(decay), pad=-80)

decay_rates = [1E-1, 1E-2, 1E-3, 1E-4]

for i in range(len(decay_rates)):

plot_no = 220 + (i+1)

pyplot.subplot(plot_no)

fit_model(X_train, y_train, X_test, y_test, decay_rates[i])

pyplot.legend()

pyplot.savefig(‘decay2.jpeg’, dpi=300)

pyplot.show()

Drop Learning Rate

ในตอนที่ Loss Value ไม่ลดลงเป็นระยะเวลาหนึ่ง เราจะเรียกสถานการณ์นี้ว่าการเจอที่ราบสูง (Plateau) เราอาจจะใช้เทคนิคการปรับลดค่า Learning Rate ด้วยการคูณกับค่า factor

from tensorflow.keras.callbacks import Callback

from tensorflow.keras.callbacks import ReduceLROnPlateau

from tensorflow.keras import backend

class LearningRateMonitor(Callback):

def on_train_begin(self, logs={}):

self.lrates = list()

def on_epoch_end(self, epoch, logs={}):

optimizer = self.model.optimizer

lrate = float(backend.get_value(self.model.optimizer.lr))

self.lrates.append(lrate)

def fit_model(trainX, trainy, testX, testy, patience):

model = Sequential()

model.add(Flatten(input_shape=(28,28)))

model.add(Dense(units = 50, activation = ‘relu’, kernel_initializer=’he_uniform’))

model.add(Dense(units = 10, activation=’softmax’))

opt = SGD(lr=0.01)

model.compile(loss=’categorical_crossentropy’, optimizer=opt, metrics=[‘accuracy’])

rlrp = ReduceLROnPlateau(monitor=’val_loss’, factor=0.1, patience=patience, min_delta=1E-7)

lrm = LearningRateMonitor()

history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=50, verbose=0, callbacks=[rlrp, lrm])

return lrm.lrates, history.history[‘loss’], history.history[‘accuracy’]

def line_plots(patiences, series, st):

for i in range(len(patiences)):

pyplot.subplot(220 + (i+1))

pyplot.plot(series[i])

pyplot.title(‘patience=’+str(patiences[i]), pad=-80)

pyplot.legend()

pyplot.savefig(‘patience.jpeg’, dpi=300)

pyplot.show()

patiences = [2, 5, 10, 15]

lr_list, loss_list, acc_list, = list(), list(), list()

for i in range(len(patiences)):

lr, loss, acc = fit_model(X_train, y_train, X_test, y_test, patiences[i])

lr_list.append(lr)

loss_list.append(loss)

acc_list.append(acc)

line_plots(patiences, lr_list, ‘lr’)

line_plots(patiences, loss_list, ‘loss’)

line_plots(patiences, acc_list, ‘acc’)

Learning Rate patience = 2, 5, 10, 15
Loss Value (แกน y) ที่เกิดจากการปรับลด Learning Rate ตามเงื่อนไขที่กำหนด (patience = 2, 5, 10, 15)
Accuracy (แกน y) ที่เกิดจากการปรับลด Learning Rate ตามเงื่อนไขที่กำหนด (patience = 2, 5, 10, 15)

Adaptive Learning Rates Gradient Descent

วิธีสุดท้าย เราจะเปรียบเทียบ Adaptive Learning Rate Algorithm ได้แก่ AdaGrad (Adaptive Gradient Algorithm), RMSprop (Root Mean Square Propagation) และ Adam (Adaptive Moment Estimation) กับ Optimizer พื้นฐาน (SGD Optimizer)

def fit_model(trainX, trainy, testX, testy, optimizer):

model = Sequential()

model.add(Flatten(input_shape=(28,28)))

model.add(Dense(units = 50, activation = ‘relu’, kernel_initializer=’he_uniform’))

model.add(Dense(units = 10, activation=’softmax’))

model.compile(loss=’categorical_crossentropy’, optimizer=optimizer, metrics=[‘accuracy’])

history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=200, verbose=0)

pyplot.plot(history.history[‘accuracy’], label=’train’)

pyplot.plot(history.history[‘val_accuracy’], label=’test’)

pyplot.title(‘opt=’+optimizer, pad=-80)

momentums = [‘sgd’, ‘rmsprop’, ‘adagrad’, ‘adam’]

for i in range(len(momentums)):

plot_no = 220 + (i+1)

pyplot.subplot(plot_no)

fit_model(X_train, y_train, X_test, y_test, momentums[i])

pyplot.legend()

pyplot.savefig(‘adaptive.jpeg’, dpi=300)

pyplot.show()

สำหรับการปรับเปลี่ยนค่า Learning Rate ด้วยวิธีการต่างๆ ก็จบแค่นี้นะครับมารอติดตามบทความต่อไปกันครับขอบคุณที่เข้ามาอ่านครับ

--

--