selfstarter

python 미분 본문

ML

python 미분

selfstarter 2019. 10. 8. 06:51

python 미분

독립변수와 종속변수

  • f(x) = x2 + 3x

  • 행렬을 미분한다

  • a = (w x), (y z)
    w가 변한다고 해서 다른 변수가 영향을 받는건 아니다

  • 각 각의 엘리먼트는 독립적

    • 동전의 앞면과 옆면이 나올 확률. 각각 별개이다
    • 온도가 높으면 땀이 날 때 온도와 땀은 종속관계일까? 인디언 민족은 더위에 적용되어 땀이 안난다. 종속은 100%이다. 반드시. 그러므로 종속이 아니다
    • 심장이 멈추면 사람은 죽는다. 종속은 100%. 종속 관계이다
    • 각각의 엘리먼트는 x가 변하면 y가 변한다는 걸 증명할 수 없으면 종속이 아니다.
  • 비가 오려면 온도, 습도, 저기압 등 다양한 영향을 받는다. 독립변수?종속변수? 기본적으로 독립적이라고 푼다. 왜냐하면 습도가 낮다면 온도가 낮은 경우의 반론이 있기 때문에.

  • 그래서 편미분 방정식을 풀 때 조건을 주고 시작한다.

  • 행렬의 각 각 편미분해도 아무 문제 없다
    => 행렬을 미분할 것. 행렬은 각 각 독립변수

f = a+b  
시그마의 항은 독립적이다(더하기 이므로)
f(x)를 미분한다

미분

  • 미분공식을 어디에 쓰는가?
    • 어떤 값의 임의의 지점(f(x))에서 세모x만큼 증가시켰을 때 x+세모x일 경우의 값f(x+세모x)
    • x와 x+세모x의 차이가 0.1일 때 차이가 세모x(분모)
    • 델타x는 가로 차이
    • 델타y는 세로 차이
    • 입력값이 미세하게 변할 때 출력이 얼마나 변하는지 확인하는 게 미분의 정의(접선의 기울기x)
    • 미세하게 변한다는 건 입력값이 있다는 것
    • 현재 입력값이 아주 조금 변할 때 출력값이 얼마나 변하는지 알아내는 것

미분 예시

  • 현재 입력값, 변수(변화시키는 값)
  • f(x) = x2일 경우 미분 f'(x) = 2x
  • f(3) = 9 해석(함수)
  • 입력값이 3일 때 출력이 9이다
  • f'(3) = 9 해석(미분)
  • 현재 입력값이 3인데 미세하게 변화시키면 6만큼 변한다
  • 결과를 보는건 함수고, 결과로 가기까지 얼마만큼 변했는지 보는건 미분
  • 변화를 제어하고 싶으면 미분
  • f(x+델타x)-f(x-델타x)/2델타x 이렇게 미분공식을 풀 수 있다
  • pt에 나와있는 수식은 증가만 있고 위 수식이 증가, 감소 전부 타나나므로(위 공식을 python 코드로 만들어야 한다)

델타 하이퍼파라메터

(사진참고)

  • 델타(하이퍼파라메터)에 따라 값이 나오기도 하고, 안나옴. 조정해야한다
  • 또 컴퓨터의 스팩이 각자 다르므로 같은 값이 나올 수도 있고, 안나올 수도 있음

미분

f(n) = 상수  
f(x) = 4  
그러므로 미분의 결과값은 0이다. 왜냐하면 상수이므로 함수는 출력이 항상 일정하므로  
f'(x) = 8x2-1 = 8x
  • 익스퍼내션x. 무한으로 뻗어나감. 미분하면 자기 자신이 나옴
  • e-x (체인룰 필요)
  • 4번 예제 정답
    f'(x) = f(x)(1-f(x))
    x가 0일 때 ex는 1이되므로 1/2 = x = 0.5 이다
  • 오차역전파?는 미분은 나눗셈을 하는데 컴퓨터는 나눗셈이 오래걸려서 곱셈으로 변환한 것
  • 오차역전파는 자신이 손으로 풀어야함

코드 구현

  • lim델타x->0은 0처럼 아주 작은 값 -> le-4 라고 누가 찾았음

  • deltn_x = le-20은 너무 소수점이 많아서 0이 되어버린다

  • f는 어떤 함수를 의미함

  • x를 delta_x만큼 변화시키는 공식

    def func1(x):
      return x**2
    f = lambda x : func1(x)
    

수치미분 함수 1차 버전

def numerical_derivative(f, x):
    delta_x = 1e-4
    return (f(x+delta_x)-(f(x-delta_x))) / (2*delta_x)

ret1 = numerical_derivative(f, 3.0)
print(ret1)
ret2 = numerical_derivative(func1, 3.0)
print(ret2)

print('변화값:',ret2 - 3.0)
  • 고등학교때는 2x 라고 x를 임의로 작성했지만 지금은 x값을 우리가 줘야한다

미분_체인룰.pdf 예제1 정리

  1. 미분코드를 짤 땐 미분하고자 하는 함수를 정의해야함(f(x)=3xe2) 파이썬코드로 만들어야 함
    그게 func2(함수 정의를 넣으면 됨)
    그리고 미분결과로 얼마만큼 변하는지 계산하는 코드를 호출 numerical_derivative

편미분

  • 입력변수가 하나 이상인 경우 다변수

  • 미분하고자 하는 변수 빼고는 상수로 취급

    f(x, y) = 2x+3xy
    
  • 다변수 함수를 미분하는 걸 편미분이라고 한다

  • 다변수 함수에서 변수를 독립변수로 본다.종속변수라면 증명해야한다

  • x가 변해도 y는 아무 변화 없다. y가 변해도 x는 아무 변화 없다. > 즉 각자 계산할 때 자신 빼고 상대 변수를 상수로 취급해도 된다

  • 혹시라도 종속일 가능성이 있으므로 오차율로 가능성을 열어둔다

  • 라운드x : 변수가 여러개

  • dx : 변수 한개

  • 처음에 관계식을 만드는 법을 정의 해야한다

f(x,y) = 2x + 3xy + y3  
af/ax = 2 + 3y  
af/ay = 3x + 2y2

관련없는 상수 빼기

chain rule

  • 합성합수란 여러함수로 구성된 함수를 뜻함
  • 3ex3 합성함수? 합성(ex2 곱한 것)
  • f(x) = xlogx ? 함성아님
  • 기본함수가 아닌 것이 합성
  • 체인룰이란 합성함수를 미분하는 것. 복잡한 함수를 미분하기 위해 같은 값일 계속 곱해줌. 왜 체인룰을 써서 합성함수를 미분할까?기본함수로 만들어서 함수미분공식으로 최대한 빨리 미분. 따로 공식 외울필요 x
  • 미분하는 이유는 행렬하기 위해(행렬 doc product가 빠르므로)
  • 체인룰 마지막으로 t를 x로 바꿔주는 작업을 해야함
  • 미분을 기본함수로 쪼개는 작업을 해야한다
  • 미분곱셈 어려우므로 더하기로 변경해야한다
  • 함수가 곱하기일 때 > 로그로 더하기로 바꿀 수 있다

편미분 코드 구성

  • 미분하고자 하는 변수 이외에는 상수로 만듬
  • 변수의 갯수만큼 반복해야한다 > for문
  • ??′(1.0, 2.0)은 x가 1.0일 때 y는 2.0이다
  • 함수가 불연속적이면 미분할 수 없다
  • 산모양(뾰족한 모양은 미분할 수 없다. 다만 수치미분으로 가능(0보다 큰 경우, 작은경우 각각 구한다))

import numpy as np

x는 행렬

import numpy as np

x는 나중에 행렬이 들어간다. 지금은 벡터

def numerical_derivative(f, x): # 수치미분 debug version  
delta_x = 1e-4 # 극한을 나타냄  
grad = np.zeros_like(x) # x의 크기와 동일하게 0으로 초기화된 행렬을 만든. 미분값 보관  
print("debug 1. initial input variable =", x)  
print("debug 2. initial grad =", grad)  
print("=============================")

it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
print(it)
while not it.finished:
    idx = it.multi_index
    print("debug 3. idx =", idx, ", x[idx] =", x[idx])

    tmp_val = x[idx]
    x[idx] = float(tmp_val) + delta_x # 3.0 + 0.00001 더해줌
    fx1 = f(x) # 3.00001 제곱을 리턴

    x[idx] = tmp_val - delta_x
    fx2 = f(x)
    grad[idx] = (fx1 - fx2) / (2*delta_x) # 미분 공식에서 분모를 의미

    print("debug 4. grad[idx] = ", grad[idx])
    print("debug 5. grad =", grad)
    print("===========================")

    x[idx] = tmp_val # x[idx] 값을 변경했으므로 원본값으로 초기화시킨다
    it.iternext()

return grad

입력변수 1개인 함수 f(x) = x**2

def func1(W):  
x = [0]  
return x**2

lambda function 정의

f = lambda W : func1(W)  
W = np.array([3.0])

x = 3.0에서의 편미분 값

ret = numerical_derivative(f, W)  
print('type(ret) =', type(ret), ', ret_val =', ret)

debug 1. initial input variable = [3.]  
debug 2. initial grad = [0.]  
=============================  
debug 3. idx = (0,) , x[idx] = 3.0  
debug 4. grad[idx] = 6.000000000012662  
debug 5. grad = [6.]  
===========================  
type(ret) = <class 'numpy.ndarray'> , ret_val = [6.]

'ML' 카테고리의 다른 글

python Numpy 정리  (0) 2019.10.08
Python List,Tuple,Dictionary,String  (0) 2019.09.17
객체이름 정의(벡터,행렬)  (0) 2019.08.19
R 벡터, 행렬 생성 함수  (0) 2019.08.17
R 추가 패키지 설치  (0) 2019.08.16
Comments