STUDY LOG/Kaggle

Intro to Deep Learning(3)

Jinwang Mok 2021. 9. 30. 00:37

확률 경사 하강법Stochastic Gradient Descent

앞선 두 강의에서 dense 레이어의 누적으로 어떻게 완전 결합fully-connected된 신경망을 만드는지 학습했습니다. 처음 만들어질 때, 모든 신경망의 가중치weight는 랜덤하게 설정됩니다. 신경망은 아직 아무것도 "알지" 못하는 것이지요. 이번 수업에서 여러분은 어떻게 신경망을 학습시키는지 배울 것입니다. 또는, 신경망이 어떻게 학습"하는지"를요.

 

모든 기계 학습 작업에서 그러하듯, 먼저 학습 데이터를 설정하는 것으로 시작합니다. 학습 데이터의 각 예시는 몇 개의 특징(입력 값)들과 예상 타겟(출력 값)으로 구성되어 있습니다. 신경망을 학습시킨다는 것은 특징을 타겟으로 변환할 수 있는 방식으로 그 가중치를 조정한다는 것을 의미합니다. 예를 들어, 여러분은 80 Cereals 데이터셋에서 각 시리얼들의 'Sugar', 'fiber', 'protein' 내용을 가지고 와서 그 시리얼의 'calories'를 예측할 수 있는 신경망을 원할 것입니다. 만약 이를 통해 신경망을 성공적으로 학습시킬 수 있다면, 그것의 가중치는 어떤 방식으로든 학습 데이터에서 표현된 것처럼 특징들과 그 타겟의 관계를 반드시 나타내야합니다.

 

학습 데이터 외에도 두가지가 더 필요합니다.

  • 손실 함수Loss Function : 신경망의 예측이 얼마나 좋은지를 측정합니다.
  • 옵티마이저Optimizer(최적화 알고리즘) : 가중치를 어떻게 바꿔야하는지 신경망에게 알려줍니다.

손실 함수

지금까지 신경망을 어떻게 설계하는지를 살펴봤지만, 신경망이 무슨 문제를 풀어야하는지 알려주지는 않았습니다. 이것이 손실함수의 역할입니다. 

 

손실함수는 타겟의 진짜 값과 모델의 예측 값 사이의 차이를 측정합니다.

 

각기 다른 문제들은 각기 다른 손실함수를 부릅니다. 지금까지 어떤 숫자로 된 값을 예측하는 회귀Regression 문제를 살펴봤습니다. 80 Cereals의 칼로리, Red Wine의 품질 점수 같은 것들 말이죠. 다른 회귀 문제로는 주택 가격을 예측하거나 차의 연비를 예측하는 문제가 있을 수 있겠군요.

 

일반적인 회귀문제의 손실함수는 평균 절대 오차Mean Absolute Error(MAE)입니다. 각 예측 값 y_pred에 대하여, MAE는 진짜 타겟의 y값인 y_true와의 차이를 abs(y_true - y_pred)와 같이 측정합니다.

 

데이터셋의 총 MAE 손실은 이 모든 절대 차이들의 평균 값입니다.

MAE는 학습 선과 데이터 점 사이의 길이의 평균입니다.

회귀 문제의 손실함수로 MAE 말고 아마 평균 제곱 오차Mean Squared Error(MSE)나 허버Huber 손실함수를 볼 수 있을 것입니다.(둘 다 Keras에서 사용가능합니다.)

 

학습하는 동안 모델은 손실함수를 그 가중치의 교정 값을 찾는 가이드로 사용할 것입니다.(오차가 적을 수록 좋은 것이겠죠.) 다른 말로 손실함수는 신경망에게 목표를 알려주는 함수입니다.

 

옵티마이저The Optimizer - 확률 경사 하강법Stochastic Gradient Descent(SGD)

신경망에게 여러분이 해결하고자 하는 문제를 설명했습니다. 하지만, 이제 어떻게 해결해야 할지를 알려줘야 합니다. 이것이 옵티마이저의 역할입니다. 옵티마이저는 가중치가 손실을 최소화하도록 조정하는 알고리즘입니다.

 

사실 딥러닝에서 사용되는 모든 옵티마이저(최적화) 알고리즘은 확률 경사 하강법이라고 불리는 가문에 속해있습니다. 이들은 단계에 따라 신경망을 반복적으로 학습시키는 알고리즘입니다. 하나의 단계는 아래와 같이 학습시킵니다.

  1. 학습 데이터를 표본으로 추출하고 신경망을 통해 이를 실행하여 예측을 만들어냅니다.
  2. 예측 값과 실제 값 사이의 손실을 측정합니다.
  3. 마지막으로, 손실을 더 작게 만드는 방향으로 가중치를 조정합니다.

그리고 손실(오차)이 여러분이 좋아할정도로 작을 때까지 또는 더 이상 내려갈 곳이 없을 때까지 이 단계를 끝없이 반복합니다.

확률 경사 하강법을 통한 신경망 학습

각 반복의 학습 데이터의 표본미니배치minibatch라고 부릅니다(또는 그냥 배치batch라고도 자주합니다.). 그리고, 학습 데이터를 완전히 한바퀴 다 학습하는(한 라운드 도는) 것을 에폭Epoch이라고 부릅니다. 학습 시키는 에폭의 수는 신경망이 각 학습 샘플을 몇 번이나 볼 것인지를 의미합니다.

 

위의 애니메이션은 첫 번쨰 수업의 선형 모델이 SGD를 통해 학습되는 것을 보여줍니다. 투명한 빨간 점들은 전체 학습 데이터셋을 나타내고, 진한 빨간 점들은 미니배치를 나타냅니다. 매 단계마다 SGD는 새로운 미니배치를 보고, 그 배치의 맞는 값쪽으로 가중치를 바꿀 것입니다.(3번째 그래프의 w는 기울기이고, b는 y 절편입니다.) 매 배치마다 선은 결과적으로 가장 잘 학습된 쪽으로 수렴하게 될 것입니다. 그리고, 가중치가 실제 값에 가까워질수록 손실이 점점 줄어드는 것을 확인할 수 있습니다.

 

학습률Learning Rate과 배치 크기Batch Size

각 배치의 방향으로 직선이 그냥 조금만 움직인다는 것을 알아두세요. 이 움직임들의 크기는 학습률에 따라 결정됩니다. 더 적은 학습률은 신경망이 그 가중치가 가장 좋은 값으로 수렴하기 전까지 더 많은 미니배치를 봐야한다는 것을 의미합니다.

  

학습률과 미니배치의 크기는 SGD가 어떻게 학습을 진행하는지에 가장 큰 영향을 주는 두가지 매개변수입니다. 이 둘의 상호작용은 자주 모호하고, 이 두 매개변수를 결정하는 것은 항상 명확하진 않습니다.

 

다행스럽게도 대부분의 작업에서 만족스러운 결과를 얻기 위해서 확장 초매개변수hyperparameter를 조사할 필요는 없습니다. Adam은 SGD 알고리즘인데 매개변수를 따로 조정하지 않고도 대부분의 문제들에 맞는 적응형 학습률을 가지고 있습니다.(어떤 의미로는 "자기 조정"입니다.) Adam은 훌륭한 범용 옵티마이저입니다.

 

손실 함수와 옵티마이저 추가하기

모델을 정의한 뒤에, 모델의 compile 메소드를 통해 손실 함수와 옵티마이저를 추가할 수 있습니다.

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

손실 함수와 옵티마이저를 명시하기 위해 문자열을 사용해야 한다는 것을 기억하세요. Keras API를 통해 이것들에 직접적으로 접근할 수 도 있습니다. 예를 들어 매개변수를 조작하려면 말이죠. 하지만, 여러분에게는 기본 설정만으로도 충분히 잘 동작할 것입니다.

 

이름은 무슨 뜻인가요?

경사gradient는 가중치가 어느 방향으로 가야 하는지를 알려주는 벡터입니다. 더 정확히는, 손실을 가장 빨리 변화시키기 위해 가중치를 바꾸는 방법을 말해줍니다. 최소로 손실 곡선을 하강시키기 위해 경사gradient를 사용하므로 이 프로세스를 경사하강법gradient descent이라고 부릅니다. 확률Stochastic이란 "우연에 의해 결정된다"는 뜻입니다. 학습은 확률적이기 때문이죠. 왜냐하면, 미니배치는 데이터셋의 무작위 샘플이기 때문입니다. 이런 이유로 "확률 경사 하강SGD"이라고 불리는 것입니다.

 

예시 - Red Wine Quality

이제 여러분은 딥러닝 모델을 학습시키기 위해서 필요한 것들을 모두 알고 있습니다. 자, 한번 실제로 보도록 하죠! Red Wine Quality 데이터셋을 사용해보겠습니다.

 

이 데이터셋은 약 1600개의 포르투갈 레드 와인의 물리화학적 측정치로 구성되어 있습니다. 또한 각 와인별로 블라인드 테스트로 매겨진 품질 점수를 포함하고 있습니다. 이러한 측정치로 와인의 품질을 얼마나 잘 예측할 수 있을까요?

 

아래의 코드는 주목할 필요는 없지만 앞으로 실습에 필요한 준비 내용들을 담고 있습니다. 그래도 알아둬야 하는 것은 각각의 특징을 [0, 1] 로 조정했다는 것입니다. 이는 다섯번째 강의에서 다시 다루겠지만, 신경망은 입력이 공통적으로 이뤄질 때 가장 잘 작동하는 경향이 있습니다.

import pandas as pd
from IPython.display import display

red_wine = pd.read_csv('../input/dl-course-data/red-wine.csv')

# 학습용 검증용 구분
df_train = red_wine.sample(frac=0.7, random_state=0)
df_valid = red_wine.drop(df_train.index)
display(df_train.head(4))

# [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_)

# 특징과 타겟 구분
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']

 

이 신경망이 몇개의 입력 값을 가져야 할까요? 여러분은 이것을 데이터 행렬에 있는 열의 개수를 확인하므로써 알아낼 수 있습니다. 하지만, 타겟인 'quality'를 포함하지 않도록 주의하세요. 입력 특징들만 입니다!

print(X_train.shape)

결과로 나오는 11개의 열은 11개의 입력을 의미합니다.

 

이번에는 1500개 이상의 뉴런으로 이루어진 3-레이어 신경망을 선택해보도록 하죠. 이 신경망은 데이터의 꽤 복잡한 관계들을 학습하기 충분할 것입니다.

from tensorflow import keras
from tensorflow.keras import layers

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

모델의 구조를 결정하는 것은 프로세스의 일부가 되어야 합니다. 간단하게 유효성 검사 손실을 가이드로 사용해봅시다. exercise에서 모델 개발에 대해 더 많이 배울 것입니다.

 

모델을 정의한 후에 손실 함수와 옵티마이저로 컴파일합니다.

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

이제 학습을 시작할 준비가 되었습니다! Keras에게 한 번(배치 크기)에 256열의 훈련 데이터를 옵티마이저에게 공급하고 이를 모든 데이터셋을 10라운드 동안(에폭) 진행하라고 합니다.

history = model.fit(
    X_train, y_train,
    validation_data=(X_valid, y_valid),
    batch_size=256,
    epochs=10,
)

이렇게 하면 Keras가 지속적으로 모델 학습에 대한 솔실률을 보여줄 것입니다.

 

종종 손실률을 보는 더 좋은 방법은 도표로 확인하는 것입니다. 사실 fit 메소드는 학습동안의 손실률을 History에 기록하고 있습니다. 여러분은 도표로 더 수월하게 나타내기 위해 이 데이터를 Pandas 데이터프레임으로 변환할 것입니다.

import pandas as pd

# 학습 History를 데이터프레임으로 변환
history_df = pd.DataFrame(history.history)
# padas의 네이티브 plot 메소드
history_df['loss'].plot()

에폭이 증가하는 동안 손실률이 어떻게 낮아지는지 확인하세요. 손실 곡선이 저렇게 수평을 이룰 때, 모델이 할 수 있는 학습을 다 했고, 추가적인 에폭을 할 필요가 없다는 것을 의미합니다.


이렇게 캐글(Kaggle)의 Intro to Deep Learning 세번째 수업을 번역하며 공부해봤습니다.

 

오늘 배운 내용을 요약하자면,

  • 신경망의 예측 품질을 평가하는 손실 함수Loss Function로 회귀 문제에 대해서 MAE, MSE, Huber 등이 있다.
  • 신경망에게 가중치를 어떻게 바꿔야하는지를 알려주는 최적화 알고리즘(Optimizer)가 있고, 딥러닝에서는 사용되는 모든 옵티마이저는 확률 경사 하강법에 속해있다.
    • 확률 경사 하강법은 표본 추출 및 예측 ⇢ 손실 측정 ⇢가중치 조정의 일련의 단계를 지속적으로 반복하면서 신경망을 학습시키는 알고리즘 입니다.
  • 미니 배치( 또는 배치)는 데이터셋에서 임의로 추출된 표본 데이터를 의미하고, 에폭은 데이터셋 전체를 모두 사용하는 횟수를 의미합니다.
    • 학습률이 적다는 것은 만족스러운 학습까지 더 많은 배치를 봐야한다는 것입니다.
    • SGD 학습에 영향을 주는 가장 큰 요소 두가지가 학습률과 배치 크기인데, 이 둘의 관계를 구하는게 모호하고 어렵습니다. 따라서, 범용적으로 좋은 적응형 학습률을 가진 옵티마이저인 Adam을 사용하면 대체로 괜찮습니다.
  • 손실 함수와 옵티마이저를 추가할 때는 model의 compile 메소드의 optimizer인자와 loss인자로 옵티마이저의 이름(ex. adam)과 손실 함수의 이름(ex. mae)을 문자열로 넣어주면 됩니다.

혹시라도 잘못된 내용이 있다면, 말씀해주시면 감사하겠습니다.

 

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

'STUDY LOG > Kaggle' 카테고리의 다른 글

Pandas(3)  (0) 2021.10.01
Intro to Deep Learning(4)  (0) 2021.09.30
Intro to Deep Learning(2)  (0) 2021.09.29
Intro to Deep Learning(1)  (0) 2021.09.28
데이터 사이언티스트를 위한 핵심 기술들_캐글(Kaggle) Discussion 번역(1)  (0) 2021.09.26