728x90

Stochastic Gradient Descent : 확률적 경사하강법

Summary 

* 신경망 훈련 방법 살펴보기

* 신경망 훈련 역시 특성(feature)과 target(출력)으로 구성된 훈련 데이터가 필요하다. 

   : "신경망을 훈련한다"는 것은 feature를 target으로 변환하기 위해 가중치를 조정하는 것을 의미한다.

* 훈련 데이터 외에 네트워크의 예측 정확도를 측정하는 손실 함수(loss function), 가중치를 최적화하는 optimizer가 필요하다.

 

Loss Function 

손실 함수(Loss Function)은 모델이 예측한 값과 Target의 실제 값의 차이를 측정하는 것으로 훈련 과정에서 모델(신경망)의 문제를 설명한다.

회귀 문제(regression problem)에서 일반적인 Loss Function은 Mean Absolute Error (MAE) 이다.
Target 실제값(y_true)에서 예측값(y_pred)을 차이의 절대값으로 절대 오차를 계산한다.  AE = abs(y_true - y_pred)

데이터셋 전체에서 이러한 절대 오차의 평균이 MAE가 된다. 

MAE 외에 다른 손실 함수는 mean-squared error (MSE), Huber loss가 있다. ( keras 모두 지원함. )

훈련하는 동안 모델은 최적에 가중치를 값을 찾기 위해 손실 함수를 사용한다. 즉, 손실 함수는 모델(신경망)의 목적을 알려준다.

The mean absolute error is the average length between the fitted curve and the data points.

 

Optimizer - Stochastic Grandient Descent 

옵티마이저(Optimizer)는 손실을 최소화 하기 위해서 가중치를 조정하는 알고리즘이다. 

딥러닝에서 대부분의 최적화 알고리즘은 확률적 경사하강법을 채택하고 있다. 

 

[신경망을 단계적으로 훈련시키는 반복 알고리즘]

1. 일부 훈련 데이터를 샘플링하고 신경망을 통해서 예측을 한다. 

2. 예측값과 실제값 사이에 손실을 측정한다.

3. 손실이 작아지는 방향으로 가중치를 조정한다. 

4. 손실이 원하는 만큼 작아지거나, 변화가 없을 때까지 이 작업을 반복한다. 

 

각 반복의 훈련 데이터 샘플을 minibatch (or batch)라고 한다.

훈련 데이터의 전체 라운드 epoch라고 한다. 

 

Training a neural network with Stochastic Gradient Descent.

위에 애니메이션은 SGD(Stochastic Grandient Descent)로 훈련되는 Lesson 1의 선형 모델을 보여준다.

옅은 빨간색 점은 전체 훈련 세트를 나타내고 진한 빨간색 점은 미니 배치를 나타낸다.

SGD는 새 미니배치를 볼 때마다 가중치(w:기울기 및 b:y-intercept)를 해당 배치의 올바른 값으로 이동한다.

배치를 반복하고, 결국 라인은 적합 수준에 수렴된다.

가중치가 실제 값에 가까워질수록 손실이 작아지는 것을 볼 수 있습니다.


728x90

Learning Rate and Batch Size

위 애니메이션에서 라인은 각 배치 때마다 조금씩 이동하고 있다. 이러한 이동은 학습률(Learning Rate)에 의해 결정된다. 

학습률이 낮다는 것은 신경망의 가중치가 최상의 값에 수렴되기 전으로 미니배치를 더 수행할 필요가 있음을 의미한다. 

대부분의 작업에서 만족스러운 결과를 얻기 위해 광범위한 하이퍼파라미터 검색을 수행할 필요는 없다. 

Adam은 매개변수 조정 없이 대부분의 문제에 적합하도록 적응 학습률을 갖는 SGD 알고리즘이다. 

 

모델을 정의한 후에 compile() 메소르를 사용하여 손실함수와 최적화 프로그램을 설정한다. 

model.compile(
    optimizer="adam",
    loss="mae",
)

reference :
* Adam Optimizer : https://www.tensorflow.org/api_docs/python/tf/keras/optimizers/Adam
* MAE : https://www.tensorflow.org/api_docs/python/tf/keras/losses/MeanAbsoluteError
* Sequential.compile() method : https://www.tensorflow.org/api_docs/python/tf/keras/Sequential#compile

더보기

tf.keras.optimizers

class Adadelta: Optimizer that implements the Adadelta algorithm.

class Adagrad: Optimizer that implements the Adagrad algorithm.

class Adam: Optimizer that implements the Adam algorithm.

class Adamax: Optimizer that implements the Adamax algorithm.

class Ftrl: Optimizer that implements the FTRL algorithm.

class Nadam: Optimizer that implements the NAdam algorithm.

class Optimizer: Base class for Keras optimizers.

class RMSprop: Optimizer that implements the RMSprop algorithm.

class SGD: Gradient descent (with momentum) optimizer.

source :  https://www.tensorflow.org/api_docs/python/tf/keras/optimizers

 

tf.keras.losses ( loss functions )

KLD(...): Computes Kullback-Leibler divergence loss between y_true and y_pred.

MAE(...): Computes the mean absolute error between labels and predictions.

MAPE(...): Computes the mean absolute percentage error between y_true and y_pred.

MSE(...): Computes the mean squared error between labels and predictions.

MSLE(...): Computes the mean squared logarithmic error between y_true and y_pred.

binary_crossentropy(...): Computes the binary crossentropy loss.

binary_focal_crossentropy(...): Computes the binary focal crossentropy loss.

categorical_crossentropy(...): Computes the categorical crossentropy loss.

categorical_hinge(...): Computes the categorical hinge loss between y_true and y_pred.

cosine_similarity(...): Computes the cosine similarity between labels and predictions.

deserialize(...): Deserializes a serialized loss class/function instance.

get(...): Retrieves a Keras loss as a function/Loss class instance.

hinge(...): Computes the hinge loss between y_true and y_pred.

huber(...): Computes Huber loss value.

kl_divergence(...): Computes Kullback-Leibler divergence loss between y_true and y_pred.

kld(...): Computes Kullback-Leibler divergence loss between y_true and y_pred.

kullback_leibler_divergence(...): Computes Kullback-Leibler divergence loss between y_true and y_pred.

log_cosh(...): Logarithm of the hyperbolic cosine of the prediction error.

logcosh(...): Logarithm of the hyperbolic cosine of the prediction error.

mae(...): Computes the mean absolute error between labels and predictions.

mape(...): Computes the mean absolute percentage error between y_true and y_pred.

mean_absolute_error(...): Computes the mean absolute error between labels and predictions.

mean_absolute_percentage_error(...): Computes the mean absolute percentage error between y_true and y_pred.

mean_squared_error(...): Computes the mean squared error between labels and predictions.

mean_squared_logarithmic_error(...): Computes the mean squared logarithmic error between y_true and y_pred.

mse(...): Computes the mean squared error between labels and predictions.

msle(...): Computes the mean squared logarithmic error between y_true and y_pred.

poisson(...): Computes the Poisson loss between y_true and y_pred.

serialize(...): Serializes loss function or Loss instance.

sparse_categorical_crossentropy(...): Computes the sparse categorical crossentropy loss.

squared_hinge(...): Computes the squared hinge loss between y_true and y_pred.

 

source : https://www.tensorflow.org/api_docs/python/tf/keras/losses

 

Example Code 

red-wine (red-wine.csv) 데이터 세트에서 quality를 Target으로 하고 나머지를 Feature해서 quality 를 예측하는 모델을 만들어보고자 한다. 

<학습용 데이터 : red-wine.csv>

red-wine.csv
0.10MB

학습 데이터 불러오고, 간단한 전처리와 훈련용/유효성검사용 데이터로 분리한다. 또한 target과 feature 분리한다. 

import pandas as pd

raw_df = pd.read_csv("../data/red-wine.csv")

# Create training and validation splits
df_train = raw_df.sample(frac=0.7, random_state=0)
df_valid = raw_df.drop(df_train.index)

#df_train.head(4)


# Scale to [0, 1]
max_ = df_train.max(axis=0)
min_ = df_train.min(axis=0)
df_train = (df_train - min_) / (max_ - min_)
df_valid = (df_valid - min_) / (max_ - min_)

# Split features and target
X_train = df_train.drop('quality', axis=1)
X_valid = df_valid.drop('quality', axis=1)
y_train = df_train['quality']
y_valid = df_valid['quality']
 

훈련용 데이터의 차원을 확인한다.

print(X_train.shape)

# output
# (1119, 11)

11개의 feature존재하는 것을 확인했다. 

 

11개의 입력을 가진 512개의 relu 로 구성된 입력 Layers, 2개의 Hidden Layer, 마지막으로 linear unit 한개로 구성된 출력 레이어를 추가한다. 

from tensorflow import keras
from tensorflow.keras import layers

model = keras.Sequential([
    layers.Dense(units=512, activation="relu", input_shape=[11]),
    layers.Dense(units=512, activation="relu"),
    layers.Dense(units=512, activation="relu"),
    layers.Dense(units=1)
])

model의 compile() 메소드를 사용하여 optimizer와 loss function 을 설정한다. 

model.compile(
    optimizer = "adam",
    loss = "mae"
)

batch_size을 128개, epochs를 15로 설정하고 훈련을 진행한다. 

history = model.fit(
    X_train, y_train,
    validation_data = (X_valid, y_valid),
    batch_size = 128,
    epochs=15
)

'''
<class 'pandas.core.frame.DataFrame'>, <class 'NoneType'>
Train on 1119 samples, validate on 480 samples
Epoch 1/15
1119/1119 [==============================] - 0s 55us/sample - loss: 0.0967 - val_loss: 0.0973
Epoch 2/15
1119/1119 [==============================] - 0s 64us/sample - loss: 0.0954 - val_loss: 0.0977
Epoch 3/15
1119/1119 [==============================] - 0s 70us/sample - loss: 0.0938 - val_loss: 0.0985
Epoch 4/15
1119/1119 [==============================] - 0s 111us/sample - loss: 0.0934 - val_loss: 0.0964
Epoch 5/15
1119/1119 [==============================] - 0s 55us/sample - loss: 0.0946 - val_loss: 0.1026
Epoch 6/15
1119/1119 [==============================] - 0s 61us/sample - loss: 0.0944 - val_loss: 0.0941
Epoch 7/15
1119/1119 [==============================] - 0s 68us/sample - loss: 0.0935 - val_loss: 0.0954
Epoch 8/15
1119/1119 [==============================] - 0s 78us/sample - loss: 0.0941 - val_loss: 0.1074
Epoch 9/15
1119/1119 [==============================] - 0s 58us/sample - loss: 0.0907 - val_loss: 0.0946
Epoch 10/15
1119/1119 [==============================] - 0s 49us/sample - loss: 0.0914 - val_loss: 0.0974
Epoch 11/15
1119/1119 [==============================] - 0s 53us/sample - loss: 0.0900 - val_loss: 0.0942
Epoch 12/15
...
Epoch 14/15
1119/1119 [==============================] - 0s 61us/sample - loss: 0.0866 - val_loss: 0.0929
Epoch 15/15
1119/1119 [==============================] - 0s 70us/sample - loss: 0.0848 - val_loss: 0.0951
'''
import pandas as pd

history_df = pd.DataFrame(history.history)
# history_df
history_df.plot()

loss history

훈련된 모델로 X_vaild 데이터를 넣어서 MAE를 계산해본다. 

def calc_ae(df):
    ae = abs(df["y_valid_test"]-df["y_valid"])
    if(ae<0.01):
        return 0
    else:
        return ae

y_valid_test = model.predict(X_valid)

df = pd.DataFrame({"y_valid_test": [round(v[0], 1) for v in y_valid_test], "y_valid": y_valid.to_numpy()})
df["y_valid"] = round(df["y_valid"], 1)
df["ae"]=df.apply(calc_ae, axis=1)

print("MAE : ", df["ae"].mean())

'''output 
MAE :  0.0916666652634742
'''

 

 

 


 

<관련 포스팅>

[Intro to Deep Learning] A Single Neuron

[Intro to Deep Learning] Deep Neural Networks

 

<참고자료>

https://www.kaggle.com/code/ryanholbrook/stochastic-gradient-descent

 

source : https://unsplash.com/photos/n6B49lTx7NM

728x90
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기
반응형