이 전에는 탐색 방향 기반 알고리즘에 대해 언급하였다.
탐색 방향 기반 알고리즘은 앞서 공부했다시피 학습률이 고정되어있으며, 스칼라 학습률에 의한 한계가 있다.
이러한 학습률 고정에 의한 한계를 극복하기 위해
1) 큰 학습률로 시작
2) 최적화 알고리즘을 통해 새로운 파라미터 추정치를 계산하고 이 추정치를 이용하여 손실함숫값을 계산
3) 새로운 추정치에 대한 손실함숫값이 기존의 손실함숫값보다 작다면 파라미터 추정치를 업데이트
4) 새로운 추정치에 대한 손실함숫값이 기존의 손실함숫값다 크면 업데이트를 하지 않고,
학습률의 크기를 절반으로 줄인 후 기존 파라미터 값을 이용하여 다시 계산을 수행
스칼라 학습률에 의한 한계를 극복하기 위해
단순히 미리 정한 상수 학습률을 곱하는 경우
≫ 탐색 방향에서 각 방향마다 크기의 불균형이 있을 때는 한쪽 방향에 치우침
≫ 추정된 최종 파라미터의 한쪽 방향은 변화량이 큰 반면 다른 방향은 변량이 적음
→ 각 방향별로 학습률을 차등해서 설정
을 가진 적응형 알고리즘이 생겨났다.
"즉, 변화량이 큰 파라미터는 이미 많이 변화했으니, 변화량이 적은 파라미터를 많이 변화시켜보자."
1. Adagrad
㉮ 초깃값을 설정하고 장기 누적 그래디언트 크기를 0으로 초기화
㉯ 전체 데이터를 임의로 섞는다.
㉰ 전체 데이터에서 개수가 m개인 부분집합 (배치, batch) 들을 만듭니다.
㉱ 각 부분집합마다 다음을 반복합니다.
- 부분집합으로 그래디언트를 현재위치에서 계산
- 장기 누적 그래디언트 크기를 계산하여 학습률 벡터를 정합니다.
- 탐색 방향을 설정합니다.
- 파라미터 추정치를 업데이트합니다.
㉲ 만들어진 부분집합을 모두 사용한 후 다시 ㉱를 Epoch번 반복합니다.
#adagrad
batch_size = 5
MaxEpochs = 2
epslion = 1.0
delta = 1E-7
r = np.zeros_like(w0)
paths = []
batch_loss = []
w0 = np.array([2.0,4.0]) #1)초깃값
print('Iter\tw_k\t\tgrad\t\tdw\t\tloss')
format_dict = {'float_kind' : lambda x: "%.2f" %x}
print('{:01d}-{:02d}\t{}'.format(1,0,
np.array2string(w0,
formatter = format_dict)))
#2) 데이터 셔플링 : 생략
#알고리즘
for epoch in range(MaxEpochs): #5)MaxEpochs번 반복
k = 0
#3) 미니 배치 생성
for x_batch,y_batch in generate_batches(batch_size,
shuffled_x_train,
shuffled_y_train):
paths.append(w0)
batch_loss.append(loss(w0,x_batch,y_batch))
#4)-1 미니 배치에서 그래디언트 계산
grad = loss_grad(w0,x_batch,y_batch)
search_direction = -grad #4-2 탐색방향 설정
#4)-3 학습률 설정
r = r + grad * grad
lr = epsilon / (delta + np.sqrt(r))
dw = lr * search_direction #4)-4 파라미터 업데이트
w0 = w0 +dw
print('{:01d}-{:02d}\t{}\t{]\t{}\t{:5.4f}'.format(epoch+1,k+1,
np.array2string(w0,formatter=format_dict),
np.array2string(grad,formatter=format_dict),
np.array2string(dw,formatter=format_dict),
loss(w0,x_train,y_train)))
k += 1
2. RMSProp (Root Mean Square Propagation)
㉮ 초깃값을 설정하고 장기 누적 그래디언트 크기를 0으로 초기화
㉯ 전체 데이터를 임의로 섞는다.
㉰ 전체 데이터에서 개수가 m개인 부분집합 (배치, batch) 들을 만듭니다.
㉱ 각 부분집합마다 다음을 반복합니다.
- 부분집합으로 그래디언트를 현재위치에서 계산
- 단기 누적 그래디언트 크기를 계산하여 학습률 벡터를 정합니다.
- 탐색 방향을 설정합니다.
- 파라미터 추정치를 업데이트합니다.
㉲ 만들어진 부분집합을 모두 사용한 후 다시 ㉱를 Epoch번 반복합니다.
#RMSProp
batch_size = 5
axEpochs = 2
epsilon = 0.25
delta = 1E-10
rho = 0.9
r - np.zeros_like(w0)
paths = []
batch_loss = []
w0 = np.array([2.0,4.0]) #1)초깃값
print('Iter\tw_k\t\tgrad\t\tdw\t\tloss')
format_dict = {'float_kind': lambda x: "%.2f" % x}
print('{:01d}-{:02d}\t{}'.format(1,0,
np.array2string(w0,
formatter=format_dict)))
#2) 데이터 셔플링 : 생략
for epoch in range(MaxEpochs): #5)MaxEpochs번 반복
k = 0
#3) 미니 배치 생성
for x_batch, y_batch in generate_batches(batch_size,
shuffled_x_train,
shuffled_y_train):
paths.append(w0)
batch_loss.append(loss(w0,x_batch,y_batch))
#4)-1 미니 배치에서 그래디언트 계산
grad = loss_grad(w0,x_batch,y_batch)
search_direction = -grad #4)-2 탐색 방향 설정
r = rho * r + (1. -rho) * grad * grad
lr = epsilon / np.sqrt(delta + r)
dw = lr * search_direction #4)-4 파라미터 업데이트
w0 = w0+ dw
print('{:01d}-{:02d}\t{}\t{}\t{}\t{:5.4f}'.format(epoch+1,k+1,
np.array2string(w0,formatter=format_dict),
np.array2string(grad,formatter=format_dict),
np.array2string(dw,formatter=format_dict),
loss(w0,x_train,y_train)))
k+=1
3. Adam
㉮ 초깃값을 설정하고 단기 누적 그래디언트 크기를 0, 단기 누적 그래디언트 합을 0으로 초기화
㉯ 전체 데이터를 임의로 섞는다.
㉰ 전체 데이터에서 개수가 m개인 부분집합 (배치, batch) 들을 만듭니다.
㉱ 각 부분집합마다 다음을 반복합니다.
- 부분집합으로 그래디언트를 현재위치에서 계산
- 탐색 방향을 단기 누적 그래디언트 합으로 설정합니다.
- 단기 누적 그래디언트 크기를 계산하여 학습률 벡터를 정합니다.
- 파라미터 추정치를 업데이트합니다.
㉲ 만들어진 부분집합을 모두 사용한 후 다시 ㉱를 Epoch번 반복합니다.
'Math > Numerical Analysis' 카테고리의 다른 글
[수치해석] 신경망 모델 (0) | 2022.02.11 |
---|---|
[수치해석] Tensorflow 이용 기본 모델 학습 (0) | 2022.02.11 |
[수치해석] 수치최적화 알고리즘(SGD, Momentum) (0) | 2022.02.11 |