Градиентный спуск через простой набор данных

Feb 22 2023
Поймите, как выполнить базовый градиентный спуск с помощью простого набора данных. Обзор: Привет, мир! В моем первом настойчивом набеге на мир публикации статей в Интернете я собираюсь продемонстрировать градиентный спуск в машинном обучении с помощью простого набора данных.

Поймите, как выполнить базовый градиентный спуск с помощью простого набора данных.

Обзор:

Привет, мир! В моем первом настойчивом набеге на мир публикации статей в Интернете я собираюсь продемонстрировать градиентный спуск в машинном обучении с помощью простого набора данных. Слово «градиент» имеет несколько значений в зависимости от контекста, в котором оно используется. Однако в общем смысле это означает нечто, что постепенно меняется. На языке математики и машинного обучения градиент называется «наклон», который указывает, насколько крутой или пологой является линия (или функция) в определенной точке на n-мерной плоскости. Крутой наклон указывает на высокую скорость изменения одного фактора по отношению к другому фактору, в то время как для пологого наклона верно обратное.

На уроках математики в школах учили, что уравнение прямой имеет вид y = mx + c (обозначения могут варьироваться в зависимости от учебника) , где y — точка на оси y, x — точка на оси x, m — наклон и c — точка пересечения по оси Y. Если Intercept по оси Y равен 0, c можно игнорировать. В машинном обучении это уравнение является основной проблемой линейной регрессии. Если на двумерной плоскости есть только одна линия, наклон и пересечение можно найти с помощью формул, подставив их вместо m и c и решив уравнение. Следовательно, она имеет единственное решение.

На самом деле каждая проблема машинного обучения включает в себя сотни или тысячи уравнений, которые чаще всего не имеют единого решения. Каждое уравнение — это «Наблюдение», а каждая ось — это «Функция». Когда система уравнений имеет больше наблюдений, чем признаков, она называется переопределенной системой. Следовательно, большинство проблем машинного обучения связаны с переопределенной системой. Градиентный спуск используется для нахождения решения (коэффициента) для каждой функции, с которым могут согласиться все наблюдения, что сведет к минимуму «коллективную разницу» между наблюдаемыми и прогнозируемыми результатами. «Коллективная разница» рассчитывается с использованием множества «Функций стоимости». Одним из них является среднеквадратическая ошибка (MSE) , которая используется в задаче машинного обучения в этой статье.

Программа:

Для этой задачи градиентного спуска подготовлен простой синтетический набор данных. Все блоки кода написаны на языке программирования Python. Программа начинается с импорта необходимых пакетов Python.

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt

Определите уравнение в Python и сгенерируйте набор данных.

def f(x):
    return 2.3*x
x = np.arange(-20, 20, 2) #Generate feature x
Y = []
for x_i in x:
    Y.append(np.round(f(x_i),2)) #Generate Observed value Y
fulldata = pd.Series(zip(x,Y))
n=len(fulldata)

Заменив y_bar,

Функция Python создана для облегчения расчета стоимости путем предоставления необходимых входных параметров.

def costfunc(Y_i, x_i, m, n):
    return (1/n)*sum(pow(Y_i-(m*x_i),2))

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

Применяя это как функцию Python,

def der_costfunc(Y_i, x_i, m, n):
    return (2/n)*sum(x_i*((m*x_i)-Y_i))

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

Другая переменная, которая используется в градиентном спуске, — это допуск . Поскольку градиентный спуск пытается уменьшить MSE с помощью нескольких итераций, должен быть способ определить, когда MSE является приемлемым, и остановить итерации. Один из способов — использовать толерантность. Может быть несколько способов определить допуск для задачи градиентного спуска. В этой статье определяется разница в MSE между последовательными итерациями, и если она меньше определенного значения, итерации останавливаются.

Наконец, начальное значение коэффициента m устанавливается таким образом, чтобы его можно было корректировать на каждой итерации для уменьшения MSE. Поместите все это в код Python, как показано ниже.

ms = []        #Hold the coefficients for each iteration for plotting purpose
errors = []    #Hold the MSE for each iteration for plotting purpose
m = 0          #Initial value of the coefficient
step = 0.001   #Ensure step is appropriate else costfunc will wildly swing.
tol=0.0001     #Acceptable difference in MSE between consecutive iterations to stop the Descent

1. Рассчитайте стоимость, используя начальное значение коэффициента.

2. Рассчитайте значение производной для начального значения m , используя уравнение первой производной функции стоимости. Умножьте это значение на значение Step , чтобы определить следующее значение для коэффициента m .

3. Рассчитайте стоимость еще раз с новым значением коэффициента m . Найдите разницу между MSE, полученной на шаге 1 и шаге 3.

4. Повторяйте шаги с 1 по 3 до тех пор, пока разница между последовательными затратами не окажется в пределах допуска.

Применяя эти шаги как код Python,

prevcost = costfunc(Y, x, m, n)
for i in range(200):
    der_m = der_costfunc(Y, x, m, n)
    m = m - (der_m*step)
    currcost = costfunc(Y, x, m, n)
    ms.append(m)
    errors.append(currcost)
    if((prevcost-currcost) < tol):
        print(f'm: {np.round(m,5)}, currcost: {currcost}, prevcost: {prevcost}')
        plt.plot(ms, errors)
        plt.xlabel("coefficient")
        plt.ylabel("MSE")
        plt.show()
        break
    prevcost = currcost

Коэффициент против MSE (стоимость) для каждой итерации

Собираем весь код Python вместе.

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt

def f(x):
    return 2.3*x
x = np.arange(-20, 20, 2)
Y = []
for x_i in x:
    Y.append(np.round(f(x_i),2))
fulldata = pd.Series(zip(x,Y))
n=len(fulldata)

def costfunc(Y_i, x_i, m, n):
    return (1/n)*sum(pow(Y_i-(m*x_i),2))

def der_costfunc(Y_i, x_i, m, n):
    return (2/n)*sum(x_i*((m*x_i)-Y_i))

ms = []        #Hold the coefficients for each iteration for plotting purpose
errors = []    #Hold the MSE for each iteration for plotting purpose
m = 0          #Initial value of the coefficient
step = 0.001   #Ensure step is appropriate else costfunc will wildly swing.
tol=0.0001     #Acceptable difference in MSE between consecutive iterations to stop the Descent

prevcost = costfunc(Y, x, m, n)
for i in range(200):
    der_m = der_costfunc(Y, x, m, n)
    m = m - (der_m*step)
    currcost = costfunc(Y, x, m, n)
    ms.append(m)
    errors.append(currcost)
    if((prevcost-currcost) < tol):
        print(f'm: {np.round(m,5)}, currcost: {currcost}, prevcost: {prevcost}')
        plt.plot(ms, errors)
        plt.xlabel("coefficient")
        plt.ylabel("MSE")
        plt.show()
        break
    prevcost = currcost

Я надеюсь, что эта статья была полезна в качестве базового введения для непосвященных. Пожалуйста, оставьте свои вопросы, комментарии или рекомендации по этой статье. Спасибо Вам и хорошего дня!