딥러닝 학습
초기 a지점에서의 x값을 W0라고 하자. 해당 지점에서의 y값은 L이다.
이 때, a의 접선 즉 a의 순간 기울기(dL/dW0)는 음수가 나타나고 a'에서의 기울기는 양수가 나타난다.
기울기가 가장 작은값, 즉 기울기가 0에 수렴하도록 W의 값을 조절해야 가장 최적의 추세선을 그릴 수 있게 된다.
이를 수식으로 나타내면 다음과 같으며 이런 작업을 '경사하강법' 이라고 한다.
딥러닝관점에서 볼때 W를 가중치라고 부르며 가중치의 비중에 따라 신경망이 어떤 데이터에 더 중요도를 줄것인지 조절한다.
위와같은 알고리즘을 통해서 에러를 최소한으로 수렴하도록 최적의 기울기를 찾아내는것이 딥러닝의 목적이다.
SGD(Stochastic Gradient Descent)
확률적 경사 하강법
- 오차가 더 이상 변하지 않을 때까지 매개변수 W를 아래와 같이 갱신하는 알고리즘
위에서 다룬 식이랑 똑같지만 용어를 다시 짚어보자.
W : 갱신할 가중치(매개변수)
dL/dW : W에 대한 손실함수(L)의 미분값(기울기)
n(에타) : 학습률
이번엔 위에서 다루지 않은 에타에 대해서 알아보자.
Learning rate(학습률)
learning rate란 학습을 진행하는 속도를 의미한다.
learning rate가 크다는 뜻은 큰 폭으로 다음을 학습한다는 의미이며 잘못하면 발산하는 경우가 생겨 원하는 값이 나오지 않을 수 있다.
반면 learning rate가 작다는 뜻은 학습속도를 느리게(촘촘히)하여 보다 정확 할 수 있지만 속도가 매우 느려서 학습이 원하는 값에 미치지 못한 채 학습이 중단 될 수 있다.
error backpropagation(오차 역전파)
error backpropagation란 input과 output간의 오차가 발생했을 때 사용한 가중치를 역으로 피드백을 하는 방식이다.
이것으로 인해 기계가 오차를 줄여나가는 방향으로 강화학습을 할 수 있다.
error backpropagation은 파이토치에서 내부적으로 구현되어 있어서 API사용법과 개념만 익히면 된다.
SGD의 한계점
사실 SGD는 딥러닝 초창기에 탄생된 알고리즘이라 오늘날 사용되는 다른 알고리즘에 비해 속도가 느릴 뿐만 아니라 input데이터가 다음과 같이 수억개가 들어오면 감당할 수 없다. 따라서 현재 많이 사용하지는 않지만 오늘날 사용하는 알고리즘이 전부 SGD에서 파생됐기 때문에 기본중 기본을 알아야 할 필요가 있다.
선형회귀 학습모델 구현(with. python)
파이토치 프레임워크를 이용해서 기본적인 함수 사용법부터 알아보자.
1. nn.Linear().to() : 신경망 생성하는 함수
2. nn.MSELoss() : mean square error방식으로 loss값 계산
3. torch.optim.SGD() : sgd로 학습모델 설정. 내부적으로 error backpropagation이 구현되어 있다.
4. zero_grad() : gradient 값을 초기화 하고 backward를 할때 계속 더한다.
5. backward() : gradient 계산
6. step() : 최종적으로 가중치 조정
기본적인 함수 사용법을 알았으니 실제 코드를 통해 구현해 보자.
import torch
from torch import nn
# --- Set device
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# --- Load data
# input data
x_data = torch.Tensor([[1.], [2.], [3.], [4.]])
# label
y_data = torch.Tensor([[2.], [4.], [6.], [8.]])
# --- Initialize neural network
model = nn.Linear(in_features=1, out_features=1, bias=True).to(device)
# 신경망 생성 -> in_features : input Layer의 뉴런 갯수, out_features : output layer 뉴런 갯수, bias : 편향, .to(device) : gpu혹은 cpu선택
# --- define Loss and optimizer
criterion = nn.MSELoss() # mean square error, loss값 계산
optimizer = torch.optim.SGD(params=model.parameters(), lr=0.001)
# Loss funtion설정 - 진짜 y값과 예측한 y값간의차이를 최소화하는데 필요한 수식
# --- Train model
for step in range(501):
# predict(forward)
prediction = model(x_data)
# loss 계산
loss = criterion(input=prediction, target=y_data)
# target == label == 정답
# update weight(SGD)
optimizer.zero_grad() # gradient 값 초기화
loss.backward() # gradient 계산 -> 기울기 계산
optimizer.step() # update weight -> 가중치 조정(sgd부분)
print(f'step={step}, loss = {loss.item()}')
# --- infer
new_x = torch.Tensor([[5.]])
# predict(forward)
prediction = model(new_x) # 학습된 모델을 이용하여 5를 input으로 넣었을 때 예측
print(f'\nnew_x = {new_x} ---> prediction result = {prediction.data.numpy()}')
위의 코드는 input으로 1, 2, 3, 4, output을 2, 4, 6, 8로 설정한 다음 과연 5를 넣으면 input의 2배인 10을 출력하도록 학습시키는 코드이다. 이렇게 input과 output을 설정해서 학습시키는 방법을 Supervised Learning이라고 한다.
loss function을 설정한 SGD함수를 보면 lr(learning rate)을 0.01로, 학습횟수는 501로 설정한 결과 다음과 같이 초반에는 오차가 매우 크지만 점점 줄여나가는 모습을 볼 수 있다.
마지막 500번때 결과를 보면 학습을 하면 할수록 오차를 상당히 많이 줄인 것을 알 수 있다.
여기서 lr의 조건은 똑같이 하고 학습을 10,000번 실행하면 오차는 더욱 줄어드는 것을 알 수 있지만 결과에 비해 시간이 많이 걸리기 때문에 결코 효율적이다고 할 수는 없다.
선형회귀 및 경사하강법에 대한 자세한 설명은 다음 링크를 참고 바랍니다.
[ML] 선형회귀와 경사하강법 (tistory.com)
'ML | DL' 카테고리의 다른 글
[ML] 선형회귀와 경사하강법 (0) | 2022.11.03 |
---|---|
[ML/DL] Cross-Entropy를 이용한 MNIST (0) | 2022.02.17 |
[ML / DL] MNIST 학습모델 (0) | 2022.02.16 |
[ML/DL] 딥러닝 기본 개념 (0) | 2022.02.15 |