Интуиция и реализация

Введение

"Привет мир!" Меня зовут Мэтью, и это моя первая запись в мире Medium. Я специалист по данным, который строит вещи с помощью чисел и компьютеров. Не нужно заморачиваться историей моей жизни; Никто из вас не пришел сюда за этим.

Эта статья направлена ​​на то, чтобы затронуть два основных момента:

  1. Развиваем интуитивное представление моделей стекирования. Я видел так много хороших объяснений для пятилетних детей по бэггингу и бустеру, но редко по стекингу.
  2. Предоставление управляемого примера для реализации нейронной сети с накоплением с использованием метода создания подклассов Кераса.

Без дальнейших церемоний…

Интуиция и метаобучение

Время истории

Давайте вернемся в школьные годы и представим себе милого молодого человека по имени Кальвин. Его домашний экзамен по математике должен быть сдан завтра, и, хотя учитель предупредил, что работа в группах ослабит его образование в целом, мы все знаем, что он собирается сделать: позже в тот же день мы найдем его с его друзьями, Алисой. и Бобби, как один справлялись с экзаменом.

Во-первых, давайте прольем свет на эту группу друзей. Алисса — прилежная ученица, которая получает пятерки на каждом экзамене, независимо от предмета. Однако она довольно высокомерна в отношении своего интеллекта и вряд ли прислушается к чужому совету или мнению. Бобби немного более средний, но у нее есть определенный дар к сходимости рядов, что является одной из тем, рассматриваемых в этом конкретном тесте. А Кальвин? Что ж, мне неприятно это говорить, но он бы провалился, если бы не два его приятеля. К счастью, они не против помочь ему.

Через несколько дней результаты тестов возвращаются:

Алиса: 92%

Бобби: 83%

Кэлвин: 94%

В ярости Алисса кричит на него: «Как это возможно!? Ты даже не выучил материал, тупица! Посмеиваясь себе под нос, Кэлвин отвечает: «Но я определенно выучил вас двоих». Он скопировал большинство ответов Алиссы, но когда ее ответы, связанные с сериалом, отличались от ответов Бобби, он встал на сторону Бобби. Теперь ему остается только надеяться, что это не викторина...

Метаобучение и ансамбли

Давайте начнем обобщать: Модель A = Алисса, Модель B = Бобби, и, барабанная дробь, пожалуйста… Модель C = Кэлвин. И Алисса, и Бобби учились более традиционным способом из учебников и практических задач, но Кальвин придерживался другого подхода к обучению. Вместо того, чтобы изучать материал, он изучил детали и тонкости того, как Алисса и Бобби учились и выступали! Это именно то, что представляет собой метаобучение: изучение об обучении.

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

Хотя заманчиво просто выбрать модель, которая показала наилучшие результаты, знайте, что точность (или любой другой показатель, который вы используете для «качества модели») не является полной мерой того, что имеет ваш весь набор моделей. научился. Да, Алисса может быть лучше, чем Бобби в целом, но у Бобби есть свои сильные стороны, и если мы сможем придумать, как объединить их вместе с Алиссой, мы потенциально сможем затмить их индивидуальные выступления. Это подводит нас к идее ансамблевых моделей: использование нескольких моделей в унисон для достижения лучшего результата.

«Ансамблирование» — это широкая идея, и есть несколько способов сделать это. Популярная пара известна как бэггинг и бустер. В первом используется та же базовая модель, но она адаптирована к другим версиям с передискретизацией (самозагрузка) исходных данных. Затем эти модели объединяются в ансамбль. Этот метод полезен для уменьшения дисперсии модели. Последний метод, повышающий, фокусируется на обучении последовательности моделей, где каждая последующая модель направлена ​​​​на исправление ошибок, которые были у предыдущих моделей; этот метод лучше подходит для уменьшения смещения модели. Эти две концепции требуют подробного обсуждения.

Стекирование

В оставшейся части этой статьи мы сосредоточим внимание на другом ансамблевом методе, стекинге. Идея стекирования четко соответствует приведенному выше примеру нашего студента: возьмите две или более базовых модели, которые выполняют одну и ту же задачу классификации, и позвольте новой модели, мета-обучаемому, взять прогнозы всех базовых моделей и собрать свои собственные. прогноз. Именно это и произошло между Алиссой, Бобби и Кэлвином. Хорошая новость заключается в том, что результаты этой истории можно применить и к машинному обучению…

С оговоркой.

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

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

Реализация(веселое)

Прежде чем мы углубимся в это, давайте подведем итог всех инструментов, которые мы будем использовать:

  1. Keras, TensorFlow 2 (ускорение графического процессора), Python 3
  2. Цифры MNIST как наш игрушечный набор данных
  3. Собаки против кошек, набор данных Kaggle

Наш план атаки состоит в том, чтобы сначала создать CNN, которая будет служить базовой моделью. Это само по себе сможет выполнять классификацию изображений. Мы допускаем некоторую гибкость в специфике модели, чтобы мы могли создавать множество CNN, отличающихся друг от друга по структуре. Далее мы создадим полную модель, которая будет включать обучение CNN и подключение всех баз к мета-обучаемому (простому ANN). Наконец, мы применим эту модель стекирования к реальным наборам данных и посмотрим, как она работает. Приступим к делу.

Базовая модель (сверточная нейронная сеть)

Во-первых, давайте создадим базовую модель. Мы собираемся работать с архитектурой LeNet, распространенным подходом к классификации изображений. LeNet состоит из двух основных частей: части извлечения признаков и части классификации. Первый отвечает за выбор релевантных частей изображения, а второй объясняется только его названием. Смотрите здесь для более подробного описания LeNet или следуйте в следующих двух абзацах для общей идеи.

Извлечение признаков:

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

Классификация:

После части извлечения признаков у нас останется изображение формы (высота, ширина, количество каналов). Все фактические значения будут напрямую зависеть от размера входного изображения и части извлечения признаков модели, но все, что нам нужно знать на данный момент, — это структура тензора, на который мы смотрим. Это изображение передается в сглаживающий слой, который преобразует тензор в вектор длины, высоты * ширины * каналов. Затем остальная часть CNN выполняется полностью связанными слоями с активацией softmax в конце. Обратите внимание, что нам нужно будет указать наш последний слой, чтобы включить столько узлов, сколько у нас есть категорий в наших данных.

Наконец, давайте перейдем к коду. Мы собираемся использовать Keras и его схему подклассов для построения этой модели; это особенно хорошо для создания нестандартных моделей машинного обучения. Кроме того, если вы в душе объектно-ориентированный программист, это, вероятно, для вас. Для заинтересованного читателя вот репозиторий исходного кода, который можно запустить самостоятельно. Примечание. Часть кода была изменена для краткости. Исходный код и Gists не будут идентичными.

Мы будем работать с родительским классом Keras Model. Есть два необходимых компонента для создания подкласса модели Keras (или слоя Keras). Во-первых, вам нужно обновить метод инициализации, чтобы включить все слои, которые вы будете использовать. Во-вторых, вам нужно написать метод вызова, который указывает, как входные данные будут поступать в конечный результат в модели.

Начнем с нашего метода инициализации. Мы добавили здесь несколько параметров, которые дадут нам гибкость для настройки структуры нашей базовой модели, чтобы мы могли позже создать несколько таких плохих парней. Предполагается, что параметры dense_units и conv_features являются списками, которые дают нам подробную информацию о плотных слоях и сверточных слоях в LeNet. Например, dense_units =[20, 30] даст нам полностью связанный слой из сплющенного изображения с вектором размером 20, за которым следует еще один полностью связанный слой размером 30, и conv_features = [16, 32] даст нам сверточный слой с 16 фильтрами, за которым следует (после максимального объединения) еще один сверточный слой с 32 фильтрами.

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

Переходя к нашему методу вызова, мы фактически конструируем порядок слоев. Наш ввод перемещается в цикл сверточных/максимальных слоев, за которыми следуют итерации полностью связанных слоев. Это соответствует первому извлечению признаков с последующей классификацией.

Поскольку мы унаследовали от keras.Model, теперь мы можем продолжить компиляцию и настройку нашей CNN… но это не то, что нам нужно. Вместо этого мы хотим сгенерировать несколько CNN для использования в более крупной модели. Но с чего же нам начать? Что ж, нам нужна другая модель, не вписывающаяся в схему, которую мы только что написали. Нам нужно закодировать еще один подкласс.

Модель стекирования (ансамбль)

Здесь та же стратегия: инициализировать слои модели, а затем вызывать их в правильном порядке на входе. «Но один из слоев, ввод мета-обучаемого, полностью зависит от других моделей», — можете подумать вы. Ну не будем об этом думать! В рамках метода init давайте обучим внутренние CNN*. Мы включим средства передачи параметров компиляции/подгонки нашей базовой модели при создании экземпляра.

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

Затем определяются наши мета-обучающие слои: единственное, что здесь следует отметить, это то, что полностью подключенный слой после выходных данных базовой модели выбирается таким образом, чтобы он был в два раза больше, чем конкатенация последних слоев в базовых моделях. Это произвольно, но в целом было бы неплохо убедиться, что этот слой как минимум больше, чем слой конкатенации.

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

Результаты и обсуждение

Я не буду вдаваться в код, связанный с очисткой данных; Я просто дам несколько кратких описаний соответствующих частей здесь и там, но не стесняйтесь копаться в репозитории проекта. Начнем со старого надежного.

Цифры MNIST

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

Мы создадим три базовые модели и изменим размер сверточных и полносвязных слоев, чтобы каждый из них немного отличался друг от друга. Для сверточных слоев обычной практикой является установка выходного канала в степени 2 (в основе этого лежит аппаратная оптимизация). Мы также хотим, чтобы набор функций распространялся на сеть, поэтому мы обязательно отсортируем количество выходных каналов от меньшего к большему. Для плотных слоев… У меня нет особых причин выбирать какие-то размеры, поэтому давайте просто возьмем [100, 500]. Ниже приводится краткий обзор моделей и итоговой точности испытаний.

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

Собаки против кошек

Этот набор данных состоит из изображений собак и кошек с 12 500 изображениями для обучения. Опять же, это сбалансированный набор данных, поэтому давайте двигаться вперед, используя точность в качестве нашей метрики. Поскольку эта задача сложнее, чем предыдущая, мы будем использовать 5 базовых моделей с большим количеством сверточных выходных каналов, а также с большими плотными слоями для классификации.

Поскольку эта модель классификации более сложна, во избежание переобучения использовались как ранняя остановка, так и снижение скорости обучения (на плато потерь при проверке). Увеличение данных (горизонтальное переворачивание, небольшие повороты, сдвиг и небольшие сдвиги по ширине/высоте) также использовалось для повышения точности модели. Обучение проводилось в течение 50 эпох максимум с пакетным градиентным спуском с использованием оптимизатора RMSProp. Я хотел бы отметить пользователя Kaggle Uysim, чье ядро было неоценимо для работы с частями обработки данных.

Лучше! У нас есть заметное увеличение точности теста при сравнении нашей лучшей базовой модели и нашего ансамбля. Поскольку мы потратили время на перечисление деталей метода обучения (не говоря уже о времени, проведенном на самом обучении), давайте вознаградим себя красивым визуальным изображением точности/потери проверки каждой базовой модели в течение всего периода настройки.

Приведенные выше графики — хорошее напоминание о том, насколько сильно выбор гиперпараметров может повлиять на нашу модель. Учитывая наши самые слабые и самые сильные базовые модели, мы видим разницу почти в 12% с точки зрения точности окончательной проверки.

Если немного порассуждать, возможно, что базовая модель номер 1 — это, так сказать, наша «Алисса». Невозможно сказать, насколько наша стековая модель использует каждую базовую модель, не глядя непосредственно на веса плотных слоев, соединяющие все с мета-учеником. Насчет нашего «Бобби» я в полной растерянности: это может быть любая комбинация базовых моделей.

Но мы с уверенностью можем сказать, что наш «Кальвин», программа метаобучения, действительно узнала что-то полезное о наших базовых моделях и превзошла своих конкурентов. Стоил ли выигрыш в точности времени, затраченного на создание самого ансамбля, каждый должен решить для себя сам.

Или, если у вас есть боссы, инвесторы или акционеры, они вполне могут сами рассказать вам об этом на менее чем хорошем уровне децибел. Всегда помните о своей цели и о том, что для вас означает «достаточно хорошо».

Заключительные мысли

Меня беспокоит то, что третья базовая модель (состоящая из сверточных фильтров, расширяющихся с 8 до 16 и далее до 32) не была стабильной в процессе подгонки. Вполне вероятно, что для обработки набора данных о собаках и кошках потребуется большее количество фильтров. Это также подтверждается тем, что его 4 аналога работают лучше практически во всех отношениях.

Я доволен моделью, поскольку она демонстрирует идею стекирования. Забавно, что точность валидации собак и кошек составила примерно 94%, такую ​​же оценку я дал Кальвину в начале статьи. Это было не намеренно, а счастливая случайность.

Есть улучшения, которые нужно сделать, и другие возможности для изучения. Один конкретный путь, который я хотел бы изучить, — это реализация ансамбля с совершенно разными базовыми моделями, выходящими за рамки возможностей (и ограничений) нейронных сетей. Другие вещи, которые все еще могут быть скорректированы в рамках этой существующей структуры, включают размер фильтра CNN, более глубокие сети и многие другие настройки гиперпараметров.

Для тех из вас, кто дочитал до этого места, спасибо за ваше время. Если у вас есть какие-либо комментарии/предложения/критика, пожалуйста, оставьте комментарий. У меня есть много мест, где можно улучшить, будь то теория, программирование или письмо.

Звездочки

(*) Если у кого-то из читателей есть мысли или предложения по улучшению подхода к этой конкретной части, я был бы признателен, если бы они были услышаны. В производственной среде, я уверен, есть более идеальные способы сделать это.

(**) Я упомянул выше, что сделал выбор, чтобы мои базовые модели оставались «необучаемыми» после начала обучения модели с накоплением. Этот выбор был сделан исключительно на том, что весь этот процесс производился на домашнем компьютере. Конечно, мой домашний ПК неплох, но я уверен, что не втисну все 5 весов базовой модели ПЛЮС веса мета-обучения на мой GPU одновременно. Не говоря уже о том, что время обучения такого зверя будет значительно хуже, чем обучение 5 баз, а затем оставление их фиксированными. Стоит отметить, что этот выбор также имеет некоторые математические последствия: исправление базовых моделей накладывает ограничения на функцию потерь нашей модели с накоплением. Кое-что, чтобы иметь в виду, если вы когда-нибудь планируете построить ансамбль.

Смотрите больше на моем основном сайте: http://matthewcampbell.io