Как "видят" нейросети

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

С чего все началось

Вообще первые публикации, относящиеся к сверточным нейросетям (если точнее, то скорее к их предкам) появились еще в конце прошлого века. Можно выделить, например, статью Neocognitron: A Self-organizing Neural Network Model for a Mechanism of Pattern Recognition Unaffected by Shift in Position (Неокогнитрон: самоорганизующаяся нейросеть для распознавания паттернов, которая не подвержена влиянию смещения позиции) 1980 года. Идея авторов статьи заключалась в следующем: мы не знаем пока, как именно наш мозг работает с изображениями, но знаем, что он как-то распознает паттерны (простые геометрические фигуры, из которых состоит сложное изображение). Если сделать нейросеть, которая хорошо справляется с распознаванием паттернов, мы по аналогии сможем предположить, что происходит в мозгу. Предшествующие попытки (авторы ссылаются на статьи шестидесятых и семидесятых годов) оказались не слишком удачными: обученные нейросети переставали воспринимать геометрические формы, если их смещали или искажали.

Опираясь на открытия биологов, которые изучали работу зрительной коры головного мозга позвоночных, авторы предлагают иерархическую структуру, состоящую из входного слоя, S-слоев и C-слоев. Я не стану вдаваться в подробности того, какие именно структуры мозга моделируют эти S-слои и C-слои, это уже нейробилогия. Но суть в том, что S-слои (Simple) распознают очень простые и конкретные формы, такие как прямые линии. Причем прямые горизонтальные линии распознает один слой, а прямые вертикальные – другой. C-слои (Complex) распознают более сложные паттерны, комбинируя данные, полученные от S-слоев. Каждый следующий слой распознает все более сложный паттерн и охватывает все большую часть изображения.Таким образом, происходит «свертка» – построение сложного изображения из простых элементов (поэтому нейросети сверточные). Конкретно в этой статье термин «сверточная нейросеть» не употребляется, он был введен позднее.

Математически свертка выглядит так:

<i>(Это скриншот презентации Марии Тихоновой, моего преподавателя по глубокому обучению из ВШЭ. Ничего не могу поделать с качеством, простите, но картинка очень наглядная)</i>
(Это скриншот презентации Марии Тихоновой, моего преподавателя по глубокому обучению из ВШЭ. Ничего не могу поделать с качеством, простите, но картинка очень наглядная)

Изображение представлено в виде матрицы из чисел. На него накладывается фильтр (kernel / filter) – другая матрица меньшего размера. Часть исходной матрицы, соразмерная фильтру, на него умножается, и мы получаем некоторое число, которое сохраняется в новой матрице. Затем фильтр сдвигается на шаг и производит такую же операцию. И так до тех пор, пока фильтр не пройдет всю исходную матрицу. Если он будет шагать каждый раз не на одно число, а на два, изображение уменьшится сильнее:

<i>(Stride – это ширина шага; скриншот из той же презентации)</i>
(Stride – это ширина шага; скриншот из той же презентации)

Еще можно несколько операций с фильтром проделать так, чтобы изменить размер новой матрицы: добавить нулей к исходной матрице или заставить фильтр собирать числа не рядом расположенные, а через одно. С помощью правильно подобранного фильтра можно сделать изображение более четким, контрастным или размытым.
Фильтров может быть много, и каждый из них будет накладывать свой эффект и выделять свой набор паттернов.
Но не будем вдаваться в технические подробности. Ключевая идея, думаю, ясна – сверточные нейронные сети умеют «разбирать» изображение и извлекать из него важные элементы, поэтому они и стали так популярны.
После публикации статьи о Неокогнитроне были написаны еще работы, некоторые из которых стали знаковыми для развития сверточных нейросетей. Например, статья о LeNet, о которой рассказывают на всех курсах по глубокому обучению. Собственно, назвать нейросети «сверточными» придумали именно ее авторы. Но мы пропустим этот шаг и переместимся немного ближе к дню сегодняшнему.

ImageNet

Чтобы нейросеть заработала, ее надо обучить. Чтобы ее обучить, нужны данные в очень, ОЧЕНЬ большом количестве. Именно поэтому создание базы данных изображений под названием ImageNet стало прорывным событием. Это огромный проект, который содержит более 14 млн. изображений с аннотациями из более чем 21 000 категорий. С 2010 по 2017 год проводились большие соревнования, на которых команды исследователей создавали нейросети, стараясь как можно лучше решить задачи, связанные с распознаванием изображений (это могла быть классификация, обнаружение объектов и др.). В 2017 году все участники соревнования прошли отметку в 95% точности предсказаний, и организаторы решили усложнить задачу, перейдя от двумерных изображений к трехмерным.
Но начиналось все скромнее. На картинке ниже можно посмотреть, какие были победители на протяжении шести лет. Только будьте внимательны: мы ранее упомянули точность предсказания, а на графике отображена величина ошибки, а не точности (то есть, чем меньше значение, тем лучше модель).

<i>(Скриншот заимствован из презентации Alexander Ecker, преподавателя Neuromatch Academy; здесь рассматривается именно классификация изображений в качестве задачи)</i>
(Скриншот заимствован из презентации Alexander Ecker, преподавателя Neuromatch Academy; здесь рассматривается именно классификация изображений в качестве задачи)

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

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

<i>(Архитектура AlexNet из статьи; dense – это как раз линейные слои. Цифрами подписаны размеры исходного изображения (224 * 224 * 3, где 3 – число цветов в RGB-схеме), фильтров и результатов применения фильтров на каждом шаге)</i>
(Архитектура AlexNet из статьи; dense – это как раз линейные слои. Цифрами подписаны размеры исходного изображения (224 * 224 * 3, где 3 – число цветов в RGB-схеме), фильтров и результатов применения фильтров на каждом шаге)

Единственное, что мы раньше не обсудили – операцию, которая на схеме подписана как Max pooling. Здесь тоже все просто, на самом деле: исходная матрица делится на равные непересекающиеся сегменты, в каждом из которых выбирается максимум и записывается в ячейку новой матрицы меньшего размера. Так можно сжать изображение, сохранив при этом наиболее важную информацию.

<i>(Картинка с сайта <a href="https://www.geeksforgeeks.org/cnn-introduction-to-pooling-layer/" rel="nofollow noreferrer noopener" target="_blank">geeksforgeeks</a>, там много хороших постов тоже, советую)</i>
(Картинка с сайта geeksforgeeks, там много хороших постов тоже, советую)

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

Что сейчас

Одна из последних и наиболее совершенных сверточных сетей – ConvNeXt, она вышла только в 2022 году и, кстати, про нее есть материалы на русском языке, например, вот этот.
Сейчас для работы с изображениями вовсю используются трансформеры или гибридные архитектуры, которые комбинируют сверточные сети и трансформеров. Эти подходы практически вытеснили сверточные нейросети в чистом виде, но это уже тема для отдельного поста (так контент-план и составляется). Некоторую базу по трансформерам в целом можно посмотреть у меня вот тут, в начале поста.

Так вот, авторы ConvNeXt решили выяснить, какая именно часть гибридной модели вносит наибольший вклад в эффективность: та, которая унаследована от трансформеров или все же от сверточных сетей. Для этой цели они решили последовательно модернизировать ResNet до тех пор, пока не получится трансформер, и на каждом шагу смотреть, как изменилась эффективность.
Сначала ResNet обучили с помощью методик, обычно применяемых к трансформерам. Потом они поработали с распределением вычислительной нагрузки по разным слоям модели, позаимствовав вариант распределения у трансформера Swin (Swin-T). Точность модели сразу выросла с 78,8% до 79,4%. У того же трансформера взяли подход к снижению размерности изображения.
Потом фильтры разделили на несколько групп. Благодаря этому стало возможно увеличить размеры (ширину) нейросети, не увеличивая при этом существенно вычислительные затраты.
Еще в архитектуре сверточной нейросети есть компонент, который называется «бутылочное горлышко».

<i>(Тоже из презентации Alexander Ecker, синее примечание дорисовано мной)</i>
(Тоже из презентации Alexander Ecker, синее примечание дорисовано мной)

Бутылочное горлышко – это слой, в котором меньше нейронов, чем в предыдущем слое. Он сжимает входные данные, отбрасывая их наименее значимые параметры. Авторы ResNeXt инвертировали бутылочное горлышко, сделав его шире, чем предыдущий слой. Здесь прирост точности получился совсем небольшим, с 80,5% до 80,6% (или с 81,9% до 82,6%, в зависимости от конфигурации).
Затем у исходной модели (которая уже не совсем ResNet) увеличили размер фильтра (стандартный размер – 3 х 3, сделали 7 х 7). Дальше уже по мелочи подкрутили архитектуру – и получилась ConvNeXt.

В профессиональном сообществе, кажется, нет единого мнения относительно будущего сверточных сетей: кто-то выражает оптимизм в отношении ConvNeXt, а кто-то предпочитает смотреть в сторону трансформеров.
Есть свежие публикации 2022-2023 годов, в которых авторы представляют результаты сравнения сверточных сетей и трансформеров. Например, есть статья «A comparative study between vision transformers and CNNs in digital pathology» («Сравнительное исследование трансформеров, предназначенных для работы с изображениями, и сверточных нейросетей в области цифровой патологии»). В этом исследовании оценивалась способность кандидатов определять тип ткани на снимках гистологических исследований и выявлять опухоли. Результаты получились очень схожие, но трансформеры немного лучше справились с гистологией, а сверточные сети – с выявлением опухолей.

Заключение

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

Начать дискуссию