Команда

Резюме части 1

В нашем предыдущем посте мы представили нашу проблему и набор данных, которые представляли собой проблему классификации с несколькими метками, в которой мы должны правильно отличить болезнь листа маниоки от группы из 5 различных болезней листьев маниоки. Мы провели EDA для нашего набора данных и обнаружили, что класс большинства (болезнь мозаики кассавы) занимает более 60% набора данных. Хотя это заболевание составляет значительную часть нашего набора данных, можно возразить, что набор данных нельзя действительно считать несбалансированным, в отличие от наборов данных обнаружения аномалий, где данные во многих случаях несбалансированы в соотношении 90 к 10.

После EDA мы применили модель логистической регрессии к нашему набору данных в качестве базовой модели. Мы решили использовать логистическую регрессию, потому что она широко известна как простейший и наименее сложный алгоритм классификации в машинном обучении. Наши базовые результаты дали точность 50%.

И что теперь?

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

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

Команда «CSV + Raw Images» - Шуя и Алекс

Как упоминалось ранее, Шуя и Алекс импортировали необработанные изображения и сопоставили их с сопоставлениями меток файлов в файле csv. Они заметили, что каталог с необработанными изображениями содержит лишние изображения. То есть были посторонние изображения, которые не были сопоставлены ни с одним изображением. Затем они удалили эти изображения из набора данных.

Чтобы загрузить набор данных, чтобы он был применим к нашим методам глубокого обучения, они создали два отдельных списка: один для изображений, а другой - для этикеток. Используя imutilslibrary, они проанализировали изображения в нашем каталоге изображений и преобразовали их в массивы numpy, используя cv2. Метки изображений были взяты из фрейма данных, созданного путем считывания сопоставлений файлов с метками. После того, как все изображения и метки были собраны, они оба были преобразованы в массивы numpy, а изображения были масштабированы таким образом, чтобы их значения пикселей были между 0 и 1. Затем метки были закодированы в горячем режиме. Затем данные были разделены 85/15 с использованием train_test_split. Изображения были дополнены с помощью ImageDataGenerator. Из-за ограниченного объема оперативной памяти единовременно можно было обучать только 1000–2000 образцов. Еще больше - и Колаб рухнет.

Команда «TFRecord» - Кевин

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

Сначала я подключился к доступным каталогам TFRecord. Файлы TFRecord можно анализировать в соответствии с различными функциями, в зависимости от типа данных, хранящихся в файле. После проверки файла наш TFRecord содержал три функции, которые можно анализировать: «изображение», «имя_образа» и «цель». Затем я определил несколько вспомогательных функций, которые разделяли ответственность за анализ файла TFRecord, предварительную обработку изображений и объединение этих изображений в набор данных TFRecord. Вместо того, чтобы храниться в списках Python, структура данных, содержащая мои проанализированные данные, была набором данных TFRecord с кортежами (изображение, метка). Последним шагом перед обучением было перемешивание файлов TFRecord и их разделение на обучающий набор и тестовый набор. Для этого я реализовал вспомогательную функцию, которая выполняет разделение на обучение / проверку / тестирование 60/20/20.

В отличие от необработанных изображений Team CSV +, я смог обучить модели на всех ~ 21 000 изображений, а не на 1000–2000. Shoutout Colab Pro.

Теперь давайте посмотрим, как работают наши модели с данными, и диагностируем поведение, лежащее в основе их работы.

Исследование производительности различных архитектур CNN

Мы применили трансферное обучение к четырем различным архитектурам CNN: ResNet50, VGG16, VGG19 и DenseNet169. Все модели были предварительно загружены ImageNet грузами. Затем эти веса были заморожены и стали недоступными для тренировки. Для каждой архитектуры применялось увеличение данных, а также различные методы регуляризации. К ним относятся обратные вызовы EarlyStopping, планировщики скорости обучения и уровни исключения. Поскольку мы заморозили веса по умолчанию, мы реализовали полностью связанные слои с обучаемыми параметрами, которые соединяют базовую модель с выходом. Поскольку у нас есть 5 классов, наш выходной слой был плотным слоем с softmax активацией.

ResNet50

ResNet50 - это архитектура CNN, в которой используются остаточные блоки. Основная предпосылка ResNet, по словам его авторов, заключается в том, что «каждый дополнительный уровень должен легче содержать функцию идентификации в качестве одного из своих элементов». Чтобы упростить эту предпосылку, ResNet изучает остаточные отображения (f (x) -x), а не только f (x). Ниже мы сравниваем различия между обычным сверточным блоком и остаточным блоком.

Алекс и Шуя обучили ResNet50 на 2000 из 21397 доступных изображений. Как я уже сказал, это было максимальное количество изображений, которое можно было разместить в оперативной памяти. Что-нибудь выше, и мы выбежим. После замораживания базовой модели ResNet50 они добавили три базовых слоя с тремя слоями Dropout, которые подключились к выходному слою. Они обучили модель с размером пакета 16 и скоростью обучения 0,001 для 30 эпох.

Ниже мы наблюдаем, что потери в обучении резко уменьшаются через 2–3 эпохи, в то время как потеря валидации снижается менее резко. Они продолжают минимально колебаться около 1,25 на протяжении 30 эпох. Интересно, что мы наблюдаем небольшое снижение точности как обучения, так и проверки, прежде чем они отскочат и сгладятся. Фактически, точность проверки остается идентичной с точностью 0,6 для эпох с 3 по 30, тогда как точность обучения делает невероятно незначительные колебания. Это странное поведение; однако это то, что мы обычно видим в наших тренировочных процессах. Мы немного рассмотрим причины этого.

Кевин обучил ResNet50, используя ту же выходную архитектуру, что и Шуя и Алекс, и получил такие же странные результаты. На этот раз точность обучения колеблется в пределах точности проверки.

VGG16 / VGG19

Затем мы обучили VGG16 и VGG19, которые являются вариантами архитектуры VGG, изобретенной группой Visual Geometry Group в Оксфордском университете. Предшественники VGGNet обучили большую последовательную цепочку компонентов нейронной сети, включая сверточный слой, нелинейность и объединение. VGGNet преобразовала эти базовые элементы в блоки и впервые применила переход от обучения отдельных нейронов к обучению целых блоков.

Шуя и Алекс тренировали как VGG16, так и VGG19 со скоростью обучения 0,001 и размером пакета 16 за 30 эпох. Как и в ResNet50, они подключили три полностью связанных слоя между базовой моделью и выходными слоями.

Мы наблюдаем, что VGG19 более численно стабилен при обучении, чем ResNet50. Однако мы не наблюдаем особого обучения в сети. Точность обучения незначительно повышается, а точность проверки в значительной степени нестабильна, снова колеблясь около 0,61. Потери как при обучении, так и при проверке постепенно уменьшаются.

Мой VGG19 показал необычное поведение. В то время как точность обучения и проверки показывает здоровое, постепенное снижение, точность обучения и проверки выражает своеобразное поведение. Во-первых, точность обучения почти всегда ниже, чем точность проверки. Во-вторых, точность обучения и проверки была довольно низкой, около 12%. Через 2 эпохи точность проверки быстро выросла до 61% и оставалась на том же уровне до конца обучения.

Модель VGG16 Алекса и Шуи демонстрирует более нормальное поведение, чем модели VGG19, описанные выше. Однако мы по-прежнему замечаем колебания, которые, как нам кажется, можно сгладить. Эта модель была нашей самой эффективной моделью с максимальной точностью проверки 74%.

DenseNet169

DenseNet можно рассматривать как расширение ResNet. В то время как ResNet разделяет функции на линейный член и более сложную нелинейную функцию, выходы DenseNet объединяются, а не складываются. Это означает, что чем дальше мы продвигаемся в обучении, тем сложнее становятся наши функции. DenseNet использует плотные блоки и переходные уровни, которые управляют объединением входов и выходов и количеством каналов соответственно. Каждый плотный блок использует одинаковое количество выходных каналов, и они регулируются переходными уровнями, которые используют свертки 1x1.

Я поместил DenseNet169 на разделение всех образцов на проверку поезда 70/30. Я использовал размер пакета 16 и скорость обучения 0,0001 с разреженной категориальной кроссентропией в качестве функции потерь. Обучение длилось 20 эпох.

Производительность была - как вы уже догадались - странной по поведению. Потери при обучении и точность колеблются в пределах высоких и низких значений соответственно и никогда не улучшаются по мере обучения. Между тем, потеря валидации очень незначительно улучшается при обучении, в то время как точность валидации остается постоянной и составляет 61,8%.

Почему наши модели так себя ведут?

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

Дисбаланс и перемешивание данных

Перестановка может сыграть роль в поведении наших моделей, особенно в ситуациях, когда точность проверки остается постоянной. Примечательно, что большая часть нашей точности проверки сходится около 61%, что по совпадению (или нет) является долей большинства классов в наборе данных. Хотя сложно считать наши данные несбалансированными, дисбаланс в наших данных может объяснить несоответствие между точностью обучения и проверки, поскольку наборы для обучения и проверки могли не отражать распределение классов набора данных. Эту проблему можно решить, убедившись, что все наборы содержат репрезентативное распределение изображений.

Скорость обучения

Наше задание скорости обучения могло сыграть роль в поведении наших моделей. Исчезающие градиенты могут возникать, когда скорость обучения слишком мала. В результате наша модель не может узнать ничего нового, что может объяснить недостаток обучения во время обучения. Однако известно, что Адам хорошо работает с особенно низкими темпами обучения. Хотя мы можем вручную экспериментировать, тестируя набор скоростей обучения, мы также можем решить эту проблему, используя планировщик скорости обучения, который регулирует скорость обучения по мере продвижения обучения. Это не только полезный метод регуляризации, он также помогает нам избежать ложных локальных минимумов, что и является нашей следующей проблемой. График обучения также может учитывать случаи, когда потери сильно колеблются.

Конвергенция

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

Подход к передаче обучения

Как вы, возможно, знаете, мы применили переносное обучение к нашим моделям, и при этом мы импортировали и заморозили предварительно обученные веса для различных архитектур. Эти веса были обучены на совершенно другом наборе данных, чем наш. Это действительно может быть тот случай, когда веса ImageNet не наиболее совместимы с нашим набором данных. Мы можем попробовать разморозить некоторые из верхних слоев базовой модели, посмотреть, улучшится ли наша модель, и медленно повторить этот процесс, чтобы избежать переобучения. Кроме того, разные архитектуры CNN лучше всего работают с разными входными размерами. Мы устанавливаем размер ввода 224 x 224 x 3, что является идеальной формой ввода для ResNet и DenseNet. Однако можно заметить улучшения, настроив формы ввода, чтобы они были максимально совместимы с используемой архитектурой.

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