최적화란 어떤 함수가 주어졌을 때 그 최솟값(또는 최댓값)을 반환하는 '입력(함수의 인수)'을 찾는 것 입니다.
신경망의 학습 목표도 손실 함수의 출력을 최소화하는 매개변수를 찾는 것이니 최적화 문제에 속함을 알 수 있습니다.
28.1 로젠브록 함수


위의 그림을 보면 포물선 모양으로 길게 뻗은 골짜기가 보입니다. 산의 등고선을 그리면 그 모양이 바나나를 닮았다고 해서 로젠브록 함수를 바나나 함수라고도 합니다. 뭔가 귀엽네요
우리의 목표가 로젠브록 함수의 출력이 최소가 되는 x0과 x1을 찾는 건데 로젠브록 함수가 최솟값이 된느 지점은 (x0, x1) = (1, 1)입니다.
28.2 미분 계산하기
(x0, x1) = (0.0, 2.0)에서의 미분을 계산한다고 했을때 아래의 코드로 구현할 수 있습니다.
import unmpy as np
from dezero import Variable
def rosenbrock(x0, x1):
y = 100 * (x1 - x0 ** 2) ** 2 + (x0 - 1) ** 2
return y
x0 = Variable(np.array(0.0))
x1 = Variable(np.array(2.0))
y = rosenbrock(x0, x1)
y.backward()
print(x0.grad, x1.grad)

수치 데이터를 Variable로 감싸서 건네주고 rosenbrock함수를 통과하고 백월드 진행하면 위의 값이 나옵니다.
이 두개의 값을 기울기 또는 기울기 벡터라고 합니다.
기울기는 각 지점에서 함수의 출력을 가장 크게 하는 방향을 가리킵니다.
해당 코드에서 (x0, x1) = (0.0, 2.0) 지점에서 y값을 가장 크게 늘려주는 방향이 -2.0, 400.0 이라는 의미입니다.
반대로 기울기에 마이너스를 곱한 -2.0, 400.0 의 방향은 y값을 가장 작게 줄여주는 방향을 뜻합니다.
28.3 경사하강법 구현
복잡한 함수는 기울기가 가리키는 방향으로 최댓값 반대 방향으로 최솟값이 존재한다고 볼 수 없지만 아주 작게 보면 기울기는 함수의 출력을 가장 크게 하는 방향을 나타내는 것이기 때문에
기울기 방향으로 일정한 거리만큼 이동하여 다시 기울기를 구하는 작업을 반복하면 접차 원하는 지점(최댓값 혹은 회솟값)에 접근하는 것이라고 기대할 수 있습니다(이것은 경사하강법!)
경사하강법을 적용한 코드는 아래에 있습니다.
lr = 0.001
iters = 1000
for i in range(iters):
print(x0, x1)
y = rosenbrock(x0, x1)
x0.cleargrad()
x1.cleargrad()
y.backward()
x0.data -= lr * x0.grad
x1.data -= lr * x1.grad
iters는 반복횟구이고 lr은 learning rate입니다.
해당 코드를 실행해보면 (x0, x1) 값이 갱신되는 과정을 확인 할 수 있습니다.

너무 많아서 다 가져오진 못했는데 출발점에서 위치가 계속 갱신되는 것을 알 수 있습니다.

iter를 수를 키웠더니 목적지인 (1.0, 1.0)에 가까워지는 것을 볼 수 있습니다.
'Study 공부할레나' 카테고리의 다른 글
| [스터디/밑시딥3] 제 3고지 고차미분계산_30. 고차 미분(준비편) (0) | 2023.09.09 |
|---|---|
| [스터디/밑시딥3] 제 3고지 고차미분계산_29. 뉴턴 방법으로 푸는 최적화(수동 계산) (0) | 2023.09.09 |
| [스터디/밑시딥3] 제 3고지 고차미분계산_27. 테일러 급수 미분 (0) | 2023.09.06 |
| [스터디/밑시딥3] 제 3고지 고차미분계산_26. 계산 그래프 시각화(2) (0) | 2023.09.03 |
| [스터디/밑시딥3] 제 3고지 고차미분계산_25. 계산 그래프 시각화(1) (1) | 2023.09.03 |