Один из основных вопросов, возникающих при изучении машинного обучения и глубокого обучения, - это несколько типов градиентного спуска. Следует ли использовать пакетный градиентный спуск? Мини-пакетный градиентный спуск или стохастический градиентный спуск? В этом посте мы собираемся понять разницу между этими концепциями и взглянуть на реализации кода из Gradient Descent, чтобы прояснить эти методы.

Изменить: обновленная версия здесь.

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

Градиентный спуск

Один из наиболее распространенных алгоритмов, помогающих сети достичь правильных значений весов и смещения. Градиентный спуск (GD) - это алгоритм минимизации функции стоимости J (W, b) на каждом этапе. Он итеративно обновляет веса и смещение, пытаясь достичь глобального минимума в функции стоимости.

Быстро просматривая это, прежде чем мы сможем вычислить GD, сначала принимаются входные данные и проходят через все узлы нейронной сети, вычисляя взвешенную сумму входных данных, весов и смещения. Этот первый проход является одним из основных шагов при вычислении градиентного спуска и называется прямое распространение. Когда у нас есть результат, мы сравниваем его с ожидаемым и вычисляем, насколько далеко они друг от друга, ошибка. С этой ошибкой мы теперь можем распространить ее в обратном направлении, обновляя каждый вес и смещение и пытаясь минимизировать эту ошибку. И эта часть называется, как вы уже догадались, Обратное распространение. Шаг обратного распространения рассчитывается с использованием производных и возвращает «градиенты», значения, которые говорят нам, в каком направлении мы должны следовать, чтобы минимизировать функцию затрат.

Теперь мы готовы обновить матрицу весов W и вектор смещения b. Правило градиентного спуска выглядит следующим образом:

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

Этот классический градиентный спуск также называется пакетным градиентным спуском. В этом методе каждая эпоха проходит через весь обучающий набор данных, чтобы только затем вычислить потери и обновить значения W и b. Хотя он обеспечивает стабильную сходимость и стабильную ошибку, этот метод использует весь обучающий набор; следовательно, это очень медленно для больших наборов данных.

Мини-пакетный градиентный спуск

Представьте, что вы разделяете набор данных на несколько частей или пакетов. Таким образом, вместо того, чтобы ждать, пока алгоритм проработает весь набор данных только после обновления весов и смещения, он обновляется в конце каждого так называемого мини-пакета. Это позволяет нам быстро перейти к глобальному минимуму в функции стоимости и теперь обновлять веса и смещения несколько раз за эпоху. Наиболее распространенные размеры мини-пакетов - 16, 32, 64, 128, 256 и 512. В большинстве проектов используется мини-пакетный GD, потому что он быстрее работает с большими наборами данных.

  • Мини-пакетный градиентный спуск:
X = data_input
Y = labels
parameters = initialize_parameters(layers_dims)
for i in range(0, num_iterations):
	
	minibatches = random_mini_batches(X, Y, mini_batch_size)
        for minibatch in minibatches:
            # Select a minibatch
	    (minibatch_X, minibatch_Y) = minibatch
	    # Forward propagation
	    a, caches = forward_propagation(X, parameters)
	    # Compute cost.
	    cost += compute_cost(a, Y)
	    # Backward propagation.
	    grads = backward_propagation(a, caches, parameters)
	    # Update parameters.
	    parameters = update_parameters(parameters, grads)

Чтобы подготовить мини-пакеты, чаще всего применяют некоторые шаги предварительной обработки: рандомизируют набор данных для случайного разделения набора данных, а затем разбивают его на нужное количество фрагментов. Но что произойдет, если мы решим установить количество пакетов равным 1 или равным количеству обучающих примеров?

Пакетный градиентный спуск

Как указывалось ранее, в этом градиентном спуске каждый пакет равен всему набору данных. Это:

Где {1} обозначает первую партию из мини-партии. Обратной стороной является то, что на итерацию уходит слишком много времени. Этот метод можно использовать для обучения наборов данных с менее чем 2000 обучающими примерами.

  • (Пакетный) градиентный спуск:
X = data_input
Y = labels
parameters = initialize_parameters(layers_dims)
for i in range(0, num_iterations):
    # Forward propagation
    a, caches = forward_propagation(X, parameters)
    # Compute cost.
    cost += compute_cost(a, Y)
    # Backward propagation.
    grads = backward_propagation(a, caches, parameters)
    # Update parameters.
    parameters = update_parameters(parameters, grads)

Стохастический градиентный спуск

С другой стороны, в этом методе каждая партия равна одному примеру из обучающей выборки. В этом примере первая мини-партия равна первому примеру обучения:

Где (1) обозначает первый обучающий пример. Обратной стороной здесь является то, что он теряет преимущество, полученное от векторизации, имеет больше колебаний, но сходится быстрее.

  • Стохастический градиентный спуск:
X = data_input
Y = labels
parameters = initialize_parameters(layers_dims)
for i in range(0, num_iterations):
    for j in range(0, m):
        # Forward propagation
        a, caches = forward_propagation(X[:,j], parameters)
        # Compute cost
        cost += compute_cost(a, Y[:,j])
        # Backward propagation
        grads = backward_propagation(a, caches, parameters)
        # Update parameters.
        parameters = update_parameters(parameters, grads)

Резюме

Важно понимать разницу между этими алгоритмами оптимизации, поскольку они составляют ключевую функцию для нейронных сетей. Таким образом, хотя Batch GD имеет более высокую точность, чем Stochastic GD, последний работает быстрее. Среднее из двух и наиболее популярное, Mini-batch GD, сочетают в себе и то, и другое для обеспечения хорошей точности и хороших характеристик.

Можно использовать только код Mini-batch Gradient Descent для реализации всех версий Gradient Descent, вам просто нужно установить mini_batch_size равным единице для Stochastic GD или количество обучающих примеров для Batch GD. Таким образом, основное различие между пакетным, мини-пакетным и стохастическим градиентным спуском - это количество примеров, используемых для каждой эпохи, а также время и усилия, необходимые для достижения глобального минимального значения функции стоимости.

Ссылка: это сообщение в блоге основано на deeplearning.ai Улучшение глубоких нейронных сетей Coursera: настройка гиперпараметров, регуляризация и оптимизация.