К списку задач
Средне Решено: 0 Процент решений: 0%

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

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

Чему вы научитесь

  • Делить данные на батчи
  • Обновлять веса после каждого батча
  • Сравнивать пакетное, мини-батч и стохастическое обучение

Условие

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

Обучите y = w × x + b по среднеквадратичной ошибке, начиная с w = 0 и b = 0. В каждой эпохе разбивайте примеры по порядку на батчи по batch_size (последний батч может быть меньше). Для каждого батча размера n:

  1. errorᵢ = w × xᵢ + b - yᵢ для каждого примера в батче
  2. dw = (2 / n) × Σ errorᵢ × xᵢ и db = (2 / n) × Σ errorᵢ
  3. w ← w - learning_rate × dw и b ← b - learning_rate × db

Реализуйте train_mini_batch(xs, ys, batch_size, learning_rate, epochs).

Входные данные

xs, ys: Точки данных (одинаковой длины).

batch_size: Число примеров в батче.

learning_rate, epochs: Размер шага и число проходов по данным.

Выходные данные

Верните [w, b] после обучения.

Ограничения

1 ≤ число точек ≤ 1 000, 1 ≤ batch_size ≤ число точек, 0 ≤ epochs ≤ 1 000

0 < learning_rate ≤ 1

-100 ≤ каждое значение ≤ 100

Примеры

Пример 1
Ввод:
xs = [1.0, 2.0, 3.0]
ys = [2.0, 4.0, 6.0]
epochs = 1
batch_size = 2
learning_rate = 0.1

Ожидаемый вывод:
expected = [2.44, 1.08]
Ввод:
std::vector<double> xs = {1.0, 2.0, 3.0};
std::vector<double> ys = {2.0, 4.0, 6.0};
long long epochs = 1;
long long batch_size = 2;
double learning_rate = 0.1;

Ожидаемый вывод:
std::vector<double> expected = {2.44, 1.08};
Ввод:
double[] xs = new double[] {1.0, 2.0, 3.0};
double[] ys = new double[] {2.0, 4.0, 6.0};
long epochs = 1;
long batch_size = 2;
double learning_rate = 0.1;

Ожидаемый вывод:
double[] expected = new double[] {2.44, 1.08};

Пояснение

Батч 1 — это x = [1, 2]: ошибки -2 и -4, dw = -10, db = -6, поэтому w = 1 и b = 0.6. Батч 2 — только x = [3]: ошибка 1×3 + 0.6 - 6 = -2.4, dw = 2 × (-2.4) × 3 = -14.4 и db = -4.8, поэтому w = 2.44 и b = 1.08. Результат: [2.44, 1.08].

Пример 2
Ввод:
xs = [1.0, 2.0, 3.0, 4.0]
ys = [3.0, 5.0, 7.0, 9.0]
epochs = 1
batch_size = 4
learning_rate = 0.05

Ожидаемый вывод:
expected = [1.75, 0.6]
Ввод:
std::vector<double> xs = {1.0, 2.0, 3.0, 4.0};
std::vector<double> ys = {3.0, 5.0, 7.0, 9.0};
long long epochs = 1;
long long batch_size = 4;
double learning_rate = 0.05;

Ожидаемый вывод:
std::vector<double> expected = {1.75, 0.6};
Ввод:
double[] xs = new double[] {1.0, 2.0, 3.0, 4.0};
double[] ys = new double[] {3.0, 5.0, 7.0, 9.0};
long epochs = 1;
long batch_size = 4;
double learning_rate = 0.05;

Ожидаемый вывод:
double[] expected = new double[] {1.75, 0.6};

Пояснение

Батч размером с весь набор данных — это обычный пакетный градиентный спуск: одно обновление за эпоху. Результат: [1.75, 0.6].

Как подступиться

Сначала попробуйте сами, затем открывайте подсказки по одной.

Подсказка 1

Обрабатывайте примеры в заданном порядке и обновляйте параметры после каждого batch, а не после каждой точки.

Подсказка 2

Для каждого batch сначала вычислите ошибки предсказания, затем используйте их средние вместе со значениями x, чтобы получить два градиента.

Подсказка 3

Последний batch может быть меньше остальных, поэтому масштабирование градиента должно использовать его размер.

Ожидаемая сложность

O(epochs × n) по времени, O(1) по дополнительной памяти

Ссылки

Это задание адаптировано для CodeUtility. Следуйте условию и ограничениям выше.

Учитесь у других

Решения сообщества

Пока нет опубликованных решений. Решите задание, чтобы поделиться первым.