기울기법으로 2차 함수의 최대값·최소값을 구한다

15385 단어 Python3matplotlibnumpy
그라디언트 방법을 사용하여 1 차 함수의 최대 값과 최소값을 탐색하고 도시하고 반복의 추이를 그래프로 나타냅니다. 이 프로그램은 신경망을 배우고 있는 동안 만든 프로그램이며, 굳이 라이브러리를 사용하지 않는 부분이 있다.
#勾配法を使って1変数関数の最大値・最小値を探索、イテレーションの推移をグラフ化
import numpy as np
import matplotlib.pyplot as plt

def function_3(x):
    return -x**2 + 5

def function_4(x):
    return -x**3 - 4*x**2 + 4*x + 10

# 数値微分
def numerical_diff(f, x):
    h = 1e-4 # 0.0001
    diff = (f(x+h)-f(x-h)) / (2*h)
    return diff

#勾配法で最小値、最大値を求める
def grad_descent_1(f, init_x, lr, steps):
    x = init_x
    grads = numerical_diff(f, x)

    if grads >= 0:
        for _ in range(steps):
            grads = numerical_diff(f, x)
            x -= lr*grads

        print('最小値:')
        return f(x)

    elif grads < 0:
        for _ in range(steps):
            grads = numerical_diff(f, x)
            x += lr*grads

        print('最大値:')
        return f(x)

# グラフ用
def grad_descent_2(f, init_x, lr, steps):
    lr = lr
    steps = steps
    x = init_x
    grads = numerical_diff(f, x)

    if grads >= 0:
        while True:
            grads = numerical_diff(f, x)
            x -= lr*grads

            yield x

    elif grads < 0:
        while True:
            grads = numerical_diff(f, x)
            x += lr*grads

            yield x

#関数の概形と現在位置、最小値を表示
def graph(f, init_x, x):
    init_y = f(init_x)
    y = f(x) #関数の設定
    plt.figure()

    def start_point(init_x):
        plt.plot(init_x, init_y, 'o', label="start", color='blue')

    start_point(init_x) #始点を表示
    plt.plot(x, y, label="x**2 + 5") #グラフを表示
    plt.plot(linear_grad, 'o', label="min") #最小点
    plt.legend() # 凡例をグラフにプロット
    plt.grid(which='both', axis = "both", linewidth =1)
    plt.show()

#最大値・最小値に収束していく様子をグラフ化
def visualize(f):
    grad = grad_descent_2(f, init_x=init_x, lr=lr, steps=steps)
    x = range(steps)
    y = [next(grad) for j in x] #gradsを配列に格納

    fig = plt.figure()
    ax = plt.axes()
    ax.set_xlabel("steps")
    ax.set_ylabel("x")
    plt.title("勾配法による収束過程")
    plt.plot(x, y)
    plt.show()


x = np.arange(-4, 6, 0.1)
func = function_3
init_x = 3.0
lr = 0.01
steps = 300
linear_grad = grad_descent_1(func, init_x=init_x, lr=lr, steps=steps)
print(linear_grad)

graph(func, init_x=init_x, x=x)
visualize(func)

# 最大値:4.99995103475578

2차 함수의 경우,

로 시작점과 최대 값이 표시됩니다. 또한 반복의 수렴 과정은

되어 수렴하고 있는 것을 알 수 있다. 최소값인 경우에도
# 最小値:-4.99995103475578

되고,

최소값이 표시됩니다.
그럼, 3차 함수의 경우라면,
# 最大値:10.900894327379042


제대로 작동하고 있습니다.

참고문헌
오라일리 재팬 제로에서 만드는 DeepLearning 사이토 야스히로

좋은 웹페이지 즐겨찾기