Алгоритм градиентного спуска в машинном обучении
Градиентный спуск – это алгоритм оптимизации, используемый для разнообразного обучения модели машинного обучения. Он лучше всего подходит для задач, в которых имеется большое количество функций и слишком много образцов, чтобы поместиться в памяти модели машинного обучения. В этой статье я познакомлю вас с алгоритмом градиентного спуска в машинном обучении и его реализацией с использованием Python.
Алгоритм градиентного спуска
В машинном обучении градиентный спуск – это алгоритм оптимизации, способный находить наиболее подходящие решения для широкого круга проблем. Он работает через повторение настройки параметров для минимизации функции стоимости.
Самым важным параметром этого алгоритма является размер шагов, который определяется скоростью обучения. Если скорость обучения очень низкая, алгоритм будет проходить множество итераций, чтобы сойтись, что в конечном итоге займет очень много времени.
Но если скорость обучения очень высока, он разделит алгоритм на большие значения, что поможет найти хорошее решение. При использовании алгоритма градиентного спуска необходимо убедиться, что все функции имеют одинаковый масштаб, в противном случае потребуется много времени, чтобы сойтись.
Типы алгоритмов градиентного спуска
Чтобы реализовать алгоритм градиентного спуска, нам необходимо вычислить градиент функции стоимости, что приводит к трем типам алгоритмов градиентного спуска, которые различаются объемом данных, используемых для вычисления градиента функции стоимости.
Пакетный градиентный спуск:
Он использует весь пакет данных на каждом этапе итерации, в результате довольно медленно обрабатывает большие наборы обучающих данных. Это предпочтительнее, только если вы хотите обработать все экземпляры в обучающем наборе. Единственное ограничение заключается в том, что если обучающий набор очень велик, он будет очень медленным. Давайте посмотрим, как реализовать его с помощью Python:
# Batch Gradient Descent import numpy as np eta = 0.1 # learning rate n_iterations = 1000 m = 100 X = 2 * np.random.rand(100, 1) y = 4 + 3 * X + np.random.randn(100, 1) X_b = np.c_[np.ones((100, 1)), X] # add x0 = 1 to each instance theta = np.random.randn(2,1) #random initilization for iteration in range(n_iterations): gradients = 2/m * X_b.T.dot(X_b.dot(theta)-y) theta = theta - eta * gradients print(theta)
Стохастический градиентный спуск:
Итак, как упоминалось выше, пакетный градиентный спуск работает очень медленно, поскольку он использует все обучающие данные для вычисления градиентов на каждом этапе итерации. Это ограничение преодолевается с помощью алгоритма стохастического градиентного спуска.
SGD извлекает случайный экземпляр обучающего набора на каждом шаге итерации и вычисляет градиенты на основе этого случайного экземпляра. Таким образом, работа с одним экземпляром идет быстрее. Теперь давайте посмотрим, как реализовать это с помощью Python:
# Stochastic Gradient Descent n_epochs = 50 t0, t1 = 5, 50 #learning schedule hyperparameters m = 100 X = 2 * np.random.rand(100, 1) y = 4 + 3 * X + np.random.randn(100, 1) X_b = np.c_[np.ones((100, 1)), X] # add x0 = 1 to each instance def learning_schedule(t): return t0/(t+t1) theta = np.random.randn(2,1) #random initilization for epoch in range(n_epochs): for i in range(m): random_index = np.random.randint(m) xi = X_b[random_index:random_index+1] yi = y[random_index:random_index+1] gradients = 2 * xi.T.dot(xi.dot(theta)-yi) eta = learning_schedule(epoch * m + i) theta = theta - eta * gradients print(theta)
Мини-пакетный градиентный спуск:
Последний тип алгоритма градиентного спуска – это мини-пакетный градиентный спуск. Он вычисляет градиенты для небольших случайных наборов экземпляров, известных как мини-пакеты, вместо вычисления набора обучающих данных или одного случайного экземпляра. Теперь давайте посмотрим, как реализовать это с помощью Python:
# Mini-batch Gradient Descent n_iterations = 50 minibatch_size = 20 m = 100 X = 2 * np.random.rand(100, 1) y = 4 + 3 * X + np.random.randn(100, 1) X_b = np.c_[np.ones((100, 1)), X] # add x0 = 1 to each instance np.random.seed(42) theta = np.random.randn(2,1) # random initialization t0, t1 = 200, 1000 def learning_schedule(t): return t0 / (t + t1) t = 0 for epoch in range(n_iterations): shuffled_indices = np.random.permutation(m) X_b_shuffled = X_b[shuffled_indices] y_shuffled = y[shuffled_indices] for i in range(0, m, minibatch_size): t += 1 xi = X_b_shuffled[i:i+minibatch_size] yi = y_shuffled[i:i+minibatch_size] gradients = 2/minibatch_size * xi.T.dot(xi.dot(theta) - yi) eta = learning_schedule(t) theta = theta - eta * gradients print(theta)
Резюме
Таким образом, градиентный спуск – это общий метод оптимизации, способный находить самые подходящие решения для широкого круга задач. Например, предположим, что вы заблудились в горах в плотном тумане и в этот момент вы можете чувствовать только наклон земли под ногами. На этом этапе хорошей стратегией для прохода на дно долины является спуск в направлении самого крутого склона. Таким же образом работают алгоритмы градиентного спуска.
Надеюсь, вам понравилась эта статья об алгоритме градиентного спуска в машинном обучении и его реализации с использованием языка программирования Python.