Модуль: PyTorch. Теория: как обучается нейросеть


Связь понятий и самопроверка


От картинки до ответа: соберём весь рассказ

Вернёмся к рукописной семёрке, с которой началось знакомство с PyTorch. Теперь мы можем описать её путь через модель без слов «компьютер сам догадался». Сначала изображение должно быть представлено в том же формате, что и обучающие примеры. В предстоящей практике это картинки 8 × 8, то есть 64 значения яркости. Мы приведём их к нужному диапазону и расположим каждое изображение отдельной строкой. Так получится входной тензор, у которого понятны форма, тип и смысл значений.

Затем начнётся прямой проход. Линейный слой соберёт из пикселей взвешенные суммы, ReLU нелинейно преобразует промежуточные значения, а следующий слой выдаст десять оценок классов. Можно сказать, что скрытый слой строит новые признаки, полезность которых определяется обучением. Но не стоит автоматически приписывать каждому нейрону понятное человеку значение вроде «детектор перекладины»: такое объяснение нужно отдельно проверять, а не выводить только из наличия скрытого слоя.

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

Что меняется, когда мы обучаем модель

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

Так соединяются все части процесса. Тензоры хранят данные, слои задают вычисления, функция ошибки формулирует, какой результат считается удачным, а оптимизатор определяет правило изменения параметров. Ни одна часть не заменяет другую. Корректный обратный проход не исправит перепутанные метки. Большое число эпох не исправит случайное смешивание объектов при изменении формы. Низкая обучающая ошибка сама по себе не докажет хорошего распознавания новых картинок.

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

Почему тестовая цифра должна быть новой для обучения

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

При этом один процент точности не рассказывает всей истории. Стоит посмотреть, какие цифры путаются, насколько сами изображения различимы и как результат сравнивается с простым способом решения. Например, можно предсказывать цифру по ближайшим обучающим картинкам. Такой ориентир помогает понять, принесла ли нейросеть пользу в конкретном опыте. Более сложный метод не обязан победить только потому, что у него больше слоёв или он называется нейросетью.

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

Что происходит с рисунком, сделанным от руки

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

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

Самопроверка перед практикой

Сначала ответьте самостоятельно. Для вопросов с вычислениями запишите промежуточные шаги; для остальных достаточно объяснения своими словами. Если ответ не получается, вернитесь к соответствующему месту рассказа и восстановите связь между данными, вычислениями и результатом.

  1. На вход nn.Linear(5, 3) подана таблица формы (12, 5). Каковы формы весов, смещений и результата?
  2. Почему A * B и A @ B могут давать разные числа, даже если обе операции допустимы?
  3. Что произойдёт при сложении тензоров форм (8, 4) и (4,)?
  4. Как представить двадцать изображений 8 × 8 для линейного слоя с 64 входами, сохранив отдельную строку для каждого изображения?
  5. Что означает X.sum(dim=0), если строки — объекты, а столбцы — признаки?
  6. При x=3, y=2, w=0.5, b=0.1 найдите предсказание, ошибку L=0.5*(w*x+b-y)**2 и производные по весу и смещению.
  7. В единственной цепочке z=w*x+b, a=ReLU(z), pred=v*a получилось z=-1. Какой градиент придёт к весу w и почему?
  8. Восстановите порядок нашего шага обучения: вычисление ошибки, очистка градиентов, обновление параметров, прямой проход, обратный проход.
  9. В цикле каждый раз заново вычисляют ошибку, вызывают backward() и step(), но нигде не очищают градиенты. Что изменится?
  10. Почему два линейных слоя без нелинейности не решают проблему XOR?
  11. Почему для четырёх объектов XOR оценки имеют форму (4, 2), а номера правильных классов — (4,)?
  12. Что нужно передать в CrossEntropyLoss: исходные logits или результат отдельного Softmax? Объясните выбор.
  13. Что доказывают четыре верных ответа на четырёх булевых входах XOR и чего этот опыт не показывает?
  14. Почему при применении модели рядом используют eval() и no_grad()?
  15. Почему нельзя просто загрузить веса сети 2 → 4 → 2 в сеть 2 → 8 → 2?
Объяснения для сверки

В первом вопросе форма весов равна (3, 5), смещений — (3,), выхода — (12, 3). Во втором поэлементное умножение нужно отличить от суммирования произведений строки и столбца. В третьем вектор из четырёх элементов прибавляется к каждой из восьми строк, и получается форма (8, 4). В четвёртом нужна форма (20, 64). В пятом складываются значения разных объектов отдельно для каждого признака.

В шестом вопросе предсказание равно 1.6, ошибка — 0.08. Производная ошибки по предсказанию равна -0.4, поэтому производная по весу составляет -0.4 · 3 = -1.2, а по смещению — -0.4. В седьмом ответ равен нулю: на отрицательном входе ReLU перекрывает данный обратный путь. В восьмом порядок такой: очистка, прямой проход, ошибка, обратный проход, обновление. В девятом к новым градиентам будут добавляться прежние, что меняет задуманный алгоритм.

В десятом вопросе два линейных преобразования без нелинейности сводятся к одному, а XOR не разделяется одной линейной границей. В одиннадцатом каждому объекту нужны две оценки возможных классов, но лишь один номер правильного класса. В двенадцатом передаются logits: необходимое преобразование уже входит в вычисление ошибки. В тринадцатом проверена вся булева таблица XOR, но ничего не установлено о произвольных вещественных входах или других задачах.

В четырнадцатом вопросе eval() переключает поведение зависимых от режима слоёв, а no_grad() отключает отслеживание производных. В пятнадцатом размеры параметров не совпадут: количество скрытых нейронов изменилось. Для восстановления результата нужно знать совместимую архитектуру, сами параметры и правила подготовки входных данных.

Где уточнить детали

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