Оглавление

  1. Вступление
  2. Предпосылки
  3. Классификация против обучения одним выстрелом
  4. Приложения
  5. Набор данных Omniglot
  6. Загрузка набора данных
  7. Сопоставление проблемы с задачей двоичной классификации
  8. Модельная архитектура и обучение
  9. Проверка модели
  10. Базовый уровень 1 - Модель ближайшего соседа
  11. Базовый уровень 2 - Случайная модель
  12. Результаты испытаний и выводы
  13. Заключение
  14. использованная литература

1. Введение

Глубокие сверточные нейронные сети стали самыми современными методами для задач классификации изображений. Однако одно из самых больших ограничений - они требуют большого количества помеченных данных. Во многих приложениях иногда невозможно собрать такой объем данных. One Shot Learning направлен на решение этой проблемы.

2. Предпосылки

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

3. Классификация против однократного обучения

В случае стандартной классификации входное изображение передается в серию слоев, и, наконец, на выходе мы генерируем распределение вероятностей по всем классам (обычно с использованием Softmax). Например, если мы пытаемся классифицировать изображение как кошка, собака, лошадь или слон, то для каждого входного изображения мы генерируем 4 вероятности, указывающие вероятность принадлежности изображения к каждому из 4 классов. Здесь следует отметить два важных момента. Во-первых, в процессе обучения нам требуется большое количество изображений для каждого класса (кошек, собак, лошадей и слонов). Во-вторых, если сеть обучается только на четырех указанных выше классах изображений, мы не можем ожидать, что сможем протестировать ее на каком-либо другом классе, например, «зебра». Если мы хотим, чтобы наша модель также классифицировала изображения зебры, нам нужно сначала получить много изображений зебры, а затем мы должны снова переобучить модель. Есть приложения, в которых у нас недостаточно данных для каждого класса, а общее количество классов огромно, а также динамически изменяется. Таким образом, стоимость сбора данных и периодического переобучения слишком высока.

С другой стороны, в классификации по одному выстрелу нам требуется только один обучающий пример для каждого класса. Да, вы правильно поняли, только один. Отсюда и название One Shot. Давайте попробуем разобраться на реальном практическом примере.

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

Проблемы:

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

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

Теперь давайте разберемся, как подойти к этой проблеме, используя классификацию по одному выстрелу, которая помогает решить обе указанные выше проблемы:

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

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

Как это решает две проблемы, о которых мы говорили выше?

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

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

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

4. Приложения

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

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

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

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

5. Набор данных Omniglot

Для целей этого блога мы будем использовать набор данных Omniglot, который представляет собой набор из 1623 нарисованных вручную символов из 50 различных алфавитов. Для каждого персонажа есть всего 20 примеров, каждый нарисован другим человеком. Каждое изображение представляет собой изображение в градациях серого с разрешением 105x105.

Прежде чем продолжить, я хотел бы пояснить разницу между символом и алфавитом. В случае английского языка набор от A до Z называется алфавитом, а каждая буква A, B и т. Д. Называется символом. Таким образом, мы говорим, что в английском алфавите 26 знаков (или букв).

Так что я надеюсь, что это проясняет тот момент, когда я говорю, что 1623 символа охватывают более 50 различных алфавитов.

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

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

Вы можете загрузить набор данных, клонировав этот репозиторий GitHub. Папка с именем Python содержит два zip-файла: images_background.zip и images_evaluation.zip. Просто разархивируйте эти два файла.

Папка images_background содержит символы из 30 алфавитов и будет использоваться для обучения модели, а папка images_evaluation содержит символы из других 20 алфавитов, которые мы будем использовать для тестирования нашей системы.

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

И вы увидите следующие папки (алфавиты) в папке images_evaluation (используется для целей тестирования):

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

6. Загрузка набора данных

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

Мы используем функцию ниже для загрузки изображений в тензоры:

Чтобы вызвать эту функцию следующим образом, передайте путь к каталогу поезда в качестве параметра следующим образом:

X,y,c = loadimgs(train_folder)

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

Давайте разберемся, что присутствует в «X»:

X.shape
(964, 20, 105, 105)

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

Давайте теперь разберемся, как заполняются ярлыки «y»:

y.shape
(19280, 1)

Общее количество изображений = 964 * 20 = 19280. Все изображения для одной буквы имеют одинаковую метку, т.е. первые 20 изображений имеют метку 0, следующие 20 имеют метку 1 и так далее… последние 20 изображений иметь этикетку 963.

Наконец, последняя переменная «c» обозначает категории, и это следующий словарь:

c.keys() # 'c' for categories
dict_keys(['Alphabet_of_the_Magi', 'Anglo-Saxon_Futhorc', 'Arcadian', 'Armenian', 'Asomtavruli_(Georgian)', 'Balinese', 'Bengali', 'Blackfoot_(Canadian_Aboriginal_Syllabics)', 'Braille', 'Burmese_(Myanmar)', 'Cyrillic', 'Early_Aramaic', 'Futurama', 'Grantha', 'Greek', 'Gujarati', 'Hebrew', 'Inuktitut_(Canadian_Aboriginal_Syllabics)', 'Japanese_(hiragana)', 'Japanese_(katakana)', 'Korean', 'Latin', 'Malay_(Jawi_-_Arabic)', 'Mkhedruli_(Georgian)', 'N_Ko', 'Ojibwe_(Canadian_Aboriginal_Syllabics)', 'Sanskrit', 'Syriac_(Estrangelo)', 'Tagalog', 'Tifinagh'])
c['Alphabet_of_the_Magi']
[0, 19]
c['Anglo-Saxon_Futhorc']
[20, 48]

Поскольку существует 30 различных алфавитов, этот словарь «c» содержит 30 элементов. Ключом к каждому элементу является название алфавита. Значение для каждого элемента представляет собой список из двух чисел: [low, high], где «low» - это метка первого символа в этом алфавите, а «high» - это метка последнего символа в этом алфавите.

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

7. Сопоставление проблемы с задачей двоичной классификации.

Давайте разберемся, как мы можем сопоставить эту проблему с задачей контролируемого обучения, где наш набор данных содержит пары (Xi, Yi), где «Xi» - это вход, а «Yi» - выход.

Напомним, что входом в нашу систему будет пара изображений, а на выходе будет оценка сходства от 0 до 1.

Xi = пара изображений

Yi = 1; если оба изображения содержат один и тот же символ

Yi = 0; если оба изображения содержат разные символы

Давайте лучше поймем, визуализировав набор данных ниже:

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

Код для создания этих пар и целей показан ниже:

Нам нужно вызвать указанную выше функцию, передав batch_size, и она вернет количество пар изображений «batch_size» вместе с их целевыми переменными.

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

8. Архитектура модели и обучение

Этот код является реализацией методологии, описанной в этой исследовательской статье Грегори Коха и др. . Архитектура модели и гиперпараметры, которые я использовал, соответствуют описанию в документе.

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

Интуиция: термин сиамский означает близнецов. Две показанные выше сверточные нейронные сети не являются разными сетями, а представляют собой две копии одной и той же сети, отсюда и название Siamese Networks. В основном они имеют одинаковые параметры. Два входных изображения (x1 и x2) проходят через ConvNet, чтобы сгенерировать вектор признаков фиксированной длины для каждого (h (x1) и h (x2)). Предполагая, что модель нейронной сети обучена правильно, мы можем выдвинуть следующую гипотезу: если два входных изображения принадлежат одному и тому же персонажу, то их векторы признаков также должны быть похожими, а если два входных изображения принадлежат разным символам, то их векторы признаков также будут разными. Таким образом, поэлементная абсолютная разница между двумя векторами признаков должна сильно отличаться в обоих вышеупомянутых случаях. И, следовательно, оценка сходства, генерируемая выходным сигмовидным слоем, также должна быть разной в этих двух случаях. Это центральная идея сиамских сетей.

Учитывая вышеупомянутую интуицию, давайте посмотрим на картину архитектуры с более подробными деталями, взятыми из самого исследования:

Следующая функция используется для создания архитектуры модели:

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

Чтобы понять форму тензоров, передаваемых на разных уровнях, обратитесь к изображению ниже, сгенерированному с помощью утилиты plot_model в Keras.

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

optimizer = Adam(lr = 0.00006)
model.compile(loss="binary_crossentropy",optimizer=optimizer)

Модель была обучена на 20000 итераций с размером пакета 32.

После каждых 200 итераций проверка модели проводилась с использованием 20-этапного одноразового обучения, а точность рассчитывалась для 250 испытаний. Эта концепция объясняется в следующем разделе.

9. Проверка модели

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

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

Хороший способ оценить модель - это N-way one shot learning. Не волнуйтесь, это намного проще, чем кажется.

Пример четырехстороннего однократного обучения:

Мы создаем набор данных из 4 пар изображений следующим образом:

По сути, один и тот же символ сравнивается с 4 разными символами, из которых только один соответствует исходному символу. Скажем, выполняя четыре вышеупомянутых сравнения, мы получаем 4 оценки сходства S1, S2, S3 и S4, как показано. Теперь, если модель обучена правильно, мы ожидаем, что S1 будет максимальным из всех 4 оценок сходства, потому что первая пара изображений - единственная, где у нас есть два одинаковых символа.

Таким образом, если S1 является максимальной оценкой, мы рассматриваем это как правильный прогноз, в противном случае мы считаем это неправильным прогнозом. Повторяя эту процедуру «k» раз, мы можем вычислить процент правильных прогнозов следующим образом:

процент_коррект = (100 * n_correct) / k

где k = ›общ. испытаний и n_correct = ›нет. правильных прогнозов из k испытаний.

Точно так же 9-этапное однократное обучение будет выглядеть следующим образом:

16-сторонний наклон с одним выстрелом будет таким, как показано ниже:

Ниже показано, как будет выглядеть 25-этапное однократное обучение:

Обратите внимание, что значение ’N’ в N-способе однократного обучения не обязательно должно быть точным квадратом. Причина, по которой я выбрал значения 4, 9, 16 и 25, заключалась в том, что это просто хорошо выглядит для презентации, когда квадрат полностью заполнен.

Совершенно очевидно, что меньшие значения ’N’ приведут к более правильным предсказаниям, а большие значения ’N’ приведут к относительно менее правильным предсказаниям при многократном повторении.

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

Код для создания тестового изображения вместе с набором опор выглядит следующим образом:

10. Базовая линия 1 - Модель ближайшего соседа

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

Наша первая базовая модель - это метод ближайшего соседа. Если вы знакомы с алгоритмом K-Nearest Neighbor, то это то же самое.

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

Это интуитивно похоже на KNN с K = 1. Давайте подробно разберемся, как работает этот подход.

Возможно, вы изучали, как мы можем вычислить расстояние L2 (также называемое евклидовым расстоянием) между двумя векторами. Если вы не помните, то вот как это делается:

Допустим, мы сравниваем расстояние L2 вектора X с тремя другими векторами, например A, B и C. Затем один из способов вычислить вектор, наиболее похожий на X, - это проверить, какой вектор имеет наименьшее расстояние L2 с X. Поскольку расстояние обратно пропорционально сходство. Так, например, если расстояние L2 между X и B минимально, мы говорим, что сходство между X и B максимальное.

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

Это просто, просто сведите матрицы к векторам, а затем вычислите расстояние L2 между этими векторами. Например:

Таким образом, при обучении N-way One Shot мы сравниваем расстояние L2 тестового изображения со всеми изображениями в наборе поддержки. Затем мы проверяем символ, для которого мы получили минимальное расстояние L2. Если этот символ совпадает с символом на тестовом изображении, то прогноз верен, иначе прогноз неверен. Например:

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

11. Базовая линия 2 - Случайная модель

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

12. Результаты тестов и выводы

N-образное тестирование проводилось для N = 1, 3, 5,…., 19.

Для каждого N-образного испытания было выполнено 50 испытаний, и по этим 50 испытаниям была вычислена средняя точность.

Ниже приводится сравнение 4 моделей:

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

13. Заключение

Это всего лишь первое решение, и многие гиперпараметры можно настроить, чтобы избежать чрезмерной подгонки. Также более тщательное тестирование можно провести, увеличив значение 'N' в N-образном тестировании и увеличив количество испытаний.

Я надеюсь, что это помогло вам понять методику однократного обучения с использованием Deep Learning.

Исходный код: пожалуйста, ссылайтесь на мой исходный код в Jupyter Notebook в моем репозитории GitHub здесь.

Примечание. Модель была обучена в облаке с графическим процессором P4000. Если вы тренируете его на CPU, вам нужно быть очень терпеливым.

Комментарии, предложения, критика приветствуются. Спасибо.

14. Ссылки

а. Https://github.com/akshaysharma096/Siamese-Networks

б. Https://sorenbouma.github.io/blog/oneshot/

c. Https://www.cs.cmu.edu/~rsalakhu/papers/oneshot1.pdf

d. Специализированный курс Эндрю Нга deeplearning.ai на Coursera