Один шаг против наклона сдвигает вес совсем чуть-чуть. Обучение — это повторение одного и того же: посчитать наклон, сдвинуть вес, посчитать наклон снова. Сейчас вы напишете такой цикл, и дальше в курсе он не изменится: будут меняться модели и данные, а цикл останется тем же вплоть до самых больших нейросетей.
Работать будем с функцией loss(w) = (w − 3)². Её минимум в точке 3 — туда спуск и должен прийти, и это удобно: ответ известен заранее, а значит видно, работает цикл или нет.
Всё решает скорость обучения. Расстояние до минимума на каждом шаге умножается на одно и то же число, и от него зависит, сходится спуск, качается на месте или расходится. Подбирать её придётся в каждой новой задаче, поэтому сейчас вы увидите все исходы сразу — на функции, у которой ответ известен заранее.
Подробно: Длина шага.
Задание
Напишите две функции
def step_once(w, lr): # не отличается от прошлого задания
...
def train1(w0, lr, steps):
...
Работаем с функцией loss(w) = (w − 3)², её наклон равен 2 · (w − 3), а шаг спуска устроен так:
новое w = w − lr · наклон
Функция
train1() ничего не печатает, а возвращает список значений
w после каждого шага, включая начальное: при
steps = 20 в списке 21 число.
Как проверить себя
При lr = 0.1 из нуля первый шаг даёт 0.6, а после двадцати шагов выходит 2.9654 — близко к тройке, но не ровно.
Затем прогоните тот же train1 при lr = 0.01, 0.1, 0.5, 1.0, 1.5 и назовите, что происходит в каждом случае. Их пять, и все пять разные. Подсказка: посчитайте для каждого lr число 1 − 2 · lr и сверьте со своими наблюдениями.
Числа сравниваются с допуском, а не как строки: достаточно совпадения в первых четырёх знаках. Печатать ничего не надо — функция возвращает значение.