Как сделать задачу градиентного спуска (машинное обучение)? - PullRequest
0 голосов
/ 11 марта 2019

Может кто-нибудь объяснить, как решить проблему градиентного спуска БЕЗ контекста функции стоимости?Я видел бесчисленные учебники, которые объясняют градиентный спуск с использованием функции стоимости, но я действительно не понимаю, как это работает в более общем смысле.

Мне дана 3D-функция:

z= 3 * ((1-xx) 2) * np.exp (- (xx 2) - (гг + 1) 2) \ - 10 * (xx / 5 - xx 3 - yy 5) * np.exp (-xx 2 - yy 2) - (1/3) * np.exp (- (xx + 1) ** 2 - yy 2)

И меня просят:

Кодировать простой алгоритм градиента.Установите параметры следующим образом:

  • скорость обучения = размер шага: 0,1
  • Максимальное количество итераций: 20
  • Критерий остановки: 0,0001 (Ваши итерации должны прекратиться, когдаваш градиент меньше порога)

Затем начните свой алгоритм с

  • (x0 = 0,5, y0 = -0,5)
  • (x0 =-0.3, y0 = -0.3)

Я видел этот кусок кода, плавающий везде, где говорится о градиентном спуске:

def update_weights(m, b, X, Y, learning_rate):
    m_deriv = 0
    b_deriv = 0
    N = len(X)
    for i in range(N):
        # Calculate partial derivatives
        # -2x(y - (mx + b))
        m_deriv += -2*X[i] * (Y[i] - (m*X[i] + b))

        # -2(y - (mx + b))
        b_deriv += -2*(Y[i] - (m*X[i] + b))

    # We subtract because the derivatives point in direction of steepest ascent
    m -= (m_deriv / float(N)) * learning_rate
    b -= (b_deriv / float(N)) * learning_rate

    return m, b
    enter code here

Но я не понимаю, какиспользуйте это для моей проблемы.Как там работает моя функция?Что я настраиваю вместо m и b?Я очень смущен.

Спасибо.

1 Ответ

0 голосов
/ 11 марта 2019

Gradient Descent - алгоритм оптимизации для нахождения минимума функции.

Очень упрощенный вид

Давайте начнем с 1D функции y = f (x)

Давайте начнем с произвольного значения x и найдем градиент (наклон) f(Икс).

  • Если наклон уменьшается в точке x, то это означает, что мы должны идти дальше в направлении (справа от числовой линии) x (для достижения минимума)
  • Если наклонувеличивается в точке x, то это означает, что мы должны отойти (слева от числовой линии) x

    Мы можем получить наклон, взяв производную функции.Производная равна -ve, если наклон уменьшается, и + ve, если наклон увеличивается

Таким образом, мы можем начать с некоторого произвольного значения x и медленно двигаться к минимуму, используя производные вэто значение х.Насколько медленно мы движемся, определяется скоростью обучения или размером шага.таким образом, у нас есть правило обновления

x = x - df_dx*lr

Мы можем видеть, что, если наклон уменьшается, производная (df_dx) равна -ve, а x увеличивается, и поэтому x перемещается вправо.С другой стороны, если наклон увеличивается, df_dx равно + ve, что уменьшает x, и поэтому мы движемся влево.

enter image description here

Мы продолжаем это либо в течение некоторого большого числа раз, либо до тех пор, пока производная не станет очень маленькой

Многомерная функция z = f (x, y)

Применяется та же логика, что и выше, за исключением того, что теперь мы берем частные производные вместо производных.Правило обновления:

x = x - dpf_dx*lr
y = y - dpf_dy*lr

Где dpf_dx - это частная производная от f по x

. Вышеприведенный алгоритм называется алгоритмом градиентного приличия.В машинном обучении f (x, y) - это функция затрат / потерь, минимум которой нас интересует.

Пример

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.axes3d import Axes3D
from pylab import meshgrid
from scipy.optimize import fmin
import math

def z_func(a):
 x, y = a
 return ((x-1)**2+(y-2)**2)

x = np.arange(-3.0,3.0,0.1)
y = np.arange(-3.0,3.0,0.1)
X,Y = meshgrid(x, y) # grid of point
Z = z_func((X, Y)) # evaluation of the function on the grid

fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1,linewidth=0, antialiased=False)
plt.show()

Минимум z_func равен (1,2),Это можно проверить с помощью функции fmin scipy

fmin(z_func,np.array([10,10]))

Теперь давайте напишем наш собственный алгоритм градиентного приличия, чтобы найти минимум z_func

def gradient_decent(x,y,lr):
    while True:
        d_x = 2*(x-1)
        d_y = 2*(y-2)

        x -= d_x*lr
        y -= d_y*lr

        if d_x < 0.0001 and d_y < 0.0001:
            break
    return x,y

print (gradient_decent(10,10,0.1)

Мы начинаем с некоторого произвольного значения x= 10 и у = 10 и скорость обучения 0,1.Приведенный выше код печатает 1.000033672997724 2.0000299315535326, что является правильным.

Итак, если у вас есть непрерывная дифференцируемая выпуклая функция, чтобы найти ее оптимальную (минимальную для выпуклой), все, что вам нужно сделать, - это найти частные производные функции по каждой переменной и использовать обновлениеПравило, упомянутое выше.Повторяйте шаги до тех пор, пока градиенты не станут маленькими, что означает, что мы достигли минимумов для выпуклой функции.

Если функция не выпуклая, мы можем застрять в локальном оптимуме.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...