이번 글에서는 "최적화"에 대해 공부한 내용을 회고 하고자한다.
최적화란?
최적화를 말하기 전 먼저 "하이퍼 파라미터"에 대해 이야기 해보자!
하이퍼 파리미터는
모델의 성능에 크게 영향을 끼치지만
자동으로 최적화되지 않는 파라미터를 의미한다.
즉, 사용자가 직접 값들을 설정해야 하는 중요한 변수를 의미한다.
학습률, 미니배치 크기, 심층신경망의 깊이, 너비등이 하이퍼파라미터에 속한다.
우리는 모델의 성능을 끌어올리기 위해서는
하이퍼파라미터의 잘 설정해주는 것이 매우 중요한데,
경사하강법과 같이 자동으로 자동으로 찾아주는 방법이 없기 때문에
사용자가 직접 실험을 통해 성능을 지켜보면서 값을 튜닝해야 한다.
적응형 학습률
학습률은 모델을 학습하는데 매우 중요한 파라미터, 하이퍼 파라미터라고 할 수 있다.
학습률의 크기에 따라 학습속도 및 학습의 성능이 결정되기 때문에
가장 먼저 튜닝을 해야하는 파라미터이다.
학습률에 따라 진행 양상이 상이하기 때문에 좋은 학습률 값을 설정해야 한다.
너무 작은 값을 가져간다면 학습 초반에는 너무 더딘 학습을 경험하게 될 것이고,
그렇다고 너무 크게 설정하면 발산하게 되어 학습 후반에 좀 더 나은 손실 값을 얻기 힘들 수도 있다.
>그렇다면 어떻게 해야 할까?<
학습 중간에 학습률을 다르게 설정하면 된다!
학습초반에는 큰 학습률을 가져가고 학습이 진행됨에 따라
점점 작은 학습률을 가져가는 방법을 취하면 된다.
학습 초반에는 어차피 갈 길이 멀기 때문에 큰 학습률을 가져가되
현재 에포크의 손실 값이
지난 과거 에포크의 손실 값보다 나아지지 않을 경우,
학습률을 일정 비율로 줄이는 방법을 적용하면 된다는 말이다.
즉, 학습률을 학습 내내, 그니까 모든 에포크에서 동일한 학습률을 취하는 것이 아니라
동적으로 가져가면 좋은 학습률을 발견할 수 있다는 것이다.
적응형 학습률에 대한 알고리즘에는 여러가지가 있지만
가장 많이 쓰이는 알고리즘은 Adam이다.
Momentum
경사하강법의 한계점인 지역 최소점에 빠질 수 있다는 점을
보완하기 위해서 나온 최적화 기법이다.
시작부터 매번 계산된 그래디언트를 누적하는 형태로 구현되어서
지역 최소점을 쉽게 탈출할 수 있을 뿐만 아니라 학습 속도를 가속화할 수도 있다.
즉 기울기 방향으로 힘을 받아 물체가 가속된다는 법칙이다.
( 물체가 아무런 힘을 받지 않을 때 서서히 움직임 > 지역최소점에 빠질 가능성 작아짐 )
Adagrad
아다그래드의 가장 큰 특징은
가중치 파라미터마다 별도의 학습률을 가진다는 것이다.
각 가중치 파라미터의 학습률을 가중치 파라미터가 업데이트될수록
반비례하여 작아지게 된다.
따라서 가중치 파라미터의 업데이트가 각자 다르게 된다고 하면
업데이트가 많이 된 파라미터의 경우
작은 학습률을 가지게 되고,
업데이트가 적게 된 파라미터의 경우
큰 학습률을 갖게 될 것이다.
문제는 학습이 진행됨에 따라
파라미터의 업데이트가 많이 될 경우
학습률이 너무 작아져 나중에는 0에 수렴하게 되면서
가중치 파라미터 업데이트가 잘 이루어지지 않을 수도 있다.
Adagrad는 이름에서도 살짝 알 수 있듯이,
손실 함수 곡면의 변화에 따라 적응적으로 학습률을 정하는 알고리즘이다.
아래 사진을 보자!
즉, 기울기가 급하여 많이 변화한 구간에 대해서는
최적화에 근접했을 거란 가정하에
작은 크기로 이동하면서 세밀하게 값을 조정하고
반대로 기울기가 완만하여 적게 변화한 변수들은
학습률을 크게 하여 빠르게 오차 값을 줄이고자 하는 방법이다.
그림을 보면 최솟값을 향해 효율적으로 움직이고 있습니다.
초반에는 기울기가 완만해서 처음에는 크게 이동하지만,
점차 기울기가 가파라지면서 보폭이 작아지도록 업데이트가 되는 것을 확인할 수 있다.
즉 AdaGrad는 곡면의 변화량에 반비례한 기법이라고 말할 수 있다.
아래 수식을 보자
수식을 보면 모멘텀과 같이 여전히 학습률이 존재하지만
학습이 진행됨에 따라 점점 작아질 것이므로
학습률에 대한 별다른 튜닝없이 기본 설정값을 가지고 준수한 성능을 보일 수 있다.
하지만 후반부에 갈수록 0에 가까운 학습률이 되어
학습이 진전되지 못할 수도 있다.
Adam
아담은 기존 적응형 학습률 방식에 모멘텀이 추가된 알고리즘이다.
기존의 알고리즘들을 보완함으로써 가장 보편적으로 쓰이는 알고리즘이다.
아담옵티마이저를 사용하면 기본 설정 값을 가지고도
대부분의 문제에서 좋은 성능을 얻을 수 있다.
아담은 수식이 복잡하여 그냥 넘어가겠다!
딥러닝에서는 Adam을 지원하는 프레임워크가 존재
(=> optim.Adam)
코드구현
SGD와 마찬가지로 Adam 또한 제공
SGD와 달리 Adam은 웬만애서는 학습률을 따로 튜닝할 필요가 없다.
# 아담 옵티마이저
#학습률 튜닝 필요x
optimizer=optim.Adam(model.parameters())
SGD를 사용하는 것보다 훨씬 편리하고 빠르게 더 낮은 손실값을 보여준다.
n_epoch=4000
batch_size=265
print_interval=500
for i in range(n_epoch):
indices=torch.randperm(x.size(0)) #인덱스를 섞어줌
x_=torch.index_select(x, dim=0, index=indices) #섞어진 인덱스 순으로 재배열
y_=torch.index_select(y, dim=0, index=indices)
x_=x_.split(batch_size, dim=0)
y_=y_.split(batch_size, dim=0)
total_loss=0
y_hat=[]
for x_i, y_i in zip(x_,y_):
y_hat_i=model(x_i)
loss=F.mse_loss(y_hat_i,y_i)
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_loss+=float(loss) #하나의 epoch에서 나오는 모든 iteration의 loss를 더함
y_hat+=[y_hat_i] #update된 예측y값을 계속 update
total_loss=total_loss/len(x_) #그리고 평균을 냄 -> 1epoch당 loss
if (i+1)% print_interval ==0:
print('Epoch %d : loss=%.4e' % (i+1, total_loss))
SGD을 사용한 것보다 0.1정도 낮은 수치를 보인다.
'✍️ STUDY > DeepLearning' 카테고리의 다른 글
[DL] 심층신경망을 활용한 다중분류 (MNIST 실습) (2) | 2023.05.22 |
---|---|
[DL] 심층신경망을 활용한 이진분류, 평가지표 (0) | 2023.05.22 |
[DL] 오버피팅(Over Fitting) , 검증(Validation) (1) | 2023.05.20 |
[DL] 심층신경망 Basic (0) | 2023.05.19 |
[DL] 선형회귀, 활성화 함수, 로지스틱 회귀 (0) | 2023.05.19 |