티스토리 뷰

728x90
반응형

경사하강법

그래디언트

(편)미분값이다. 최고 값, 최솟 값을 찾기 위해서 그래프의 증감방향으로 점진적으로 접근하는 방법이다.

경사하강법, 경사 상승법

경사 하강법은 Local(범위가 정해진) minimum을 찾는 방법이다. 반대로 경사 상승법은 Local maximum을 찾는 방법이다. 경사 하강법에서 부호만 반대로 하면 경사 상승법 적용이 가능하다.

경사하강법

현재 x 값의 미분값(기울기)에 따라 기울기가 음수이면 x 값을 양의 방향으로 이동하고, 기울기가 양수이면 x 값을 음의 방향으로 이동한다.

경사상승법

현재 x 값의 미분값(기울기)에 따라 기울기가 음수이면 x 값을 음의 방향으로 이동하고, 기울기가 양수이면 x 값을 양의 방향으로 이동한다.

그래디언트 계산하기

sum of squares 최저점 구하기

sum_of_sqaures = y = x1^2 + x2^2 + x3^2 식의 최솟값(최저점)을 구한다.

import random
from datascience.mathematics.vector import distance, add, scalar_multiply # 이전글 참고
from typing import List
Vector = List[float]

def gradient_step(v: Vector, gradient: Vector, step_size: float) -> Vector:
    """Moves 'step_size' int the 'gradient' direction from 'v'"""
    assert len(v) == len(gradient)
    step = scalar_multiply(step_size, gradient)
    return add(v, step)

def sum_of_squares_gradient(v: Vector) -> Vector:
    return [2*v_i for v_i in v]

#fixme pick a random starting poing
v = [random.uniform(-10, 10) for i in range(3)]

for epoch in range(1000):
    grad = sum_of_squares_gradient(v) #fixme compute the gradient at v
    v = gradient_step(v, grad, -0.01)
    print(epoch, v)

assert distance(v, [0, 0, 0]) < 0.001 #fixme should be close to 0

경사하강법으로 모델학습

linear_gradient

[-50, 49]에서 Y = 20X + 5로부터 산출된 데이터를 제공한다. Loss function; 평균제곱오차의 편미분 값을 반환한다.

from typing import List

Vector = List[float]

# fixme ranges from -50 to 49, y is always 20 * x + 5
inputs = [(x, 20 * x + 5) for x in range(-50, 50)]

def linear_gradient(x: float, y: float, theta: Vector) -> Vector:
    slope, intercept = theta #fixme 기울기, y절편
    predicted = slope * x + intercept #fixme 모델
    error = (predicted - y) #fixme 주어진 함수의 y 값과 input y값 과의 차이
    squared_error = error ** 2 # fixme 그것의 제곱
    grad = [2 * error * x, 2 * error] #fixme 편미분
    return grad

여러점일 경우 loss function

여러점일 경우의 loss function; 평균 제곱 오차(mean squared error)는 임의의 theta로 시작하며, 모든 그래디언트의 평균을 계산한다. 다음 theta를 gradient_step() 함수로 grad, 즉 진짜 기울기와의 격차를 좁힌다.

from typing import List
from datascience.mathematics.vector import vector_mean #fixme 이전 글 참고
from datascience.경사하강법.경사하강법으로모델학습 import linear_gradient #fixme 이전 글 참고
from datascience.경사하강법.최저점구하기 import gradient_step #fixme 이전 글 참고

import random

Vector = List[float]
inputs = [(x, 20 * x + 5) for x in range(-50, 50)]

#fixme Start with random values for slope and intercept
theta = [random.uniform(-1, 1), random.uniform(-1, 1)]

learning_rate = 0.001

for epoch in range(5000):
    #fixme Compute the mean of the gradients
    grad = vector_mean([linear_gradient(x, y, theta) for x, y in inputs])
    #fixme Take a step in that direction
    theta = gradient_step(theta, grad, -learning_rate)
    print(epoch, theta)


slope, intercept = theta
assert 19.9 < slope < 20.1, "slope should be about 20"
assert 4.9 < intercept < 5.1, "intercept shuld be about 5"
728x90
반응형
댓글
반응형
250x250
글 보관함
최근에 달린 댓글
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Total
Today
Yesterday
링크