Почему макаки-резусы?

Макаки-резусы — очень социальные обезьяны Старого Света, и мы будем смотреть на тех, кто живет на Кайо-Сантьяго, небольшом острове у восточного побережья Пуэрто-Рико. Они являются исключительными моделями для понимания человеческого поведения. Изучая макак-резусов, мы можем лучше понять, как гены влияют на социальное поведение. Для этого нам нужно изучить образцы их крови, чтобы понять состояние здоровья населения. Нам необходимо идентифицировать четыре различных типа лейкоцитов: моноциты, эозинофилы, нейтрофилы и лимфоциты лейкоцитов. Сравнивая эти данные между животными, мы можем определить количество и типы клеток у средней обезьяны в нашей популяции, чтобы понять, какие из них здоровы, а какие могут быть больны. Затем мы можем сравнить эту информацию анализа крови с их поведенческими показателями, чтобы увидеть, как здоровье животных влияет на различия в их поведении. Спасибо Zooniverse за предоставление этой информации.

Что нужно знать перед чтением

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

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

Прямое распространение. Прямое распространение — это когда входные обучающие данные подаются в алгоритм/сеть в прямом направлении от входного к выходному слою.

Обратное распространение. Обратное распространение — это, по сути, прямое распространение, но обратное. У 3Blue1Brown есть отличное видео, объясняющее, как работает обратное распространение.

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

IOU:IOU, также известный как индекс Жаккара, расшифровывается как пересечение над объединением. Он определяется как доля площади перекрытия двух ограничивающих рамок от площади объединенных ограничивающих рамок. У Эндрю Нг есть видео, объясняющее, что это такое.

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

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

Пакеты. При обучении нейронной сети мы обычно передаем в сеть/алгоритм определенное количество изображений за раз. Например, предположим, что у нас есть 550 обучающих выборок и задано значение batch_size, равное 100. Алгоритм берет каждые 100 выборок из обучающего набора данных и обучает нейронную сеть. Мы можем продолжать делать это до тех пор, пока мы не распространим все выборки данных по сети. Остальные 50 изображений запустятся на последнем шаге эпохи.

Эпоха. Эпоха – это количество циклов алгоритма по набору данных. Например, если я установлю для эпох значение 100, алгоритм будет перебирать набор данных 100 раз, выполняя четыре шага в процессе: инициализация параметров, прямое распространение, вычисление ошибки. , и настройка параметров. Думайте об этом процессе как о функции цикла for, где каждый цикл проходит через обучающий набор данных. Внутри этого цикла for есть еще один вложенный цикл for, который выполняет итерацию по каждой партии выборок, где одна партия имеет указанное количество выборок размера партии.

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

Поля привязки. Поля привязки обычно используются для обнаружения объектов разных размеров/размеров и особенно полезны, когда в одной ячейке сетки находится несколько объектов. У Эндрю Нг есть видео на Coursera, в котором объясняется, что такое якорные блоки. Блоки привязки также могут быть полезны при попытке идентифицировать мелкие объекты.

Порог. Порог — это минимальное значение достоверности, обнаруженное моделью. Например, если у вас порог 0,6, вы отбрасываете все прогнозы с вероятностью/достоверностью менее 0,6.

Функция потерь. По сути, функция потерь показывает, насколько хорошо алгоритм машинного обучения моделирует набор данных. Если прогнозы вашего алгоритма крайне неточны, функция потерь выдаст большее число. Напротив, если ваш алгоритм очень точен, функция выдаст меньшее число. Обычно вы хотите получить наименьшее возможное число. Убыток рассчитывается как среднее квадратов разностей между прогнозируемыми и фактическими значениями (Actual — Predicted)².

Что такое ЙОЛО?

YOLO — это алгоритм обнаружения объектов, который расшифровывается как «You Only Look Once». Как вы можете догадаться по названию, YOLO уникален тем, что для обнаружения объектов на изображении требуется только однократное распространение по сети. Он предсказывает как вероятности, так и ограничивающие рамки одновременно, что делает его чрезвычайно быстрым и эффективным. Для этого алгоритм YOLO сначала разбивает изображение на сетку.

Каждая ячейка сетки будет обнаруживать объекты, находящиеся внутри них, а ячейки, содержащие центр объекта, например собаку, будут отвечать за обнаружение этого объекта. Затем каждая ячейка будет предсказывать определенное количество ограничивающих рамок вместе с оценкой достоверности для каждой рамки. Оценка достоверности показывает, насколько модель уверена в том, что объект находится внутри ограничивающей рамки, и насколько точна эта рамка. Этот показатель уверенности колеблется от 0 до 1, где 0 — совсем не уверен, а 1 — полностью уверен. Каждая ограничивающая рамка также имеет ширину (bw), высоту (bh), центр (bx, by) и класс (c).

Оценка достоверности рассчитывается на основе IOU или Intersection Over Union. Как указывалось ранее, долговая расписка — это площадь пересечения прогнозируемой ограничивающей рамки и фактической ограничивающей рамки над площадью объединенных ограничивающих рамок. Когда объект имеет несколько ограничивающих рамок, модель выберет ограничивающую рамку с наибольшей вероятностью и удалит все другие ограничивающие рамки с высокой долговой распиской с той ограничивающей рамкой, которую выбрала модель. Это делается для того, чтобы удалить любые другие ненужные ограничивающие рамки для каждого объекта.

Наконец, объединив все это, мы можем успешно идентифицировать объекты на изображении с соответствующими ограничивающими рамками.

Как работает ваша программа?

Для моего детектора объектов лейкоцитов я использовал YOLOv3 Darknet. Darknet — это нейросетевой фреймворк с открытым исходным кодом, написанный на C и CUDA. Сама программа запускалась через Google Colab.

Сначала я клонировал репозиторий Даркнета, чтобы тренировать и тестировать свои изображения. Затем я убедился, что мой GPU и OpenCV включены. Убедившись, что CUDA установлена, я создал файл Darknet.

Я приступил к настройке трех функций: imShow, загрузка и загрузка.

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

После этого я разархивировал свой файл obj.zip и загрузил свой собственный файл .cfg, файлы obj.data и obj.names с Google Диска на виртуальную машину Colab. Затем я запустил скрипт Python, который генерирует файл train.txt со всеми путями к каждому тренировочному изображению, что важно для процесса обучения. Перед тренировкой я загрузил предварительно обученные веса сверточных слоев, чтобы ускорить процесс обучения и повысить точность моей модели. Как только загрузка была завершена, я выполнил обучающую команду:

!./darknet detector train data/obj.data cfg/yolov3_custom.cfg darknet53.conv.74 -dont_show

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

Наконец, после обучения модели я могу запустить алгоритм и загрузить тестовые изображения для предсказания модели.

Обратите внимание, что у меня нет раздела обучения в файле Google Colab, так как я уже обучил свои данные в отдельном файле и собрал свои веса.

Если вы хотите посмотреть программу или запустить ее самостоятельно, вы можете проверить ее на GitHub.

Конечный результат

Вот некоторые из предсказаний детектора объектов.

Проблемы и другие недостатки

Было много проблем, с которыми я столкнулся на своем пути. Некоторые из них были короткими, незначительными проблемами, в то время как другие были гораздо более серьезными.

Одна из основных проблем, с которыми я столкнулся, заключалась в том, что мой набор данных был слишком маленьким. Раньше мой набор данных состоял только из 20 размеченных изображений, но этого явно было недостаточно для обучения модели. Итак, я увеличил его до 114 помеченных изображений и должен был пометить каждое изображение вручную с помощью LabelImg. После многих дней попыток обучить свои данные мне наконец удалось успешно обучить модель Darknet Yolov3, используя больший набор данных. Вот что выдал мой алгоритм при пороге 0,99:

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

  1. Мозаика — Мозаика или нарезка — это идея разделения обучающих данных/изображений на маленькие плитки. По сути, мозаичное изображение приближает ваш детектор к небольшим объектам, сохраняя при этом небольшое входное разрешение для быстрого вывода.
  2. Размер пакета. Так как у меня небольшой размер выборки (114 изображений), я могу попытаться уменьшить размер пакета с 64 до 32.
  3. Якоря. Я также могу попробовать поиграть с якорями, чтобы увидеть, не слишком ли они велики или слишком малы.
  4. Настройка .cfg-файла даркнета в целом. В файле yolo.cfg есть много настроек, включая размер пакета и привязки, поэтому я мог повозиться с этими настройками, чтобы попытаться получить более точную информацию. алгоритм.

Зная это, я сформировал список идей, которые хотел протестировать:

  1. Поэкспериментируйте с файлом .cfg. Как уже говорилось ранее, я хотел поэкспериментировать с файлом .cfg, так как он содержит множество функций настройки для процесса обучения.
  2. Обучение и тестирование только для ОДНОГО типа лейкоцитов — проверка на наличие ошибок в данных (изображения могут быть слишком большими, а данные/лейкоциты слишком маленькими).
  3. Обучение нескольких лейкоцитов и тестирование только ОДНОГО типа лейкоцитов за раз (обрезанное и уменьшенное изображение) — это проверка того, не может ли алгоритм YOLO обработать такое большое изображение. и может тестировать только изображения меньшего размера
  4. Jupyter Notebook. Поскольку Google Colab ограничивает частоту его использования, я планирую запустить программу в исходном формате, чтобы не беспокоиться об ограничении использования.

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

batch = 32
...
...
saturation = .0
exposure = .0
hue=.0

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

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

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

Что я выучил

Главный вывод, который я сделал в этом долгом путешествии, — научиться преодолевать препятствия. Хотя я довольно много узнал об алгоритме YOLO и усовершенствовал свои знания в области машинного обучения, опыт преодоления трудностей, с которыми я столкнулся, был гораздо более впечатляющим. То, что я вел дневник о своем прогрессе, помогло мне задуматься о том, чего я добился за день и над чем мне нужно поработать на следующий день. Это позволило мне найти решения для любых проблем, с которыми я столкнулся. Этот проект был невероятным опытом, и я с нетерпением жду продолжения работы с машинным обучением и искусственным интеллектом.