<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=OvsyannikovaSA</id>
	<title>Алговики - Вклад [ru]</title>
	<link rel="self" type="application/atom+xml" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=OvsyannikovaSA"/>
	<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/ru/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/OvsyannikovaSA"/>
	<updated>2026-10-22T15:38:37Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%9F%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%BD%D0%B0%D1%8F_%D1%80%D0%B5%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D1%81%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B3%D0%BE_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D1%81%D0%BF%D1%83%D1%81%D0%BA%D0%B0&amp;diff=30316</id>
		<title>Участница:OvsyannikovaSA/Программная реализация стохастического градиентного спуска</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%9F%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%BD%D0%B0%D1%8F_%D1%80%D0%B5%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D1%81%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B3%D0%BE_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D1%81%D0%BF%D1%83%D1%81%D0%BA%D0%B0&amp;diff=30316"/>
		<updated>2025-12-09T12:22:10Z</updated>

		<summary type="html">&lt;p&gt;OvsyannikovaSA: /* Масштабируемость реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Ссылки==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
===Теоретическая масштабируемость алгоритма===&lt;br /&gt;
Масштабируемость алгоритма SGD определяется его структурой и необходимостью синхронизации на каждом шаге.&lt;br /&gt;
&lt;br /&gt;
Масштабируемость самого алгоритма SGD (не зависимо от платформы) ограничена его последовательной природой в цикле обновления весов.&lt;br /&gt;
&lt;br /&gt;
На каждом шаге SGD происходят следующие критические операции, которые ограничивают масштабируемость:&lt;br /&gt;
&lt;br /&gt;
1. Вычисление частных градиентов: массово параллельный этап. Потоки работают независимо на своих частях мини-батча.&lt;br /&gt;
&lt;br /&gt;
2. Редукция: после вычисления частных градиентов все потоки должны выполнить редукцию для получения общего градиента. Эта операция является точкой барьерной синхронизации, т.к. ни один поток не может перейти к обновлению весов, пока не получен окончательный градиент.&lt;br /&gt;
&lt;br /&gt;
3. Обновление весов: последовательный по времени этап, но параллельный по координатам вектора весов.&lt;br /&gt;
&lt;br /&gt;
Максимальное ускорение &amp;lt;math&amp;gt;S_{max}&amp;lt;/math&amp;gt; на одном шаге SGD ограничено законом Амдала, где последовательная часть — это время, затраченное на глобальную редукцию и, в меньшей степени, на векторное обновление. На практике масштабируемость ограничивается эффективностью редукции при росте числа процессоров.&lt;br /&gt;
&lt;br /&gt;
===Масштабируемость реализации===&lt;br /&gt;
&lt;br /&gt;
Параллелизация алгоритма стохастического градиентного спуска была произведена на основе принципа массового параллелизма, используя библиотеку OpenMP для организации многопоточности в общей памяти.&lt;br /&gt;
&lt;br /&gt;
Главная цель состояла в ускорении вычислительно наиболее затратной фазы одного шага SGD: вычисление градиента по мини-батчу.&lt;br /&gt;
&lt;br /&gt;
Сильная масштабируемость SGD хорошая до определенного предела. При увеличении &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; рабочая нагрузка на один процессор &amp;lt;math&amp;gt;B/P&amp;lt;/math&amp;gt; уменьшается, что приводит к сокращению времени вычисления градиента.&lt;br /&gt;
&lt;br /&gt;
Когда &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; становится близким к &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;, уменьшение времени вычисления градиента замедляется. При дальнейшем росте &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; время, затрачиваемое на синхронизацию, начинает доминировать над временем полезных вычислений. Это приводит к падению эффективности и остановке роста ускорения.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S_{max}&amp;lt;/math&amp;gt; достигается, когда &amp;lt;math&amp;gt;P \approx B&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;P \approx d&amp;lt;/math&amp;gt; (зависит от того, что больше; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; - размерность вектора весов).&lt;br /&gt;
&lt;br /&gt;
Слабая масштабируемость SGD очень хорошая. При одновременном увеличении общего размера данных &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; и числа процессоров &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; время вычисления градиента (самая затратная часть) остается примерно постоянным, поскольку нагрузка на один процессор неизменна.&lt;br /&gt;
&lt;br /&gt;
Слабая масштабируемость ограничивается временем глобальных операций. При очень больших &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; накладные расходы на редукцию и коммуникацию начинают увеличиваться, вызывая медленный, но стабильный рост общего времени выполнения.&lt;br /&gt;
&lt;br /&gt;
Реализация выполнена с помощью OpenMP на суперкомпьютере &amp;quot;Ломоносов-2&amp;quot;. Число объектов в выборке &amp;lt;math&amp;gt;N=200000&amp;lt;/math&amp;gt;, размерность признаков &amp;lt;math&amp;gt;m=20&amp;lt;/math&amp;gt;, число эпох &amp;lt;math&amp;gt;E=30&amp;lt;/math&amp;gt;, learning rate &amp;lt;math&amp;gt;\alpha=0.005&amp;lt;/math&amp;gt;.&lt;br /&gt;
[[Файл:Ускорение параллельного SGD в зависимости от числа потоков и размера батча.png]]&lt;br /&gt;
&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Результаты прогонов==&lt;/div&gt;</summary>
		<author><name>OvsyannikovaSA</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=30315</id>
		<title>Участница:OvsyannikovaSA/Стохастический градиентный спуск</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=30315"/>
		<updated>2025-12-09T12:01:26Z</updated>

		<summary type="html">&lt;p&gt;OvsyannikovaSA: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Свойства и структура алгоритмов==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
&#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039; (Stochastic Gradient Descent, SGD) представляет собой один из базовых и наиболее распространённых алгоритмов оптимизации, применяемых для обучения моделей машинного обучения и нейронных сетей. Он относится к классу итерационных методов минимизации функций.&lt;br /&gt;
&lt;br /&gt;
===Математическое описание алгоритма===&lt;br /&gt;
&lt;br /&gt;
Пусть даны &amp;lt;math&amp;gt;\{x_i, y_i\}_{i=1}^N, x_i \in \mathbb{R}^m&amp;lt;/math&amp;gt; - вектор признаков &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го объекта, &amp;lt;math&amp;gt;y_i \in \mathbb{R}&amp;lt;/math&amp;gt; - значение целевой переменной; класс моделей &amp;lt;math&amp;gt;a_\omega: \mathbb{R}^m \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;; функция потерь &amp;lt;math&amp;gt;f: \mathbb{R}\times \mathbb{R} \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;. Задача: найти вектор параметров модели (весов) &amp;lt;math&amp;gt;\omega \in \mathbb{R}^d&amp;lt;/math&amp;gt;, т.ч. &amp;lt;math&amp;gt;\omega = argmin_{\omega\in \mathbb{R}^d}\;L(\omega),\;L(\omega)=\sum_{i=1}^N f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм &#039;&#039;&#039;классического градиентного спуска (batch gradient descent)&#039;&#039;&#039; можно сформулировать следующим образом:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Здесь и далее шаг обучения (learning rate) &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; является гиперпараметром, т.е. параметром, который не оптимизируется в ходе работы алгоритма и который необходимо выбрать заранее. Начальное приближение &amp;lt;math&amp;gt;\omega_0&amp;lt;/math&amp;gt; также необходимо выбрать заранее исходя из некоторых соображений.&lt;br /&gt;
Условие достижения сходимости на практике обычно заменяется повторением процедуры некоторое количество раз, после чего можно считать, что алгоритм сошелся в требуемом приближении.&lt;br /&gt;
В данном подходе для того, чтобы совершить одно обновление весов, необходимо вычислить функцию потерь для всех элементов выборки. Этот метод может оказаться неподходящим в некоторых случаях, например, при использовании больших датасетов, не помещающихся в памяти, или в случае, когда новые данные поступают в реальном времени.&lt;br /&gt;
&lt;br /&gt;
Модернизацией этого алгоритма является &#039;&#039;&#039;стохастический градиентный спуск (stochastic gradient descent)&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xi, yi)&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad f(ω; xi, yi);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Алгоритм отличается от предыдущего тем, что обновление весов происходит после обработки одного объекта выборки. Компромиссом между двумя этими подходами служит &#039;&#039;&#039;стохастический градиентный спуск на мини-батчах (mini-batch gradient descent)&#039;&#039;&#039;. Для него требуется выбрать размер батча (batch_size, &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;). Обозначим &amp;lt;math&amp;gt;L(\omega)=\sum_{i=1}^{B} f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск с мини-батчами&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α, размер батча B&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xik, yik), 1&amp;lt;=k&amp;lt;=B&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω; (xik, yik), 1&amp;lt;=k&amp;lt;=B);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Преимущество алгоритма заключается в частом обновлении градиента и возможности использовать эффективные матричные вычисления.&lt;br /&gt;
В этой работе мы сосредоточимся на реализации градиентного спуска с мини-батчами.&lt;br /&gt;
&lt;br /&gt;
Необходимо некоторым способом определить условия, при которых будет считаться, что алгоритм сошелся. Будем считать, что сходимость достигается за &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; итераций обработки всей выборки (будем называть одну итерацию &#039;&#039;&#039;эпохой&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
В начале каждой эпохи будем случайно перемешивать выборку, а затем последовательно выбирать порции данных по &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; объектов. Это обеспечит локальность расположения в памяти последовательно идущих мини-батчей и сохранит логику случайного выбора мини-батчей. Таким образом, процедура случайного выбора мини-батча заменяется на линейный проход по всем данным.&lt;br /&gt;
&lt;br /&gt;
===Вычислительное ядро алгоритма===&lt;br /&gt;
Основное время работы алгоритма приходится на вычисление градиента, которые повторяются, пока сходимость не будет достигнута.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Алгоритм стохастического градиентного спуска с мини-батчами представляется повторением следующих макроопераций:&lt;br /&gt;
&lt;br /&gt;
1. Инициализация параметров: задание начального приближения вектора параметров модели &amp;lt;math&amp;gt;w_0&amp;lt;/math&amp;gt;. Может быть случайной инициализацией, загрузкой предварительно обученной модели и т.п.&lt;br /&gt;
&lt;br /&gt;
  w ← ИнициализацияПараметров(описание_модели, стратегия_инициализации)&lt;br /&gt;
&lt;br /&gt;
2. Перемешивание обучающей выборки: получение случайной перестановки обучающей выборки в начале эпохи. Можно выполнять, например, алгоритмом Фишера-Йетса.&lt;br /&gt;
&lt;br /&gt;
Входные данные: &amp;lt;math&amp;gt;D=\{(x_i, y_i)\}_{i=1}^N&amp;lt;/math&amp;gt; - обучающая выборка.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: &amp;lt;math&amp;gt;D_{perm}&amp;lt;/math&amp;gt; - перемешанная выборка.&lt;br /&gt;
&lt;br /&gt;
  D_perm ← ПеремешиваниеОбучающейВыборки(D, генератор_случайных_чисел)&lt;br /&gt;
&lt;br /&gt;
3. Формирование мини-батчей: разбиение переставленной выборки на последовательность мини-батчей.&lt;br /&gt;
&lt;br /&gt;
Входные данные: &amp;lt;math&amp;gt;D_{perm}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выходные данные: последовательность подмножеств &amp;lt;math&amp;gt;B_k\subset D, \; k=1,..., K, \; \cup_k B_k=D, B_k \cap B_j = \emptyset, k\neq j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
  СписокБатчей ← ФормированиеМиниБатчей((X,y)_perm, размер_батча)&lt;br /&gt;
&lt;br /&gt;
4. Вычисление градиента на батче. Может включать вычисление значений модели на батче, матрично-векторные умножения, суммирование по объектам батча.&lt;br /&gt;
&lt;br /&gt;
Входные данные: текущие параметры &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;, мини-батч &amp;lt;math&amp;gt;B=\{(x_i, y_i)\}_{i\in I_B}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выходные данные: &amp;lt;math&amp;gt;g_B&amp;lt;/math&amp;gt; - градиент по параметрам на этом батче.&lt;br /&gt;
&lt;br /&gt;
  g_B ← ВычислениеГрадиентаНаБатче(w, B)&lt;br /&gt;
&lt;br /&gt;
5. Обновление параметров: осуществление одного шага метода по вычисленному градиенту на батче.&lt;br /&gt;
&lt;br /&gt;
Входные данные: текущие параметры &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;, градиент на батче &amp;lt;math&amp;gt;g_B&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: новые параметры &amp;lt;math&amp;gt;w_{new}=w-\alpha g_B&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
  w ← ОбновлениеПараметров(w, g_B, гиперпараметры_шага)&lt;br /&gt;
&lt;br /&gt;
6. Проверка критерия останова: проверка условий завершения итерационного процесса. Может быть проверкой номера эпохи, проверкой изменения функции потерь и т.п.&lt;br /&gt;
&lt;br /&gt;
  флаг_стоп ← ПроверкаКритерияОстановки(номер_эпохи, номер_шага, значение_критерия, история)&lt;br /&gt;
&lt;br /&gt;
На макроуровне алгоритм можно описать так:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:100%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Макроструктура алгоритма&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
w ← ИнициализацияПараметров(описание_модели, стратегия_инициализации)&lt;br /&gt;
номер_эпохи ← 0&lt;br /&gt;
повторять&lt;br /&gt;
  номер_эпохи ← номер_эпохи + 1&lt;br /&gt;
  D_perm ← ПеремешиваниеОбучающейВыборки(D, генератор_случайных_чисел)&lt;br /&gt;
  СписокБатчей ← ФормированиеМиниБатчей(D_perm, размер_батча)&lt;br /&gt;
  Для каждого B из СписокБатчей:&lt;br /&gt;
    g_B ← ВычислениеГрадиентаНаБатче(w, B)&lt;br /&gt;
    w ← ОбновлениеПараметров(w, g_B, гиперпараметры_шага)&lt;br /&gt;
  флаг_стоп ← ПроверкаКритерияОстановки(номер_эпохи, значение_критерия, история)&lt;br /&gt;
Пока флаг_стоп = ЛОЖЬ&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
[[Файл:Sequential SGD with mini-batches scheme.png|Схема последовательной реализации стохастического градиентного спуска с мини-батчами]]&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; - размер выборки,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; - размер батча (&amp;lt;math&amp;gt;batch\_size&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - сложность вычисления производной функции потерь на одном примере,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - число эпох.&lt;br /&gt;
&lt;br /&gt;
Как уже упоминалось, будем перемешивать выборку случайным образом в начале каждой эпохи. Сложность случайного перемешивания выборки объема &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; алгоритмом Фишера-Йетса - &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. Если отказаться от этого предположения, можно считать, что сложность выбора &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; случайных элементов - &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;. Такая оценка будет верна, если в системе реализован произвольный доступ к памяти. Однако для больших выборок, не помещающихся целиком в памяти, произвольный доступ к элементам выборки не будет возможен.&lt;br /&gt;
&lt;br /&gt;
Сложность обработки одного батча - &amp;lt;math&amp;gt;O(B \cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что количество батчей &amp;lt;math&amp;gt;N/B&amp;lt;/math&amp;gt; - целое число; тогда сложность вычисления градиентов в течение одной эпохи - &amp;lt;math&amp;gt;O(N/B \cdot B \cdot C) = O(N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность одной эпохи с учетом перемешивания выборки - &amp;lt;math&amp;gt;O(N)+O(N\cdot C)=O(N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность всего алгоритма с &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; эпохами - &amp;lt;math&amp;gt;O(E\cdot N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
На схеме изображен информационный граф стохастического градиентного спуска с мини-батчами.&lt;br /&gt;
&lt;br /&gt;
[[file:Informational_graph_minibatch_SGD.png|center|Информационный граф стохастического градиентного спуска с мини-батчами]]&lt;br /&gt;
Здесь приводится схема выполнения одной эпохи. Стрелки, изображающие обработку остальных объектов данного батча, опущены для улучшения читаемости схемы. После обработки одного батча с весами &amp;lt;math&amp;gt;w_i&amp;lt;/math&amp;gt; производится шаг градиентного спуска, и следующий батч обрабатывается уже с весами &amp;lt;math&amp;gt;w_{i+1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Ресурс параллелизма алгоритма===&lt;br /&gt;
Ресурс параллелизма алгоритма стохастического градиентного спуска (SGD) определяется зависимостями данных между его основными шагами: вычислением градиента и обновлением весов.&lt;br /&gt;
&lt;br /&gt;
====Иерархическая Структура Параллелизма====&lt;br /&gt;
&lt;br /&gt;
Параллелизм в SGD имеет &#039;&#039;&#039;двухуровневую (иерархическую)&#039;&#039;&#039; структуру, которая напрямую связана с циклическим профилем последовательной реализации.&lt;br /&gt;
&lt;br /&gt;
1. Внешний уровень: &#039;&#039;&#039;конечный параллелизм&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Внешний уровень параллелизма определяется последовательностью итераций по эпохам и по батчам:&lt;br /&gt;
* цикл по эпохам: итерации по эпохам зависимы, поскольку веса, полученные на одной эпохе, используются на следующей. Этот цикл не имеет параллельного ресурса.&lt;br /&gt;
* цикл по батчам (мини-батчам): обновления весов на основе последовательных мини-батчей информационно зависимы. Обновление &amp;lt;math&amp;gt;w_{k+1}&amp;lt;/math&amp;gt; зависит от &amp;lt;math&amp;gt;w_k&amp;lt;/math&amp;gt; и градиента &amp;lt;math&amp;gt;g_k&amp;lt;/math&amp;gt;. Это создает ресурс конечного параллелизма.&lt;br /&gt;
&lt;br /&gt;
2. Внутренний уровень: &#039;&#039;&#039;массовый параллелизм&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Внутренний уровень связан с обработкой данных внутри одного шага SGD (одного мини-батча).&lt;br /&gt;
&lt;br /&gt;
Это ресурс массового параллелизма, который может быть реализован двумя способами:&lt;br /&gt;
&lt;br /&gt;
* Вычисление градиента: вычисление частных градиентов для каждого примера (&amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt;) в мини-батче полностью независимо: &amp;lt;math&amp;gt;\frac{1}{|B|} \sum_{x_i \in B} \nabla L_i(w)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот этап демонстрирует &#039;&#039;&#039;координатный параллелизм&#039;&#039;&#039; (независимость итераций цикла по примерам в батче).&lt;br /&gt;
* Обновление весов: операция &amp;lt;math&amp;gt;w_{k+1} = w_k - \alpha g_k&amp;lt;/math&amp;gt; представляет собой векторные операции (вычитание и скалярное умножение), которые также могут быть распараллелены по координатам вектора весов (&amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
====Параллельная сложность и высота ярусно-параллельной формы====&lt;br /&gt;
&lt;br /&gt;
Оценка параллельной сложности алгоритма (высота канонической ярусно-параллельной формы) дается в терминах числа операций умножения/деления и сложения (которые доминируют).&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; — размерность вектора весов, &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — размер мини-батча.&lt;br /&gt;
&lt;br /&gt;
Основной вычислительный шаг SGD состоит из трех этапов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+ Параллельная сложность одного шага Стохастического Градиентного Спуска (SGD)&lt;br /&gt;
|-&lt;br /&gt;
! Этап&lt;br /&gt;
! Параллельная сложность&amp;lt;br&amp;gt;(Высота ЯПФ, &#039;&#039;H&#039;&#039;)&lt;br /&gt;
! Ширина ЯПФ&amp;lt;br&amp;gt;(&#039;&#039;W&#039;&#039; - Сбалансированность)&lt;br /&gt;
! Описание Ресурса Параллелизма&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Вычисление градиентов&#039;&#039;&#039;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(\log_2 B + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(d \times B)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &#039;&#039;&#039;Массовый параллелизм&#039;&#039;&#039; (Координатный параллелизм) по примерам в мини-батче. Требуется редукция/суммирование.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Усреднение и масштабирование&#039;&#039;&#039;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(d)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &#039;&#039;&#039;Конечный параллелизм&#039;&#039;&#039; (Координатный параллелизм) по координатам вектора весов.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Обновление весов&#039;&#039;&#039;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(d)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &#039;&#039;&#039;Конечный параллелизм&#039;&#039;&#039; (Координатный параллелизм) по координатам вектора весов.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Таким образом, параллельная сложность (высота) одного шага SGD составляет &amp;lt;math&amp;gt;H = O(\log_2 B)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
====Сбалансированность параллельных шагов (ширина ярусов)====&lt;br /&gt;
&lt;br /&gt;
Ширина ярусов отражает сбалансированность параллельных шагов по числу операций:&lt;br /&gt;
&lt;br /&gt;
* Ширина этапа градиентов: на этапе вычисления градиентов ширина ярусов максимальна, достигает &amp;lt;math&amp;gt;W = O(d \times B)&amp;lt;/math&amp;gt;. Этот этап сбалансирован при &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; процессорах, где &amp;lt;math&amp;gt;P \le B&amp;lt;/math&amp;gt;, поскольку каждому процессу можно поручить обработку &amp;lt;math&amp;gt;\lceil B/P \rceil&amp;lt;/math&amp;gt; примеров.&lt;br /&gt;
* Ширина этапов обновления: на этапах усреднения и обновления весов ширина ярусов составляет &amp;lt;math&amp;gt;W = O(d)&amp;lt;/math&amp;gt;. Этот этап также сбалансирован, если &amp;lt;math&amp;gt;P \le d&amp;lt;/math&amp;gt;, поскольку операции могут быть распределены по &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; процессорам.&lt;br /&gt;
&lt;br /&gt;
Алгоритм SGD обладает хорошей сбалансированностью на каждом шаге, что позволяет эффективно использовать большое число процессоров (ядер), особенно когда произведение &amp;lt;math&amp;gt;d \times B&amp;lt;/math&amp;gt; велико.&lt;br /&gt;
&lt;br /&gt;
===Входные и выходные данные алгоритма===&lt;br /&gt;
====Входные данные====&lt;br /&gt;
&lt;br /&gt;
Обучающая выборка (&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;) обычно представляется в виде двух плотных структур данных:&lt;br /&gt;
&lt;br /&gt;
1. Матрица Признаков (&amp;lt;math&amp;gt;X\in\mathbb{R}^{N \times m}&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — общее число обучающих примеров, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; — число признаков.&lt;br /&gt;
&lt;br /&gt;
В задачах машинного обучения &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; часто значительно больше, чем &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; (много примеров, но относительно небольшое число признаков), или же &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; может быть очень большим (например, при использовании One-Hot-Encoding).&lt;br /&gt;
&lt;br /&gt;
В зависимости от задачи, матрица &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; может быть:&lt;br /&gt;
* плотной (dense): каждая ячейка содержит значащее числовое значение.&lt;br /&gt;
* разреженной (sparse): если большая часть элементов равна нулю.&lt;br /&gt;
&lt;br /&gt;
2. Вектор целевых значений (&amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;) - вектор размера &amp;lt;math&amp;gt;N \times 1&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;N \times C&amp;lt;/math&amp;gt; (для многоклассовой классификации, где &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — число классов).&lt;br /&gt;
&lt;br /&gt;
Обычно плотный, содержит действительные числа (для регрессии) или целочисленные метки/векторы (для классификации).&lt;br /&gt;
&lt;br /&gt;
3. Параметры обучения&lt;br /&gt;
&lt;br /&gt;
* Скорость обучения (&amp;lt;math&amp;gt;\alpha\in\mathbb{R}&amp;lt;/math&amp;gt;, learning rate): его значение обычно мало (например, &amp;lt;math&amp;gt;10^{-2}&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;10^{-3}&amp;lt;/math&amp;gt;) и оказывает критическое влияние на сходимость.&lt;br /&gt;
* Размер мини-батча (&amp;lt;math&amp;gt;B\in\mathbb{R}&amp;lt;/math&amp;gt;, batch size): определяет число примеров, используемых для одного шага. Обычно является степенью двойки (&amp;lt;math&amp;gt;32, 64, 128, \dots&amp;lt;/math&amp;gt;).&lt;br /&gt;
* Число эпох (&amp;lt;math&amp;gt;E\in\mathbb{N}&amp;lt;/math&amp;gt;, epochs): число полных проходов по всему набору данных.&lt;br /&gt;
&lt;br /&gt;
====Выходные Данные====&lt;br /&gt;
&lt;br /&gt;
* Вектор весов модели (&amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;): вектор размера &amp;lt;math&amp;gt;d \times 1&amp;lt;/math&amp;gt; (или матрица &amp;lt;math&amp;gt;d \times C&amp;lt;/math&amp;gt;, если модель содержит скрытые слои или многоклассовый вывод).&lt;br /&gt;
&lt;br /&gt;
Является плотной структурой данных. Диапазон значений зависит от функции потерь и регуляризации, но обычно это числа, близкие к нулю, или числа малого/среднего диапазона.&lt;br /&gt;
&lt;br /&gt;
* История потерь (loss history, опционально): вектор, содержащий значение функции потерь, вычисленное после каждого шага SGD. Объем равен &amp;lt;math&amp;gt;(E \times N) / B&amp;lt;/math&amp;gt;. Используется для анализа сходимости и отладки алгоритма.&lt;br /&gt;
&lt;br /&gt;
===Свойства алгоритма===&lt;br /&gt;
====Соотношение последовательной и параллельной сложности====&lt;br /&gt;
&lt;br /&gt;
Алгоритм SGD является последовательным по отношению к шагам обновления весов. Однако в рамках одного шага обновления (одного мини-батча) он обладает высоким ресурсом параллелизма.&lt;br /&gt;
&lt;br /&gt;
* Последовательная сложность одного шага SGD: &amp;lt;math&amp;gt;T_{seq} = O(B \cdot d)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; - размер батча, &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; - размерность весов.&lt;br /&gt;
* Параллельная сложность одного шага SGD (высота ЯПФ): &amp;lt;math&amp;gt;H = O(\log_2 B + 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теоретический выигрыш от параллельной реализации (ускорение) составляет:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S = \frac{T_{seq}}{H} = \frac{O(B \cdot d)}{O(\log_2 B + 1)}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теоретически, параллельная реализация обеспечивает значительное ускорение &amp;lt;math&amp;gt;O(B \cdot d)&amp;lt;/math&amp;gt;, которое растет линейно с размером батча и размерностью задачи, если есть достаточное количество процессоров &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Сложности параллелизации: главная сложность заключается в информационной зависимости между последовательными шагами обновления. Параллельная реализация дает выигрыш только внутри одного шага (градиент и обновление), но не может ускорить последовательность шагов, что является фундаментальным ограничением SGD.&lt;br /&gt;
====Вычислительная Мощность====&lt;br /&gt;
* Общее число операций (за одну эпоху): &amp;lt;math&amp;gt;O(N \cdot d)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — общее число объектов.&lt;br /&gt;
* Объем входных данных (матрица &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;): &amp;lt;math&amp;gt;O(N \cdot d)&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Объем выходных данных (вектор весов &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;): &amp;lt;math&amp;gt;O(d)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;W_{comp} = \frac{\text{Число операций}}{\text{Объем входных данных}} = \frac{O(N \cdot d)}{O(N \cdot d + d)}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
При больших &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;N \cdot d&amp;lt;/math&amp;gt; доминирует в знаменателе. Таким образом, вычислительная мощность SGD составляет:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;W_{comp} \approx O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность SGD близка к константе (&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;). Это означает, что число операций примерно равно объему исходных данных. Это значение относительно невысокое. Это свойство требует, чтобы алгоритм выполнялся &amp;quot;близко&amp;quot; к памяти с данными (например, на том же узле кластера), чтобы минимизировать накладные расходы на перемещение данных.&lt;br /&gt;
====Устойчивость Алгоритма====&lt;br /&gt;
&lt;br /&gt;
Алгоритм SGD является &#039;&#039;&#039;стохастическим и неустойчивым&#039;&#039;&#039; в смысле получения одного и того же результата при каждом запуске.&lt;br /&gt;
&lt;br /&gt;
* Неустойчивость к входным данным: поскольку SGD использует только часть данных (мини-батч) для каждого шага, дисперсия в оценке градиента высокая. Это приводит к флуктуациям в траектории сходимости.&lt;br /&gt;
* Ошибка округления: при использовании массового параллелизма (например, при суммировании градиентов от &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; примеров) на системах с массовым параллелизмом порядок выполнения ассоциативных операций (сложение) может меняться от запуска к запуску. Это приводит к неповторяемости результатов работы параллельных программ, что является серьезной проблемой на практике.&lt;br /&gt;
&lt;br /&gt;
====Сбалансированность вычислительного процесса====&lt;br /&gt;
&lt;br /&gt;
Алгоритм обладает хорошей сбалансированностью с точки зрения распределения нагрузки.&lt;br /&gt;
&lt;br /&gt;
На каждой итерации преобладают арифметические операции при вычислении градиента. Соотношение между арифметическими операциями и обращениями к памяти (чтение/запись) определяется параметром &amp;lt;math&amp;gt;B \cdot d&amp;lt;/math&amp;gt;, который обычно достаточно велик, что обеспечивает эффективную работу процессоров.&lt;br /&gt;
&lt;br /&gt;
Распределение нагрузки по &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; процессам на этапе вычисления градиента достигается просто: каждый процессор обрабатывает &amp;lt;math&amp;gt;\lceil B/P \rceil&amp;lt;/math&amp;gt; примеров. Это обеспечивает высокую балансировку нагрузки.&lt;br /&gt;
&lt;br /&gt;
====Детерминированность====&lt;br /&gt;
Алгоритм SGD является &#039;&#039;&#039;недетерминированным&#039;&#039;&#039; по следующим причинам:&lt;br /&gt;
&lt;br /&gt;
1. Порядок обработки мини-батчей: в классическом SGD набор мини-батчей на каждой эпохе случаен, что меняет структуру вычислительного процесса и итоговый результат.&lt;br /&gt;
2. Изменение порядка ассоциативных операций: как было описано выше, изменение порядка суммирования градиентов в параллельной среде приводит к непостоянству ошибок округления, что является причиной недетерминированности конечного результата в параллельной реализации.&lt;br /&gt;
&lt;br /&gt;
====Дополнительные свойства====&lt;br /&gt;
&lt;br /&gt;
* Степень исхода вершины: высока для вектора весов &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. На каждом шаге &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; используется для вычисления градиента для всех &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; примеров. На этапе реализации это требует эффективной рассылки вектора &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; всем параллельным процессам/потокам, работающим над батчем, и эффективного доступа к нему.&lt;br /&gt;
* &amp;quot;Длинные&amp;quot; дуги: возникают в информационном графе SGD при рассылке величин (таких как learning rate &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; или текущие веса &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;) по всем итерациям цикла мини-батчей. В случае вектора весов (&amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;), это рассылка всего вектора. Поскольку эта процедура хорошо изучена и оптимизирована на практике, она обычно не вызывает серьезных проблем с размещением данных в иерархии памяти, но требует эффективной коммуникации.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
&lt;br /&gt;
===Результаты прогонов===&lt;br /&gt;
&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
Yujing Ma, Florin Rusu, Martin Torres. Stochastic Gradient Descent on Highly-Parallel Architectures [Электронный ресурс] // arXiv:1802.08800 [math.ST]. – 2018. – Режим доступа: https://arxiv.org/abs/1802.08800&lt;br /&gt;
&lt;br /&gt;
Sebastian Ruder. An overview of gradient descent optimization algorithms [Электронный ресурс] // arXiv:1609.04747 [math.ST]. – 2016. – Режим доступа: https://arxiv.org/abs/1609.04747&lt;/div&gt;</summary>
		<author><name>OvsyannikovaSA</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=30314</id>
		<title>Участница:OvsyannikovaSA/Стохастический градиентный спуск</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=30314"/>
		<updated>2025-12-09T11:59:45Z</updated>

		<summary type="html">&lt;p&gt;OvsyannikovaSA: /* Схема реализации последовательного алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Свойства и структура алгоритмов==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
&#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039; (Stochastic Gradient Descent, SGD) представляет собой один из базовых и наиболее распространённых алгоритмов оптимизации, применяемых для обучения моделей машинного обучения и нейронных сетей. Он относится к классу итерационных методов минимизации функций.&lt;br /&gt;
&lt;br /&gt;
===Математическое описание алгоритма===&lt;br /&gt;
&lt;br /&gt;
Пусть даны &amp;lt;math&amp;gt;\{x_i, y_i\}_{i=1}^N, x_i \in \mathbb{R}^m&amp;lt;/math&amp;gt; - вектор признаков &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го объекта, &amp;lt;math&amp;gt;y_i \in \mathbb{R}&amp;lt;/math&amp;gt; - значение целевой переменной; класс моделей &amp;lt;math&amp;gt;a_\omega: \mathbb{R}^m \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;; функция потерь &amp;lt;math&amp;gt;f: \mathbb{R}\times \mathbb{R} \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;. Задача: найти вектор параметров модели (весов) &amp;lt;math&amp;gt;\omega \in \mathbb{R}^d&amp;lt;/math&amp;gt;, т.ч. &amp;lt;math&amp;gt;\omega = argmin_{\omega\in \mathbb{R}^d}\;L(\omega),\;L(\omega)=\sum_{i=1}^N f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм &#039;&#039;&#039;классического градиентного спуска (batch gradient descent)&#039;&#039;&#039; можно сформулировать следующим образом:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Здесь и далее шаг обучения (learning rate) &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; является гиперпараметром, т.е. параметром, который не оптимизируется в ходе работы алгоритма и который необходимо выбрать заранее. Начальное приближение &amp;lt;math&amp;gt;\omega_0&amp;lt;/math&amp;gt; также необходимо выбрать заранее исходя из некоторых соображений.&lt;br /&gt;
Условие достижения сходимости на практике обычно заменяется повторением процедуры некоторое количество раз, после чего можно считать, что алгоритм сошелся в требуемом приближении.&lt;br /&gt;
В данном подходе для того, чтобы совершить одно обновление весов, необходимо вычислить функцию потерь для всех элементов выборки. Этот метод может оказаться неподходящим в некоторых случаях, например, при использовании больших датасетов, не помещающихся в памяти, или в случае, когда новые данные поступают в реальном времени.&lt;br /&gt;
&lt;br /&gt;
Модернизацией этого алгоритма является &#039;&#039;&#039;стохастический градиентный спуск (stochastic gradient descent)&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xi, yi)&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad f(ω; xi, yi);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Алгоритм отличается от предыдущего тем, что обновление весов происходит после обработки одного объекта выборки. Компромиссом между двумя этими подходами служит &#039;&#039;&#039;стохастический градиентный спуск на мини-батчах (mini-batch gradient descent)&#039;&#039;&#039;. Для него требуется выбрать размер батча (batch_size, &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;). Обозначим &amp;lt;math&amp;gt;L(\omega)=\sum_{i=1}^{B} f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск с мини-батчами&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α, размер батча B&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xik, yik), 1&amp;lt;=k&amp;lt;=B&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω; (xik, yik), 1&amp;lt;=k&amp;lt;=B);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Преимущество алгоритма заключается в частом обновлении градиента и возможности использовать эффективные матричные вычисления.&lt;br /&gt;
В этой работе мы сосредоточимся на реализации градиентного спуска с мини-батчами.&lt;br /&gt;
&lt;br /&gt;
Необходимо некоторым способом определить условия, при которых будет считаться, что алгоритм сошелся. Будем считать, что сходимость достигается за &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; итераций обработки всей выборки (будем называть одну итерацию &#039;&#039;&#039;эпохой&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
В начале каждой эпохи будем случайно перемешивать выборку, а затем последовательно выбирать порции данных по &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; объектов. Это обеспечит локальность расположения в памяти последовательно идущих мини-батчей и сохранит логику случайного выбора мини-батчей. Таким образом, процедура случайного выбора мини-батча заменяется на линейный проход по всем данным.&lt;br /&gt;
&lt;br /&gt;
===Вычислительное ядро алгоритма===&lt;br /&gt;
Основное время работы алгоритма приходится на вычисление градиента, которые повторяются, пока сходимость не будет достигнута.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Алгоритм стохастического градиентного спуска с мини-батчами представляется повторением следующих макроопераций:&lt;br /&gt;
&lt;br /&gt;
1. Инициализация параметров: задание начального приближения вектора параметров модели &amp;lt;math&amp;gt;w_0&amp;lt;/math&amp;gt;. Может быть случайной инициализацией, загрузкой предварительно обученной модели и т.п.&lt;br /&gt;
&lt;br /&gt;
  w ← ИнициализацияПараметров(описание_модели, стратегия_инициализации)&lt;br /&gt;
&lt;br /&gt;
2. Перемешивание обучающей выборки: получение случайной перестановки обучающей выборки в начале эпохи. Можно выполнять, например, алгоритмом Фишера-Йетса.&lt;br /&gt;
&lt;br /&gt;
Входные данные: &amp;lt;math&amp;gt;D=\{(x_i, y_i)\}_{i=1}^N&amp;lt;/math&amp;gt; - обучающая выборка.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: &amp;lt;math&amp;gt;D_{perm}&amp;lt;/math&amp;gt; - перемешанная выборка.&lt;br /&gt;
&lt;br /&gt;
  D_perm ← ПеремешиваниеОбучающейВыборки(D, генератор_случайных_чисел)&lt;br /&gt;
&lt;br /&gt;
3. Формирование мини-батчей: разбиение переставленной выборки на последовательность мини-батчей.&lt;br /&gt;
&lt;br /&gt;
Входные данные: &amp;lt;math&amp;gt;D_{perm}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выходные данные: последовательность подмножеств &amp;lt;math&amp;gt;B_k\subset D, \; k=1,..., K, \; \cup_k B_k=D, B_k \cap B_j = \emptyset, k\neq j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
  СписокБатчей ← ФормированиеМиниБатчей((X,y)_perm, размер_батча)&lt;br /&gt;
&lt;br /&gt;
4. Вычисление градиента на батче. Может включать вычисление значений модели на батче, матрично-векторные умножения, суммирование по объектам батча.&lt;br /&gt;
&lt;br /&gt;
Входные данные: текущие параметры &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;, мини-батч &amp;lt;math&amp;gt;B=\{(x_i, y_i)\}_{i\in I_B}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выходные данные: &amp;lt;math&amp;gt;g_B&amp;lt;/math&amp;gt; - градиент по параметрам на этом батче.&lt;br /&gt;
&lt;br /&gt;
  g_B ← ВычислениеГрадиентаНаБатче(w, B)&lt;br /&gt;
&lt;br /&gt;
5. Обновление параметров: осуществление одного шага метода по вычисленному градиенту на батче.&lt;br /&gt;
&lt;br /&gt;
Входные данные: текущие параметры &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;, градиент на батче &amp;lt;math&amp;gt;g_B&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: новые параметры &amp;lt;math&amp;gt;w_{new}=w-\alpha g_B&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
  w ← ОбновлениеПараметров(w, g_B, гиперпараметры_шага)&lt;br /&gt;
&lt;br /&gt;
6. Проверка критерия останова: проверка условий завершения итерационного процесса. Может быть проверкой номера эпохи, проверкой изменения функции потерь и т.п.&lt;br /&gt;
&lt;br /&gt;
  флаг_стоп ← ПроверкаКритерияОстановки(номер_эпохи, номер_шага, значение_критерия, история)&lt;br /&gt;
&lt;br /&gt;
На макроуровне алгоритм можно описать так:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:100%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Макроструктура алгоритма&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
w ← ИнициализацияПараметров(описание_модели, стратегия_инициализации)&lt;br /&gt;
номер_эпохи ← 0&lt;br /&gt;
повторять&lt;br /&gt;
  номер_эпохи ← номер_эпохи + 1&lt;br /&gt;
  D_perm ← ПеремешиваниеОбучающейВыборки(D, генератор_случайных_чисел)&lt;br /&gt;
  СписокБатчей ← ФормированиеМиниБатчей(D_perm, размер_батча)&lt;br /&gt;
  Для каждого B из СписокБатчей:&lt;br /&gt;
    g_B ← ВычислениеГрадиентаНаБатче(w, B)&lt;br /&gt;
    w ← ОбновлениеПараметров(w, g_B, гиперпараметры_шага)&lt;br /&gt;
  флаг_стоп ← ПроверкаКритерияОстановки(номер_эпохи, значение_критерия, история)&lt;br /&gt;
Пока флаг_стоп = ЛОЖЬ&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
[[Файл:Sequential SGD with mini-batches scheme.png|Схема последовательной реализации стохастического градиентного спуска с мини-батчами]]&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; - размер выборки,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; - размер батча (&amp;lt;math&amp;gt;batch\_size&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - сложность вычисления производной функции потерь на одном примере,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - число эпох.&lt;br /&gt;
&lt;br /&gt;
Как уже упоминалось, будем перемешивать выборку случайным образом в начале каждой эпохи. Сложность случайного перемешивания выборки объема &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; алгоритмом Фишера-Йетса - &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. Если отказаться от этого предположения, можно считать, что сложность выбора &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; случайных элементов - &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;. Такая оценка будет верна, если в системе реализован произвольный доступ к памяти. Однако для больших выборок, не помещающихся целиком в памяти, произвольный доступ к элементам выборки не будет возможен.&lt;br /&gt;
&lt;br /&gt;
Сложность обработки одного батча - &amp;lt;math&amp;gt;O(B \cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что количество батчей &amp;lt;math&amp;gt;N/B&amp;lt;/math&amp;gt; - целое число; тогда сложность вычисления градиентов в течение одной эпохи - &amp;lt;math&amp;gt;O(N/B \cdot B \cdot C) = O(N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность одной эпохи с учетом перемешивания выборки - &amp;lt;math&amp;gt;O(N)+O(N\cdot C)=O(N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность всего алгоритма с &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; эпохами - &amp;lt;math&amp;gt;O(E\cdot N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
На схеме изображен информационный граф стохастического градиентного спуска с мини-батчами.&lt;br /&gt;
&lt;br /&gt;
[[file:Informational_graph_minibatch_SGD.png|thumb|center|Информационный граф стохастического градиентного спуска с мини-батчами]]&lt;br /&gt;
Здесь приводится схема выполнения одной эпохи. Стрелки, изображающие обработку остальных объектов данного батча, опущены для улучшения читаемости схемы. После обработки одного батча с весами &amp;lt;math&amp;gt;w_i&amp;lt;/math&amp;gt; производится шаг градиентного спуска, и следующий батч обрабатывается уже с весами &amp;lt;math&amp;gt;w_{i+1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Ресурс параллелизма алгоритма===&lt;br /&gt;
Ресурс параллелизма алгоритма стохастического градиентного спуска (SGD) определяется зависимостями данных между его основными шагами: вычислением градиента и обновлением весов.&lt;br /&gt;
&lt;br /&gt;
====Иерархическая Структура Параллелизма====&lt;br /&gt;
&lt;br /&gt;
Параллелизм в SGD имеет &#039;&#039;&#039;двухуровневую (иерархическую)&#039;&#039;&#039; структуру, которая напрямую связана с циклическим профилем последовательной реализации.&lt;br /&gt;
&lt;br /&gt;
1. Внешний уровень: &#039;&#039;&#039;конечный параллелизм&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Внешний уровень параллелизма определяется последовательностью итераций по эпохам и по батчам:&lt;br /&gt;
* цикл по эпохам: итерации по эпохам зависимы, поскольку веса, полученные на одной эпохе, используются на следующей. Этот цикл не имеет параллельного ресурса.&lt;br /&gt;
* цикл по батчам (мини-батчам): обновления весов на основе последовательных мини-батчей информационно зависимы. Обновление &amp;lt;math&amp;gt;w_{k+1}&amp;lt;/math&amp;gt; зависит от &amp;lt;math&amp;gt;w_k&amp;lt;/math&amp;gt; и градиента &amp;lt;math&amp;gt;g_k&amp;lt;/math&amp;gt;. Это создает ресурс конечного параллелизма.&lt;br /&gt;
&lt;br /&gt;
2. Внутренний уровень: &#039;&#039;&#039;массовый параллелизм&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Внутренний уровень связан с обработкой данных внутри одного шага SGD (одного мини-батча).&lt;br /&gt;
&lt;br /&gt;
Это ресурс массового параллелизма, который может быть реализован двумя способами:&lt;br /&gt;
&lt;br /&gt;
* Вычисление градиента: вычисление частных градиентов для каждого примера (&amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt;) в мини-батче полностью независимо: &amp;lt;math&amp;gt;\frac{1}{|B|} \sum_{x_i \in B} \nabla L_i(w)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот этап демонстрирует &#039;&#039;&#039;координатный параллелизм&#039;&#039;&#039; (независимость итераций цикла по примерам в батче).&lt;br /&gt;
* Обновление весов: операция &amp;lt;math&amp;gt;w_{k+1} = w_k - \alpha g_k&amp;lt;/math&amp;gt; представляет собой векторные операции (вычитание и скалярное умножение), которые также могут быть распараллелены по координатам вектора весов (&amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
====Параллельная сложность и высота ярусно-параллельной формы====&lt;br /&gt;
&lt;br /&gt;
Оценка параллельной сложности алгоритма (высота канонической ярусно-параллельной формы) дается в терминах числа операций умножения/деления и сложения (которые доминируют).&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; — размерность вектора весов, &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — размер мини-батча.&lt;br /&gt;
&lt;br /&gt;
Основной вычислительный шаг SGD состоит из трех этапов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+ Параллельная сложность одного шага Стохастического Градиентного Спуска (SGD)&lt;br /&gt;
|-&lt;br /&gt;
! Этап&lt;br /&gt;
! Параллельная сложность&amp;lt;br&amp;gt;(Высота ЯПФ, &#039;&#039;H&#039;&#039;)&lt;br /&gt;
! Ширина ЯПФ&amp;lt;br&amp;gt;(&#039;&#039;W&#039;&#039; - Сбалансированность)&lt;br /&gt;
! Описание Ресурса Параллелизма&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Вычисление градиентов&#039;&#039;&#039;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(\log_2 B + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(d \times B)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &#039;&#039;&#039;Массовый параллелизм&#039;&#039;&#039; (Координатный параллелизм) по примерам в мини-батче. Требуется редукция/суммирование.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Усреднение и масштабирование&#039;&#039;&#039;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(d)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &#039;&#039;&#039;Конечный параллелизм&#039;&#039;&#039; (Координатный параллелизм) по координатам вектора весов.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Обновление весов&#039;&#039;&#039;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(d)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &#039;&#039;&#039;Конечный параллелизм&#039;&#039;&#039; (Координатный параллелизм) по координатам вектора весов.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Таким образом, параллельная сложность (высота) одного шага SGD составляет &amp;lt;math&amp;gt;H = O(\log_2 B)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
====Сбалансированность параллельных шагов (ширина ярусов)====&lt;br /&gt;
&lt;br /&gt;
Ширина ярусов отражает сбалансированность параллельных шагов по числу операций:&lt;br /&gt;
&lt;br /&gt;
* Ширина этапа градиентов: на этапе вычисления градиентов ширина ярусов максимальна, достигает &amp;lt;math&amp;gt;W = O(d \times B)&amp;lt;/math&amp;gt;. Этот этап сбалансирован при &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; процессорах, где &amp;lt;math&amp;gt;P \le B&amp;lt;/math&amp;gt;, поскольку каждому процессу можно поручить обработку &amp;lt;math&amp;gt;\lceil B/P \rceil&amp;lt;/math&amp;gt; примеров.&lt;br /&gt;
* Ширина этапов обновления: на этапах усреднения и обновления весов ширина ярусов составляет &amp;lt;math&amp;gt;W = O(d)&amp;lt;/math&amp;gt;. Этот этап также сбалансирован, если &amp;lt;math&amp;gt;P \le d&amp;lt;/math&amp;gt;, поскольку операции могут быть распределены по &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; процессорам.&lt;br /&gt;
&lt;br /&gt;
Алгоритм SGD обладает хорошей сбалансированностью на каждом шаге, что позволяет эффективно использовать большое число процессоров (ядер), особенно когда произведение &amp;lt;math&amp;gt;d \times B&amp;lt;/math&amp;gt; велико.&lt;br /&gt;
&lt;br /&gt;
===Входные и выходные данные алгоритма===&lt;br /&gt;
====Входные данные====&lt;br /&gt;
&lt;br /&gt;
Обучающая выборка (&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;) обычно представляется в виде двух плотных структур данных:&lt;br /&gt;
&lt;br /&gt;
1. Матрица Признаков (&amp;lt;math&amp;gt;X\in\mathbb{R}^{N \times m}&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — общее число обучающих примеров, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; — число признаков.&lt;br /&gt;
&lt;br /&gt;
В задачах машинного обучения &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; часто значительно больше, чем &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; (много примеров, но относительно небольшое число признаков), или же &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; может быть очень большим (например, при использовании One-Hot-Encoding).&lt;br /&gt;
&lt;br /&gt;
В зависимости от задачи, матрица &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; может быть:&lt;br /&gt;
* плотной (dense): каждая ячейка содержит значащее числовое значение.&lt;br /&gt;
* разреженной (sparse): если большая часть элементов равна нулю.&lt;br /&gt;
&lt;br /&gt;
2. Вектор целевых значений (&amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;) - вектор размера &amp;lt;math&amp;gt;N \times 1&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;N \times C&amp;lt;/math&amp;gt; (для многоклассовой классификации, где &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — число классов).&lt;br /&gt;
&lt;br /&gt;
Обычно плотный, содержит действительные числа (для регрессии) или целочисленные метки/векторы (для классификации).&lt;br /&gt;
&lt;br /&gt;
3. Параметры обучения&lt;br /&gt;
&lt;br /&gt;
* Скорость обучения (&amp;lt;math&amp;gt;\alpha\in\mathbb{R}&amp;lt;/math&amp;gt;, learning rate): его значение обычно мало (например, &amp;lt;math&amp;gt;10^{-2}&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;10^{-3}&amp;lt;/math&amp;gt;) и оказывает критическое влияние на сходимость.&lt;br /&gt;
* Размер мини-батча (&amp;lt;math&amp;gt;B\in\mathbb{R}&amp;lt;/math&amp;gt;, batch size): определяет число примеров, используемых для одного шага. Обычно является степенью двойки (&amp;lt;math&amp;gt;32, 64, 128, \dots&amp;lt;/math&amp;gt;).&lt;br /&gt;
* Число эпох (&amp;lt;math&amp;gt;E\in\mathbb{N}&amp;lt;/math&amp;gt;, epochs): число полных проходов по всему набору данных.&lt;br /&gt;
&lt;br /&gt;
====Выходные Данные====&lt;br /&gt;
&lt;br /&gt;
* Вектор весов модели (&amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;): вектор размера &amp;lt;math&amp;gt;d \times 1&amp;lt;/math&amp;gt; (или матрица &amp;lt;math&amp;gt;d \times C&amp;lt;/math&amp;gt;, если модель содержит скрытые слои или многоклассовый вывод).&lt;br /&gt;
&lt;br /&gt;
Является плотной структурой данных. Диапазон значений зависит от функции потерь и регуляризации, но обычно это числа, близкие к нулю, или числа малого/среднего диапазона.&lt;br /&gt;
&lt;br /&gt;
* История потерь (loss history, опционально): вектор, содержащий значение функции потерь, вычисленное после каждого шага SGD. Объем равен &amp;lt;math&amp;gt;(E \times N) / B&amp;lt;/math&amp;gt;. Используется для анализа сходимости и отладки алгоритма.&lt;br /&gt;
&lt;br /&gt;
===Свойства алгоритма===&lt;br /&gt;
====Соотношение последовательной и параллельной сложности====&lt;br /&gt;
&lt;br /&gt;
Алгоритм SGD является последовательным по отношению к шагам обновления весов. Однако в рамках одного шага обновления (одного мини-батча) он обладает высоким ресурсом параллелизма.&lt;br /&gt;
&lt;br /&gt;
* Последовательная сложность одного шага SGD: &amp;lt;math&amp;gt;T_{seq} = O(B \cdot d)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; - размер батча, &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; - размерность весов.&lt;br /&gt;
* Параллельная сложность одного шага SGD (высота ЯПФ): &amp;lt;math&amp;gt;H = O(\log_2 B + 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теоретический выигрыш от параллельной реализации (ускорение) составляет:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S = \frac{T_{seq}}{H} = \frac{O(B \cdot d)}{O(\log_2 B + 1)}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теоретически, параллельная реализация обеспечивает значительное ускорение &amp;lt;math&amp;gt;O(B \cdot d)&amp;lt;/math&amp;gt;, которое растет линейно с размером батча и размерностью задачи, если есть достаточное количество процессоров &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Сложности параллелизации: главная сложность заключается в информационной зависимости между последовательными шагами обновления. Параллельная реализация дает выигрыш только внутри одного шага (градиент и обновление), но не может ускорить последовательность шагов, что является фундаментальным ограничением SGD.&lt;br /&gt;
====Вычислительная Мощность====&lt;br /&gt;
* Общее число операций (за одну эпоху): &amp;lt;math&amp;gt;O(N \cdot d)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — общее число объектов.&lt;br /&gt;
* Объем входных данных (матрица &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;): &amp;lt;math&amp;gt;O(N \cdot d)&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Объем выходных данных (вектор весов &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;): &amp;lt;math&amp;gt;O(d)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;W_{comp} = \frac{\text{Число операций}}{\text{Объем входных данных}} = \frac{O(N \cdot d)}{O(N \cdot d + d)}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
При больших &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;N \cdot d&amp;lt;/math&amp;gt; доминирует в знаменателе. Таким образом, вычислительная мощность SGD составляет:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;W_{comp} \approx O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность SGD близка к константе (&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;). Это означает, что число операций примерно равно объему исходных данных. Это значение относительно невысокое. Это свойство требует, чтобы алгоритм выполнялся &amp;quot;близко&amp;quot; к памяти с данными (например, на том же узле кластера), чтобы минимизировать накладные расходы на перемещение данных.&lt;br /&gt;
====Устойчивость Алгоритма====&lt;br /&gt;
&lt;br /&gt;
Алгоритм SGD является &#039;&#039;&#039;стохастическим и неустойчивым&#039;&#039;&#039; в смысле получения одного и того же результата при каждом запуске.&lt;br /&gt;
&lt;br /&gt;
* Неустойчивость к входным данным: поскольку SGD использует только часть данных (мини-батч) для каждого шага, дисперсия в оценке градиента высокая. Это приводит к флуктуациям в траектории сходимости.&lt;br /&gt;
* Ошибка округления: при использовании массового параллелизма (например, при суммировании градиентов от &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; примеров) на системах с массовым параллелизмом порядок выполнения ассоциативных операций (сложение) может меняться от запуска к запуску. Это приводит к неповторяемости результатов работы параллельных программ, что является серьезной проблемой на практике.&lt;br /&gt;
&lt;br /&gt;
====Сбалансированность вычислительного процесса====&lt;br /&gt;
&lt;br /&gt;
Алгоритм обладает хорошей сбалансированностью с точки зрения распределения нагрузки.&lt;br /&gt;
&lt;br /&gt;
На каждой итерации преобладают арифметические операции при вычислении градиента. Соотношение между арифметическими операциями и обращениями к памяти (чтение/запись) определяется параметром &amp;lt;math&amp;gt;B \cdot d&amp;lt;/math&amp;gt;, который обычно достаточно велик, что обеспечивает эффективную работу процессоров.&lt;br /&gt;
&lt;br /&gt;
Распределение нагрузки по &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; процессам на этапе вычисления градиента достигается просто: каждый процессор обрабатывает &amp;lt;math&amp;gt;\lceil B/P \rceil&amp;lt;/math&amp;gt; примеров. Это обеспечивает высокую балансировку нагрузки.&lt;br /&gt;
&lt;br /&gt;
====Детерминированность====&lt;br /&gt;
Алгоритм SGD является &#039;&#039;&#039;недетерминированным&#039;&#039;&#039; по следующим причинам:&lt;br /&gt;
&lt;br /&gt;
1. Порядок обработки мини-батчей: в классическом SGD набор мини-батчей на каждой эпохе случаен, что меняет структуру вычислительного процесса и итоговый результат.&lt;br /&gt;
2. Изменение порядка ассоциативных операций: как было описано выше, изменение порядка суммирования градиентов в параллельной среде приводит к непостоянству ошибок округления, что является причиной недетерминированности конечного результата в параллельной реализации.&lt;br /&gt;
&lt;br /&gt;
====Дополнительные свойства====&lt;br /&gt;
&lt;br /&gt;
* Степень исхода вершины: высока для вектора весов &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. На каждом шаге &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; используется для вычисления градиента для всех &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; примеров. На этапе реализации это требует эффективной рассылки вектора &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; всем параллельным процессам/потокам, работающим над батчем, и эффективного доступа к нему.&lt;br /&gt;
* &amp;quot;Длинные&amp;quot; дуги: возникают в информационном графе SGD при рассылке величин (таких как learning rate &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; или текущие веса &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;) по всем итерациям цикла мини-батчей. В случае вектора весов (&amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;), это рассылка всего вектора. Поскольку эта процедура хорошо изучена и оптимизирована на практике, она обычно не вызывает серьезных проблем с размещением данных в иерархии памяти, но требует эффективной коммуникации.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
&lt;br /&gt;
===Результаты прогонов===&lt;br /&gt;
&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
Yujing Ma, Florin Rusu, Martin Torres. Stochastic Gradient Descent on Highly-Parallel Architectures [Электронный ресурс] // arXiv:1802.08800 [math.ST]. – 2018. – Режим доступа: https://arxiv.org/abs/1802.08800&lt;br /&gt;
&lt;br /&gt;
Sebastian Ruder. An overview of gradient descent optimization algorithms [Электронный ресурс] // arXiv:1609.04747 [math.ST]. – 2016. – Режим доступа: https://arxiv.org/abs/1609.04747&lt;/div&gt;</summary>
		<author><name>OvsyannikovaSA</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%9F%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%BD%D0%B0%D1%8F_%D1%80%D0%B5%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D1%81%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B3%D0%BE_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D1%81%D0%BF%D1%83%D1%81%D0%BA%D0%B0&amp;diff=30313</id>
		<title>Участница:OvsyannikovaSA/Программная реализация стохастического градиентного спуска</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%9F%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%BD%D0%B0%D1%8F_%D1%80%D0%B5%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D1%81%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B3%D0%BE_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D1%81%D0%BF%D1%83%D1%81%D0%BA%D0%B0&amp;diff=30313"/>
		<updated>2025-12-09T11:54:08Z</updated>

		<summary type="html">&lt;p&gt;OvsyannikovaSA: /* Масштабируемость реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Ссылки==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
===Теоретическая масштабируемость алгоритма===&lt;br /&gt;
Масштабируемость алгоритма SGD определяется его структурой и необходимостью синхронизации на каждом шаге.&lt;br /&gt;
&lt;br /&gt;
Масштабируемость самого алгоритма SGD (не зависимо от платформы) ограничена его последовательной природой в цикле обновления весов.&lt;br /&gt;
&lt;br /&gt;
На каждом шаге SGD происходят следующие критические операции, которые ограничивают масштабируемость:&lt;br /&gt;
&lt;br /&gt;
1. Вычисление частных градиентов: массово параллельный этап. Потоки работают независимо на своих частях мини-батча.&lt;br /&gt;
&lt;br /&gt;
2. Редукция: после вычисления частных градиентов все потоки должны выполнить редукцию для получения общего градиента. Эта операция является точкой барьерной синхронизации, т.к. ни один поток не может перейти к обновлению весов, пока не получен окончательный градиент.&lt;br /&gt;
&lt;br /&gt;
3. Обновление весов: последовательный по времени этап, но параллельный по координатам вектора весов.&lt;br /&gt;
&lt;br /&gt;
Максимальное ускорение &amp;lt;math&amp;gt;S_{max}&amp;lt;/math&amp;gt; на одном шаге SGD ограничено законом Амдала, где последовательная часть — это время, затраченное на глобальную редукцию и, в меньшей степени, на векторное обновление. На практике масштабируемость ограничивается эффективностью редукции при росте числа процессоров.&lt;br /&gt;
&lt;br /&gt;
===Масштабируемость реализации===&lt;br /&gt;
&lt;br /&gt;
Сильная масштабируемость SGD хорошая до определенного предела. При увеличении &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; рабочая нагрузка на один процессор &amp;lt;math&amp;gt;B/P&amp;lt;/math&amp;gt; уменьшается, что приводит к сокращению времени вычисления градиента.&lt;br /&gt;
&lt;br /&gt;
Когда &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; становится близким к &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;, уменьшение времени вычисления градиента замедляется. При дальнейшем росте &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; время, затрачиваемое на синхронизацию, начинает доминировать над временем полезных вычислений. Это приводит к падению эффективности и остановке роста ускорения.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S_{max}&amp;lt;/math&amp;gt; достигается, когда &amp;lt;math&amp;gt;P \approx B&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;P \approx d&amp;lt;/math&amp;gt; (зависит от того, что больше; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; - размерность вектора весов).&lt;br /&gt;
&lt;br /&gt;
Слабая масштабируемость SGD очень хорошая. При одновременном увеличении общего размера данных &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; и числа процессоров &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; время вычисления градиента (самая затратная часть) остается примерно постоянным, поскольку нагрузка на один процессор неизменна.&lt;br /&gt;
&lt;br /&gt;
Слабая масштабируемость ограничивается временем глобальных операций. При очень больших &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; накладные расходы на редукцию и коммуникацию начинают увеличиваться, вызывая медленный, но стабильный рост общего времени выполнения.&lt;br /&gt;
&lt;br /&gt;
Реализация выполнена с помощью OpenMP на суперкомпьютере &amp;quot;Ломоносов-2&amp;quot;. Число объектов в выборке &amp;lt;math&amp;gt;N=200000&amp;lt;/math&amp;gt;, размерность признаков &amp;lt;math&amp;gt;m=20&amp;lt;/math&amp;gt;, число эпох &amp;lt;math&amp;gt;E=30&amp;lt;/math&amp;gt;, learning rate &amp;lt;math&amp;gt;\alpha=0.005&amp;lt;/math&amp;gt;.&lt;br /&gt;
[[Файл:Ускорение параллельного SGD в зависимости от числа потоков и размера батча.png]]&lt;br /&gt;
&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Результаты прогонов==&lt;/div&gt;</summary>
		<author><name>OvsyannikovaSA</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%9F%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%BD%D0%B0%D1%8F_%D1%80%D0%B5%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D1%81%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B3%D0%BE_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D1%81%D0%BF%D1%83%D1%81%D0%BA%D0%B0&amp;diff=30312</id>
		<title>Участница:OvsyannikovaSA/Программная реализация стохастического градиентного спуска</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%9F%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%BD%D0%B0%D1%8F_%D1%80%D0%B5%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D1%81%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B3%D0%BE_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D1%81%D0%BF%D1%83%D1%81%D0%BA%D0%B0&amp;diff=30312"/>
		<updated>2025-12-09T09:06:09Z</updated>

		<summary type="html">&lt;p&gt;OvsyannikovaSA: /* Масштабируемость реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Ссылки==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
===Теоретическая масштабируемость алгоритма===&lt;br /&gt;
Масштабируемость алгоритма SGD определяется его структурой и необходимостью синхронизации на каждом шаге.&lt;br /&gt;
&lt;br /&gt;
Масштабируемость самого алгоритма SGD (не зависимо от платформы) ограничена его последовательной природой в цикле обновления весов.&lt;br /&gt;
&lt;br /&gt;
На каждом шаге SGD происходят следующие критические операции, которые ограничивают масштабируемость:&lt;br /&gt;
&lt;br /&gt;
1. Вычисление частных градиентов: массово параллельный этап. Потоки работают независимо на своих частях мини-батча.&lt;br /&gt;
&lt;br /&gt;
2. Редукция: после вычисления частных градиентов все потоки должны выполнить редукцию для получения общего градиента. Эта операция является точкой барьерной синхронизации, т.к. ни один поток не может перейти к обновлению весов, пока не получен окончательный градиент.&lt;br /&gt;
&lt;br /&gt;
3. Обновление весов: последовательный по времени этап, но параллельный по координатам вектора весов.&lt;br /&gt;
&lt;br /&gt;
Максимальное ускорение &amp;lt;math&amp;gt;S_{max}&amp;lt;/math&amp;gt; на одном шаге SGD ограничено законом Амдала, где последовательная часть — это время, затраченное на глобальную редукцию и, в меньшей степени, на векторное обновление. На практике масштабируемость ограничивается эффективностью редукции при росте числа процессоров.&lt;br /&gt;
&lt;br /&gt;
===Масштабируемость реализации===&lt;br /&gt;
&lt;br /&gt;
Сильная масштабируемость SGD хорошая до определенного предела. При увеличении &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; рабочая нагрузка на один процессор &amp;lt;math&amp;gt;B/P&amp;lt;/math&amp;gt; уменьшается, что приводит к сокращению времени вычисления градиента.&lt;br /&gt;
&lt;br /&gt;
Когда &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; становится близким к &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;, уменьшение времени вычисления градиента замедляется. При дальнейшем росте &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; время, затрачиваемое на синхронизацию, начинает доминировать над временем полезных вычислений. Это приводит к падению эффективности и остановке роста ускорения.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S_{max}&amp;lt;/math&amp;gt; достигается, когда &amp;lt;math&amp;gt;P \approx B&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;P \approx d&amp;lt;/math&amp;gt; (зависит от того, что больше; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; - размерность вектора весов).&lt;br /&gt;
&lt;br /&gt;
Слабая масштабируемость SGD очень хорошая. При одновременном увеличении общего размера данных &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; и числа процессоров &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; время вычисления градиента (самая затратная часть) остается примерно постоянным, поскольку нагрузка на один процессор неизменна.&lt;br /&gt;
&lt;br /&gt;
Слабая масштабируемость ограничивается временем глобальных операций. При очень больших &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; накладные расходы на редукцию и коммуникацию начинают увеличиваться, вызывая медленный, но стабильный рост общего времени выполнения.&lt;br /&gt;
&lt;br /&gt;
Реализация выполнена с помощью OpenMP на суперкомпьютере &amp;quot;Ломоносов-2&amp;quot;.&lt;br /&gt;
[[Файл:Ускорение параллельного SGD в зависимости от числа потоков и размера батча.png]]&lt;br /&gt;
&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Результаты прогонов==&lt;/div&gt;</summary>
		<author><name>OvsyannikovaSA</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%9F%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%BD%D0%B0%D1%8F_%D1%80%D0%B5%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D1%81%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B3%D0%BE_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D1%81%D0%BF%D1%83%D1%81%D0%BA%D0%B0&amp;diff=30311</id>
		<title>Участница:OvsyannikovaSA/Программная реализация стохастического градиентного спуска</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%9F%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%BD%D0%B0%D1%8F_%D1%80%D0%B5%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D1%81%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B3%D0%BE_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D1%81%D0%BF%D1%83%D1%81%D0%BA%D0%B0&amp;diff=30311"/>
		<updated>2025-12-09T09:04:50Z</updated>

		<summary type="html">&lt;p&gt;OvsyannikovaSA: добавлено: масштабируемость алгоритма и его реализации&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Ссылки==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
===Теоретическая масштабируемость алгоритма===&lt;br /&gt;
Масштабируемость алгоритма SGD определяется его структурой и необходимостью синхронизации на каждом шаге.&lt;br /&gt;
&lt;br /&gt;
Масштабируемость самого алгоритма SGD (не зависимо от платформы) ограничена его последовательной природой в цикле обновления весов.&lt;br /&gt;
&lt;br /&gt;
На каждом шаге SGD происходят следующие критические операции, которые ограничивают масштабируемость:&lt;br /&gt;
&lt;br /&gt;
1. Вычисление частных градиентов: массово параллельный этап. Потоки работают независимо на своих частях мини-батча.&lt;br /&gt;
&lt;br /&gt;
2. Редукция: после вычисления частных градиентов все потоки должны выполнить редукцию для получения общего градиента. Эта операция является точкой барьерной синхронизации, т.к. ни один поток не может перейти к обновлению весов, пока не получен окончательный градиент.&lt;br /&gt;
&lt;br /&gt;
3. Обновление весов: последовательный по времени этап, но параллельный по координатам вектора весов.&lt;br /&gt;
&lt;br /&gt;
Максимальное ускорение &amp;lt;math&amp;gt;S_{max}&amp;lt;/math&amp;gt; на одном шаге SGD ограничено законом Амдала, где последовательная часть — это время, затраченное на глобальную редукцию и, в меньшей степени, на векторное обновление. На практике масштабируемость ограничивается эффективностью редукции при росте числа процессоров.&lt;br /&gt;
&lt;br /&gt;
===Масштабируемость реализации===&lt;br /&gt;
&lt;br /&gt;
Сильная масштабируемость SGD хорошая до определенного предела. При увеличении &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; рабочая нагрузка на один процессор &amp;lt;math&amp;gt;B/P&amp;lt;/math&amp;gt; уменьшается, что приводит к сокращению времени вычисления градиента.&lt;br /&gt;
&lt;br /&gt;
Когда &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; становится близким к &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;, уменьшение времени вычисления градиента замедляется. При дальнейшем росте &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; время, затрачиваемое на синхронизацию, начинает доминировать над временем полезных вычислений. Это приводит к падению эффективности и остановке роста ускорения.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S_{max}&amp;lt;/math&amp;gt; достигается, когда &amp;lt;math&amp;gt;P \approx B&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;P \approx d&amp;lt;/math&amp;gt; (зависит от того, что больше; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; - размерность вектора весов).&lt;br /&gt;
&lt;br /&gt;
Слабая масштабируемость SGD очень хорошая. При одновременном увеличении общего размера данных &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; и числа процессоров &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; время вычисления градиента (самая затратная часть) остается примерно постоянным, поскольку нагрузка на один процессор неизменна.&lt;br /&gt;
&lt;br /&gt;
Слабая масштабируемость ограничивается временем глобальных операций. При очень больших &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; накладные расходы на редукцию и коммуникацию начинают увеличиваться, вызывая медленный, но стабильный рост общего времени выполнения.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Ускорение параллельного SGD в зависимости от числа потоков и размера батча.png]]&lt;br /&gt;
&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Результаты прогонов==&lt;/div&gt;</summary>
		<author><name>OvsyannikovaSA</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%A3%D1%81%D0%BA%D0%BE%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BF%D0%B0%D1%80%D0%B0%D0%BB%D0%BB%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE_SGD_%D0%B2_%D0%B7%D0%B0%D0%B2%D0%B8%D1%81%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B8_%D0%BE%D1%82_%D1%87%D0%B8%D1%81%D0%BB%D0%B0_%D0%BF%D0%BE%D1%82%D0%BE%D0%BA%D0%BE%D0%B2_%D0%B8_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%B0_%D0%B1%D0%B0%D1%82%D1%87%D0%B0.png&amp;diff=30310</id>
		<title>Файл:Ускорение параллельного SGD в зависимости от числа потоков и размера батча.png</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%A3%D1%81%D0%BA%D0%BE%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BF%D0%B0%D1%80%D0%B0%D0%BB%D0%BB%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE_SGD_%D0%B2_%D0%B7%D0%B0%D0%B2%D0%B8%D1%81%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B8_%D0%BE%D1%82_%D1%87%D0%B8%D1%81%D0%BB%D0%B0_%D0%BF%D0%BE%D1%82%D0%BE%D0%BA%D0%BE%D0%B2_%D0%B8_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%B0_%D0%B1%D0%B0%D1%82%D1%87%D0%B0.png&amp;diff=30310"/>
		<updated>2025-12-09T09:02:20Z</updated>

		<summary type="html">&lt;p&gt;OvsyannikovaSA: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ускорение параллельного SGD в зависимости от числа потоков и размера батча&lt;/div&gt;</summary>
		<author><name>OvsyannikovaSA</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=30309</id>
		<title>Участница:OvsyannikovaSA/Стохастический градиентный спуск</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=30309"/>
		<updated>2025-12-09T08:33:29Z</updated>

		<summary type="html">&lt;p&gt;OvsyannikovaSA: исправления неточностей&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Свойства и структура алгоритмов==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
&#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039; (Stochastic Gradient Descent, SGD) представляет собой один из базовых и наиболее распространённых алгоритмов оптимизации, применяемых для обучения моделей машинного обучения и нейронных сетей. Он относится к классу итерационных методов минимизации функций.&lt;br /&gt;
&lt;br /&gt;
===Математическое описание алгоритма===&lt;br /&gt;
&lt;br /&gt;
Пусть даны &amp;lt;math&amp;gt;\{x_i, y_i\}_{i=1}^N, x_i \in \mathbb{R}^m&amp;lt;/math&amp;gt; - вектор признаков &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го объекта, &amp;lt;math&amp;gt;y_i \in \mathbb{R}&amp;lt;/math&amp;gt; - значение целевой переменной; класс моделей &amp;lt;math&amp;gt;a_\omega: \mathbb{R}^m \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;; функция потерь &amp;lt;math&amp;gt;f: \mathbb{R}\times \mathbb{R} \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;. Задача: найти вектор параметров модели (весов) &amp;lt;math&amp;gt;\omega \in \mathbb{R}^d&amp;lt;/math&amp;gt;, т.ч. &amp;lt;math&amp;gt;\omega = argmin_{\omega\in \mathbb{R}^d}\;L(\omega),\;L(\omega)=\sum_{i=1}^N f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм &#039;&#039;&#039;классического градиентного спуска (batch gradient descent)&#039;&#039;&#039; можно сформулировать следующим образом:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Здесь и далее шаг обучения (learning rate) &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; является гиперпараметром, т.е. параметром, который не оптимизируется в ходе работы алгоритма и который необходимо выбрать заранее. Начальное приближение &amp;lt;math&amp;gt;\omega_0&amp;lt;/math&amp;gt; также необходимо выбрать заранее исходя из некоторых соображений.&lt;br /&gt;
Условие достижения сходимости на практике обычно заменяется повторением процедуры некоторое количество раз, после чего можно считать, что алгоритм сошелся в требуемом приближении.&lt;br /&gt;
В данном подходе для того, чтобы совершить одно обновление весов, необходимо вычислить функцию потерь для всех элементов выборки. Этот метод может оказаться неподходящим в некоторых случаях, например, при использовании больших датасетов, не помещающихся в памяти, или в случае, когда новые данные поступают в реальном времени.&lt;br /&gt;
&lt;br /&gt;
Модернизацией этого алгоритма является &#039;&#039;&#039;стохастический градиентный спуск (stochastic gradient descent)&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xi, yi)&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad f(ω; xi, yi);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Алгоритм отличается от предыдущего тем, что обновление весов происходит после обработки одного объекта выборки. Компромиссом между двумя этими подходами служит &#039;&#039;&#039;стохастический градиентный спуск на мини-батчах (mini-batch gradient descent)&#039;&#039;&#039;. Для него требуется выбрать размер батча (batch_size, &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;). Обозначим &amp;lt;math&amp;gt;L(\omega)=\sum_{i=1}^{B} f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск с мини-батчами&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α, размер батча B&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xik, yik), 1&amp;lt;=k&amp;lt;=B&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω; (xik, yik), 1&amp;lt;=k&amp;lt;=B);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Преимущество алгоритма заключается в частом обновлении градиента и возможности использовать эффективные матричные вычисления.&lt;br /&gt;
В этой работе мы сосредоточимся на реализации градиентного спуска с мини-батчами.&lt;br /&gt;
&lt;br /&gt;
Необходимо некоторым способом определить условия, при которых будет считаться, что алгоритм сошелся. Будем считать, что сходимость достигается за &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; итераций обработки всей выборки (будем называть одну итерацию &#039;&#039;&#039;эпохой&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
В начале каждой эпохи будем случайно перемешивать выборку, а затем последовательно выбирать порции данных по &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; объектов. Это обеспечит локальность расположения в памяти последовательно идущих мини-батчей и сохранит логику случайного выбора мини-батчей. Таким образом, процедура случайного выбора мини-батча заменяется на линейный проход по всем данным.&lt;br /&gt;
&lt;br /&gt;
===Вычислительное ядро алгоритма===&lt;br /&gt;
Основное время работы алгоритма приходится на вычисление градиента, которые повторяются, пока сходимость не будет достигнута.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Алгоритм стохастического градиентного спуска с мини-батчами представляется повторением следующих макроопераций:&lt;br /&gt;
&lt;br /&gt;
1. Инициализация параметров: задание начального приближения вектора параметров модели &amp;lt;math&amp;gt;w_0&amp;lt;/math&amp;gt;. Может быть случайной инициализацией, загрузкой предварительно обученной модели и т.п.&lt;br /&gt;
&lt;br /&gt;
  w ← ИнициализацияПараметров(описание_модели, стратегия_инициализации)&lt;br /&gt;
&lt;br /&gt;
2. Перемешивание обучающей выборки: получение случайной перестановки обучающей выборки в начале эпохи. Можно выполнять, например, алгоритмом Фишера-Йетса.&lt;br /&gt;
&lt;br /&gt;
Входные данные: &amp;lt;math&amp;gt;D=\{(x_i, y_i)\}_{i=1}^N&amp;lt;/math&amp;gt; - обучающая выборка.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: &amp;lt;math&amp;gt;D_{perm}&amp;lt;/math&amp;gt; - перемешанная выборка.&lt;br /&gt;
&lt;br /&gt;
  D_perm ← ПеремешиваниеОбучающейВыборки(D, генератор_случайных_чисел)&lt;br /&gt;
&lt;br /&gt;
3. Формирование мини-батчей: разбиение переставленной выборки на последовательность мини-батчей.&lt;br /&gt;
&lt;br /&gt;
Входные данные: &amp;lt;math&amp;gt;D_{perm}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выходные данные: последовательность подмножеств &amp;lt;math&amp;gt;B_k\subset D, \; k=1,..., K, \; \cup_k B_k=D, B_k \cap B_j = \emptyset, k\neq j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
  СписокБатчей ← ФормированиеМиниБатчей((X,y)_perm, размер_батча)&lt;br /&gt;
&lt;br /&gt;
4. Вычисление градиента на батче. Может включать вычисление значений модели на батче, матрично-векторные умножения, суммирование по объектам батча.&lt;br /&gt;
&lt;br /&gt;
Входные данные: текущие параметры &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;, мини-батч &amp;lt;math&amp;gt;B=\{(x_i, y_i)\}_{i\in I_B}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выходные данные: &amp;lt;math&amp;gt;g_B&amp;lt;/math&amp;gt; - градиент по параметрам на этом батче.&lt;br /&gt;
&lt;br /&gt;
  g_B ← ВычислениеГрадиентаНаБатче(w, B)&lt;br /&gt;
&lt;br /&gt;
5. Обновление параметров: осуществление одного шага метода по вычисленному градиенту на батче.&lt;br /&gt;
&lt;br /&gt;
Входные данные: текущие параметры &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;, градиент на батче &amp;lt;math&amp;gt;g_B&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: новые параметры &amp;lt;math&amp;gt;w_{new}=w-\alpha g_B&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
  w ← ОбновлениеПараметров(w, g_B, гиперпараметры_шага)&lt;br /&gt;
&lt;br /&gt;
6. Проверка критерия останова: проверка условий завершения итерационного процесса. Может быть проверкой номера эпохи, проверкой изменения функции потерь и т.п.&lt;br /&gt;
&lt;br /&gt;
  флаг_стоп ← ПроверкаКритерияОстановки(номер_эпохи, номер_шага, значение_критерия, история)&lt;br /&gt;
&lt;br /&gt;
На макроуровне алгоритм можно описать так:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:100%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Макроструктура алгоритма&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
w ← ИнициализацияПараметров(описание_модели, стратегия_инициализации)&lt;br /&gt;
номер_эпохи ← 0&lt;br /&gt;
повторять&lt;br /&gt;
  номер_эпохи ← номер_эпохи + 1&lt;br /&gt;
  D_perm ← ПеремешиваниеОбучающейВыборки(D, генератор_случайных_чисел)&lt;br /&gt;
  СписокБатчей ← ФормированиеМиниБатчей(D_perm, размер_батча)&lt;br /&gt;
  Для каждого B из СписокБатчей:&lt;br /&gt;
    g_B ← ВычислениеГрадиентаНаБатче(w, B)&lt;br /&gt;
    w ← ОбновлениеПараметров(w, g_B, гиперпараметры_шага)&lt;br /&gt;
  флаг_стоп ← ПроверкаКритерияОстановки(номер_эпохи, значение_критерия, история)&lt;br /&gt;
Пока флаг_стоп = ЛОЖЬ&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
[[Файл:Sequential SGD with mini-batches scheme.png|мини|Схема последовательной реализации стохастического градиентного спуска с мини-батчами]]&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; - размер выборки,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; - размер батча (&amp;lt;math&amp;gt;batch\_size&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - сложность вычисления производной функции потерь на одном примере,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - число эпох.&lt;br /&gt;
&lt;br /&gt;
Как уже упоминалось, будем перемешивать выборку случайным образом в начале каждой эпохи. Сложность случайного перемешивания выборки объема &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; алгоритмом Фишера-Йетса - &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. Если отказаться от этого предположения, можно считать, что сложность выбора &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; случайных элементов - &amp;lt;math&amp;gt;O(B)&amp;lt;/math&amp;gt;. Такая оценка будет верна, если в системе реализован произвольный доступ к памяти. Однако для больших выборок, не помещающихся целиком в памяти, произвольный доступ к элементам выборки не будет возможен.&lt;br /&gt;
&lt;br /&gt;
Сложность обработки одного батча - &amp;lt;math&amp;gt;O(B \cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что количество батчей &amp;lt;math&amp;gt;N/B&amp;lt;/math&amp;gt; - целое число; тогда сложность вычисления градиентов в течение одной эпохи - &amp;lt;math&amp;gt;O(N/B \cdot B \cdot C) = O(N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность одной эпохи с учетом перемешивания выборки - &amp;lt;math&amp;gt;O(N)+O(N\cdot C)=O(N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность всего алгоритма с &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; эпохами - &amp;lt;math&amp;gt;O(E\cdot N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
На схеме изображен информационный граф стохастического градиентного спуска с мини-батчами.&lt;br /&gt;
&lt;br /&gt;
[[file:Informational_graph_minibatch_SGD.png|thumb|center|Информационный граф стохастического градиентного спуска с мини-батчами]]&lt;br /&gt;
Здесь приводится схема выполнения одной эпохи. Стрелки, изображающие обработку остальных объектов данного батча, опущены для улучшения читаемости схемы. После обработки одного батча с весами &amp;lt;math&amp;gt;w_i&amp;lt;/math&amp;gt; производится шаг градиентного спуска, и следующий батч обрабатывается уже с весами &amp;lt;math&amp;gt;w_{i+1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Ресурс параллелизма алгоритма===&lt;br /&gt;
Ресурс параллелизма алгоритма стохастического градиентного спуска (SGD) определяется зависимостями данных между его основными шагами: вычислением градиента и обновлением весов.&lt;br /&gt;
&lt;br /&gt;
====Иерархическая Структура Параллелизма====&lt;br /&gt;
&lt;br /&gt;
Параллелизм в SGD имеет &#039;&#039;&#039;двухуровневую (иерархическую)&#039;&#039;&#039; структуру, которая напрямую связана с циклическим профилем последовательной реализации.&lt;br /&gt;
&lt;br /&gt;
1. Внешний уровень: &#039;&#039;&#039;конечный параллелизм&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Внешний уровень параллелизма определяется последовательностью итераций по эпохам и по батчам:&lt;br /&gt;
* цикл по эпохам: итерации по эпохам зависимы, поскольку веса, полученные на одной эпохе, используются на следующей. Этот цикл не имеет параллельного ресурса.&lt;br /&gt;
* цикл по батчам (мини-батчам): обновления весов на основе последовательных мини-батчей информационно зависимы. Обновление &amp;lt;math&amp;gt;w_{k+1}&amp;lt;/math&amp;gt; зависит от &amp;lt;math&amp;gt;w_k&amp;lt;/math&amp;gt; и градиента &amp;lt;math&amp;gt;g_k&amp;lt;/math&amp;gt;. Это создает ресурс конечного параллелизма.&lt;br /&gt;
&lt;br /&gt;
2. Внутренний уровень: &#039;&#039;&#039;массовый параллелизм&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Внутренний уровень связан с обработкой данных внутри одного шага SGD (одного мини-батча).&lt;br /&gt;
&lt;br /&gt;
Это ресурс массового параллелизма, который может быть реализован двумя способами:&lt;br /&gt;
&lt;br /&gt;
* Вычисление градиента: вычисление частных градиентов для каждого примера (&amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt;) в мини-батче полностью независимо: &amp;lt;math&amp;gt;\frac{1}{|B|} \sum_{x_i \in B} \nabla L_i(w)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот этап демонстрирует &#039;&#039;&#039;координатный параллелизм&#039;&#039;&#039; (независимость итераций цикла по примерам в батче).&lt;br /&gt;
* Обновление весов: операция &amp;lt;math&amp;gt;w_{k+1} = w_k - \alpha g_k&amp;lt;/math&amp;gt; представляет собой векторные операции (вычитание и скалярное умножение), которые также могут быть распараллелены по координатам вектора весов (&amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
====Параллельная сложность и высота ярусно-параллельной формы====&lt;br /&gt;
&lt;br /&gt;
Оценка параллельной сложности алгоритма (высота канонической ярусно-параллельной формы) дается в терминах числа операций умножения/деления и сложения (которые доминируют).&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; — размерность вектора весов, &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — размер мини-батча.&lt;br /&gt;
&lt;br /&gt;
Основной вычислительный шаг SGD состоит из трех этапов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+ Параллельная сложность одного шага Стохастического Градиентного Спуска (SGD)&lt;br /&gt;
|-&lt;br /&gt;
! Этап&lt;br /&gt;
! Параллельная сложность&amp;lt;br&amp;gt;(Высота ЯПФ, &#039;&#039;H&#039;&#039;)&lt;br /&gt;
! Ширина ЯПФ&amp;lt;br&amp;gt;(&#039;&#039;W&#039;&#039; - Сбалансированность)&lt;br /&gt;
! Описание Ресурса Параллелизма&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Вычисление градиентов&#039;&#039;&#039;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(\log_2 B + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(d \times B)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &#039;&#039;&#039;Массовый параллелизм&#039;&#039;&#039; (Координатный параллелизм) по примерам в мини-батче. Требуется редукция/суммирование.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Усреднение и масштабирование&#039;&#039;&#039;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(d)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &#039;&#039;&#039;Конечный параллелизм&#039;&#039;&#039; (Координатный параллелизм) по координатам вектора весов.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Обновление весов&#039;&#039;&#039;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(d)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &#039;&#039;&#039;Конечный параллелизм&#039;&#039;&#039; (Координатный параллелизм) по координатам вектора весов.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Таким образом, параллельная сложность (высота) одного шага SGD составляет &amp;lt;math&amp;gt;H = O(\log_2 B)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
====Сбалансированность параллельных шагов (ширина ярусов)====&lt;br /&gt;
&lt;br /&gt;
Ширина ярусов отражает сбалансированность параллельных шагов по числу операций:&lt;br /&gt;
&lt;br /&gt;
* Ширина этапа градиентов: на этапе вычисления градиентов ширина ярусов максимальна, достигает &amp;lt;math&amp;gt;W = O(d \times B)&amp;lt;/math&amp;gt;. Этот этап сбалансирован при &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; процессорах, где &amp;lt;math&amp;gt;P \le B&amp;lt;/math&amp;gt;, поскольку каждому процессу можно поручить обработку &amp;lt;math&amp;gt;\lceil B/P \rceil&amp;lt;/math&amp;gt; примеров.&lt;br /&gt;
* Ширина этапов обновления: на этапах усреднения и обновления весов ширина ярусов составляет &amp;lt;math&amp;gt;W = O(d)&amp;lt;/math&amp;gt;. Этот этап также сбалансирован, если &amp;lt;math&amp;gt;P \le d&amp;lt;/math&amp;gt;, поскольку операции могут быть распределены по &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; процессорам.&lt;br /&gt;
&lt;br /&gt;
Алгоритм SGD обладает хорошей сбалансированностью на каждом шаге, что позволяет эффективно использовать большое число процессоров (ядер), особенно когда произведение &amp;lt;math&amp;gt;d \times B&amp;lt;/math&amp;gt; велико.&lt;br /&gt;
&lt;br /&gt;
===Входные и выходные данные алгоритма===&lt;br /&gt;
====Входные данные====&lt;br /&gt;
&lt;br /&gt;
Обучающая выборка (&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;) обычно представляется в виде двух плотных структур данных:&lt;br /&gt;
&lt;br /&gt;
1. Матрица Признаков (&amp;lt;math&amp;gt;X\in\mathbb{R}^{N \times m}&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — общее число обучающих примеров, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; — число признаков.&lt;br /&gt;
&lt;br /&gt;
В задачах машинного обучения &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; часто значительно больше, чем &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; (много примеров, но относительно небольшое число признаков), или же &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; может быть очень большим (например, при использовании One-Hot-Encoding).&lt;br /&gt;
&lt;br /&gt;
В зависимости от задачи, матрица &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; может быть:&lt;br /&gt;
* плотной (dense): каждая ячейка содержит значащее числовое значение.&lt;br /&gt;
* разреженной (sparse): если большая часть элементов равна нулю.&lt;br /&gt;
&lt;br /&gt;
2. Вектор целевых значений (&amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;) - вектор размера &amp;lt;math&amp;gt;N \times 1&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;N \times C&amp;lt;/math&amp;gt; (для многоклассовой классификации, где &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — число классов).&lt;br /&gt;
&lt;br /&gt;
Обычно плотный, содержит действительные числа (для регрессии) или целочисленные метки/векторы (для классификации).&lt;br /&gt;
&lt;br /&gt;
3. Параметры обучения&lt;br /&gt;
&lt;br /&gt;
* Скорость обучения (&amp;lt;math&amp;gt;\alpha\in\mathbb{R}&amp;lt;/math&amp;gt;, learning rate): его значение обычно мало (например, &amp;lt;math&amp;gt;10^{-2}&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;10^{-3}&amp;lt;/math&amp;gt;) и оказывает критическое влияние на сходимость.&lt;br /&gt;
* Размер мини-батча (&amp;lt;math&amp;gt;B\in\mathbb{R}&amp;lt;/math&amp;gt;, batch size): определяет число примеров, используемых для одного шага. Обычно является степенью двойки (&amp;lt;math&amp;gt;32, 64, 128, \dots&amp;lt;/math&amp;gt;).&lt;br /&gt;
* Число эпох (&amp;lt;math&amp;gt;E\in\mathbb{N}&amp;lt;/math&amp;gt;, epochs): число полных проходов по всему набору данных.&lt;br /&gt;
&lt;br /&gt;
====Выходные Данные====&lt;br /&gt;
&lt;br /&gt;
* Вектор весов модели (&amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;): вектор размера &amp;lt;math&amp;gt;d \times 1&amp;lt;/math&amp;gt; (или матрица &amp;lt;math&amp;gt;d \times C&amp;lt;/math&amp;gt;, если модель содержит скрытые слои или многоклассовый вывод).&lt;br /&gt;
&lt;br /&gt;
Является плотной структурой данных. Диапазон значений зависит от функции потерь и регуляризации, но обычно это числа, близкие к нулю, или числа малого/среднего диапазона.&lt;br /&gt;
&lt;br /&gt;
* История потерь (loss history, опционально): вектор, содержащий значение функции потерь, вычисленное после каждого шага SGD. Объем равен &amp;lt;math&amp;gt;(E \times N) / B&amp;lt;/math&amp;gt;. Используется для анализа сходимости и отладки алгоритма.&lt;br /&gt;
&lt;br /&gt;
===Свойства алгоритма===&lt;br /&gt;
====Соотношение последовательной и параллельной сложности====&lt;br /&gt;
&lt;br /&gt;
Алгоритм SGD является последовательным по отношению к шагам обновления весов. Однако в рамках одного шага обновления (одного мини-батча) он обладает высоким ресурсом параллелизма.&lt;br /&gt;
&lt;br /&gt;
* Последовательная сложность одного шага SGD: &amp;lt;math&amp;gt;T_{seq} = O(B \cdot d)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; - размер батча, &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; - размерность весов.&lt;br /&gt;
* Параллельная сложность одного шага SGD (высота ЯПФ): &amp;lt;math&amp;gt;H = O(\log_2 B + 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теоретический выигрыш от параллельной реализации (ускорение) составляет:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S = \frac{T_{seq}}{H} = \frac{O(B \cdot d)}{O(\log_2 B + 1)}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теоретически, параллельная реализация обеспечивает значительное ускорение &amp;lt;math&amp;gt;O(B \cdot d)&amp;lt;/math&amp;gt;, которое растет линейно с размером батча и размерностью задачи, если есть достаточное количество процессоров &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Сложности параллелизации: главная сложность заключается в информационной зависимости между последовательными шагами обновления. Параллельная реализация дает выигрыш только внутри одного шага (градиент и обновление), но не может ускорить последовательность шагов, что является фундаментальным ограничением SGD.&lt;br /&gt;
====Вычислительная Мощность====&lt;br /&gt;
* Общее число операций (за одну эпоху): &amp;lt;math&amp;gt;O(N \cdot d)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — общее число объектов.&lt;br /&gt;
* Объем входных данных (матрица &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;): &amp;lt;math&amp;gt;O(N \cdot d)&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Объем выходных данных (вектор весов &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;): &amp;lt;math&amp;gt;O(d)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;W_{comp} = \frac{\text{Число операций}}{\text{Объем входных данных}} = \frac{O(N \cdot d)}{O(N \cdot d + d)}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
При больших &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;N \cdot d&amp;lt;/math&amp;gt; доминирует в знаменателе. Таким образом, вычислительная мощность SGD составляет:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;W_{comp} \approx O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность SGD близка к константе (&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;). Это означает, что число операций примерно равно объему исходных данных. Это значение относительно невысокое. Это свойство требует, чтобы алгоритм выполнялся &amp;quot;близко&amp;quot; к памяти с данными (например, на том же узле кластера), чтобы минимизировать накладные расходы на перемещение данных.&lt;br /&gt;
====Устойчивость Алгоритма====&lt;br /&gt;
&lt;br /&gt;
Алгоритм SGD является &#039;&#039;&#039;стохастическим и неустойчивым&#039;&#039;&#039; в смысле получения одного и того же результата при каждом запуске.&lt;br /&gt;
&lt;br /&gt;
* Неустойчивость к входным данным: поскольку SGD использует только часть данных (мини-батч) для каждого шага, дисперсия в оценке градиента высокая. Это приводит к флуктуациям в траектории сходимости.&lt;br /&gt;
* Ошибка округления: при использовании массового параллелизма (например, при суммировании градиентов от &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; примеров) на системах с массовым параллелизмом порядок выполнения ассоциативных операций (сложение) может меняться от запуска к запуску. Это приводит к неповторяемости результатов работы параллельных программ, что является серьезной проблемой на практике.&lt;br /&gt;
&lt;br /&gt;
====Сбалансированность вычислительного процесса====&lt;br /&gt;
&lt;br /&gt;
Алгоритм обладает хорошей сбалансированностью с точки зрения распределения нагрузки.&lt;br /&gt;
&lt;br /&gt;
На каждой итерации преобладают арифметические операции при вычислении градиента. Соотношение между арифметическими операциями и обращениями к памяти (чтение/запись) определяется параметром &amp;lt;math&amp;gt;B \cdot d&amp;lt;/math&amp;gt;, который обычно достаточно велик, что обеспечивает эффективную работу процессоров.&lt;br /&gt;
&lt;br /&gt;
Распределение нагрузки по &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; процессам на этапе вычисления градиента достигается просто: каждый процессор обрабатывает &amp;lt;math&amp;gt;\lceil B/P \rceil&amp;lt;/math&amp;gt; примеров. Это обеспечивает высокую балансировку нагрузки.&lt;br /&gt;
&lt;br /&gt;
====Детерминированность====&lt;br /&gt;
Алгоритм SGD является &#039;&#039;&#039;недетерминированным&#039;&#039;&#039; по следующим причинам:&lt;br /&gt;
&lt;br /&gt;
1. Порядок обработки мини-батчей: в классическом SGD набор мини-батчей на каждой эпохе случаен, что меняет структуру вычислительного процесса и итоговый результат.&lt;br /&gt;
2. Изменение порядка ассоциативных операций: как было описано выше, изменение порядка суммирования градиентов в параллельной среде приводит к непостоянству ошибок округления, что является причиной недетерминированности конечного результата в параллельной реализации.&lt;br /&gt;
&lt;br /&gt;
====Дополнительные свойства====&lt;br /&gt;
&lt;br /&gt;
* Степень исхода вершины: высока для вектора весов &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. На каждом шаге &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; используется для вычисления градиента для всех &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; примеров. На этапе реализации это требует эффективной рассылки вектора &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; всем параллельным процессам/потокам, работающим над батчем, и эффективного доступа к нему.&lt;br /&gt;
* &amp;quot;Длинные&amp;quot; дуги: возникают в информационном графе SGD при рассылке величин (таких как learning rate &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; или текущие веса &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;) по всем итерациям цикла мини-батчей. В случае вектора весов (&amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;), это рассылка всего вектора. Поскольку эта процедура хорошо изучена и оптимизирована на практике, она обычно не вызывает серьезных проблем с размещением данных в иерархии памяти, но требует эффективной коммуникации.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
&lt;br /&gt;
===Результаты прогонов===&lt;br /&gt;
&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
Yujing Ma, Florin Rusu, Martin Torres. Stochastic Gradient Descent on Highly-Parallel Architectures [Электронный ресурс] // arXiv:1802.08800 [math.ST]. – 2018. – Режим доступа: https://arxiv.org/abs/1802.08800&lt;br /&gt;
&lt;br /&gt;
Sebastian Ruder. An overview of gradient descent optimization algorithms [Электронный ресурс] // arXiv:1609.04747 [math.ST]. – 2016. – Режим доступа: https://arxiv.org/abs/1609.04747&lt;/div&gt;</summary>
		<author><name>OvsyannikovaSA</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=30294</id>
		<title>Участница:OvsyannikovaSA/Стохастический градиентный спуск</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=30294"/>
		<updated>2025-12-08T23:06:55Z</updated>

		<summary type="html">&lt;p&gt;OvsyannikovaSA: добавлено: свойства алгоритма&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Свойства и структура алгоритмов==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
&#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039; (Stochastic Gradient Descent, SGD) представляет собой один из базовых и наиболее распространённых алгоритмов оптимизации, применяемых для обучения моделей машинного обучения и нейронных сетей. Он относится к классу итерационных методов минимизации функций.&lt;br /&gt;
&lt;br /&gt;
===Математическое описание алгоритма===&lt;br /&gt;
&lt;br /&gt;
Пусть даны &amp;lt;math&amp;gt;\{x_i, y_i\}_{i=1}^N, x_i \in \mathbb{R}^m&amp;lt;/math&amp;gt; - вектор признаков &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го объекта, &amp;lt;math&amp;gt;y_i \in \mathbb{R}&amp;lt;/math&amp;gt; - значение целевой переменной; класс моделей &amp;lt;math&amp;gt;a_\omega: \mathbb{R}^m \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;; функция потерь &amp;lt;math&amp;gt;f: \mathbb{R}\times \mathbb{R} \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;. Задача: найти вектор параметров модели (весов) &amp;lt;math&amp;gt;\omega \in \mathbb{R}^d&amp;lt;/math&amp;gt;, т.ч. &amp;lt;math&amp;gt;\omega = argmin_{\omega\in \mathbb{R}^d}\;L(\omega),\;L(\omega)=\sum_{i=1}^N f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм &#039;&#039;&#039;классического градиентного спуска (batch gradient descent)&#039;&#039;&#039; можно сформулировать следующим образом:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Здесь и далее шаг обучения (learning rate) &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; является гиперпараметром, т.е. параметром, который не оптимизируется в ходе работы алгоритма и который необходимо выбрать заранее. Начальное приближение &amp;lt;math&amp;gt;\omega_0&amp;lt;/math&amp;gt; также необходимо выбрать заранее исходя из некоторых соображений.&lt;br /&gt;
Условие достижения сходимости на практике обычно заменяется повторением процедуры некоторое количество раз, после чего можно считать, что алгоритм сошелся в требуемом приближении.&lt;br /&gt;
В данном подходе для того, чтобы совершить одно обновление весов, необходимо вычислить функцию потерь для всех элементов выборки. Этот метод может оказаться неподходящим в некоторых случаях, например, при использовании больших датасетов, не помещающихся в памяти, или в случае, когда новые данные поступают в реальном времени.&lt;br /&gt;
&lt;br /&gt;
Модернизацией этого алгоритма является &#039;&#039;&#039;стохастический градиентный спуск (stochastic gradient descent)&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xi, yi)&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad f(ω; xi, yi);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Алгоритм отличается от предыдущего тем, что обновление весов происходит после обработки одного объекта выборки. Компромиссом между двумя этими подходами служит &#039;&#039;&#039;стохастический градиентный спуск на мини-батчах (mini-batch gradient descent)&#039;&#039;&#039;. Для него требуется выбрать размер батча (batch_size). Обозначим &amp;lt;math&amp;gt;L(\omega)=\sum_{i=1}^{batch\_size} f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск с мини-батчами&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α, размер батча batch_size&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xik, yik), 1&amp;lt;=k&amp;lt;=batch_size&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω; (xik, yik), 1&amp;lt;=k&amp;lt;=batch_size);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Преимущество алгоритма заключается в частом обновлении градиента и возможности использовать эффективные матричные вычисления.&lt;br /&gt;
В этой работе мы сосредоточимся на реализации градиентного спуска с мини-батчами.&lt;br /&gt;
&lt;br /&gt;
Необходимо некоторым способом определить условия, при которых будет считаться, что алгоритм сошелся. Будем считать, что сходимость достигается за &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; итераций обработки всей выборки (будем называть одну итерацию &#039;&#039;&#039;эпохой&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
В начале каждой эпохи будем случайно перемешивать выборку, а затем последовательно выбирать порции данных по &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов. Это обеспечит локальность расположения в памяти последовательно идущих мини-батчей и сохранит логику случайного выбора мини-батчей. Таким образом, процедура случайного выбора мини-батча заменяется на линейный проход по всем данным.&lt;br /&gt;
&lt;br /&gt;
===Вычислительное ядро алгоритма===&lt;br /&gt;
Основное время работы алгоритма приходится на вычисление градиента, которые повторяются, пока сходимость не будет достигнута.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Алгоритм стохастического градиентного спуска с мини-батчами представляется повторением следующих макроопераций:&lt;br /&gt;
&lt;br /&gt;
1. Инициализация параметров: задание начального приближения вектора параметров модели &amp;lt;math&amp;gt;w_0&amp;lt;/math&amp;gt;. Может быть случайной инициализацией, загрузкой предварительно обученной модели и т.п.&lt;br /&gt;
&lt;br /&gt;
  w ← ИнициализацияПараметров(описание_модели, стратегия_инициализации)&lt;br /&gt;
&lt;br /&gt;
2. Перемешивание обучающей выборки: получение случайной перестановки обучающей выборки в начале эпохи. Можно выполнять, например, алгоритмом Фишера-Йетса.&lt;br /&gt;
&lt;br /&gt;
Входные данные: &amp;lt;math&amp;gt;D=\{(x_i, y_i)\}_{i=1}^N&amp;lt;/math&amp;gt; - обучающая выборка.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: &amp;lt;math&amp;gt;D_{perm}&amp;lt;/math&amp;gt; - перемешанная выборка.&lt;br /&gt;
&lt;br /&gt;
  D_perm ← ПеремешиваниеОбучающейВыборки(D, генератор_случайных_чисел)&lt;br /&gt;
&lt;br /&gt;
3. Формирование мини-батчей: разбиение переставленной выборки на последовательность мини-батчей.&lt;br /&gt;
&lt;br /&gt;
Входные данные: &amp;lt;math&amp;gt;D_{perm}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выходные данные: последовательность подмножеств &amp;lt;math&amp;gt;B_k\subset D, \; k=1,..., K, \; \cup_k B_k=D, B_k \cap B_j = \emptyset, k\neq j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
  СписокБатчей ← ФормированиеМиниБатчей((X,y)_perm, размер_батча)&lt;br /&gt;
&lt;br /&gt;
4. Вычисление градиента на батче. Может включать вычисление значений модели на батче, матрично-векторные умножения, суммирование по объектам батча.&lt;br /&gt;
&lt;br /&gt;
Входные данные: текущие параметры &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;, мини-батч &amp;lt;math&amp;gt;B=\{(x_i, y_i)\}_{i\in I_B}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выходные данные: &amp;lt;math&amp;gt;g_B&amp;lt;/math&amp;gt; - градиент по параметрам на этом батче.&lt;br /&gt;
&lt;br /&gt;
  g_B ← ВычислениеГрадиентаНаБатче(w, B)&lt;br /&gt;
&lt;br /&gt;
5. Обновление параметров: осуществление одного шага метода по вычисленному градиенту на батче.&lt;br /&gt;
&lt;br /&gt;
Входные данные: текущие параметры &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;, градиент на батче &amp;lt;math&amp;gt;g_B&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: новые параметры &amp;lt;math&amp;gt;w_{new}=w-\alpha g_B&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
  w ← ОбновлениеПараметров(w, g_B, гиперпараметры_шага)&lt;br /&gt;
&lt;br /&gt;
6. Проверка критерия останова: проверка условий завершения итерационного процесса. Может быть проверкой номера эпохи, проверкой изменения функции потерь и т.п.&lt;br /&gt;
&lt;br /&gt;
  флаг_стоп ← ПроверкаКритерияОстановки(номер_эпохи, номер_шага, значение_критерия, история)&lt;br /&gt;
&lt;br /&gt;
На макроуровне алгоритм можно описать так:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:100%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Макроструктура алгоритма&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
w ← ИнициализацияПараметров(описание_модели, стратегия_инициализации)&lt;br /&gt;
номер_эпохи ← 0&lt;br /&gt;
повторять&lt;br /&gt;
  номер_эпохи ← номер_эпохи + 1&lt;br /&gt;
  D_perm ← ПеремешиваниеОбучающейВыборки(D, генератор_случайных_чисел)&lt;br /&gt;
  СписокБатчей ← ФормированиеМиниБатчей(D_perm, размер_батча)&lt;br /&gt;
  Для каждого B из СписокБатчей:&lt;br /&gt;
    g_B ← ВычислениеГрадиентаНаБатче(w, B)&lt;br /&gt;
    w ← ОбновлениеПараметров(w, g_B, гиперпараметры_шага)&lt;br /&gt;
  флаг_стоп ← ПроверкаКритерияОстановки(номер_эпохи, значение_критерия, история)&lt;br /&gt;
Пока флаг_стоп = ЛОЖЬ&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
[[Файл:Sequential SGD with mini-batches scheme.png|мини|Схема последовательной реализации стохастического градиентного спуска с мини-батчами]]&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; - размер выборки,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - размер батча (&amp;lt;math&amp;gt;batch\_size&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - сложность вычисления производной функции потерь на одном примере,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - число эпох.&lt;br /&gt;
&lt;br /&gt;
Как уже упоминалось, будем перемешивать выборку случайным образом в начале каждой эпохи. Сложность случайного перемешивания выборки объема &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; алгоритмом Фишера-Йетса - &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. Если отказаться от этого предположения, можно считать, что сложность выбора &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; случайных элементов - &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. Такая оценка будет верна, если в системе реализован произвольный доступ к памяти. Однако для больших выборок, не помещающихся целиком в памяти, произвольный доступ к элементам выборки не будет возможен.&lt;br /&gt;
&lt;br /&gt;
Сложность обработки одного батча - &amp;lt;math&amp;gt;O(n \cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что количество батчей &amp;lt;math&amp;gt;N/n&amp;lt;/math&amp;gt; - целое число; тогда сложность вычисления градиентов в течение одной эпохи - &amp;lt;math&amp;gt;O(N/n \cdot n \cdot C) = O(N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность одной эпохи с учетом перемешивания выборки - &amp;lt;math&amp;gt;O(N)+O(N\cdot C)=O(N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность всего алгоритма с &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; эпохами - &amp;lt;math&amp;gt;O(E\cdot N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
На схеме изображен информационный граф стохастического градиентного спуска с мини-батчами.&lt;br /&gt;
&lt;br /&gt;
[[file:Informational_graph_minibatch_SGD.png|thumb|center|Информационный граф стохастического градиентного спуска с мини-батчами]]&lt;br /&gt;
Здесь приводится схема выполнения одной эпохи. Стрелки, изображающие обработку остальных объектов данного батча, опущены для улучшения читаемости схемы. После обработки одного батча с весами &amp;lt;math&amp;gt;w_i&amp;lt;/math&amp;gt; производится шаг градиентного спуска, и следующий батч обрабатывается уже с весами &amp;lt;math&amp;gt;w_{i+1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Ресурс параллелизма алгоритма===&lt;br /&gt;
Ресурс параллелизма алгоритма стохастического градиентного спуска (SGD) определяется зависимостями данных между его основными шагами: вычислением градиента и обновлением весов.&lt;br /&gt;
&lt;br /&gt;
====Иерархическая Структура Параллелизма====&lt;br /&gt;
&lt;br /&gt;
Параллелизм в SGD имеет &#039;&#039;&#039;двухуровневую (иерархическую)&#039;&#039;&#039; структуру, которая напрямую связана с циклическим профилем последовательной реализации.&lt;br /&gt;
&lt;br /&gt;
1. Внешний уровень: конечный параллелизм&lt;br /&gt;
&lt;br /&gt;
Внешний уровень параллелизма определяется последовательностью итераций по эпохам и по батчам:&lt;br /&gt;
* цикл по эпохам: итерации по эпохам зависимы, поскольку веса, полученные на одной эпохе, используются на следующей. Этот цикл не имеет параллельного ресурса.&lt;br /&gt;
* цикл по батчам (мини-батчам): обновления весов на основе последовательных мини-батчей информационно зависимы. Обновление &amp;lt;math&amp;gt;w_{k+1}&amp;lt;/math&amp;gt; зависит от &amp;lt;math&amp;gt;w_k&amp;lt;/math&amp;gt; и градиента &amp;lt;math&amp;gt;g_k&amp;lt;/math&amp;gt;. Это создает ресурс конечного параллелизма, то есть высокая параллельность внутри каждого шага, но последовательность между шагами.&lt;br /&gt;
&lt;br /&gt;
2. Внутренний уровень: массовый параллелизм&lt;br /&gt;
&lt;br /&gt;
Внутренний уровень связан с обработкой данных внутри одного шага SGD (одного мини-батча).&lt;br /&gt;
&lt;br /&gt;
Это ресурс массового параллелизма, который может быть реализован двумя способами:&lt;br /&gt;
&lt;br /&gt;
* Вычисление градиента: вычисление частных градиентов для каждого примера (&amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt;) в мини-батче полностью независимо: &amp;lt;math&amp;gt;\frac{1}{|B|} \sum_{x_i \in B} \nabla Q_i(W)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот этап демонстрирует координатный параллелизм (независимость итераций цикла по примерам в батче).&lt;br /&gt;
* Обновление весов: операция &amp;lt;math&amp;gt;w_{k+1} = w_k - \eta g_k&amp;lt;/math&amp;gt; представляет собой векторные операции (вычитание и скалярное умножение), которые также могут быть распараллелены по координатам вектора весов ($w$).&lt;br /&gt;
&lt;br /&gt;
====Параллельная Сложность и Высота Ярусно-Параллельной Формы====&lt;br /&gt;
&lt;br /&gt;
Оценка параллельной сложности алгоритма (высота канонической ярусно-параллельной формы) дается в терминах числа операций умножения/деления и сложения (которые доминируют).&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; — размерность вектора весов (число признаков), &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — размер мини-батча.&lt;br /&gt;
&lt;br /&gt;
Основной вычислительный шаг SGD состоит из трех этапов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+ Параллельная сложность одного шага Стохастического Градиентного Спуска (SGD)&lt;br /&gt;
|-&lt;br /&gt;
! Этап&lt;br /&gt;
! Параллельная сложность&amp;lt;br&amp;gt;(Высота ЯПФ, &#039;&#039;H&#039;&#039;)&lt;br /&gt;
! Ширина ЯПФ&amp;lt;br&amp;gt;(&#039;&#039;W&#039;&#039; - Сбалансированность)&lt;br /&gt;
! Описание Ресурса Параллелизма&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Вычисление градиентов&#039;&#039;&#039;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(\log_2 B + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(m \times B)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &#039;&#039;&#039;Массовый параллелизм&#039;&#039;&#039; (Координатный параллелизм) по примерам в мини-батче. Требуется редукция/суммирование.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Усреднение и масштабирование&#039;&#039;&#039;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(m)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &#039;&#039;&#039;Конечный параллелизм&#039;&#039;&#039; (Координатный параллелизм) по координатам вектора весов.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Обновление весов&#039;&#039;&#039;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(m)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &#039;&#039;&#039;Конечный параллелизм&#039;&#039;&#039; (Координатный параллелизм) по координатам вектора весов.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Таким образом, параллельная сложность (высота) одного шага SGD составляет &amp;lt;math&amp;gt;H = O(\log_2 B)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
====Сбалансированность параллельных шагов (ширина ярусов)====&lt;br /&gt;
&lt;br /&gt;
Ширина ярусов отражает сбалансированность параллельных шагов по числу операций:&lt;br /&gt;
&lt;br /&gt;
* Ширина этапа градиентов: на этапе вычисления градиентов ширина ярусов максимальна, достигая &amp;lt;math&amp;gt;W = O(m \times B)&amp;lt;/math&amp;gt;. Этот этап сбалансирован при &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; процессорах, где &amp;lt;math&amp;gt;P \le B&amp;lt;/math&amp;gt;, поскольку каждому процессу можно поручить обработку &amp;lt;math&amp;gt;\lceil B/P \rceil&amp;lt;/math&amp;gt; примеров.&lt;br /&gt;
* Ширина этапов обновления: на этапах усреднения и обновления весов ширина ярусов составляет &amp;lt;math&amp;gt;W = O(m)&amp;lt;/math&amp;gt;. Этот этап также сбалансирован, если &amp;lt;math&amp;gt;P \le m&amp;lt;/math&amp;gt;, поскольку операции могут быть распределены по &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; процессорам.&lt;br /&gt;
&lt;br /&gt;
Алгоритм SGD обладает хорошей сбалансированностью на каждом шаге, что позволяет эффективно использовать большое число процессоров (ядер), особенно когда произведение &amp;lt;math&amp;gt;m \times B&amp;lt;/math&amp;gt; велико.&lt;br /&gt;
&lt;br /&gt;
===Входные и выходные данные алгоритма===&lt;br /&gt;
====Входные данные====&lt;br /&gt;
&lt;br /&gt;
Обучающая выборка (&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;) обычно представляется в виде двух плотных структур данных:&lt;br /&gt;
&lt;br /&gt;
1. Матрица Признаков (&amp;lt;math&amp;gt;X\in\mathbb{R}^{N \times m}&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — общее число обучающих примеров, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; — число признаков (размерность векторов весов).&lt;br /&gt;
&lt;br /&gt;
В задачах машинного обучения &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; часто значительно больше, чем &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; (много примеров, но относительно небольшое число признаков), или же &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; может быть очень большим (например, при использовании One-Hot-Encoding).&lt;br /&gt;
&lt;br /&gt;
В зависимости от задачи, матрица &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; может быть:&lt;br /&gt;
* плотной (dense): каждая ячейка содержит значащее числовое значение.&lt;br /&gt;
* разреженной (sparse): если большая часть элементов равна нулю.&lt;br /&gt;
&lt;br /&gt;
2. Вектор целевых значений (&amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;) - вектор размера &amp;lt;math&amp;gt;N \times 1&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;N \times C&amp;lt;/math&amp;gt; (для многоклассовой классификации, где &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — число классов).&lt;br /&gt;
&lt;br /&gt;
Обычно плотный, содержит действительные числа (для регрессии) или целочисленные метки/векторы (для классификации).&lt;br /&gt;
&lt;br /&gt;
3. Параметры обучения&lt;br /&gt;
&lt;br /&gt;
* Скорость обучения (&amp;lt;math&amp;gt;\alpha\in\mathbb{R}&amp;lt;/math&amp;gt;, learning rate): его значение обычно мало (например, &amp;lt;math&amp;gt;10^{-2}&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;10^{-3}&amp;lt;/math&amp;gt;) и оказывает критическое влияние на сходимость.&lt;br /&gt;
* Размер мини-батча (&amp;lt;math&amp;gt;B\in\mathbb{R}&amp;lt;/math&amp;gt;, batch size): определяет число примеров, используемых для одного шага. Обычно является степенью двойки (&amp;lt;math&amp;gt;32, 64, 128, \dots&amp;lt;/math&amp;gt;).&lt;br /&gt;
* Число эпох (&amp;lt;math&amp;gt;E\in\mathbb{N}&amp;lt;/math&amp;gt;, epochs): число полных проходов по всему набору данных.&lt;br /&gt;
&lt;br /&gt;
====Выходные Данные====&lt;br /&gt;
&lt;br /&gt;
* Вектор весов модели (&amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;): вектор размера &amp;lt;math&amp;gt;m \times 1&amp;lt;/math&amp;gt; (или матрица &amp;lt;math&amp;gt;m \times C&amp;lt;/math&amp;gt;, если модель содержит скрытые слои или многоклассовый вывод).&lt;br /&gt;
&lt;br /&gt;
Является плотной структурой данных. Диапазон значений зависит от функции потерь и регуляризации, но обычно это числа, близкие к нулю, или числа малого/среднего диапазона.&lt;br /&gt;
&lt;br /&gt;
* История потерь (loss history, опционально): вектор, содержащий значение функции потерь, вычисленное после каждого шага SGD. Объем равен &amp;lt;math&amp;gt;(E \times N) / B&amp;lt;/math&amp;gt;. Используется для анализа сходимости и отладки алгоритма.&lt;br /&gt;
&lt;br /&gt;
===Свойства алгоритма===&lt;br /&gt;
====Соотношение последовательной и параллельной сложности====&lt;br /&gt;
&lt;br /&gt;
Алгоритм SGD является последовательным по отношению к шагам обновления весов. Однако в рамках одного шага обновления (одного мини-батча) он обладает высоким ресурсом параллелизма.&lt;br /&gt;
&lt;br /&gt;
* Последовательная сложность одного шага SGD: &amp;lt;math&amp;gt;T_{seq} = O(B \cdot d)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; - размер батча, &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; - размерность весов.&lt;br /&gt;
* Параллельная сложность одного шага SGD (высота ЯПФ): &amp;lt;math&amp;gt;H = O(\log_2 B + 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теоретический выигрыш от параллельной реализации (ускорение) составляет:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S = \frac{T_{seq}}{H} = \frac{O(B \cdot d)}{O(\log_2 B + 1)}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теоретически, параллельная реализация обеспечивает значительное ускорение &amp;lt;math&amp;gt;O(B \cdot d)&amp;lt;/math&amp;gt;, которое растет линейно с размером батча и размерностью задачи, если есть достаточное количество процессоров &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Сложности параллелизации: главная сложность заключается в информационной зависимости между последовательными шагами обновления. Параллельная реализация дает выигрыш только внутри одного шага (градиент и обновление), но не может ускорить последовательность шагов, что является фундаментальным ограничением SGD.&lt;br /&gt;
====Вычислительная Мощность====&lt;br /&gt;
* Общее число операций (за одну эпоху): &amp;lt;math&amp;gt;O(N \cdot d)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — общее число объектов.&lt;br /&gt;
* Объем входных данных (матрица &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;): &amp;lt;math&amp;gt;O(N \cdot d)&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Объем выходных данных (вектор весов &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;): &amp;lt;math&amp;gt;O(d)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;W_{comp} = \frac{\text{Число операций}}{\text{Объем входных данных}} = \frac{O(N \cdot d)}{O(N \cdot d + d)}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
При больших &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;N \cdot d&amp;lt;/math&amp;gt; доминирует в знаменателе. Таким образом, вычислительная мощность SGD составляет:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;W_{comp} \approx O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность SGD близка к константе (&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;). Это означает, что число операций примерно равно объему исходных данных. Это значение относительно невысокое. Это свойство требует, чтобы алгоритм выполнялся &amp;quot;близко&amp;quot; к памяти с данными (например, на том же узле кластера), чтобы минимизировать накладные расходы на перемещение данных.&lt;br /&gt;
====Устойчивость Алгоритма====&lt;br /&gt;
&lt;br /&gt;
Алгоритм SGD является &#039;&#039;&#039;стохастическим и неустойчивым&#039;&#039;&#039; в смысле получения одного и того же результата при каждом запуске.&lt;br /&gt;
&lt;br /&gt;
* Неустойчивость к входным данным: поскольку SGD использует только часть данных (мини-батч) для каждого шага, дисперсия в оценке градиента высокая. Это приводит к флуктуациям в траектории сходимости.&lt;br /&gt;
* Ошибка округления: при использовании массового параллелизма (например, при суммировании градиентов от &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; примеров) на системах с массовым параллелизмом порядок выполнения ассоциативных операций (сложение) может меняться от запуска к запуску. Это приводит к неповторяемости результатов работы параллельных программ, что является серьезной проблемой на практике.&lt;br /&gt;
&lt;br /&gt;
====Сбалансированность вычислительного процесса====&lt;br /&gt;
&lt;br /&gt;
Алгоритм обладает хорошей сбалансированностью с точки зрения распределения нагрузки.&lt;br /&gt;
&lt;br /&gt;
На каждой итерации преобладают арифметические операции (умножение и сложение) при вычислении градиента. Соотношение между арифметическими операциями и обращениями к памяти (чтение/запись) определяется параметром &amp;lt;math&amp;gt;B \cdot d&amp;lt;/math&amp;gt;, который обычно достаточно велик, что обеспечивает эффективную работу процессоров.&lt;br /&gt;
&lt;br /&gt;
Распределение нагрузки по &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; процессам на этапе вычисления градиента достигается просто: каждый процессор обрабатывает &amp;lt;math&amp;gt;\lceil B/P \rceil&amp;lt;/math&amp;gt; примеров. Это обеспечивает высокую балансировку нагрузки.&lt;br /&gt;
&lt;br /&gt;
====Детерминированность====&lt;br /&gt;
Алгоритм SGD является недетерминированным по следующим причинам:&lt;br /&gt;
&lt;br /&gt;
1. Порядок обработки мини-батчей: в классическом SGD набор мини-батчей на каждой эпохе случаен, что меняет структуру вычислительного процесса и итоговый результат.&lt;br /&gt;
2. Изменение порядка ассоциативных операций: как было описано выше, изменение порядка суммирования градиентов в параллельной среде приводит к непостоянству ошибок округления, что является причиной недетерминированности конечного результата в параллельной реализации.&lt;br /&gt;
&lt;br /&gt;
====Дополнительные свойства====&lt;br /&gt;
&lt;br /&gt;
* Степень исхода вершины: высока для вектора весов &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. На каждом шаге &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; используется для вычисления градиента для всех &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; примеров. На этапе реализации это требует эффективной рассылки вектора &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; всем параллельным процессам/потокам, работающим над батчем, и эффективного доступа к нему.&lt;br /&gt;
* &amp;quot;Длинные&amp;quot; дуги: типичные &amp;quot;длинные&amp;quot; дуги в информационном графе SGD возникают при рассылке скалярных величин (таких как learning rate &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; или текущие веса &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;) по всем итерациям цикла мини-батчей. В случае вектора весов (&amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;), это рассылка всего вектора. Поскольку этот паттерн (рассылка) хорошо изучен и оптимизирован на практике, он обычно не вызывает серьезных проблем с размещением данных в иерархии памяти, но требует эффективной коммуникации.&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
Yujing Ma, Florin Rusu, Martin Torres. Stochastic Gradient Descent on Highly-Parallel Architectures [Электронный ресурс] // arXiv:1802.08800 [math.ST]. – 2018. – Режим доступа: https://arxiv.org/abs/1802.08800&lt;br /&gt;
&lt;br /&gt;
Sebastian Ruder. An overview of gradient descent optimization algorithms [Электронный ресурс] // arXiv:1609.04747 [math.ST]. – 2016. – Режим доступа: https://arxiv.org/abs/1609.04747&lt;/div&gt;</summary>
		<author><name>OvsyannikovaSA</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=30292</id>
		<title>Участница:OvsyannikovaSA/Стохастический градиентный спуск</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=30292"/>
		<updated>2025-12-08T22:05:39Z</updated>

		<summary type="html">&lt;p&gt;OvsyannikovaSA: добавлено: ресурс параллелизма алгоритма, входные и выходные данные алгоритма&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Свойства и структура алгоритмов==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
&#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039; (Stochastic Gradient Descent, SGD) представляет собой один из базовых и наиболее распространённых алгоритмов оптимизации, применяемых для обучения моделей машинного обучения и нейронных сетей. Он относится к классу итерационных методов минимизации функций.&lt;br /&gt;
&lt;br /&gt;
===Математическое описание алгоритма===&lt;br /&gt;
&lt;br /&gt;
Пусть даны &amp;lt;math&amp;gt;\{x_i, y_i\}_{i=1}^N, x_i \in \mathbb{R}^m&amp;lt;/math&amp;gt; - вектор признаков &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го объекта, &amp;lt;math&amp;gt;y_i \in \mathbb{R}&amp;lt;/math&amp;gt; - значение целевой переменной; класс моделей &amp;lt;math&amp;gt;a_\omega: \mathbb{R}^m \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;; функция потерь &amp;lt;math&amp;gt;f: \mathbb{R}\times \mathbb{R} \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;. Задача: найти вектор параметров модели (весов) &amp;lt;math&amp;gt;\omega \in \mathbb{R}^d&amp;lt;/math&amp;gt;, т.ч. &amp;lt;math&amp;gt;\omega = argmin_{\omega\in \mathbb{R}^d}\;L(\omega),\;L(\omega)=\sum_{i=1}^N f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм &#039;&#039;&#039;классического градиентного спуска (batch gradient descent)&#039;&#039;&#039; можно сформулировать следующим образом:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Здесь и далее шаг обучения (learning rate) &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; является гиперпараметром, т.е. параметром, который не оптимизируется в ходе работы алгоритма и который необходимо выбрать заранее. Начальное приближение &amp;lt;math&amp;gt;\omega_0&amp;lt;/math&amp;gt; также необходимо выбрать заранее исходя из некоторых соображений.&lt;br /&gt;
Условие достижения сходимости на практике обычно заменяется повторением процедуры некоторое количество раз, после чего можно считать, что алгоритм сошелся в требуемом приближении.&lt;br /&gt;
В данном подходе для того, чтобы совершить одно обновление весов, необходимо вычислить функцию потерь для всех элементов выборки. Этот метод может оказаться неподходящим в некоторых случаях, например, при использовании больших датасетов, не помещающихся в памяти, или в случае, когда новые данные поступают в реальном времени.&lt;br /&gt;
&lt;br /&gt;
Модернизацией этого алгоритма является &#039;&#039;&#039;стохастический градиентный спуск (stochastic gradient descent)&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xi, yi)&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad f(ω; xi, yi);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Алгоритм отличается от предыдущего тем, что обновление весов происходит после обработки одного объекта выборки. Компромиссом между двумя этими подходами служит &#039;&#039;&#039;стохастический градиентный спуск на мини-батчах (mini-batch gradient descent)&#039;&#039;&#039;. Для него требуется выбрать размер батча (batch_size). Обозначим &amp;lt;math&amp;gt;L(\omega)=\sum_{i=1}^{batch\_size} f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск с мини-батчами&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α, размер батча batch_size&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xik, yik), 1&amp;lt;=k&amp;lt;=batch_size&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω; (xik, yik), 1&amp;lt;=k&amp;lt;=batch_size);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Преимущество алгоритма заключается в частом обновлении градиента и возможности использовать эффективные матричные вычисления.&lt;br /&gt;
В этой работе мы сосредоточимся на реализации градиентного спуска с мини-батчами.&lt;br /&gt;
&lt;br /&gt;
Необходимо некоторым способом определить условия, при которых будет считаться, что алгоритм сошелся. Будем считать, что сходимость достигается за &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; итераций обработки всей выборки (будем называть одну итерацию &#039;&#039;&#039;эпохой&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
В начале каждой эпохи будем случайно перемешивать выборку, а затем последовательно выбирать порции данных по &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов. Это обеспечит локальность расположения в памяти последовательно идущих мини-батчей и сохранит логику случайного выбора мини-батчей. Таким образом, процедура случайного выбора мини-батча заменяется на линейный проход по всем данным.&lt;br /&gt;
&lt;br /&gt;
===Вычислительное ядро алгоритма===&lt;br /&gt;
Основное время работы алгоритма приходится на вычисление градиента, которые повторяются, пока сходимость не будет достигнута.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Алгоритм стохастического градиентного спуска с мини-батчами представляется повторением следующих макроопераций:&lt;br /&gt;
&lt;br /&gt;
1. Инициализация параметров: задание начального приближения вектора параметров модели &amp;lt;math&amp;gt;w_0&amp;lt;/math&amp;gt;. Может быть случайной инициализацией, загрузкой предварительно обученной модели и т.п.&lt;br /&gt;
&lt;br /&gt;
  w ← ИнициализацияПараметров(описание_модели, стратегия_инициализации)&lt;br /&gt;
&lt;br /&gt;
2. Перемешивание обучающей выборки: получение случайной перестановки обучающей выборки в начале эпохи. Можно выполнять, например, алгоритмом Фишера-Йетса.&lt;br /&gt;
&lt;br /&gt;
Входные данные: &amp;lt;math&amp;gt;D=\{(x_i, y_i)\}_{i=1}^N&amp;lt;/math&amp;gt; - обучающая выборка.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: &amp;lt;math&amp;gt;D_{perm}&amp;lt;/math&amp;gt; - перемешанная выборка.&lt;br /&gt;
&lt;br /&gt;
  D_perm ← ПеремешиваниеОбучающейВыборки(D, генератор_случайных_чисел)&lt;br /&gt;
&lt;br /&gt;
3. Формирование мини-батчей: разбиение переставленной выборки на последовательность мини-батчей.&lt;br /&gt;
&lt;br /&gt;
Входные данные: &amp;lt;math&amp;gt;D_{perm}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выходные данные: последовательность подмножеств &amp;lt;math&amp;gt;B_k\subset D, \; k=1,..., K, \; \cup_k B_k=D, B_k \cap B_j = \emptyset, k\neq j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
  СписокБатчей ← ФормированиеМиниБатчей((X,y)_perm, размер_батча)&lt;br /&gt;
&lt;br /&gt;
4. Вычисление градиента на батче. Может включать вычисление значений модели на батче, матрично-векторные умножения, суммирование по объектам батча.&lt;br /&gt;
&lt;br /&gt;
Входные данные: текущие параметры &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;, мини-батч &amp;lt;math&amp;gt;B=\{(x_i, y_i)\}_{i\in I_B}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выходные данные: &amp;lt;math&amp;gt;g_B&amp;lt;/math&amp;gt; - градиент по параметрам на этом батче.&lt;br /&gt;
&lt;br /&gt;
  g_B ← ВычислениеГрадиентаНаБатче(w, B)&lt;br /&gt;
&lt;br /&gt;
5. Обновление параметров: осуществление одного шага метода по вычисленному градиенту на батче.&lt;br /&gt;
&lt;br /&gt;
Входные данные: текущие параметры &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;, градиент на батче &amp;lt;math&amp;gt;g_B&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: новые параметры &amp;lt;math&amp;gt;w_{new}=w-\alpha g_B&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
  w ← ОбновлениеПараметров(w, g_B, гиперпараметры_шага)&lt;br /&gt;
&lt;br /&gt;
6. Проверка критерия останова: проверка условий завершения итерационного процесса. Может быть проверкой номера эпохи, проверкой изменения функции потерь и т.п.&lt;br /&gt;
&lt;br /&gt;
  флаг_стоп ← ПроверкаКритерияОстановки(номер_эпохи, номер_шага, значение_критерия, история)&lt;br /&gt;
&lt;br /&gt;
На макроуровне алгоритм можно описать так:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:100%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Макроструктура алгоритма&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
w ← ИнициализацияПараметров(описание_модели, стратегия_инициализации)&lt;br /&gt;
номер_эпохи ← 0&lt;br /&gt;
повторять&lt;br /&gt;
  номер_эпохи ← номер_эпохи + 1&lt;br /&gt;
  D_perm ← ПеремешиваниеОбучающейВыборки(D, генератор_случайных_чисел)&lt;br /&gt;
  СписокБатчей ← ФормированиеМиниБатчей(D_perm, размер_батча)&lt;br /&gt;
  Для каждого B из СписокБатчей:&lt;br /&gt;
    g_B ← ВычислениеГрадиентаНаБатче(w, B)&lt;br /&gt;
    w ← ОбновлениеПараметров(w, g_B, гиперпараметры_шага)&lt;br /&gt;
  флаг_стоп ← ПроверкаКритерияОстановки(номер_эпохи, значение_критерия, история)&lt;br /&gt;
Пока флаг_стоп = ЛОЖЬ&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
[[Файл:Sequential SGD with mini-batches scheme.png|мини|Схема последовательной реализации стохастического градиентного спуска с мини-батчами]]&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; - размер выборки,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - размер батча (&amp;lt;math&amp;gt;batch\_size&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - сложность вычисления производной функции потерь на одном примере,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - число эпох.&lt;br /&gt;
&lt;br /&gt;
Как уже упоминалось, будем перемешивать выборку случайным образом в начале каждой эпохи. Сложность случайного перемешивания выборки объема &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; алгоритмом Фишера-Йетса - &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. Если отказаться от этого предположения, можно считать, что сложность выбора &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; случайных элементов - &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. Такая оценка будет верна, если в системе реализован произвольный доступ к памяти. Однако для больших выборок, не помещающихся целиком в памяти, произвольный доступ к элементам выборки не будет возможен.&lt;br /&gt;
&lt;br /&gt;
Сложность обработки одного батча - &amp;lt;math&amp;gt;O(n \cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что количество батчей &amp;lt;math&amp;gt;N/n&amp;lt;/math&amp;gt; - целое число; тогда сложность вычисления градиентов в течение одной эпохи - &amp;lt;math&amp;gt;O(N/n \cdot n \cdot C) = O(N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность одной эпохи с учетом перемешивания выборки - &amp;lt;math&amp;gt;O(N)+O(N\cdot C)=O(N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность всего алгоритма с &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; эпохами - &amp;lt;math&amp;gt;O(E\cdot N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
На схеме изображен информационный граф стохастического градиентного спуска с мини-батчами.&lt;br /&gt;
&lt;br /&gt;
[[file:Informational_graph_minibatch_SGD.png|thumb|center|Информационный граф стохастического градиентного спуска с мини-батчами]]&lt;br /&gt;
Здесь приводится схема выполнения одной эпохи. Стрелки, изображающие обработку остальных объектов данного батча, опущены для улучшения читаемости схемы. После обработки одного батча с весами &amp;lt;math&amp;gt;w_i&amp;lt;/math&amp;gt; производится шаг градиентного спуска, и следующий батч обрабатывается уже с весами &amp;lt;math&amp;gt;w_{i+1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Ресурс параллелизма алгоритма===&lt;br /&gt;
Ресурс параллелизма алгоритма стохастического градиентного спуска (SGD) определяется зависимостями данных между его основными шагами: вычислением градиента и обновлением весов.&lt;br /&gt;
&lt;br /&gt;
====Иерархическая Структура Параллелизма====&lt;br /&gt;
&lt;br /&gt;
Параллелизм в SGD имеет &#039;&#039;&#039;двухуровневую (иерархическую)&#039;&#039;&#039; структуру, которая напрямую связана с циклическим профилем последовательной реализации.&lt;br /&gt;
&lt;br /&gt;
1. Внешний уровень: конечный параллелизм&lt;br /&gt;
&lt;br /&gt;
Внешний уровень параллелизма определяется последовательностью итераций по эпохам и по батчам:&lt;br /&gt;
* цикл по эпохам: итерации по эпохам зависимы, поскольку веса, полученные на одной эпохе, используются на следующей. Этот цикл не имеет параллельного ресурса.&lt;br /&gt;
* цикл по батчам (мини-батчам): обновления весов на основе последовательных мини-батчей информационно зависимы. Обновление &amp;lt;math&amp;gt;w_{k+1}&amp;lt;/math&amp;gt; зависит от &amp;lt;math&amp;gt;w_k&amp;lt;/math&amp;gt; и градиента &amp;lt;math&amp;gt;g_k&amp;lt;/math&amp;gt;. Это создает ресурс конечного параллелизма, то есть высокая параллельность внутри каждого шага, но последовательность между шагами.&lt;br /&gt;
&lt;br /&gt;
2. Внутренний уровень: массовый параллелизм&lt;br /&gt;
&lt;br /&gt;
Внутренний уровень связан с обработкой данных внутри одного шага SGD (одного мини-батча).&lt;br /&gt;
&lt;br /&gt;
Это ресурс массового параллелизма, который может быть реализован двумя способами:&lt;br /&gt;
&lt;br /&gt;
* Вычисление градиента: вычисление частных градиентов для каждого примера (&amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt;) в мини-батче полностью независимо: &amp;lt;math&amp;gt;\frac{1}{|B|} \sum_{x_i \in B} \nabla Q_i(W)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Этот этап демонстрирует координатный параллелизм (независимость итераций цикла по примерам в батче).&lt;br /&gt;
* Обновление весов: операция &amp;lt;math&amp;gt;w_{k+1} = w_k - \eta g_k&amp;lt;/math&amp;gt; представляет собой векторные операции (вычитание и скалярное умножение), которые также могут быть распараллелены по координатам вектора весов ($w$).&lt;br /&gt;
&lt;br /&gt;
====Параллельная Сложность и Высота Ярусно-Параллельной Формы====&lt;br /&gt;
&lt;br /&gt;
Оценка параллельной сложности алгоритма (высота канонической ярусно-параллельной формы) дается в терминах числа операций умножения/деления и сложения (которые доминируют).&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; — размерность вектора весов (число признаков), &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; — размер мини-батча.&lt;br /&gt;
&lt;br /&gt;
Основной вычислительный шаг SGD состоит из трех этапов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+ Параллельная сложность одного шага Стохастического Градиентного Спуска (SGD)&lt;br /&gt;
|-&lt;br /&gt;
! Этап&lt;br /&gt;
! Параллельная сложность&amp;lt;br&amp;gt;(Высота ЯПФ, &#039;&#039;H&#039;&#039;)&lt;br /&gt;
! Ширина ЯПФ&amp;lt;br&amp;gt;(&#039;&#039;W&#039;&#039; - Сбалансированность)&lt;br /&gt;
! Описание Ресурса Параллелизма&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Вычисление градиентов&#039;&#039;&#039;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(\log_2 B + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(m \times B)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &#039;&#039;&#039;Массовый параллелизм&#039;&#039;&#039; (Координатный параллелизм) по примерам в мини-батче. Требуется редукция/суммирование.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Усреднение и масштабирование&#039;&#039;&#039;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(m)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &#039;&#039;&#039;Конечный параллелизм&#039;&#039;&#039; (Координатный параллелизм) по координатам вектора весов.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Обновление весов&#039;&#039;&#039;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;O(m)&amp;lt;/math&amp;gt;&lt;br /&gt;
| &#039;&#039;&#039;Конечный параллелизм&#039;&#039;&#039; (Координатный параллелизм) по координатам вектора весов.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Таким образом, параллельная сложность (высота) одного шага SGD составляет &amp;lt;math&amp;gt;H = O(\log_2 B)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
====Сбалансированность параллельных шагов (ширина ярусов)====&lt;br /&gt;
&lt;br /&gt;
Ширина ярусов отражает сбалансированность параллельных шагов по числу операций:&lt;br /&gt;
&lt;br /&gt;
* Ширина этапа градиентов: на этапе вычисления градиентов ширина ярусов максимальна, достигая &amp;lt;math&amp;gt;W = O(m \times B)&amp;lt;/math&amp;gt;. Этот этап сбалансирован при &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; процессорах, где &amp;lt;math&amp;gt;P \le B&amp;lt;/math&amp;gt;, поскольку каждому процессу можно поручить обработку &amp;lt;math&amp;gt;\lceil B/P \rceil&amp;lt;/math&amp;gt; примеров.&lt;br /&gt;
* Ширина этапов обновления: на этапах усреднения и обновления весов ширина ярусов составляет &amp;lt;math&amp;gt;W = O(m)&amp;lt;/math&amp;gt;. Этот этап также сбалансирован, если &amp;lt;math&amp;gt;P \le m&amp;lt;/math&amp;gt;, поскольку операции могут быть распределены по &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; процессорам.&lt;br /&gt;
&lt;br /&gt;
Алгоритм SGD обладает хорошей сбалансированностью на каждом шаге, что позволяет эффективно использовать большое число процессоров (ядер), особенно когда произведение &amp;lt;math&amp;gt;m \times B&amp;lt;/math&amp;gt; велико.&lt;br /&gt;
&lt;br /&gt;
===Входные и выходные данные алгоритма===&lt;br /&gt;
====Входные данные====&lt;br /&gt;
&lt;br /&gt;
Обучающая выборка (&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;) обычно представляется в виде двух плотных структур данных:&lt;br /&gt;
&lt;br /&gt;
1. Матрица Признаков (&amp;lt;math&amp;gt;X\in\mathbb{R}^{N \times m}&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — общее число обучающих примеров, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; — число признаков (размерность векторов весов).&lt;br /&gt;
&lt;br /&gt;
В задачах машинного обучения &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; часто значительно больше, чем &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; (много примеров, но относительно небольшое число признаков), или же &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; может быть очень большим (например, при использовании One-Hot-Encoding).&lt;br /&gt;
&lt;br /&gt;
В зависимости от задачи, матрица &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; может быть:&lt;br /&gt;
* плотной (dense): каждая ячейка содержит значащее числовое значение.&lt;br /&gt;
* разреженной (sparse): если большая часть элементов равна нулю.&lt;br /&gt;
&lt;br /&gt;
2. Вектор целевых значений (&amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;) - вектор размера &amp;lt;math&amp;gt;N \times 1&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;N \times C&amp;lt;/math&amp;gt; (для многоклассовой классификации, где &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — число классов).&lt;br /&gt;
&lt;br /&gt;
Обычно плотный, содержит действительные числа (для регрессии) или целочисленные метки/векторы (для классификации).&lt;br /&gt;
&lt;br /&gt;
3. Параметры обучения&lt;br /&gt;
&lt;br /&gt;
* Скорость обучения (&amp;lt;math&amp;gt;\alpha\in\mathbb{R}&amp;lt;/math&amp;gt;, learning rate): его значение обычно мало (например, &amp;lt;math&amp;gt;10^{-2}&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;10^{-3}&amp;lt;/math&amp;gt;) и оказывает критическое влияние на сходимость.&lt;br /&gt;
* Размер мини-батча (&amp;lt;math&amp;gt;B\in\mathbb{R}&amp;lt;/math&amp;gt;, batch size): определяет число примеров, используемых для одного шага. Обычно является степенью двойки (&amp;lt;math&amp;gt;32, 64, 128, \dots&amp;lt;/math&amp;gt;).&lt;br /&gt;
* Число эпох (&amp;lt;math&amp;gt;E\in\mathbb{N}&amp;lt;/math&amp;gt;, epochs): число полных проходов по всему набору данных.&lt;br /&gt;
&lt;br /&gt;
====Выходные Данные====&lt;br /&gt;
&lt;br /&gt;
* Вектор весов модели (&amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;): вектор размера &amp;lt;math&amp;gt;m \times 1&amp;lt;/math&amp;gt; (или матрица &amp;lt;math&amp;gt;m \times C&amp;lt;/math&amp;gt;, если модель содержит скрытые слои или многоклассовый вывод).&lt;br /&gt;
&lt;br /&gt;
Является плотной структурой данных. Диапазон значений зависит от функции потерь и регуляризации, но обычно это числа, близкие к нулю, или числа малого/среднего диапазона.&lt;br /&gt;
&lt;br /&gt;
* История потерь (loss history, опционально): вектор, содержащий значение функции потерь, вычисленное после каждого шага SGD. Объем равен &amp;lt;math&amp;gt;(E \times N) / B&amp;lt;/math&amp;gt;. Используется для анализа сходимости и отладки алгоритма.&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
Yujing Ma, Florin Rusu, Martin Torres. Stochastic Gradient Descent on Highly-Parallel Architectures [Электронный ресурс] // arXiv:1802.08800 [math.ST]. – 2018. – Режим доступа: https://arxiv.org/abs/1802.08800&lt;br /&gt;
&lt;br /&gt;
Sebastian Ruder. An overview of gradient descent optimization algorithms [Электронный ресурс] // arXiv:1609.04747 [math.ST]. – 2016. – Режим доступа: https://arxiv.org/abs/1609.04747&lt;/div&gt;</summary>
		<author><name>OvsyannikovaSA</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=30096</id>
		<title>Участница:OvsyannikovaSA/Стохастический градиентный спуск</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=30096"/>
		<updated>2025-11-27T17:22:11Z</updated>

		<summary type="html">&lt;p&gt;OvsyannikovaSA: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Свойства и структура алгоритмов==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
&#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039; (Stochastic Gradient Descent, SGD) представляет собой один из базовых и наиболее распространённых алгоритмов оптимизации, применяемых для обучения моделей машинного обучения и нейронных сетей. Он относится к классу итерационных методов минимизации функций.&lt;br /&gt;
&lt;br /&gt;
===Математическое описание алгоритма===&lt;br /&gt;
&lt;br /&gt;
Пусть даны &amp;lt;math&amp;gt;\{x_i, y_i\}_{i=1}^N, x_i \in \mathbb{R}^m&amp;lt;/math&amp;gt; - вектор признаков &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го объекта, &amp;lt;math&amp;gt;y_i \in \mathbb{R}&amp;lt;/math&amp;gt; - значение целевой переменной; класс моделей &amp;lt;math&amp;gt;a_\omega: \mathbb{R}^m \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;; функция потерь &amp;lt;math&amp;gt;f: \mathbb{R}\times \mathbb{R} \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;. Задача: найти вектор параметров модели (весов) &amp;lt;math&amp;gt;\omega \in \mathbb{R}^d&amp;lt;/math&amp;gt;, т.ч. &amp;lt;math&amp;gt;\omega = argmin_{\omega\in \mathbb{R}^d}\;L(\omega),\;L(\omega)=\sum_{i=1}^N f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм &#039;&#039;&#039;классического градиентного спуска (batch gradient descent)&#039;&#039;&#039; можно сформулировать следующим образом:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Здесь и далее шаг обучения (learning rate) &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; является гиперпараметром, т.е. параметром, который не оптимизируется в ходе работы алгоритма и который необходимо выбрать заранее. Начальное приближение &amp;lt;math&amp;gt;\omega_0&amp;lt;/math&amp;gt; также необходимо выбрать заранее исходя из некоторых соображений.&lt;br /&gt;
Условие достижения сходимости на практике обычно заменяется повторением процедуры некоторое количество раз, после чего можно считать, что алгоритм сошелся в требуемом приближении.&lt;br /&gt;
В данном подходе для того, чтобы совершить одно обновление весов, необходимо вычислить функцию потерь для всех элементов выборки. Этот метод может оказаться неподходящим в некоторых случаях, например, при использовании больших датасетов, не помещающихся в памяти, или в случае, когда новые данные поступают в реальном времени.&lt;br /&gt;
&lt;br /&gt;
Модернизацией этого алгоритма является &#039;&#039;&#039;стохастический градиентный спуск (stochastic gradient descent)&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xi, yi)&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad f(ω; xi, yi);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Алгоритм отличается от предыдущего тем, что обновление весов происходит после обработки одного объекта выборки. Компромиссом между двумя этими подходами служит &#039;&#039;&#039;стохастический градиентный спуск на мини-батчах (mini-batch gradient descent)&#039;&#039;&#039;. Для него требуется выбрать размер батча (batch_size). Обозначим &amp;lt;math&amp;gt;L(\omega)=\sum_{i=1}^{batch\_size} f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск с мини-батчами&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α, размер батча batch_size&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xik, yik), 1&amp;lt;=k&amp;lt;=batch_size&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω; (xik, yik), 1&amp;lt;=k&amp;lt;=batch_size);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Преимущество алгоритма заключается в частом обновлении градиента и возможности использовать эффективные матричные вычисления.&lt;br /&gt;
В этой работе мы сосредоточимся на реализации градиентного спуска с мини-батчами.&lt;br /&gt;
&lt;br /&gt;
Необходимо некоторым способом определить условия, при которых будет считаться, что алгоритм сошелся. Будем считать, что сходимость достигается за &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; итераций обработки всей выборки (будем называть одну итерацию &#039;&#039;&#039;эпохой&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
В начале каждой эпохи будем случайно перемешивать выборку, а затем последовательно выбирать порции данных по &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов. Это обеспечит локальность расположения в памяти последовательно идущих мини-батчей и сохранит логику случайного выбора мини-батчей. Таким образом, процедура случайного выбора мини-батча заменяется на линейный проход по всем данным.&lt;br /&gt;
&lt;br /&gt;
===Вычислительное ядро алгоритма===&lt;br /&gt;
Основное время работы алгоритма приходится на вычисление градиента, которые повторяются, пока сходимость не будет достигнута.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Алгоритм стохастического градиентного спуска с мини-батчами представляется повторением следующих макроопераций:&lt;br /&gt;
&lt;br /&gt;
1. Инициализация параметров: задание начального приближения вектора параметров модели &amp;lt;math&amp;gt;w_0&amp;lt;/math&amp;gt;. Может быть случайной инициализацией, загрузкой предварительно обученной модели и т.п.&lt;br /&gt;
&lt;br /&gt;
  w ← ИнициализацияПараметров(описание_модели, стратегия_инициализации)&lt;br /&gt;
&lt;br /&gt;
2. Перемешивание обучающей выборки: получение случайной перестановки обучающей выборки в начале эпохи. Можно выполнять, например, алгоритмом Фишера-Йетса.&lt;br /&gt;
&lt;br /&gt;
Входные данные: &amp;lt;math&amp;gt;D=\{(x_i, y_i)\}_{i=1}^N&amp;lt;/math&amp;gt; - обучающая выборка.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: &amp;lt;math&amp;gt;D_{perm}&amp;lt;/math&amp;gt; - перемешанная выборка.&lt;br /&gt;
&lt;br /&gt;
  D_perm ← ПеремешиваниеОбучающейВыборки(D, генератор_случайных_чисел)&lt;br /&gt;
&lt;br /&gt;
3. Формирование мини-батчей: разбиение переставленной выборки на последовательность мини-батчей.&lt;br /&gt;
&lt;br /&gt;
Входные данные: &amp;lt;math&amp;gt;D_{perm}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выходные данные: последовательность подмножеств &amp;lt;math&amp;gt;B_k\subset D, \; k=1,..., K, \; \cup_k B_k=D, B_k \cap B_j = \emptyset, k\neq j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
  СписокБатчей ← ФормированиеМиниБатчей((X,y)_perm, размер_батча)&lt;br /&gt;
&lt;br /&gt;
4. Вычисление градиента на батче. Может включать вычисление значений модели на батче, матрично-векторные умножения, суммирование по объектам батча.&lt;br /&gt;
&lt;br /&gt;
Входные данные: текущие параметры &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;, мини-батч &amp;lt;math&amp;gt;B=\{(x_i, y_i)\}_{i\in I_B}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выходные данные: &amp;lt;math&amp;gt;g_B&amp;lt;/math&amp;gt; - градиент по параметрам на этом батче.&lt;br /&gt;
&lt;br /&gt;
  g_B ← ВычислениеГрадиентаНаБатче(w, B)&lt;br /&gt;
&lt;br /&gt;
5. Обновление параметров: осуществление одного шага метода по вычисленному градиенту на батче.&lt;br /&gt;
&lt;br /&gt;
Входные данные: текущие параметры &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;, градиент на батче &amp;lt;math&amp;gt;g_B&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: новые параметры &amp;lt;math&amp;gt;w_{new}=w-\alpha g_B&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
  w ← ОбновлениеПараметров(w, g_B, гиперпараметры_шага)&lt;br /&gt;
&lt;br /&gt;
6. Проверка критерия останова: проверка условий завершения итерационного процесса. Может быть проверкой номера эпохи, проверкой изменения функции потерь и т.п.&lt;br /&gt;
&lt;br /&gt;
  флаг_стоп ← ПроверкаКритерияОстановки(номер_эпохи, номер_шага, значение_критерия, история)&lt;br /&gt;
&lt;br /&gt;
На макроуровне алгоритм можно описать так:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:100%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Макроструктура алгоритма&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
w ← ИнициализацияПараметров(описание_модели, стратегия_инициализации)&lt;br /&gt;
номер_эпохи ← 0&lt;br /&gt;
повторять&lt;br /&gt;
  номер_эпохи ← номер_эпохи + 1&lt;br /&gt;
  D_perm ← ПеремешиваниеОбучающейВыборки(D, генератор_случайных_чисел)&lt;br /&gt;
  СписокБатчей ← ФормированиеМиниБатчей(D_perm, размер_батча)&lt;br /&gt;
  Для каждого B из СписокБатчей:&lt;br /&gt;
    g_B ← ВычислениеГрадиентаНаБатче(w, B)&lt;br /&gt;
    w ← ОбновлениеПараметров(w, g_B, гиперпараметры_шага)&lt;br /&gt;
  флаг_стоп ← ПроверкаКритерияОстановки(номер_эпохи, значение_критерия, история)&lt;br /&gt;
Пока флаг_стоп = ЛОЖЬ&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
[[Файл:Sequential SGD with mini-batches scheme.png|мини|Схема последовательной реализации стохастического градиентного спуска с мини-батчами]]&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; - размер выборки,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - размер батча (&amp;lt;math&amp;gt;batch\_size&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - сложность вычисления производной функции потерь на одном примере,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - число эпох.&lt;br /&gt;
&lt;br /&gt;
Как уже упоминалось, будем перемешивать выборку случайным образом в начале каждой эпохи. Сложность случайного перемешивания выборки объема &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; алгоритмом Фишера-Йетса - &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. Если отказаться от этого предположения, можно считать, что сложность выбора &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; случайных элементов - &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. Такая оценка будет верна, если в системе реализован произвольный доступ к памяти. Однако для больших выборок, не помещающихся целиком в памяти, произвольный доступ к элементам выборки не будет возможен.&lt;br /&gt;
&lt;br /&gt;
Сложность обработки одного батча - &amp;lt;math&amp;gt;O(n \cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что количество батчей &amp;lt;math&amp;gt;N/n&amp;lt;/math&amp;gt; - целое число; тогда сложность вычисления градиентов в течение одной эпохи - &amp;lt;math&amp;gt;O(N/n \cdot n \cdot C) = O(N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность одной эпохи с учетом перемешивания выборки - &amp;lt;math&amp;gt;O(N)+O(N\cdot C)=O(N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность всего алгоритма с &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; эпохами - &amp;lt;math&amp;gt;O(E\cdot N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
На схеме изображен информационный граф стохастического градиентного спуска с мини-батчами.&lt;br /&gt;
&lt;br /&gt;
[[file:Informational_graph_minibatch_SGD.png|thumb|center|Информационный граф стохастического градиентного спуска с мини-батчами]]&lt;br /&gt;
Здесь приводится схема выполнения одной эпохи. Стрелки, изображающие обработку остальных объектов данного батча, опущены для улучшения читаемости схемы. После обработки одного батча с весами &amp;lt;math&amp;gt;w_i&amp;lt;/math&amp;gt; производится шаг градиентного спуска, и следующий батч обрабатывается уже с весами &amp;lt;math&amp;gt;w_{i+1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
Yujing Ma, Florin Rusu, Martin Torres. Stochastic Gradient Descent on Highly-Parallel Architectures [Электронный ресурс] // arXiv:1802.08800 [math.ST]. – 2018. – Режим доступа: https://arxiv.org/abs/1802.08800&lt;br /&gt;
&lt;br /&gt;
Sebastian Ruder. An overview of gradient descent optimization algorithms [Электронный ресурс] // arXiv:1609.04747 [math.ST]. – 2016. – Режим доступа: https://arxiv.org/abs/1609.04747&lt;/div&gt;</summary>
		<author><name>OvsyannikovaSA</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Informational_graph_minibatch_SGD.png&amp;diff=30095</id>
		<title>Файл:Informational graph minibatch SGD.png</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Informational_graph_minibatch_SGD.png&amp;diff=30095"/>
		<updated>2025-11-27T17:19:00Z</updated>

		<summary type="html">&lt;p&gt;OvsyannikovaSA: OvsyannikovaSA загрузила новую версию Файл:Informational graph minibatch SGD.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Информационный граф стохастического градиентного спуска с мини-батчами&lt;/div&gt;</summary>
		<author><name>OvsyannikovaSA</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=30094</id>
		<title>Участница:OvsyannikovaSA/Стохастический градиентный спуск</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=30094"/>
		<updated>2025-11-27T17:17:34Z</updated>

		<summary type="html">&lt;p&gt;OvsyannikovaSA: информационный граф&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Свойства и структура алгоритмов==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
&#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039; (Stochastic Gradient Descent, SGD) представляет собой один из базовых и наиболее распространённых алгоритмов оптимизации, применяемых для обучения моделей машинного обучения и нейронных сетей. Он относится к классу итерационных методов минимизации функций.&lt;br /&gt;
&lt;br /&gt;
===Математическое описание алгоритма===&lt;br /&gt;
&lt;br /&gt;
Пусть даны &amp;lt;math&amp;gt;\{x_i, y_i\}_{i=1}^N, x_i \in \mathbb{R}^m&amp;lt;/math&amp;gt; - вектор признаков &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го объекта, &amp;lt;math&amp;gt;y_i \in \mathbb{R}&amp;lt;/math&amp;gt; - значение целевой переменной; класс моделей &amp;lt;math&amp;gt;a_\omega: \mathbb{R}^m \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;; функция потерь &amp;lt;math&amp;gt;f: \mathbb{R}\times \mathbb{R} \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;. Задача: найти вектор параметров модели (весов) &amp;lt;math&amp;gt;\omega \in \mathbb{R}^d&amp;lt;/math&amp;gt;, т.ч. &amp;lt;math&amp;gt;\omega = argmin_{\omega\in \mathbb{R}^d}\;L(\omega),\;L(\omega)=\sum_{i=1}^N f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм &#039;&#039;&#039;классического градиентного спуска (batch gradient descent)&#039;&#039;&#039; можно сформулировать следующим образом:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Здесь и далее шаг обучения (learning rate) &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; является гиперпараметром, т.е. параметром, который не оптимизируется в ходе работы алгоритма и который необходимо выбрать заранее. Начальное приближение &amp;lt;math&amp;gt;\omega_0&amp;lt;/math&amp;gt; также необходимо выбрать заранее исходя из некоторых соображений.&lt;br /&gt;
Условие достижения сходимости на практике обычно заменяется повторением процедуры некоторое количество раз, после чего можно считать, что алгоритм сошелся в требуемом приближении.&lt;br /&gt;
В данном подходе для того, чтобы совершить одно обновление весов, необходимо вычислить функцию потерь для всех элементов выборки. Этот метод может оказаться неподходящим в некоторых случаях, например, при использовании больших датасетов, не помещающихся в памяти, или в случае, когда новые данные поступают в реальном времени.&lt;br /&gt;
&lt;br /&gt;
Модернизацией этого алгоритма является &#039;&#039;&#039;стохастический градиентный спуск (stochastic gradient descent)&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xi, yi)&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad f(ω; xi, yi);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Алгоритм отличается от предыдущего тем, что обновление весов происходит после обработки одного объекта выборки. Компромиссом между двумя этими подходами служит &#039;&#039;&#039;стохастический градиентный спуск на мини-батчах (mini-batch gradient descent)&#039;&#039;&#039;. Для него требуется выбрать размер батча (batch_size). Обозначим &amp;lt;math&amp;gt;L(\omega)=\sum_{i=1}^{batch\_size} f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск с мини-батчами&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α, размер батча batch_size&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xik, yik), 1&amp;lt;=k&amp;lt;=batch_size&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω; (xik, yik), 1&amp;lt;=k&amp;lt;=batch_size);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Преимущество алгоритма заключается в частом обновлении градиента и возможности использовать эффективные матричные вычисления.&lt;br /&gt;
В этой работе мы сосредоточимся на реализации градиентного спуска с мини-батчами.&lt;br /&gt;
&lt;br /&gt;
Необходимо некоторым способом определить условия, при которых будет считаться, что алгоритм сошелся. Будем считать, что сходимость достигается за &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; итераций обработки всей выборки (будем называть одну итерацию &#039;&#039;&#039;эпохой&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
В начале каждой эпохи будем случайно перемешивать выборку, а затем последовательно выбирать порции данных по &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов. Это обеспечит локальность расположения в памяти последовательно идущих мини-батчей и сохранит логику случайного выбора мини-батчей. Таким образом, процедура случайного выбора мини-батча заменяется на линейный проход по всем данным.&lt;br /&gt;
&lt;br /&gt;
===Вычислительное ядро алгоритма===&lt;br /&gt;
Основное время работы алгоритма приходится на вычисление градиента, которые повторяются, пока сходимость не будет достигнута.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Алгоритм стохастического градиентного спуска с мини-батчами представляется повторением следующих макроопераций:&lt;br /&gt;
&lt;br /&gt;
1. Инициализация параметров: задание начального приближения вектора параметров модели &amp;lt;math&amp;gt;w_0&amp;lt;/math&amp;gt;. Может быть случайной инициализацией, загрузкой предварительно обученной модели и т.п.&lt;br /&gt;
&lt;br /&gt;
  w ← ИнициализацияПараметров(описание_модели, стратегия_инициализации)&lt;br /&gt;
&lt;br /&gt;
2. Перемешивание обучающей выборки: получение случайной перестановки обучающей выборки в начале эпохи. Можно выполнять, например, алгоритмом Фишера-Йетса.&lt;br /&gt;
&lt;br /&gt;
Входные данные: &amp;lt;math&amp;gt;D=\{(x_i, y_i)\}_{i=1}^N&amp;lt;/math&amp;gt; - обучающая выборка.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: &amp;lt;math&amp;gt;D_{perm}&amp;lt;/math&amp;gt; - перемешанная выборка.&lt;br /&gt;
&lt;br /&gt;
  D_perm ← ПеремешиваниеОбучающейВыборки(D, генератор_случайных_чисел)&lt;br /&gt;
&lt;br /&gt;
3. Формирование мини-батчей: разбиение переставленной выборки на последовательность мини-батчей.&lt;br /&gt;
&lt;br /&gt;
Входные данные: &amp;lt;math&amp;gt;D_{perm}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выходные данные: последовательность подмножеств &amp;lt;math&amp;gt;B_k\subset D, \; k=1,..., K, \; \cup_k B_k=D, B_k \cap B_j = \emptyset, k\neq j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
  СписокБатчей ← ФормированиеМиниБатчей((X,y)_perm, размер_батча)&lt;br /&gt;
&lt;br /&gt;
4. Вычисление градиента на батче. Может включать вычисление значений модели на батче, матрично-векторные умножения, суммирование по объектам батча.&lt;br /&gt;
&lt;br /&gt;
Входные данные: текущие параметры &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;, мини-батч &amp;lt;math&amp;gt;B=\{(x_i, y_i)\}_{i\in I_B}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выходные данные: &amp;lt;math&amp;gt;g_B&amp;lt;/math&amp;gt; - градиент по параметрам на этом батче.&lt;br /&gt;
&lt;br /&gt;
  g_B ← ВычислениеГрадиентаНаБатче(w, B)&lt;br /&gt;
&lt;br /&gt;
5. Обновление параметров: осуществление одного шага метода по вычисленному градиенту на батче.&lt;br /&gt;
&lt;br /&gt;
Входные данные: текущие параметры &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;, градиент на батче &amp;lt;math&amp;gt;g_B&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: новые параметры &amp;lt;math&amp;gt;w_{new}=w-\alpha g_B&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
  w ← ОбновлениеПараметров(w, g_B, гиперпараметры_шага)&lt;br /&gt;
&lt;br /&gt;
6. Проверка критерия останова: проверка условий завершения итерационного процесса. Может быть проверкой номера эпохи, проверкой изменения функции потерь и т.п.&lt;br /&gt;
&lt;br /&gt;
  флаг_стоп ← ПроверкаКритерияОстановки(номер_эпохи, номер_шага, значение_критерия, история)&lt;br /&gt;
&lt;br /&gt;
На макроуровне алгоритм можно описать так:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:100%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Макроструктура алгоритма&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
w ← ИнициализацияПараметров(описание_модели, стратегия_инициализации)&lt;br /&gt;
номер_эпохи ← 0&lt;br /&gt;
повторять&lt;br /&gt;
  номер_эпохи ← номер_эпохи + 1&lt;br /&gt;
  D_perm ← ПеремешиваниеОбучающейВыборки(D, генератор_случайных_чисел)&lt;br /&gt;
  СписокБатчей ← ФормированиеМиниБатчей(D_perm, размер_батча)&lt;br /&gt;
  Для каждого B из СписокБатчей:&lt;br /&gt;
    g_B ← ВычислениеГрадиентаНаБатче(w, B)&lt;br /&gt;
    w ← ОбновлениеПараметров(w, g_B, гиперпараметры_шага)&lt;br /&gt;
  флаг_стоп ← ПроверкаКритерияОстановки(номер_эпохи, значение_критерия, история)&lt;br /&gt;
Пока флаг_стоп = ЛОЖЬ&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
[[Файл:Sequential SGD with mini-batches scheme.png|мини|Схема последовательной реализации стохастического градиентного спуска с мини-батчами]]&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; - размер выборки,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - размер батча (&amp;lt;math&amp;gt;batch\_size&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - сложность вычисления производной функции потерь на одном примере,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - число эпох.&lt;br /&gt;
&lt;br /&gt;
Как уже упоминалось, будем перемешивать выборку случайным образом в начале каждой эпохи. Сложность случайного перемешивания выборки объема &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; алгоритмом Фишера-Йетса - &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. Если отказаться от этого предположения, можно считать, что сложность выбора &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; случайных элементов - &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. Такая оценка будет верна, если в системе реализован произвольный доступ к памяти. Однако для больших выборок, не помещающихся целиком в памяти, произвольный доступ к элементам выборки не будет возможен.&lt;br /&gt;
&lt;br /&gt;
Сложность обработки одного батча - &amp;lt;math&amp;gt;O(n \cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что количество батчей &amp;lt;math&amp;gt;N/n&amp;lt;/math&amp;gt; - целое число; тогда сложность вычисления градиентов в течение одной эпохи - &amp;lt;math&amp;gt;O(N/n \cdot n \cdot C) = O(N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность одной эпохи с учетом перемешивания выборки - &amp;lt;math&amp;gt;O(N)+O(N\cdot C)=O(N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность всего алгоритма с &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; эпохами - &amp;lt;math&amp;gt;O(E\cdot N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
На схеме изображен информационный граф стохастического градиентного спуска с мини-батчами.&lt;br /&gt;
&lt;br /&gt;
[[file:Informational graph minibatch SGD.png|thumb|center|Информационный граф стохастического градиентного спуска с мини-батчами]]&lt;br /&gt;
Здесь приводится схема выполнения одной эпохи. Стрелки, изображающие обработку остальных объектов данного батча и всех других батчей опущены, чтобы не перегружать схему.&lt;br /&gt;
==Литература==&lt;br /&gt;
Yujing Ma, Florin Rusu, Martin Torres. Stochastic Gradient Descent on Highly-Parallel Architectures [Электронный ресурс] // arXiv:1802.08800 [math.ST]. – 2018. – Режим доступа: https://arxiv.org/abs/1802.08800&lt;br /&gt;
&lt;br /&gt;
Sebastian Ruder. An overview of gradient descent optimization algorithms [Электронный ресурс] // arXiv:1609.04747 [math.ST]. – 2016. – Режим доступа: https://arxiv.org/abs/1609.04747&lt;/div&gt;</summary>
		<author><name>OvsyannikovaSA</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Informational_graph_SGD.png&amp;diff=30093</id>
		<title>Файл:Informational graph SGD.png</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Informational_graph_SGD.png&amp;diff=30093"/>
		<updated>2025-11-27T17:15:27Z</updated>

		<summary type="html">&lt;p&gt;OvsyannikovaSA: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Информационный граф стохастического градиентного спуска с мини-батчами&lt;/div&gt;</summary>
		<author><name>OvsyannikovaSA</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Informational_graph_minibatch_SGD.png&amp;diff=30091</id>
		<title>Файл:Informational graph minibatch SGD.png</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Informational_graph_minibatch_SGD.png&amp;diff=30091"/>
		<updated>2025-11-27T16:45:56Z</updated>

		<summary type="html">&lt;p&gt;OvsyannikovaSA: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Информационный граф стохастического градиентного спуска с мини-батчами&lt;/div&gt;</summary>
		<author><name>OvsyannikovaSA</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=30083</id>
		<title>Участница:OvsyannikovaSA/Стохастический градиентный спуск</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=30083"/>
		<updated>2025-11-27T12:44:11Z</updated>

		<summary type="html">&lt;p&gt;OvsyannikovaSA: /* Макроструктура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Свойства и структура алгоритмов==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
&#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039; (Stochastic Gradient Descent, SGD) представляет собой один из базовых и наиболее распространённых алгоритмов оптимизации, применяемых для обучения моделей машинного обучения и нейронных сетей. Он относится к классу итерационных методов минимизации функций.&lt;br /&gt;
&lt;br /&gt;
===Математическое описание алгоритма===&lt;br /&gt;
&lt;br /&gt;
Пусть даны &amp;lt;math&amp;gt;\{x_i, y_i\}_{i=1}^N, x_i \in \mathbb{R}^m&amp;lt;/math&amp;gt; - вектор признаков &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го объекта, &amp;lt;math&amp;gt;y_i \in \mathbb{R}&amp;lt;/math&amp;gt; - значение целевой переменной; класс моделей &amp;lt;math&amp;gt;a_\omega: \mathbb{R}^m \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;; функция потерь &amp;lt;math&amp;gt;f: \mathbb{R}\times \mathbb{R} \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;. Задача: найти вектор параметров модели (весов) &amp;lt;math&amp;gt;\omega \in \mathbb{R}^d&amp;lt;/math&amp;gt;, т.ч. &amp;lt;math&amp;gt;\omega = argmin_{\omega\in \mathbb{R}^d}\;L(\omega),\;L(\omega)=\sum_{i=1}^N f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм &#039;&#039;&#039;классического градиентного спуска (batch gradient descent)&#039;&#039;&#039; можно сформулировать следующим образом:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Здесь и далее шаг обучения (learning rate) &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; является гиперпараметром, т.е. параметром, который не оптимизируется в ходе работы алгоритма и который необходимо выбрать заранее. Начальное приближение &amp;lt;math&amp;gt;\omega_0&amp;lt;/math&amp;gt; также необходимо выбрать заранее исходя из некоторых соображений.&lt;br /&gt;
Условие достижения сходимости на практике обычно заменяется повторением процедуры некоторое количество раз, после чего можно считать, что алгоритм сошелся в требуемом приближении.&lt;br /&gt;
В данном подходе для того, чтобы совершить одно обновление весов, необходимо вычислить функцию потерь для всех элементов выборки. Этот метод может оказаться неподходящим в некоторых случаях, например, при использовании больших датасетов, не помещающихся в памяти, или в случае, когда новые данные поступают в реальном времени.&lt;br /&gt;
&lt;br /&gt;
Модернизацией этого алгоритма является &#039;&#039;&#039;стохастический градиентный спуск (stochastic gradient descent)&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xi, yi)&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad f(ω; xi, yi);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Алгоритм отличается от предыдущего тем, что обновление весов происходит после обработки одного объекта выборки. Компромиссом между двумя этими подходами служит &#039;&#039;&#039;стохастический градиентный спуск на мини-батчах (mini-batch gradient descent)&#039;&#039;&#039;. Для него требуется выбрать размер батча (batch_size). Обозначим &amp;lt;math&amp;gt;L(\omega)=\sum_{i=1}^{batch\_size} f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск с мини-батчами&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α, размер батча batch_size&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xik, yik), 1&amp;lt;=k&amp;lt;=batch_size&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω; (xik, yik), 1&amp;lt;=k&amp;lt;=batch_size);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Преимущество алгоритма заключается в частом обновлении градиента и возможности использовать эффективные матричные вычисления.&lt;br /&gt;
В этой работе мы сосредоточимся на реализации градиентного спуска с мини-батчами.&lt;br /&gt;
&lt;br /&gt;
Необходимо некоторым способом определить условия, при которых будет считаться, что алгоритм сошелся. Будем считать, что сходимость достигается за &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; итераций обработки всей выборки (будем называть одну итерацию &#039;&#039;&#039;эпохой&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
В начале каждой эпохи будем случайно перемешивать выборку, а затем последовательно выбирать порции данных по &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов. Это обеспечит локальность расположения в памяти последовательно идущих мини-батчей и сохранит логику случайного выбора мини-батчей. Таким образом, процедура случайного выбора мини-батча заменяется на линейный проход по всем данным.&lt;br /&gt;
&lt;br /&gt;
===Вычислительное ядро алгоритма===&lt;br /&gt;
Основное время работы алгоритма приходится на вычисление градиента, которые повторяются, пока сходимость не будет достигнута.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Алгоритм стохастического градиентного спуска с мини-батчами представляется повторением следующих макроопераций:&lt;br /&gt;
&lt;br /&gt;
1. Инициализация параметров: задание начального приближения вектора параметров модели &amp;lt;math&amp;gt;w_0&amp;lt;/math&amp;gt;. Может быть случайной инициализацией, загрузкой предварительно обученной модели и т.п.&lt;br /&gt;
&lt;br /&gt;
  w ← ИнициализацияПараметров(описание_модели, стратегия_инициализации)&lt;br /&gt;
&lt;br /&gt;
2. Перемешивание обучающей выборки: получение случайной перестановки обучающей выборки в начале эпохи. Можно выполнять, например, алгоритмом Фишера-Йетса.&lt;br /&gt;
&lt;br /&gt;
Входные данные: &amp;lt;math&amp;gt;D=\{(x_i, y_i)\}_{i=1}^N&amp;lt;/math&amp;gt; - обучающая выборка.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: &amp;lt;math&amp;gt;D_{perm}&amp;lt;/math&amp;gt; - перемешанная выборка.&lt;br /&gt;
&lt;br /&gt;
  D_perm ← ПеремешиваниеОбучающейВыборки(D, генератор_случайных_чисел)&lt;br /&gt;
&lt;br /&gt;
3. Формирование мини-батчей: разбиение переставленной выборки на последовательность мини-батчей.&lt;br /&gt;
&lt;br /&gt;
Входные данные: &amp;lt;math&amp;gt;D_{perm}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выходные данные: последовательность подмножеств &amp;lt;math&amp;gt;B_k\subset D, \; k=1,..., K, \; \cup_k B_k=D, B_k \cap B_j = \emptyset, k\neq j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
  СписокБатчей ← ФормированиеМиниБатчей((X,y)_perm, размер_батча)&lt;br /&gt;
&lt;br /&gt;
4. Вычисление градиента на батче. Может включать вычисление значений модели на батче, матрично-векторные умножения, суммирование по объектам батча.&lt;br /&gt;
&lt;br /&gt;
Входные данные: текущие параметры &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;, мини-батч &amp;lt;math&amp;gt;B=\{(x_i, y_i)\}_{i\in I_B}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выходные данные: &amp;lt;math&amp;gt;g_B&amp;lt;/math&amp;gt; - градиент по параметрам на этом батче.&lt;br /&gt;
&lt;br /&gt;
  g_B ← ВычислениеГрадиентаНаБатче(w, B)&lt;br /&gt;
&lt;br /&gt;
5. Обновление параметров: осуществление одного шага метода по вычисленному градиенту на батче.&lt;br /&gt;
&lt;br /&gt;
Входные данные: текущие параметры &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;, градиент на батче &amp;lt;math&amp;gt;g_B&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: новые параметры &amp;lt;math&amp;gt;w_{new}=w-\alpha g_B&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
  w ← ОбновлениеПараметров(w, g_B, гиперпараметры_шага)&lt;br /&gt;
&lt;br /&gt;
На макроуровне алгоритм можно описать так:&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
[[Файл:Sequential SGD with mini-batches scheme.png|мини|Схема последовательной реализации стохастического градиентного спуска с мини-батчами]]&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; - размер выборки,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - размер батча (&amp;lt;math&amp;gt;batch\_size&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - сложность вычисления производной функции потерь на одном примере,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - число эпох.&lt;br /&gt;
&lt;br /&gt;
Как уже упоминалось, будем перемешивать выборку случайным образом в начале каждой эпохи. Сложность случайного перемешивания выборки объема &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; алгоритмом Фишера-Йетса - &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. Если отказаться от этого предположения, можно считать, что сложность выбора &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; случайных элементов - &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. Такая оценка будет верна, если в системе реализован произвольный доступ к памяти. Однако для больших выборок, не помещающихся целиком в памяти, произвольный доступ к элементам выборки не будет возможен.&lt;br /&gt;
&lt;br /&gt;
Сложность обработки одного батча - &amp;lt;math&amp;gt;O(n \cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что количество батчей &amp;lt;math&amp;gt;N/n&amp;lt;/math&amp;gt; - целое число; тогда сложность вычисления градиентов в течение одной эпохи - &amp;lt;math&amp;gt;O(N/n \cdot n \cdot C) = O(N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность одной эпохи с учетом перемешивания выборки - &amp;lt;math&amp;gt;O(N)+O(N\cdot C)=O(N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность всего алгоритма с &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; эпохами - &amp;lt;math&amp;gt;O(E\cdot N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
Yujing Ma, Florin Rusu, Martin Torres. Stochastic Gradient Descent on Highly-Parallel Architectures [Электронный ресурс] // arXiv:1802.08800 [math.ST]. – 2018. – Режим доступа: https://arxiv.org/abs/1802.08800&lt;br /&gt;
&lt;br /&gt;
Sebastian Ruder. An overview of gradient descent optimization algorithms [Электронный ресурс] // arXiv:1609.04747 [math.ST]. – 2016. – Режим доступа: https://arxiv.org/abs/1609.04747&lt;/div&gt;</summary>
		<author><name>OvsyannikovaSA</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=30082</id>
		<title>Участница:OvsyannikovaSA/Стохастический градиентный спуск</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=30082"/>
		<updated>2025-11-27T11:07:48Z</updated>

		<summary type="html">&lt;p&gt;OvsyannikovaSA: /* Схема реализации последовательного алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Свойства и структура алгоритмов==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
&#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039; (Stochastic Gradient Descent, SGD) представляет собой один из базовых и наиболее распространённых алгоритмов оптимизации, применяемых для обучения моделей машинного обучения и нейронных сетей. Он относится к классу итерационных методов минимизации функций.&lt;br /&gt;
&lt;br /&gt;
===Математическое описание алгоритма===&lt;br /&gt;
&lt;br /&gt;
Пусть даны &amp;lt;math&amp;gt;\{x_i, y_i\}_{i=1}^N, x_i \in \mathbb{R}^m&amp;lt;/math&amp;gt; - вектор признаков &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го объекта, &amp;lt;math&amp;gt;y_i \in \mathbb{R}&amp;lt;/math&amp;gt; - значение целевой переменной; класс моделей &amp;lt;math&amp;gt;a_\omega: \mathbb{R}^m \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;; функция потерь &amp;lt;math&amp;gt;f: \mathbb{R}\times \mathbb{R} \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;. Задача: найти вектор параметров модели (весов) &amp;lt;math&amp;gt;\omega \in \mathbb{R}^d&amp;lt;/math&amp;gt;, т.ч. &amp;lt;math&amp;gt;\omega = argmin_{\omega\in \mathbb{R}^d}\;L(\omega),\;L(\omega)=\sum_{i=1}^N f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм &#039;&#039;&#039;классического градиентного спуска (batch gradient descent)&#039;&#039;&#039; можно сформулировать следующим образом:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Здесь и далее шаг обучения (learning rate) &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; является гиперпараметром, т.е. параметром, который не оптимизируется в ходе работы алгоритма и который необходимо выбрать заранее. Начальное приближение &amp;lt;math&amp;gt;\omega_0&amp;lt;/math&amp;gt; также необходимо выбрать заранее исходя из некоторых соображений.&lt;br /&gt;
Условие достижения сходимости на практике обычно заменяется повторением процедуры некоторое количество раз, после чего можно считать, что алгоритм сошелся в требуемом приближении.&lt;br /&gt;
В данном подходе для того, чтобы совершить одно обновление весов, необходимо вычислить функцию потерь для всех элементов выборки. Этот метод может оказаться неподходящим в некоторых случаях, например, при использовании больших датасетов, не помещающихся в памяти, или в случае, когда новые данные поступают в реальном времени.&lt;br /&gt;
&lt;br /&gt;
Модернизацией этого алгоритма является &#039;&#039;&#039;стохастический градиентный спуск (stochastic gradient descent)&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xi, yi)&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad f(ω; xi, yi);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Алгоритм отличается от предыдущего тем, что обновление весов происходит после обработки одного объекта выборки. Компромиссом между двумя этими подходами служит &#039;&#039;&#039;стохастический градиентный спуск на мини-батчах (mini-batch gradient descent)&#039;&#039;&#039;. Для него требуется выбрать размер батча (batch_size). Обозначим &amp;lt;math&amp;gt;L(\omega)=\sum_{i=1}^{batch\_size} f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск с мини-батчами&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α, размер батча batch_size&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xik, yik), 1&amp;lt;=k&amp;lt;=batch_size&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω; (xik, yik), 1&amp;lt;=k&amp;lt;=batch_size);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Преимущество алгоритма заключается в частом обновлении градиента и возможности использовать эффективные матричные вычисления.&lt;br /&gt;
В этой работе мы сосредоточимся на реализации градиентного спуска с мини-батчами.&lt;br /&gt;
&lt;br /&gt;
Необходимо некоторым способом определить условия, при которых будет считаться, что алгоритм сошелся. Будем считать, что сходимость достигается за &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; итераций обработки всей выборки (будем называть одну итерацию &#039;&#039;&#039;эпохой&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
В начале каждой эпохи будем случайно перемешивать выборку, а затем последовательно выбирать порции данных по &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов. Это обеспечит локальность расположения в памяти последовательно идущих мини-батчей и сохранит логику случайного выбора мини-батчей. Таким образом, процедура случайного выбора мини-батча заменяется на линейный проход по всем данным.&lt;br /&gt;
&lt;br /&gt;
===Вычислительное ядро алгоритма===&lt;br /&gt;
Основное время работы алгоритма приходится на вычисление градиента, которые повторяются, пока сходимость не будет достигнута.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
[[Файл:Sequential SGD with mini-batches scheme.png|мини|Схема последовательной реализации стохастического градиентного спуска с мини-батчами]]&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; - размер выборки,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - размер батча (&amp;lt;math&amp;gt;batch\_size&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - сложность вычисления производной функции потерь на одном примере,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - число эпох.&lt;br /&gt;
&lt;br /&gt;
Как уже упоминалось, будем перемешивать выборку случайным образом в начале каждой эпохи. Сложность случайного перемешивания выборки объема &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; алгоритмом Фишера-Йетса - &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. Если отказаться от этого предположения, можно считать, что сложность выбора &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; случайных элементов - &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. Такая оценка будет верна, если в системе реализован произвольный доступ к памяти. Однако для больших выборок, не помещающихся целиком в памяти, произвольный доступ к элементам выборки не будет возможен.&lt;br /&gt;
&lt;br /&gt;
Сложность обработки одного батча - &amp;lt;math&amp;gt;O(n \cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что количество батчей &amp;lt;math&amp;gt;N/n&amp;lt;/math&amp;gt; - целое число; тогда сложность вычисления градиентов в течение одной эпохи - &amp;lt;math&amp;gt;O(N/n \cdot n \cdot C) = O(N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность одной эпохи с учетом перемешивания выборки - &amp;lt;math&amp;gt;O(N)+O(N\cdot C)=O(N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность всего алгоритма с &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; эпохами - &amp;lt;math&amp;gt;O(E\cdot N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
Yujing Ma, Florin Rusu, Martin Torres. Stochastic Gradient Descent on Highly-Parallel Architectures [Электронный ресурс] // arXiv:1802.08800 [math.ST]. – 2018. – Режим доступа: https://arxiv.org/abs/1802.08800&lt;br /&gt;
&lt;br /&gt;
Sebastian Ruder. An overview of gradient descent optimization algorithms [Электронный ресурс] // arXiv:1609.04747 [math.ST]. – 2016. – Режим доступа: https://arxiv.org/abs/1609.04747&lt;/div&gt;</summary>
		<author><name>OvsyannikovaSA</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Sequential_SGD_with_mini-batches_scheme.png&amp;diff=30081</id>
		<title>Файл:Sequential SGD with mini-batches scheme.png</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Sequential_SGD_with_mini-batches_scheme.png&amp;diff=30081"/>
		<updated>2025-11-27T11:06:54Z</updated>

		<summary type="html">&lt;p&gt;OvsyannikovaSA: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Схема последовательной реализации стохастического градиентного спуска с мини-батчами&lt;/div&gt;</summary>
		<author><name>OvsyannikovaSA</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=30051</id>
		<title>Участница:OvsyannikovaSA/Стохастический градиентный спуск</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=30051"/>
		<updated>2025-11-23T15:24:43Z</updated>

		<summary type="html">&lt;p&gt;OvsyannikovaSA: исправлено мат. описание алгоритма&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Свойства и структура алгоритмов==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
&#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039; (Stochastic Gradient Descent, SGD) представляет собой один из базовых и наиболее распространённых алгоритмов оптимизации, применяемых для обучения моделей машинного обучения и нейронных сетей. Он относится к классу итерационных методов минимизации функций.&lt;br /&gt;
&lt;br /&gt;
===Математическое описание алгоритма===&lt;br /&gt;
&lt;br /&gt;
Пусть даны &amp;lt;math&amp;gt;\{x_i, y_i\}_{i=1}^N, x_i \in \mathbb{R}^m&amp;lt;/math&amp;gt; - вектор признаков &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го объекта, &amp;lt;math&amp;gt;y_i \in \mathbb{R}&amp;lt;/math&amp;gt; - значение целевой переменной; класс моделей &amp;lt;math&amp;gt;a_\omega: \mathbb{R}^m \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;; функция потерь &amp;lt;math&amp;gt;f: \mathbb{R}\times \mathbb{R} \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;. Задача: найти вектор параметров модели (весов) &amp;lt;math&amp;gt;\omega \in \mathbb{R}^d&amp;lt;/math&amp;gt;, т.ч. &amp;lt;math&amp;gt;\omega = argmin_{\omega\in \mathbb{R}^d}\;L(\omega),\;L(\omega)=\sum_{i=1}^N f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм &#039;&#039;&#039;классического градиентного спуска (batch gradient descent)&#039;&#039;&#039; можно сформулировать следующим образом:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Здесь и далее шаг обучения (learning rate) &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; является гиперпараметром, т.е. параметром, который не оптимизируется в ходе работы алгоритма и который необходимо выбрать заранее. Начальное приближение &amp;lt;math&amp;gt;\omega_0&amp;lt;/math&amp;gt; также необходимо выбрать заранее исходя из некоторых соображений.&lt;br /&gt;
Условие достижения сходимости на практике обычно заменяется повторением процедуры некоторое количество раз, после чего можно считать, что алгоритм сошелся в требуемом приближении.&lt;br /&gt;
В данном подходе для того, чтобы совершить одно обновление весов, необходимо вычислить функцию потерь для всех элементов выборки. Этот метод может оказаться неподходящим в некоторых случаях, например, при использовании больших датасетов, не помещающихся в памяти, или в случае, когда новые данные поступают в реальном времени.&lt;br /&gt;
&lt;br /&gt;
Модернизацией этого алгоритма является &#039;&#039;&#039;стохастический градиентный спуск (stochastic gradient descent)&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xi, yi)&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad f(ω; xi, yi);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Алгоритм отличается от предыдущего тем, что обновление весов происходит после обработки одного объекта выборки. Компромиссом между двумя этими подходами служит &#039;&#039;&#039;стохастический градиентный спуск на мини-батчах (mini-batch gradient descent)&#039;&#039;&#039;. Для него требуется выбрать размер батча (batch_size). Обозначим &amp;lt;math&amp;gt;L(\omega)=\sum_{i=1}^{batch\_size} f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск с мини-батчами&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α, размер батча batch_size&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xik, yik), 1&amp;lt;=k&amp;lt;=batch_size&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω; (xik, yik), 1&amp;lt;=k&amp;lt;=batch_size);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Преимущество алгоритма заключается в частом обновлении градиента и возможности использовать эффективные матричные вычисления.&lt;br /&gt;
В этой работе мы сосредоточимся на реализации градиентного спуска с мини-батчами.&lt;br /&gt;
&lt;br /&gt;
Необходимо некоторым способом определить условия, при которых будет считаться, что алгоритм сошелся. Будем считать, что сходимость достигается за &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; итераций обработки всей выборки (будем называть одну итерацию &#039;&#039;&#039;эпохой&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
В начале каждой эпохи будем случайно перемешивать выборку, а затем последовательно выбирать порции данных по &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов. Это обеспечит локальность расположения в памяти последовательно идущих мини-батчей и сохранит логику случайного выбора мини-батчей. Таким образом, процедура случайного выбора мини-батча заменяется на линейный проход по всем данным.&lt;br /&gt;
&lt;br /&gt;
===Вычислительное ядро алгоритма===&lt;br /&gt;
Основное время работы алгоритма приходится на вычисление градиента, которые повторяются, пока сходимость не будет достигнута.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; - размер выборки,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - размер батча (&amp;lt;math&amp;gt;batch\_size&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - сложность вычисления производной функции потерь на одном примере,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - число эпох.&lt;br /&gt;
&lt;br /&gt;
Как уже упоминалось, будем перемешивать выборку случайным образом в начале каждой эпохи. Сложность случайного перемешивания выборки объема &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; алгоритмом Фишера-Йетса - &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;. Если отказаться от этого предположения, можно считать, что сложность выбора &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; случайных элементов - &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. Такая оценка будет верна, если в системе реализован произвольный доступ к памяти. Однако для больших выборок, не помещающихся целиком в памяти, произвольный доступ к элементам выборки не будет возможен.&lt;br /&gt;
&lt;br /&gt;
Сложность обработки одного батча - &amp;lt;math&amp;gt;O(n \cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что количество батчей &amp;lt;math&amp;gt;N/n&amp;lt;/math&amp;gt; - целое число; тогда сложность вычисления градиентов в течение одной эпохи - &amp;lt;math&amp;gt;O(N/n \cdot n \cdot C) = O(N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность одной эпохи с учетом перемешивания выборки - &amp;lt;math&amp;gt;O(N)+O(N\cdot C)=O(N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность всего алгоритма с &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; эпохами - &amp;lt;math&amp;gt;O(E\cdot N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
Yujing Ma, Florin Rusu, Martin Torres. Stochastic Gradient Descent on Highly-Parallel Architectures [Электронный ресурс] // arXiv:1802.08800 [math.ST]. – 2018. – Режим доступа: https://arxiv.org/abs/1802.08800&lt;br /&gt;
&lt;br /&gt;
Sebastian Ruder. An overview of gradient descent optimization algorithms [Электронный ресурс] // arXiv:1609.04747 [math.ST]. – 2016. – Режим доступа: https://arxiv.org/abs/1609.04747&lt;/div&gt;</summary>
		<author><name>OvsyannikovaSA</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=30044</id>
		<title>Участница:OvsyannikovaSA/Стохастический градиентный спуск</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=30044"/>
		<updated>2025-11-23T08:57:40Z</updated>

		<summary type="html">&lt;p&gt;OvsyannikovaSA: добавлено: последовательная сложность алгоритма&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Свойства и структура алгоритмов==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
&#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039; (Stochastic Gradient Descent, SGD) представляет собой один из базовых и наиболее распространённых алгоритмов оптимизации, применяемых для обучения моделей машинного обучения и нейронных сетей. Он относится к классу итерационных методов минимизации функций.&lt;br /&gt;
&lt;br /&gt;
===Математическое описание алгоритма===&lt;br /&gt;
&lt;br /&gt;
Пусть даны &amp;lt;math&amp;gt;\{x_i, y_i\}_{i=1}^N, x_i \in \mathbb{R}^m&amp;lt;/math&amp;gt; - вектор признаков &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го объекта, &amp;lt;math&amp;gt;y_i \in \mathbb{R}&amp;lt;/math&amp;gt; - значение целевой переменной; класс моделей &amp;lt;math&amp;gt;a_\omega: \mathbb{R}^m \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;; функция потерь &amp;lt;math&amp;gt;f: \mathbb{R}\times \mathbb{R} \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;. Задача: найти вектор параметров модели (весов) &amp;lt;math&amp;gt;\omega \in \mathbb{R}^d&amp;lt;/math&amp;gt;, т.ч. &amp;lt;math&amp;gt;\omega = argmin_{\omega\in \mathbb{R}^d}\;L(\omega),\;L(\omega)=\sum_{i=1}^N f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм &#039;&#039;&#039;классического градиентного спуска (batch gradient descent)&#039;&#039;&#039; можно сформулировать следующим образом:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Здесь и далее шаг обучения (learning rate) &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; является гиперпараметром, т.е. параметром, который не оптимизируется в ходе работы алгоритма и который необходимо выбрать заранее. Начальное приближение &amp;lt;math&amp;gt;\omega_0&amp;lt;/math&amp;gt; также необходимо выбрать заранее исходя из некоторых соображений.&lt;br /&gt;
Условие достижения сходимости на практике обычно заменяется повторением процедуры некоторое количество раз, после чего можно считать, что алгоритм сошелся в требуемом приближении.&lt;br /&gt;
В данном подходе для того, чтобы совершить одно обновление весов, необходимо вычислить функцию потерь для всех элементов выборки. Этот метод может оказаться неподходящим в некоторых случаях, например, при использовании больших датасетов, не помещающихся в памяти, или в случае, когда новые данные поступают в реальном времени.&lt;br /&gt;
&lt;br /&gt;
Модернизацией этого алгоритма является &#039;&#039;&#039;стохастический градиентный спуск (stochastic gradient descent)&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xi, yi)&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad f(ω; xi, yi);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Алгоритм отличается от предыдущего тем, что обновление весов происходит после обработки одного объекта выборки. Компромиссом между двумя этими подходами служит &#039;&#039;&#039;стохастический градиентный спуск на мини-батчах (mini-batch gradient descent)&#039;&#039;&#039;. Для него требуется выбрать размер батча (batch_size). Обозначим &amp;lt;math&amp;gt;L(\omega)=\sum_{i=1}^{batch\_size} f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск с мини-батчами&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α, размер батча batch_size&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xik, yik), 1&amp;lt;=k&amp;lt;=batch_size&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω; (xik, yik), 1&amp;lt;=k&amp;lt;=batch_size);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Часто случайный выбор батча заменяют на линейный проход по всем данным. Преимущество алгоритма заключается в частом обновлении градиента и возможности использовать эффективные матричные вычисления.&lt;br /&gt;
В этой работе мы сосредоточимся на реализации градиентного спуска с мини-батчами.&lt;br /&gt;
&lt;br /&gt;
===Вычислительное ядро алгоритма===&lt;br /&gt;
Основное время работы алгоритма приходится на выбор мини-батча и вычисление градиента, которые повторяются, пока сходимость не будет достигнута.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; - размер выборки,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - размер батча (&amp;lt;math&amp;gt;batch\_size&amp;lt;/math&amp;gt;),&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - сложность вычисления производной функции потерь на одном примере.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что сходимость достигается за &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; итераций обработки всей выборки (будем называть одну итерацию эпохой).&lt;br /&gt;
В начале каждой эпохи будем случайно перемешивать выборку, а затем последовательно выбирать порции данных по &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов. Это обеспечит локальность расположения в памяти последовательно идущих мини-батчей и сохранит логику случайного выбора мини-батчей. Сложность случайного перемешивания выборки объема &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; алгоритмом Фишера-Йетса - &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность обработки одного батча - &amp;lt;math&amp;gt;O(n \cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что количество батчей &amp;lt;math&amp;gt;N/n&amp;lt;/math&amp;gt; - целое число; тогда сложность вычисления градиентов в течение одной эпохи - &amp;lt;math&amp;gt;O(N/n \cdot n \cdot C) = O(N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность одной эпохи с учетом перемешивания выборки - &amp;lt;math&amp;gt;O(N)+O(N\cdot C)=O(N\cdot C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность всего алгоритма с &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; эпохами - &amp;lt;math&amp;gt;O(E\cdot N\cdot C)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
Yujing Ma, Florin Rusu, Martin Torres. Stochastic Gradient Descent on Highly-Parallel Architectures [Электронный ресурс] // arXiv:1802.08800 [math.ST]. – 2018. – Режим доступа: https://arxiv.org/abs/1802.08800&lt;br /&gt;
&lt;br /&gt;
Sebastian Ruder. An overview of gradient descent optimization algorithms [Электронный ресурс] // arXiv:1609.04747 [math.ST]. – 2016. – Режим доступа: https://arxiv.org/abs/1609.04747&lt;/div&gt;</summary>
		<author><name>OvsyannikovaSA</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=29871</id>
		<title>Участница:OvsyannikovaSA/Стохастический градиентный спуск</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:OvsyannikovaSA/%D0%A1%D1%82%D0%BE%D1%85%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D1%83%D1%81%D0%BA&amp;diff=29871"/>
		<updated>2025-11-03T20:12:16Z</updated>

		<summary type="html">&lt;p&gt;OvsyannikovaSA: добавлено: общее описание алгоритма, математическое описание алгоритма, литература&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Свойства и структура алгоритмов==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
&#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039; (Stochastic Gradient Descent, SGD) представляет собой один из базовых и наиболее распространённых алгоритмов оптимизации, применяемых для обучения моделей машинного обучения и нейронных сетей. Он относится к классу итерационных методов минимизации функций.&lt;br /&gt;
&lt;br /&gt;
===Математическое описание алгоритма===&lt;br /&gt;
&lt;br /&gt;
Пусть даны &amp;lt;math&amp;gt;\{x_i, y_i\}_{i=1}^N, x_i \in \mathbb{R}^m&amp;lt;/math&amp;gt; - вектор признаков &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го объекта, &amp;lt;math&amp;gt;y_i \in \mathbb{R}&amp;lt;/math&amp;gt; - значение целевой переменной; класс моделей &amp;lt;math&amp;gt;a_\omega: \mathbb{R}^m \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;; функция потерь &amp;lt;math&amp;gt;f: \mathbb{R}\times \mathbb{R} \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;. Задача: найти вектор параметров модели (весов) &amp;lt;math&amp;gt;\omega \in \mathbb{R}^d&amp;lt;/math&amp;gt;, т.ч. &amp;lt;math&amp;gt;\omega = argmin_{\omega\in \mathbb{R}^d}\;L(\omega),\;L(\omega)=\sum_{i=1}^N f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм &#039;&#039;&#039;классического градиентного спуска (batch gradient descent)&#039;&#039;&#039; можно сформулировать следующим образом:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Здесь и далее шаг обучения (learning rate) &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; является гиперпараметром, т.е. параметром, который не оптимизируется в ходе работы алгоритма и который необходимо выбрать заранее. Начальное приближение &amp;lt;math&amp;gt;\omega_0&amp;lt;/math&amp;gt; также необходимо выбрать заранее исходя из некоторых соображений.&lt;br /&gt;
Условие достижения сходимости на практике обычно заменяется повторением процедуры некоторое количество раз, после чего можно считать, что алгоритм сошелся в требуемом приближении.&lt;br /&gt;
В данном подходе для того, чтобы совершить одно обновление весов, необходимо вычислить функцию потерь для всех элементов выборки. Этот метод может оказаться неподходящим в некоторых случаях, например, при использовании больших датасетов, не помещающихся в памяти, или в случае, когда новые данные поступают в реальном времени.&lt;br /&gt;
&lt;br /&gt;
Модернизацией этого алгоритма является &#039;&#039;&#039;стохастический градиентный спуск (stochastic gradient descent)&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xi, yi)&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad f(ω; xi, yi);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Алгоритм отличается от предыдущего тем, что обновление весов происходит после обработки одного объекта выборки. Компромиссом между двумя этими подходами служит &#039;&#039;&#039;стохастический градиентный спуск на мини-батчах (mini-batch gradient descent)&#039;&#039;&#039;. Для него требуется выбрать размер батча (batch_size). Обозначим &amp;lt;math&amp;gt;L(\omega)=\sum_{i=1}^{batch\_size} f(a_{\omega}(x_i), y_i)&amp;lt;/math&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;background:#f9f9f9; border:2px solid #ccc; width:60%;&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Стохастический градиентный спуск с мини-батчами&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;syntaxhighlight lang=&amp;quot;pseudo&amp;quot;&amp;gt;&lt;br /&gt;
вход: функция потерь L(ω), шаг обучения α, размер батча batch_size&lt;br /&gt;
выбрать начальное приближение ω0&lt;br /&gt;
пока не достигнута сходимость:&lt;br /&gt;
    случайно выбрать (xik, yik), 1&amp;lt;=k&amp;lt;=batch_size&lt;br /&gt;
    вычислить градиент g &amp;lt;- grad L(ω; (xik, yik), 1&amp;lt;=k&amp;lt;=batch_size);&lt;br /&gt;
    обновить веса ω &amp;lt;- ω - αg;&lt;br /&gt;
вернуть ω&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
Часто случайный выбор батча заменяют на линейный проход по всем данным. Преимущество алгоритма заключается в частом обновлении градиента и возможности использовать эффективные матричные вычисления.&lt;br /&gt;
В этой работе мы сосредоточимся на реализации градиентного спуска с мини-батчами.&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
Yujing Ma, Florin Rusu, Martin Torres. Stochastic Gradient Descent on Highly-Parallel Architectures [Электронный ресурс] // arXiv:1802.08800 [math.ST]. – 2018. – Режим доступа: https://arxiv.org/abs/1802.08800&lt;br /&gt;
&lt;br /&gt;
Sebastian Ruder. An overview of gradient descent optimization algorithms [Электронный ресурс] // arXiv:1609.04747 [math.ST]. – 2016. – Режим доступа: https://arxiv.org/abs/1609.04747&lt;/div&gt;</summary>
		<author><name>OvsyannikovaSA</name></author>
	</entry>
</feed>