В этом уроке TensorFlow я объясню, как работает алгоритм градиентного спуска, на простом примере. Затем я покажу, как он помогает повысить эффективность прогнозирования нейронных сетей или моделей машинного обучения.

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

Содержание

Что такое градиентный спуск в нейронных сетях?

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

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

Здесь при обучении модели нейронной сети ошибка вычисляется с использованием различных функций потерь. Эта ошибка показывает, насколько хорошо модель обучается; чем больше ошибка, тем меньше обучение модели, и чем меньше ошибка, тем больше обучение модели.

Это означает, что цель — минимизировать ошибку; алгоритм градиентного спуска используется для минимизации этой ошибки.

Например, предположим, что вы находитесь на вершине долины. Вам нужно спуститься или добраться до ландшафта. Для этого вам нужно сделать много маленьких шагов в направлении, которое кажется самым крутым спуском, и надеяться в конце концов достичь дна.

Это означает, что вам нужно найти самую низкую точку в долине, которая приведет вас на дно долины.

Точно так же минимизация функции ошибок или потерь означает поиск самой низкой точки, но здесь исчисление используется для вычисления самой низкой точки в текущей позиции(или точке);

Эти небольшие шаги вычисляются в направлении уменьшения функции потерь или ошибки.

Я имею в виду, что алгоритм использует расчеты для вычисления наклона, который минимизирует ошибку, допущенную моделью. Но какова основная цель градиентного спуска? Основная цель — настроить параметры модели нейронной сети, такие как веса и смещение, чтобы минимизировать функцию потерь, что делает прогноз модели более точным.

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

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

Почему функция потерь? Ошибка используется для улучшения модели нейронной сети, цель состоит в том, чтобы минимизировать эту ошибку. Здесь в игру вступает градиентный спуск — итеративный процесс улучшения, метод или алгоритм.

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

Этот процесс повторяется итеративно, корректируя параметры модели, такие как веса и смещение, чтобы минимизировать функцию потерь.

Функция потерь и градиентный спуск могут систематически улучшить прогнозы модели. Каждая итерация или повторение улучшает модель, корректируя параметры на основе ошибки функции потерь, чтобы повысить точность модели.

Построение алгоритма

Здесь вы должны понимать разницу между градиентом (наклоном) и ступенями. Здесь я покажу вам основные примеры градиентов и шаги, демонстрирующие их концепцию.

Для вычисления градиента используется исчисление, поэтому здесь я покажу, как найти производную квадратичной функции в Python.

Создайте функцию простого квадратного уравнения f(x) = x2 с глобальным минимумом в x=0.

Если вы знакомы с дифференцированием в математике, вам нужно найти производную f(x) = x2. Если вы вычислите вывод этой квадратичной функции, вы получите f'(x) = 2x, что дает нам наклон при любом x.

Давайте создадим функцию и ее производную на Python.

def f(x):
    return x**2

def df(x):
    return 2 * x

Как вы знаете, алгоритм градиентного спуска используется итеративно, поэтому мы начнем с первоначального предположения для x и итеративно применим правило обновления градиентного спуска:

xnew = xold – a. f'(xold), здесь a — скорость обучения.

Определите функцию градиентного спуска, как показано ниже.

def gradient_descent(start_x, learning_rate, n_iterations):
  x = start_x
  for i in range(n_iterations):
    grad = df(x)
    x = x - learning_rate * grad
    print(f"Iteration {i+1}: x = {x}, f(x) = {f(x)}")
  return x

Инициализируйте параметры, как показано ниже.

start_x = 2
learning_rate = 0.1
n_iterations = 10

Используйте градиентный спуск, как показано ниже.

x_final = gradient_descent(start_x, learning_rate, n_iterations)
print(f"Final x: {x_final}")

Построение алгоритма градиентного спуска

Приведенный выше код выполнится десять раз и подстроит x к минимуму функции f(x) = x2. Минимальное значение x составляет 0,2147, но какова связь между приведенным выше кодом и обсуждаемым нами градиентным спуском?

Вы только что создали алгоритм градиентного спуска, который находит минимальное значение функции f(x) = x2. Именно так алгоритм градиентного спуска минимизирует ошибку или потери. Здесь минимизация означает нахождение минимального значения.

Давайте разберемся глубже, как работает алгоритм градиентного спуска. Функция gradient_descent (start_x, Learning_rate, n_iterations) принимает три входных параметра.

  • start_x: представляет собой начальное предположение значения x. Здесь алгоритм начинает поиск минимального значения.
  • Learning_rate: определяет, насколько большой шаг должен быть сделан на каждой итерации. Если указаны меньшие скорости обучения, шаги будут меньшими, что приведет к более точным результатам, но для сходимости может потребоваться больше времени. Более высокая скорость обучения увеличивает сходимость, но рискует превысить минимум.
  • n_iterations: это способ указать, сколько раз алгоритм будет обновлять значение x после нахождения минимума на каждой итерации.

В функции Gradent_descent() сначала инициализируется начальное предполагаемое значение, которое является отправной точкой в поиске минимума функции с использованием x = start_x.

Затем инициализируется цикл, который выполняется 10 раз. На каждой итерации выполняются два действия:

  1. Во-первых, он вычисляет производную f(x), вызывая функцию df(x) для текущего значения x, которая определяет наклон функции в этой точке. В контексте минимизации ошибки этот наклон представляет собой направление, в котором функция возрастает наиболее круто. Зная это, мы можем двигаться в противоположном направлении, чтобы найти минимум.
  2. Во-вторых, он корректирует текущее значение x, перемещая его в направлении уменьшения f(x), используя x=x-learning_rate * grad, что уменьшает ошибку. Размер шага определяется скоростью обучения и величиной градиента (grad). Движение против градиента — это суть спуска к минимуму.

После завершения всех итераций функция возвращает окончательное значение x(0,214), лучшее предположение алгоритма для минимума.

Позвольте мне снова показать вам, как происходят вычисления, так что у вас есть квадратичная функция f(x) = x2, когда вы дифференцируете это значение, вы получаете 2*x.

Итак, в алгоритме мы инициализируем x случайным значением, например x=2.

Затем внутри цикла оператор grad=df(x) представляет собой вывод или дифференцирование функции f(x) = x2. Рассмотрим это утверждение, представляющее 2*x.

Следующий оператор x = x – Learning_rate * grad использует градиент и скорость обучения и вычитает их из значения x. Итак, именно здесь был сделан шаг в направлении, противоположном вычисленному градиенту, чтобы уменьшить ошибку; вот как ошибка сводится к минимуму.

Ошибку невозможно минимизировать за одну итерацию; чтобы найти минимальное значение функции, нам нужно повторить те же действия.

Теперь давайте посмотрим, что значение x равно 2, производная или градиент f(x) = x2 равна 2*x, а значение скорости обучения равно 0,1, и цикл должен выполняться 10 раз, как указано в n_iterations.

Теперь посмотрим, как выглядит функция.

def gradient_descent(start_x, learning_rate, n_iterations):
  x = 2
  for i in range(10):
    grad = 2*x
    x = 2 - 0.1 * grad
    print(f"Iteration {i+1}: x = {x}, f(x) = {f(x)}")
  return x

Давайте запустим цикл в первый раз и отследим значение переменной x, которое представляет собой минимальное значение:

  • Первая итерация: текущее значение x равно 2, после итерации x= 2-0,1 * 2 * 2 оно становится x=1,6, поэтому новое значение x равно 1,6.
  • Вторая итерация: текущее значение x равно 1,6, после итерации x = 1,6-0,1 * 2 *1,6 оно становится x = 1,28, поэтому новое значение x равно 1,28; понять закономерность того, как он обновляет или корректирует значение x.
  • Третья итерация: текущее значение x равно 1,28, после итерации x = 1,28-0,1 * 2 * 1,28 оно становится x = 1,024, поэтому новое значение x равно 1,024.
  • Четвертая итерация: текущее значение x равно 1,024, после итерации x = 1,024-0,1 * 2 * 1,024 оно становится x = 0,8192, поэтому новое значение x составляет 0,8192.

Выполните те же действия 10 раз, вы получите значение x = 0,21478364, которое является минимальным значением или ошибка уменьшается.

Именно так алгоритм градиентного спуска минимизирует функцию потерь или ошибку, допущенную моделью.

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

Следует отметить, что ваша функция потерь равна f(x) = x2. Здесь мы минимизировали эту функцию, отрегулировав значение x, но мы скорректировали значение так, что использовали алгоритм градиентного спуска.

Теперь вы готовы, давайте покажем, как использовать градиентный спуск в Tensorflow.

Как реализовать

Сначала убедитесь, что вы установили TensorFlow в своей системе. Здесь я покажу вам, как оптимизировать переменные, чтобы минимизировать одну и ту же квадратичную функцию f(x) = x2.

Сначала импортируйте библиотеку tensorflow.

import tensorflow as tf

Определите переменную x и инициализируйте ее значением 5.

x = tf.Variable(5.0)

Определите функцию потерь, которую мы хотим минимизировать, поэтому здесь функция потерь равна f(x) = x2.

loss = lambda: x**2

Определите оптимизатор, который внутри использует градиентный спуск, как показано ниже.

optimizer = tf.optimizers.SGD(learning_rate=0.1)

Здесь, в приведенном выше коде, оптимизаторы представляют собой своего рода механизм, который минимизирует функцию потерь. Он использует варианты алгоритма градиентного спуска, который называется SGD (Stochastic Gradient Descent).

Кроме того, в SGD передается Learning_rate(0,1), поскольку вы знаете, насколько важна скорость обучения.

После определения давайте оптимизируем, как показано в коде ниже.

n_iterations = 10

for i in range(n_iterations):

      optimizer.minimize(loss, var_list=[x])

      print(f"Iteration {i+1}: x = {x.numpy()}, f(x) = {loss().numpy()}")

Реализация градиентного спуска тензорного потока в нейронной сети

Из выходных данных минимальное значение x составляет 0,536, а значение функции f(x) — 0,2882329. Итак, 0,536 — оптимальное значение, которое минимизирует значение функции потерь до 0,28823.

Посмотрите на каждую итерацию, это указывает на то, что значение f(x) уменьшается на следующей итерации.

В приведенном выше коде внутри цикла используется оператор Optimizer.minimize(loss, var_list=[x]). Объект оптимизатора является экземпляром SGD. Помните, что оптимизаторы несут ответственность за применение алгоритма оптимизации для настройки параметра модели.

Затем minimize(loss, var_list=[x]), этот метод дает указание оптимизатору минимизировать заданную функцию потерь, которая равна x2 относительно переменных, перечисленных в var_list. Проще говоря, это дает указание оптимизатору настроить список переменных (параметров) в var_list, чтобы уменьшить значение функции потерь.

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

Здесь настраивается только параметр x в var_list, но это может быть любой обучаемый параметр модели, которую вы обучаете.

В тензорном потоке в var_list в функции minimize() вы указываете все параметры, которые хотите настроить или обновить во время обучения, чтобы минимизировать функцию потерь.

Любая модель нейронной сети или машинного обучения обучается на основе нескольких параметров. Чтобы улучшить производительность прогнозирования модели, алгоритмы оптимизатора используются для настройки или обновления параметров для минимизации функции потерь.

Создание модели

Импортируйте необходимую библиотеку, как показано ниже.

import tensorflow as tf
import numpy as np

Определите входной слой, используя приведенный ниже код.

X = tf.keras.Input(shape=(1,), name='X')

Входной слой определяется формой входных данных.

Определите режим линейной регрессии, как показано ниже.

y_predicted = tf.keras.layers.Dense(1, name='y_predicted')(X)

model = tf.keras.Model(X, y_predicted)

Во-первых, плотный слой показывает взаимосвязь между вводом и выводом. Полная модель создается путем объединения входного и плотного слоев.

Скомпилируйте модель, используя приведенный ниже код.

model.compile(optimizer='sgd', loss='mean_squared_error')

Компиляция модели означает подготовку модели к обучению, на этом этапе указываются наш оптимизатор и функция потерь.

При построении полной модели нейронной сети или машинного обучения именно так указывается оптимизатор или функция потерь в TensorFlow. Оптимизатор — «sgd», а функция потерь — «mean_square_error».

Оптимизатор оптимизирует функцию потерь mean_square_error, используя алгоритм стохастического градиентного спуска. Таким образом, вес и смещение параметра корректируются или обновляются.

Тренируйтесь или подгоняйте модель.

model.fit(X_train, y_train, epochs=1000)

Здесь метод fit() вызывается для модели для обучения модели на данных X_train и y_train.

Окончательное значение веса и смещения параметров получается из модели, которая корректируется или обновляется с помощью алгоритма градиентного спуска.

W_final, b_final = model.layers[1].get_weights()

Давайте напечатаем окончательные значения.

print("Weight(W):", W_final)
print("Bias(b):", b_final)

Создание модели

Когда вы запустите приведенный выше код, вы получите окончательный вес и значение смещения модели линейной регрессии, как показано ниже.

Алгоритм градиентного спуска

Итоговые значения параметров Weight и Bias составляют 1,9885721 и 1,0247945 соответственно.

Добавить комментарий