Gradient Descent (경사 하강법)

3단 분석법

순서
분석
단어
내용
1
정의
경사 하강법
가중치를 반복적으로 조정하는 최적화 알고리즘 즉, 기울기를 이용하여 함수 값이 가장 크게 감소하는 방향으로 반복적으로 이동함으로써 함수의 최소값에 도달하려는 방법이다
2
알아야하는 이유
경사 하강법
신경망 학습 과정에서 손실 함수 호출을 최소화하여 모델의 예측 성능을 최적화하기 위해서
3
동작방식
경사 하강법
1. 초기화 2. 순전파 계산 3. 손실 계산 4. 경사 계산 5. 가중치 업데이트 6. 반복

정의

경사 하강법
손실 함수를 최소화하기 위해 가중치를 반복적으로 조정하는 최적화 알고리즘
경사 하강법(Gradient Descent)은 머신러닝과 딥러닝에서 손실 함수를 최소화하기 위해 가중치를 반복적으로 조정하는 최적화 알고리즘입니다.
이 알고리즘은 손실 함수의 기울기를 계산하여 가중치를 기울기의 반대 방향으로 업데이트함으로써 손실 값을 점진적으로 줄여 나갑니다.
이는 모델이 데이터에 더욱 잘 맞도록 학습시키는 핵심 기법입니다.
기본적으로 딥 러닝 모델을 학습할 때는 기울기(gradient)에 따라 미분을 하면서(기울기를 조정하면서) 그래프를 최적화하고 그에 따라 가중치(weight)를 업데이트 합니다.
이 과정은 최적의 손실 값을 찾는 과정이며, 이 과정을 통해 모델의 가중치를 최적화하는 것이 경사 하강법(Gradient Descent)입니다.
기울기 소실(Vanishing Gradient)이 무엇인가요?
Vanishing Gradient는 activation function의 기울기 값이 계속 곱해지다 보면 weight에 따른 결과 값의 기울기가 0에 가까워져 weight를 변경할 수 없게 되는 현상을 말 합니다.
기울기 소실 문제는 역전파 과정에서 발생하며, 네트워크의 깊은 층으로 갈수록 기울기 값이 점점 작아져서 가중치 업데이트가 거의 이루어지지 않는 현상입니다.
이는 시그모이드나 Tanh와 같은 활성화 함수에서 주로 발생하며, 신경망의 학습을 어렵게 만듭니다.
렐루 함수는 이 문제를 일부 완화하지만, 음수 영역에서의 (특정 뉴런이 더 이상 학습에 기여하지 않는 상태를 말하는) 뉴런 죽음 문제(dead neurons)를 야기할 수 있습니다.
활성화 함수를 선택할 때 이러한 장단점을 고려하여 적절한 함수를 사용하는 것이 중요합니다.
신경망의 구조와 데이터의 특성에 따라 최적의 활성화 함수를 선택하면 학습 성능을 크게 향상시킬 수 있습니다.
learning rate값에 따라서 learning step이 진행이 된다.

알아야하는 이유

경사 하강법
신경망 학습 과정에서 손실 함수 호출을 최소화하여 모델의 예측 성능을 최적화하기 위해서
Backpropagation (역전파)은 실제 데이터와 예측 데이터 사이의 차이를 최소화하기 위해 가중치를 조정하는 과정이다.
손실 함수는 실제 데이터와 예측 데이터 사이의 차이를 측정하는 함수이다.
따라서 손실 함수의 값을 줄인다면 모델의 예측값과 실제값이 가까워지기 때문에 성능이 좋은 모델이라 할 수 있다. 손실 함수를 최소화하기 위해 경사 하강법을 사용한다.
이유
설명
모델 성능 최적화
경사 하강법은 손실 함수를 최소화하여 모델의 예측 성능을 최적화합니다. 이는 모델이 훈련 데이터에 잘 맞고, 새로운 데이터에 대해 높은 예측 정확도를 가지도록 합니다.
효율적인 학습
경사 하강법은 대규모 데이터셋과 복잡한 모델을 효율적으로 학습시키는 데 사용됩니다. 이는 계산 비용을 절감하고 학습 시간을 단축시키는 데 중요한 역할을 합니다.
기계 학습의 기초
경사 하강법은 기계 학습 및 딥러닝 모델의 학습 과정에서 기본적인 역할을 하며, 다양한 최적화 기법의 기초가 됩니다. 이를 이해함으로써 더 복잡한 최적화 알고리즘을 이해하고 응용할 수 있습니다.
실제 적용
경사 하강법은 실생활의 다양한 문제 해결에 사용됩니다. 예를 들어, 이미지 분류, 자연어 처리, 음성 인식 등 다양한 응용 분야에서 경사 하강법을 통해 모델을 학습시킵니다.

동작 방식

경사 하강법
1. 초기화 2. 순전파 계산 3. 손실 계산 4. 경사 계산 5. 가중치 업데이트 6. 반복

1. 초기화

모델 학습의 시작 단계입니다. 데이터를 생성하고, 가중치와 편향을 초기화합니다.
import numpy as np # 데이터 생성 np.random.seed(42) X = 2 * np.random.rand(100, 1) y = 4 + 3 * X + np.random.randn(100, 1) # 파라미터 초기화 theta = np.random.randn(2, 1)
Python
복사
np.random.seed(42): 난수 생성을 위한 시드 값을 설정합니다. 이를 통해 코드 실행 시 동일한 난수 값을 생성할 수 있습니다.
X = 2 * np.random.rand(100, 1): 0과 2 사이의 난수로 이루어진 100개의 데이터를 생성합니다.
y = 4 + 3 * X + np.random.randn(100, 1): X 데이터에 대해 4 + 3 * X의 선형 함수 값을 만들고, np.random.randn(100, 1)을 더해 노이즈를 추가합니다.
theta = np.random.randn(2, 1): 초기 가중치와 편향을 무작위 값으로 설정합니다.

2. 순전파 계산

입력 데이터를 통해 예측값을 계산합니다.
# 데이터 준비 X_b = np.c_[np.ones((100, 1)), X] # X 데이터에 절편 항 추가
Python
복사
X_b: 절편 항(1)을 추가한 입력 데이터입니다. 이는 선형 회귀 모델에서 편향(bias)을 포함하기 위해 사용됩니다. np.c_는 배열을 열 방향으로 연결하는 함수입니다.
순전파(Feed-Forward)란?
순전파는 입력 데이터를 입력층부터 출력층까지 순차적으로 전달하여 최종 예측값을 계산하는 과정입니다.

3. 손실 계산

예측값과 실제 값 간의 오차를 손실 함수로 계산합니다.
def compute_cost(X_b, y, theta): m = len(y) cost = (1 / (2 * m)) * np.sum(np.square(X_b.dot(theta) - y)) return cost
Python
복사
compute_cost: 손실 함수입니다. 예측값과 실제 값의 차이를 제곱한 후 평균을 계산하여 반환합니다.
X_b.dot(theta): 예측값을 계산합니다.
np.square: 오차(차이)의 제곱을 계산합니다.
np.sum: 제곱 오차의 합을 계산합니다.
(1 / (2 * m)): 제곱 오차의 평균을 계산하기 위한 상수입니다.

4. 경사 계산

손실 함수의 가중치에 대한 기울기(경사)를 계산합니다.
def compute_gradient(X_b, y, theta): m = len(y) gradients = 2 / m * X_b.T.dot(X_b.dot(theta) - y) return gradients
Python
복사
compute_gradient: 손실 함수의 기울기를 계산하여 반환합니다.
X_b.T.dot(X_b.dot(theta) - y): 기울기를 계산합니다.

5. 가중치 업데이트

경사 하강법 공식을 사용하여 가중치를 업데이트합니다.
def gradient_descent(X_b, y, theta, learning_rate, n_iterations): for iteration in range(n_iterations): gradients = compute_gradient(X_b, y, theta) theta = theta - learning_rate * gradients return theta
Python
복사
gradient_descent: 주어진 학습률과 반복 횟수를 사용하여 가중치를 업데이트합니다.
theta = theta - learning_rate * gradients: 가중치를 기울기의 반대 방향으로 업데이트합니다.

6. 반복

손실 값이 충분히 줄어들 때까지 2~5단계를 반복합니다.
# 학습률과 반복 횟수 설정 learning_rate = 0.1 n_iterations = 1000 # 경사 하강법 실행 theta_best = gradient_descent(X_b, y, theta, learning_rate, n_iterations) print("최적의 파라미터:", theta_best)
Python
복사
learning_rate: 학습률입니다. 모델이 얼마나 빠르게 또는 느리게 학습할지를 결정합니다.
n_iterations: 경사 하강법을 반복할 횟수입니다.
theta_best: 학습 후의 최적 파라미터입니다.

7. 예측 및 시각화

최적의 파라미터를 사용하여 예측하고, 이를 시각화합니다.
# 예측 X_new = np.array([[0], [2]]) X_new_b = np.c_[np.ones((2, 1)), X_new] y_predict = X_new_b.dot(theta_best) # 시각화 import matplotlib.pyplot as plt print("경사 하강법을 이용한 선형 회귀 그래프") plt.plot(X, y, "b.") plt.plot(X_new, y_predict, "r-", linewidth=2) plt.xlabel("X") plt.ylabel("y") plt.title("Linear Regression with Gradient Descent") plt.show()
Python
복사
X_new: 새로운 입력 데이터입니다.
y_predict: 예측된 출력값입니다.
matplotlib.pyplot: 데이터 시각화를 위한 라이브러리입니다.
plt.plot: 데이터 시각화 함수입니다.

Google Colab

알아두면 좋은 정보

경사 하강법 변형 버전

경사 하강법은 여러 변형된 버전이 있으며, 각 버전은 특정 상황에서 더 효율적으로 작동할 수 있습니다.
번형 버전
설명
배치 경사 하강법 (Batch Gradient Descent)
전전체 데이터셋을 사용하여 한 번에 가중치를 업데이트합니다. 이는 안정적이지만 계산 비용이 높을 수 있습니다.
확률적 경사 하강법 (Stochastic Gradient Descent)
각 데이터 포인트마다 가중치를 업데이트합니다. 이는 계산이 빠르고, 큰 데이터셋에서 더 효율적일 수 있습니다.
미니 배치 경사 하강법(Mini-batch Gradient Descent):
데이터셋을 작은 배치로 나누어 각 배치마다 가중치를 업데이트합니다. 이는 배치 경사 하강법과 확률적 경사 하강법의 장점을 결합한 방식입니다.
또한, 학습률을 동적으로 조정하는 다양한 기법(예: Adam, RMSprop 등)이 있으며, 이러한 기법들은 경사 하강법의 수렴 속도와 안정성을 개선하는 데 도움이 됩니다.

미니퀘스트

1번 미니퀘스트 - 경사 하강법을 이용한 단순 선형 회귀

문제 설명

1.
데이터 생성
가상의 데이터셋을 생성합니다. 여기서는 Xy라는 두 변수를 사용합니다.
예시데이터
# 데이터 생성 np.random.seed(42) X = 2 * np.random.rand(100, 1) y = 4 + 3 * X + np.random.randn(100, 1)
Python
복사
2.
파라미터 초기화
모델의 파라미터(절편과 기울기)를 무작위로 초기화합니다.
3.
경사 하강법 함수 정의
경사 하강법을 통해 모델의 파라미터를 업데이트하는 함수를 정의합니다.
4.
데이터 준비
입력 데이터에 절편 항을 추가합니다.
5.
경사 하강법 실행
경사 하강법을 실행하여 최적의 파라미터를 찾습니다.
6.
예측 및 시각화
최적의 파라미터를 사용하여 예측하고, 이를 시각화합니다.

코드

import numpy as np import matplotlib.pyplot as plt # 데이터 생성 np.random.seed(42) X = 2 * np.random.rand(100, 1) y = 4 + 3 * X + np.random.randn(100, 1) # 파라미터 초기화 theta = np.random.randn(2, 1) # 학습률과 반복 횟수 설정 learning_rate = 0.1 n_iterations = 1000 m = len(X) # 경사 하강법 함수 정의 def gradient_descent(X_b, y, theta, learning_rate, n_iterations): for iteration in range(n_iterations): gradients = 2/m * X_b.T.dot(X_b.dot(theta) - y) theta = theta - learning_rate * gradients return theta # 데이터 준비 X_b = np.c_[np.ones((100, 1)), X] # X 데이터에 절편 항 추가 # 경사 하강법 실행 theta_best = gradient_descent(X_b, y, theta, learning_rate, n_iterations) print("최적의 파라미터:", theta_best) # 예측 X_new = np.array([[0], [2]]) X_new_b = np.c_[np.ones((2, 1)), X_new] y_predict = X_new_b.dot(theta_best) print("새로운 데이터에 대한 예측값:") for i, x in enumerate(X_new): print(f"X_new = {x[0]}, 예측값 = {y_predict[i][0]}")
Python
복사

코드 설명

미니퀘스트 답안지

알아 두면 좋은 정보

Local minima, Global minima

Local minima : 최적의 Loss 라고 생각한 곳 Global minima : 전체의 Loss라고 생각한 곳

모델을 학습할 때 Learning Rate를 적절히 설정해주는 것은 매우 중요합니다.
Learning Rate에 대해 설명하면서 Hyperparameter 설정을 통해 너비를 조정할 수 있다 했습니다.
이때, 데이터셋마다, 그리고 모델마다 적절한 Learning Rate는 모두 다르기 때문에 직접 실험을 해보면서 적절한 Learning Rate를 찾아야 합니다.
만약, Learning Rate를 너무 크게 설정한다면, 그래프를 학습하는 간격이 너무 벌어지기 때문에 최적의 Loss를 찾지 못하고 학습이 끝나 버릴 수 있습니다.
이런 경우, Loss를 찾지 못하기 때문에 weight 조정이 불가능 해 성능이 좋은 모델을 만들 수 없게 됩니다.
반대로, Learning Rate를 너무 작게 설정한다면 어떻게 될까요?
언뜻보면, 세세하게 학습을 하게 되는 것처럼 보여 모델의 성능이 좋아질 것이라 생각할 수 있습니다.
하지만, 이 경우 올바르지 않은 Loss 구간을 찾게될 가능성이 높아집니다.
이때, 최적의 Loss 라고 생각한 곳을 Local minima 라고 부릅니다.
하지만, 전체적인 그래프로 보았을 때 Loss 가 더 낮은 지점이 존재합니다.
이곳을 Global minima라고 부릅니다.
Global minima가 존재하지만 너무 작은 Learning Rate 설정으로 인해 Local minima에서 최적의 Loss 값이 설정된다면 모델은 더 좋은 성능을 낼 수 있음에도 그렇지 못하게 됩니다.
이러한 이유 때문에 상황에 맞는 Learning Rate를 잘 찾아서 적용하는 것이 모델의 성능을 올리는데 매우 중요합니다.
ⓒ 2024 startupcode. 모든 권리 보유. 무단 복제 금지.