수식이 나오지 않는다면 새로고침(F5)을 해주세요
모바일은 수식이 나오지 않습니다.
경사하강법(Gradient Descent)와 역전파 알고리즘(Backpropagation)은 딥러닝하면 빼놓을 수 없이 항상 같이 나오는 알고리즘들 입니다.
이들이 뭐고 왜 중요할까요?
딥러닝의 학습 구조는 크게 아래와 같이 이루어져있으며 이를 반복합니다.
1. 입력 데이터를 받아 출력 계산 (Forward Propagation; 순전파)
2. 예측 결과와 정답 비교 >> 오차 계산 (Loss)
3. 오차를 기준으로 가중치 수정 (Back Propagation + Gradient Descent)
조금 더 자세히 설명해보면 순전파를 통해 output을 계산하고 해당 output과 정답 label을 비교하여 cost function을 계산합니다.
이 후 역전파를 통해 각 가중치에 대한 편미분 값 계산. 경사하강법을 사용하여 비용함수를 최소화하는 방향으로 가중치 확인.
사전에 정한 특정 규칙을 만족하거나 cost function를 최소화할 때 까지 반복..
쉽게 보면??
- 역전파 : 잘못된 부분을 찾는 방법
- 경사하강법 : 잘못된 걸 고쳐나가는 방법
정도로 보면 되겠습니다.
📌 역전파 알고리즘 (Back Propagation)
: 오차가 발생했을 때, 그 오차가 어떤 파라미터에서 비롯되었는지를 계산해 해당 파라미터를 조정할 수 있도록 gradient를 전달하는 알고리즘
왜 필요한가?
딥러닝은 수천, 수만 개의 파라미터(가중치)를 가지고 있는데, 각 파라미터가 결과에 어떤 영향을 줬는지 파악해야 학습이 가능하다. 이 때 역전파는 체인 룰을 이용하여 이 영향을 자동으로 계산한다.
1개의 은닉층을 가진 MLP(Multi-Layer Perceptron)를 예로 들어보자.
1. Forward Pass : 예측값 만들기
$$
z^{(1)} = W^{(1)}x + b^{(1)}, a^{(1)} = \phi(z^{(1)}) \\
z^{(2)} = W^{(2)}a^{(1)} + b^{(2)}, \hat{y} = \sigma(z^{(2)})
$$
: 입력 $x$가 들어오면 가중치 $W^{(1)}$와 곱하고, 편향인 $b^{(1)}$를 더해줌 > 이게 첫 은닉층의 계산 전 값 $z^{(1)}$
: 여기에 활성화 함수 $\phi$ (예 : ReLU, sigmoid 등)를 적용해 출력 $a^{(1)}$을 만듦 > 이게 은닉층의 출력값
: 이 출력값을 다시 다음 층에 입력으로 넣어 또 계산 > 마찬가지로 가중치 $W^{(2)}$, 편향 $b^{(2)}$로 계산 > $z^{(2)}$
: 마지막엔 sigmoid 함수 $\sigma$를 사용해 출력값 $\hat{y}$(예측값)을 만듦
2. Loss Function : 오차 계산
$$
\mathcal{L} = -[y \log{(\hat{y})} + (1-y) \log{(1-\hat{y})}]
$$
해당 수식은 이진 분류에서 자주 쓰이는 Binary Cross Entropy Loss function.
외에도 여러 loss function들이 존재하며 정답 $y$와 예측값 $\hat{y}$를 비교해서 얼마나 틀렸는지를 수치로 계산하는 함수
3. Backward Pass : 거꾸로 계산
$$
\delta^{(2)} = \hat{y} - y \\
\delta^{(1)} = (W^{(2)})^T \delta^{(2)} \cdot \phi' (z^{(1)})
$$
: 오차인 $\delta$ 중 $\delta^{(2)}$는 출력층의 오차
: 이 오차를 기반으로 은닉층으로 거꾸로 전달하면서, 은닉층 가중치도 얼마나 잘못됐는지 계산 > 이게 역전파
: $\phi' (z^{(1)})$ > 은닉층에서 활성화 함수의 미분값이 들어가. 오차를 다음층으로 전파할 때 얼마나 줄어들지 계산하는데 사용
📌 경사하강법(Gradient Descent)
: 비용 함수를 최소화하기 위해, 기울기(gradient)가 감소하는 방향으로 파라미터를 조정하는 최적화 알고리즘
핵심 아이디어는 경사가 내려가는 방향으로 한 걸음씩 이동하면, 언젠가 가장 낮은 지점(최솟값)에 도달할 수 있다는 직관.
$$
\theta = \theta - \eta \cdot \dfrac{\partial \mathcal{L}}{\partial \theta}
$$
: $\theta$는 조정할 파라미터 (예: 가중치)
: $\eta$는 학습률 (learning rate)
: $\dfrac{\partial \mathcal{L}}{\partial \theta}$는 파라미터에 대한 오차의 기울기
경사하강법에 대한 더 자세한 설명은 아래 글을 참고해주세요.
경사 하강법 : 배치, 확률적, 미니 배치 경사하강법(Batch, Stochastic, Mini Batch)
이번 포스팅은 경사 하강법입니다. 굳이 Deep learning 카테고리에 추가 안 해도 됐지만.. 뉴럴 네트워크와 연결되니 여기에 포스팅하는 걸로! 📌 Batch Gradient Descent(배치경사하강법) 앞선 포스팅에
datanovice.tistory.com
📌 Python으로 구현
이번 구현은 tensor를 사용하지 않고 numpy를 통해 직접 구현해보겠습니다.
# 역전파 + 경사하강법 직접 구현 (단순한 1층 MLP)
import numpy as np
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def sigmoid_deriv(x):
sx = sigmoid(x)
return sx * (1 - sx)
# 임의 데이터
X = np.random.rand(100, 2)
y = (X[:, 0] + X[:, 1] > 1).astype(float).reshape(-1, 1)
# 초기 가중치
W1 = np.random.randn(2, 4)
b1 = np.zeros((1, 4))
W2 = np.random.randn(4, 1)
b2 = np.zeros((1, 1))
lr = 0.1
for epoch in range(1000):
# Forward
z1 = X @ W1 + b1
a1 = sigmoid(z1)
z2 = a1 @ W2 + b2
y_hat = sigmoid(z2)
# Loss (binary cross-entropy)
loss = -np.mean(y * np.log(y_hat + 1e-8) + (1 - y) * np.log(1 - y_hat + 1e-8))
# Backward
dz2 = y_hat - y
dW2 = a1.T @ dz2 / len(X)
db2 = np.mean(dz2, axis=0)
dz1 = dz2 @ W2.T * sigmoid_deriv(z1)
dW1 = X.T @ dz1 / len(X)
db1 = np.mean(dz1, axis=0)
# Gradient Descent
W2 -= lr * dW2
b2 -= lr * db2
W1 -= lr * dW1
b1 -= lr * db1
if epoch % 100 == 0:
print(f"Epoch {epoch}, Loss: {loss:.4f}")
Epoch 0, Loss: 0.7066
Epoch 100, Loss: 0.6421
Epoch 200, Loss: 0.6225
Epoch 300, Loss: 0.5987
Epoch 400, Loss: 0.5699
Epoch 500, Loss: 0.5360
Epoch 600, Loss: 0.4981
Epoch 700, Loss: 0.4581
Epoch 800, Loss: 0.4185
Epoch 900, Loss: 0.3813
'👨💻 Deep Learning > Deep learning' 카테고리의 다른 글
[Deep Learning] CNN에 대한 기본 설명 (with pooling, padding) (0) | 2025.05.20 |
---|---|
[Deep Learning] ANN / DNN에 대한 기본 설명 (2) | 2025.05.20 |
[Pytorch] squeeze, unsqueeze 란? (0) | 2025.04.21 |
[Pytorch] ANN 구현과 용어 설명 (0) | 2025.02.12 |
TensorFlow(텐서플로우 2.x) 선형회귀 예제 (0) | 2024.08.01 |