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


XOR: первая сеть-классификатор


Войдите на сайт, чтобы ответы сохранялись и баллы за тетрадь засчитывались.

Как сеть выбирает класс: задача XOR

До сих пор сеть предсказывала числовую величину. При распознавании цифр вопрос устроен иначе: нужно выбрать один вариант из нескольких. Такую задачу называют классификацией, а возможные варианты — классами. Цифры от 0 до 9 образуют десять классов. Прежде чем переходить к изображениям, разберём маленькую задачу с двумя классами, чтобы все объекты и все ответы помещались перед глазами.

Задача называется XOR, или исключающее ИЛИ. На вход подаются два числа, каждое из которых равно нулю или единице. Правильный ответ равен 1, когда входы различаются, и 0, когда они одинаковы. Значит, пары (0, 0) и (1, 1) относятся к классу 0, а пары (0, 1) и (1, 0) — к классу 1. Мы знаем логическое правило, но снова не будем записывать его в вычисление модели: предоставим ей только примеры.

Входы организуем в таблицу формы (4, 2). Для каждого объекта достаточно одного правильного номера класса, поэтому метки образуют вектор формы (4,). Здесь числа 0 и 1 являются названиями вариантов. Для выбранного далее способа вычисления ошибки эти номера должны иметь целочисленный тип torch.long.



Четыре пары можно представить как углы квадрата. Объекты одинакового класса расположены по диагонали, поэтому одной прямой нельзя отделить класс 0 от класса 1. Если сравнивать два выхода линейного слоя, граница их равенства тоже будет прямой. Следовательно, одного линейного слоя для такого разделения недостаточно. Это наглядный пример того, зачем мы добавляли нелинейность: скрытый слой с ReLU позволяет построить более сложную зависимость от входов.

Соберём сеть 2 → 4 → 2. Последние два выхода будут содержать logits — числовые оценки классов до преобразования в вероятности. Первый выход относится к классу 0, второй к классу 1. Эти оценки могут быть отрицательными и не обязаны давать в сумме единицу. Чтобы выбрать ответ, достаточно найти индекс наибольшей оценки в каждой строке с помощью argmax(dim=1).



Мы получили четыре строки по две оценки и четыре номера предсказанных классов. В сети 22 параметра: (2 · 4 + 4) + (4 · 2 + 2). Пока они только инициализированы, поэтому ответы не следует воспринимать как решение XOR. Важно другое: выход модели и метки имеют разную форму по смыслу. Модель сообщает оценки всех вариантов, а правильная метка указывает один нужный вариант.

Почему правильного ответа недостаточно для измерения ошибки

Можно посчитать долю верных ответов — accuracy. Однако для обучения нам полезно знать не только, какой класс оказался первым, но и как изменяются оценки. Представьте два ответа модели: оценки [0.01, 0] и [2, 0] при правильном классе 0. В обоих случаях выбран правильный вариант, но во втором его преимущество заметно больше. Доля верных ответов не различает эти ситуации.

Для обучения будем использовать nn.CrossEntropyLoss(). Смысл этой ошибки можно понять через вероятности. Функция Softmax преобразует оценки [2, 0] примерно в [0.881, 0.119]: сначала берёт экспоненты, затем делит каждую на их сумму. Для правильного класса 0 ошибка равна -ln(0.881) ≈ 0.1269. Чем меньше вероятность, отведённая правильному классу, тем больше такой штраф. Внутри CrossEntropyLoss соответствующее вычисление организовано численно устойчиво, поэтому ей передают исходные logits и не добавляют отдельный Softmax перед функцией ошибки.



Все четыре выбранных класса в примере правильные, но ошибка положительна. Здесь нет противоречия: метрика accuracy учитывает только победивший вариант, а функция ошибки — ещё и распределение оценок. Получившийся тензор ошибки имеет форму (), то есть содержит одно скалярное значение, усреднённое по объектам. Именно от него мы запустим обратный проход.

Сам цикл обучения остаётся знакомым: очистить градиенты, вычислить logits, сравнить их с метками, выполнить backward() и обновить параметры. Разница с предсказанием числа состоит в форме выхода и выборе функции ошибки. Зафиксируем начальное состояние генератора случайных чисел, чтобы пример было легче воспроизвести, и выполним тысячу небольших шагов на всех четырёх объектах.



При указанных настройках модель получает ответы [0, 1, 1, 0], а финальная ошибка оказывается меньше начальной. Параметры были подобраны по примерам, хотя в коде прямого прохода нигде не появилось условие «если входы различаются». Это и показывает работу обучения: выбранное семейство вычислений постепенно настроилось на нужную зависимость.

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

Так же устроен будущий классификатор цифр: вместо двух входных признаков будут 64 яркости пикселей, а вместо двух выходных оценок — десять. При этом высокая оценка одного класса не гарантирует правильного ответа. Даже Softmax может дать большое значение на непривычном рисунке. Чтобы применять модель осмысленно, нужно знать, на каких данных она училась, как подготовлен новый вход и какие ошибки она допускает.

Проверим понимание

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


Logits одного объекта: [-2, 0, 3]. Какой номер класса вернёт argmax?


Все ответы верны, но CrossEntropyLoss положительна. Это…