Ai tech Day7


Mathematics for Artificial Intelligence


びぶん


微分(differentiation)は、変数の移動に伴う関数値の変化を測定する閾値である.
  • 最適化で最も一般的な技術
  • 最近では、手動で微分を計算する代わりにコンピュータを使用することができます.
  • import sympy as sym
    from sympy.abc import x
    
    sym.diff(sym.poly(x**2 + 2*x + 3), x)
    # Poly(2𝑥+2,𝑥,𝑑𝑜𝑚𝑎𝑖𝑛=ℤ)
  • 微分関数fの与えられた点(x,f(x))上の接線の傾斜を求める.
  • 点で接線の傾きが分かれば、どの方向に移動点を上げるか、関数値が増加するか減少するかを知ることができます.



  • 微分値を加えて勾配上昇法と呼ばれ,関数極大値の位置を求めるために用いられる.
  • 微分値を除去することを勾配降下法と呼び,関数の極小値の位置を求める.
  • 上り坂/下り坂方法が極値に達した後、移動を停止します.
  • 計算機で計算すると、微分が正確にゼロになることは不可能であるため、eps未満では終了条件が必要である.
  • var = init
    grad = gradient(var)
    while(abs(grad > eps):
       var = var - lr * grad # lr은 학습률로서 미분을 통해 업데이트하는 속도를 조절한다
       grad = gradient(var) # 종료 조건이 성립하기 전까지 미분 값을 계속 업데이트한다
    def func(val):
        fun = sym.poly(x**2 + 2*x + 3)
        return fun.subs(x, val), fun
        
    def func_gradient(fun, val):
        _, function = fun(val)
        diff = sym.diff(function, x)
        return diff.subs(x, val), diff
        
    def gradient_descent(fun, init_point, lr_rate = 1e-2, epsilon = 1e-5):
        cnt = 0
        val = init_point
        diff, _ = func_gradient(fun, init_point)
        while np.abs(diff) > epsilon:
            val = val - lr_rate * diff
            diff, _ = func_gradient(fun, val)
            cnt += 1
            
        print(f"함수: {fun(val)[1]}, 연산횟수: {cnt}, 최소점: ({val}, {fun(val)[0]})")
        
    gradient_descent(fun = func, init_point = np.random.uniform(-2, 2))
    # 함수: Poly(x**2 + 2*x + 3, x, domain='ZZ'), 연산횟수: 624, 최소점: (-0.999995082008834, 2.00000000002419)

    ベクトルの微分


    ベクトルが入力の多変数関数の場合、偏微分(partialdifferentiation)を使用します.
    import sympy as sym
    from sympy.abc import x, y
    
    sym.diff(sym.poly(x**2 + 2 * x * y + 3) + sym.cos(x + 2 * y) , x)
    # 2𝑥+2𝑦−sin(𝑥+2𝑦)
  • の各変数を用いて偏微分の勾配ベクトルを計算し,傾斜降下/傾斜上昇法に用いることができる.



  • def eval_(fun, val):
        val_x, val_y = val
        fun_eval = fun.subs(x, val_x).subs(y, val_y)
        return fun_eval
        
    def func_multi(val):
        x_, y_ = val
        func = sym.poly(x ** 2 + 2 * y ** 2)
        return eval_(func, [x_, y_]), func
        
    def func_gradient(fun, val):
        x_, y_ =val
        _, function = fun(val)
        diff_x = sym.diff(function, x)
        diff_y = sym.diff(function, y)
        grad_vec = np.array([eval_(diff_x, [x_, y_]), eval_(diff_y, [x_, y_])], dtype = float)
        return grad_vec, [diff_x, diff_y]
        
    def gradient_descent(fun, init_point, lr_rate = 1e-2, epsilon = 1e-5):
        cnt = 0
        val = init_point
        diff, _ = func_gradient(fun, init_point)
        while np.linalg.norm(diff) > epsilon:
            val = val - lr_rate * diff
            diff, _ = func_gradient(fun, val)
            cnt += 1
            
        print(f"함수: {fun(val)[1]}, 연산횟수: {cnt}, 최소점: ({val}, {fun(val)[0]})")
        
    pt = [np.random.uniform(-2, 2), np.random.uniform(-2, 2)]
    gradient_descent(fun = func_multi, init_point = pt)
    # 함수: Poly(x**2 + 2*y**2, x, y, domain='ZZ'), 연산횟수: 529, 최소점: ([ 4.96374105e-06 -5.33676420e-10], 2.46387257323552E-11)

    せんけいかいきかいせき


    線形回帰の目的式はβ∣∣2||y - X\beta ||_{2}∣∣y−Xβ∣∣2,β\betaβ 検索が必要なため、次の勾配ベクトルを求める必要があります.



  • 現在はβ\betaβ解の傾斜降下法アルゴリズムは以下の通りである.



  • 傾斜降下法アルゴリズムでは,学習率と学習回数が重要なパラメータとなっている.
  • for t in range(T): # 학습 횟수가 너무 적으면 경사하강법이 수렴하지 못할 수 있다
        error = y - X @ beta
        grad = - transpose(X) @ error
        beta = beta - lr * grad
    X = np.array([[1, 1], [1, 2], [2, 2], [2, 3]])
    y = np.dot(X, np.array([1, 2])) + 3
    
    beta_gd = [10.1, 15.1, -6.5] # [1, 2, 3] 이 정답
    X_ = np.array([np.append(x, [1]) for x in X]) # intercept 항 추가
    
    for t in range(5000):
        error = y - X_ @ beta_gd
        # error = error / np.linalg.norm(error)
        grad = - np.transpose(X_) @ error
        beta_gd = beta_gd - 0.01 * grad
        
    print(beta_gd)
    # [1.00000367 1.99999949 2.99999516]

    けいしゃこうかほう


    理論的には,傾斜降下法は微分可能であり,凸(凸)関数に対して適切な学習率と学習回数を選択すると収束性を保証できる.
    特に線形回帰,目的式∣∣y Xβ∣∣2||y - X\beta||_{2}∣∣y−Xβ∣∣2は回帰係数であるβ\betaβ凸関数であるため,アルゴリズムを十分に回転させると収束が確保される.

    しかし,非線形回帰問題では,ターゲット関数が凸でない可能性があるため,収束を保証することはできない.

    かくりつけいしゃこうかほう


    確率傾斜降下法(ランダム勾配降下法)は、すべてのデータを用いて更新するのではなく、1つ以上のデータを用いてデータを更新する.
  • SGDは、一部のデータのミラーリングを更新し、コンピューティングリソースのより効率的な利用を支援する.

  • SGDは非凸目的学習に用いることができ,傾斜降下法に比べて機械をより効果的に学習する.