анализ спутниковых снимков с Fastai 1.0

[Часть 1]

Этот пост - своего рода эксперимент. Меня неизменно впечатляют и сбивают с толку такие исследователи, как Лесли Смит и Джереми Ховард, качеством и объемом их работы, а также тем, насколько сложными их эксперименты кажутся со стороны. Одна из самых сложных задач в изучении искусственного интеллекта - просто отслеживать, что я делаю и почему. Как вы организуете проект, когда вы проводите несколько экспериментов параллельно и у вас есть другие дела? Ведение заметок может быть хорошей идеей…

Чтобы поэкспериментировать с лучшими экспериментами, этот пост в значительной степени является результатом написания заметок во время работы. Это уже помогло мне обнаружить несколько ошибок и отточить некоторые мысли. Но сначала резюмируем некоторые важные изменения в рабочей инфраструктуре с прошлого раза.

Часть 1.5:

Это небольшой прыжок из части 1. Короче говоря: было много борьбы за загрузку данных о планете на виртуальную машину и еще больше борьбы за то, чтобы API Kaggle заработал. Все это было заменено несколькими строчками кода в новой записной книжке курса fast.ai. Немного адаптируя это, сделано для очень быстрого процесса установки (это делается внутри ноутбука Jupyter на машине Linux):

установите Kaggle API в свою среду:

! pip install kaggle --upgrade

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

! mkdir -p ~/.kaggle/
! chmod 600 kaggle.json
! mv kaggle.json ~/.kaggle/

Создайте каталог данных (после from fastai import *):

path = Config.data_path()/'planet'
path.mkdir(parents=True, exist_ok=True)

Загрузите данные:

! kaggle competitions download -c planet-understanding-the-amazon-from-space -f train-jpg.tar.7z -p {path}

(& сделайте то же самое для test-jpg.tar.7z, train_v2.csv и test_v2_file_mapping.csv)

Разархивируйте ZIP-файл примерно так:

! unzip {path}/train_v2.csv.zip -d {path}

Разархивируйте .tar.7z вот так:

! 7za -bd -y x {path}/train-jpg.tar.7z -o{path}
! tar -xf {path}/train-jpg.tar -C {path}

И очистите файлы архива (при этом удаляются все файлы .zip, .7z и .tar в {path} рекурсивно и без запроса подтверждения):

! rm -rf {path}/*.zip
! rm -rf {path}/*.7z
! rm -rf {path}/*.tar

Вот и все. Другими важными выводами были научиться делать некоторые базовые вещи в библиотеке fastai и найти более эффективные способы для быстрого экспериментирования (например, определение пороговых значений классификации, автоматическое создание файла для отправки на их основе и загрузка в Kaggle). Думаю, я напишу небольшой пост именно по этому поводу, поскольку подобные механические / инфраструктурные вещи - самая сложная часть проекта, прежде чем вы заставите их работать, а потом покажутся настолько простыми, что вы почти забываете о них. Я поставлю здесь ссылку, когда сделаю это.

Часть 2:

Цель состоит в том, чтобы выиграть конкурс Planet Amazon Kaggle, прежде чем перейти к набору данных xView. Моя идея - использовать выигрышное решение в качестве отправной точки. Но перед этим я хочу превзойти искусственный тест: 0.93 (частный рейтинг) с ResNet34, просто чтобы убедиться, что у меня работает надежная модель.

Поначалу мне не удавалось добиться значительных улучшений по сравнению с реализацией курса fast.ai. Я попробовал «прогрессивное повторное замораживание», которое блокирует слои после размораживания модели, и оба раза неудачно, несмотря на то, что показатели валидации отображались нормально. Это привело к снижению рейтинга лидеров с ~ 0,92 до 0,3 - 0,5, если я играл с порогами. Это падение примерно с 100-го места до 920-го… из 938. Подобные сбои обычно являются результатом испорченного файла представленных материалов, но я еще не проверял, что именно произошло.

Я собирался двигаться дальше, пока не набрал 4-й лучший результат дважды за ночь. И одна из этих оценок была обучена только на 80% данных. В настоящее время это 0,92638. Но почему 4-й? Поскольку в 2017 году, следуя более ранней версии этого класса, я получил 0.92873 с ResNet34. Как я получил лучший результат с той же моделью и более ограниченной версией библиотеки fastai (0,7)?

Глядя в ту записную книжку, я обнаружил важную часть интуиции:

Сверточные слои обучаются более агрессивно, чем обычно, потому что они были предварительно обучены в ImageNet, который не содержит каких-либо спутниковых изображений. Что ж, в этом есть смысл. Вместо типичного 10-кратного изменения скорости обучения для каждой группы слоев я использовал 3-кратное. А также очень большие начальные темпы обучения (lr=0.2). (похоже, вы также более точно настраиваете линейный слой, но сначала я пропустил этот бит)

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

Примечание. Я буду иметь в виду одну и ту же модель, обученную несколькими разными способами. Чтобы это не сбивало с толку: norm-1 - это модель, которую обучили «обычно» до того, как я начал смотреть на более высокие темпы обучения. aggr-n - модель, которая обучается не так агрессивно. Обычно aggr будут иметь разность мощности-3 между группами слоев (скажем: LR / 9, LR / 3, LR), а norm-1 будет иметь мощность-10. Если не указано иное, все прогоны проходят в общей сложности 24 эпохи: длина - 6 1 цикл для каждой стадии (1: линейная, 2: полная конверсия) для каждого размера.

График размера агрессивного бега128 2-й этап:

и сравните это с размером 128 второго этапа первого прогона (norm-1):

и графики окончательных потерь (оранжевый - подтверждение) агрессивного бега:

сравните это с нормальным запуском:

Вы хотите что-то вроде последнего. OneCycle исследует пространство решений и дает резкий скачок в потерях, а затем устанавливается на почти постоянное низкое значение. Это не совсем то, что происходит в новом забеге… так что либо я слишком агрессивен, либо, может быть, мне нужно более длительное обучение, чтобы немного успокоиться; потому что этот верхний график выглядит так, будто все идет в постоянном движении.

В сторону: если вам интересно, я использую тему material-dark в jupyter lab. Я использую jupyter lab больше, чем блокнот, потому что, хотя он имеет меньше полезных расширений, чем блокнот, он имеет встроенные представления, так что вы можете просматривать несколько блокнотов или несколько частей блокнотов одновременно.

После отправки прогнозов в Kaggle ... новая модель не работает лучше. У меня есть подозрение, что это потому, что я сделал скорость обучения - все они - слишком агрессивной. Для size128 stage2 я использовал learn.lr_range(slice(lr/2/9, lr/2)) = lr/2/9, lr/2/3, lr/2, а для size256 stage2 я использовал: lr/9, lr/3, lr.

Оформляем результаты в удобочитаемую форму:

norm-1 - это модель ResNet, которая следует за записной книжкой курса fastai. aggr-1 - первая «агрессивная» модель. Я думаю, что я слишком усердно работал с моими DLR в новой модели. В некоторых случаях я тренировался с LR на 3 порядка выше, чем раньше.

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

Антракт

Я пробовал это (aggr-2), и он работал хуже, чем norm-1 или agr-1 ... Графики потерь выглядели хорошо, но я думаю, что они просто не были обучены достаточно. Глядя на цифры, модель выглядит недостаточно подходящей. Потери при обучении на 1,8% выше, чем при проверке: 0,083386 против 0,081870, пороговая точность упала примерно на сотые доли процента, а показатель fbeta вырос примерно на 0,3% с 0,924608 до 0,927831.

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

Старый блокнот начинается с размера 64, затем 128, затем 256. Я могу попробовать это.

Но перед этим…. дополнительное обучение на agr2…. дополнительный цикл длиной 6 256 этапов-2 с уменьшенными вдвое LR… на самом деле работает лучше, чем aggr2, вместо того, чтобы давать сбой. Окончательный график потерь выглядит так, как вы и ожидали:

Что ж, интересно

Здесь несколько примечаний. Первоначально я думал, что aggr1 превосходит norm1, потому что я перепутал значения для этих двух (я исправил результаты на f5). Оказывается, это не так, но дополнительное обучение действительно помогает aggr2x.

Агрессивные тренировки работают, и не похоже, что я был слишком агрессивен с LR. И, несмотря на запутанный опыт в прошлом, тренировка цикла 2-й стадии2 в конце на самом деле немного помогает модели.

Теперь пора потренироваться aggr1 (поскольку я сохранил веса, я могу просто перезагрузить его) для дополнительного цикла и посмотреть, что произойдет. Затем я попробую прогрессивное изменение размера до 64–128–256.

Антракт

Самое забавное в том, что с точностью 96% мы просто гоняемся за цифрой. Это 96% точность рассчитывается следующим образом:

((preds>thresh).float()==targs).float().mean()

Это создает тензор с горячим кодированием (например, [0.,1.,1.,0.,..]) с единицами везде, где предсказание совпадает с целевым, и с нулем во всех остальных случаях. Среднее значение возвращается как значение точности.

Прогнозы имеют пороговые значения: любые большие вероятности преобразуются в 1, иначе 0. Это сравнивается с целью (которая также является 1-горячей).

Это также скрывает тот факт, что модель может получить очень высокую точность, научившись игнорировать редкие классы (0==0) = 1. Тем не менее, в таблице лидеров F2 scores по-прежнему на высоте +0.92.

К сожалению, модель не улучшилась. Интересно, имеет ли перезагрузка модели, а затем ее дальнейшее обучение - как я сделал здесь - иной результат, чем продолжение обучения модели, над которой вы уже работаете. У меня нет времени проверять это прямо сейчас. Вместо этого пришло время постепенного изменения размера с использованием наиболее подходящей рабочей модели. Это займет не меньше часа. Что мне действительно нравится в работе ИИ, так это то, как он подталкивает вас к организованности. Если вы планируете свою работу и время ожидания, у вас будет много свободного времени.

И я думаю, что это хорошая отправная точка для этого поста. Далее будут результаты прогрессивного изменения размера от размера 64, сравнение 6-тактовой модели с 7-тактной и модель с 6-м циклом двойной длины. После этого нужно «обучить лучшего из всего набора данных и посмотреть, что у вас получится». После этого: сделайте это еще раз с ResNet50 и обратите внимание на то, справляется ли большая модель лучше с большей скоростью обучения.

После всего этого будет спешка внедрить дегазатор и посмотреть, стоит ли добавлять регрессию L2. Моя цель - начать работу с xView в понедельник, послезавтра, так что посмотрим, как это пойдет.

Прежде чем рассматривать более длинные или многократные циклы (что дало мне некоторые плохие результаты) или возвращаться к ноутбуку 2017 года, я собираюсь посмотреть, что произойдет, если я тренирую модель size256 на LR / 2 и LR / 5 (что является максимальное значение «нормальной» модели).