Обычно есть два способа выбрать скорость обучения для нейронной сети. 1. Использование фиксированной скорости обучения и 2. Использование планировщика скорости обучения. Здесь я покажу вам третий метод. Используемый код можно найти здесь.
Метаобучение можно рассматривать как «обучение, чтобы учиться». Проще говоря, мы берем систему, состоящую из нескольких компонентов, и обучаем другую систему изучению одного из этих компонентов.
Представьте, что у нас есть нейронная сеть. Обычно мы просто тренируем его от начала до конца, используя некоторые данные, функцию потерь и гиперпараметры. Но если подумать, эта нейронная сеть имеет несколько компонентов, которые мы обычно принимаем как должное. Например, правило обновления (например, градиентный спуск), количество нейронов в слое, оптимизаторы или скорость обучения. Обычный подход заключается в том, чтобы экспериментально попробовать множество таких компонентов, например, попробовать различное количество слоев или оптимизаторов и посмотреть, какие из них работают лучше всего. Однако что, если вместо этого мы могли бы просто обучить другую нейронную сеть обучению такому оптимальному компоненту? Это то, что я покажу здесь. В частности, вместо того, чтобы экспериментально выбирать скорость обучения, пробуя разные и наблюдая, какая из них работает лучше всего, мы будем обучать нейронную сеть (НС) выводить такую скорость обучения.
Задача, над которой мы будем работать — MNIST. В частности, мы будем обучать нейросеть классифицировать цифры с помощью PyTorch. Я довольно быстро расскажу об основах, поэтому вам может понадобиться освежить в памяти Pytorch, NN, Python и т. д., если это было давно.
Рассмотрим следующую полносвязную (FC) нейронную сеть. И да, обычно мы не используем сеть FC для изображений, но цель здесь не в том, чтобы получить лучшую систему, а в том, чтобы научиться использовать метаобучение.
Эта сеть состоит из 4 слоев, каждый из которых содержит 64 нейрона (кроме последнего, содержащего 10). В прямом методе мы сначала берем изображение размером 28x28, сглаживаем его в вектор длиной 28*28*1, а затем передаем этот вектор на первый слой NN.
Обычно мы либо выбираем фиксированную скорость обучения:
Или выберите планировщик скорости обучения.
Здесь мы используем простой оптимизатор стохастического градиентного спуска.
Цикл обучения часто выглядит так:
Мы перебираем количество эпох, загружаем наши входные данные и метки из нашего загрузчика данных (x и target соответственно), отправляем их в нашу NN, получаем потери на основе прогнозов и меток и меняем параметры NN с помощью оптимизатора.
Часть метаобучения
Вместо того, чтобы использовать фиксированную скорость обучения, давайте обучим другую NN, чтобы она сообщала нам, какая скорость обучения является наилучшей для этой сети. В общих чертах это выглядит примерно так:
Вы можете думать об этом как о 2 петлях. Во внутреннем цикле мы делаем то же самое, что и только что: получаем партию, потери и обновляем простую NN. Выходной цикл не сложнее этого. Помните, что для обучения NN нам нужна функция потерь. То есть мы отправляем наши входные данные, получаем прогнозы и на основе меток и функции потерь (перекрестная энтропия в простой NN) получаем некоторые потери.
Для обучения модели метаобучения мы делаем то же самое. Единственное, о чем вам нужно подумать, это: какие входные данные вы хотите отправить.
Например, здесь я просто буду использовать общие потери, накопленные в простой нейронной сети, в качестве потерь для модели метаобучения. Где интуиция такова, что более высокая скорость обучения приведет к меньшим потерям.
Модель метаобучения снова представляет собой простую нейронную сеть:
Модель метаобучения принимает 1 вход (в данном случае общий накопленный убыток) и выводит 1 вывод (скорость обучения).
Обратите внимание, что это немного отличается от того, как обычно работает планировщик скорости обучения. Эта модель метаобучения основана на потере сети на каждом этапе, в то время как планировщики обычно основаны на размере шага.
Проще говоря, наша модель метаобучения адаптирует скорость обучения на основе потерь модели (представьте, что у вас более высокая скорость обучения, когда потери велики, и меньшая скорость обучения, когда потери низки), а не на фиксированном шаге.
Полученные результаты
Мы видим, что когда потери низкие (слева) и близки к 0, метамодель выдает меньшую скорость обучения (около 0,01). В то время как, когда потери выше (ближе к 1), выходная скорость обучения выше (около 0,08).
Мы также можем сравнить точность теста в одной и той же простой нейронной сети, используя несколько фиксированных скоростей обучения и адаптивную скорость обучения метамодели:
Мы видим, что скорость мета-обучения превзошла все остальные скорости обучения (хотя я пробовал только 3 случайных).
Попробуйте разные входные данные для метамодели и посмотрите, сможете ли вы превзойти ее. Вы также можете попробовать научить метамодель учиться разным вещам, как указано выше.
Если вас интересуют другие мои работы, вы можете посетить мой Github, мою научную страницу или мой веб-сайт.