Классификация по нескольким категориям в Caffe
Я подумал, что мы могли бы скомпилировать описание Caffeinated некоторых методов выполнения классификации нескольких категорий.
Под классификацией нескольких категорий я имею в виду: Входные данные, содержащие представления о множественных модельных категориях и/или просто классифицируемые в разных категориях вывода модели.
например. Изображение, содержащее кошку и собаку, будет выводить (в идеале) ~ 1 для категорий предсказания для кошки и собаки и ~ 0 для всех остальных.
-
Основываясь на этой статье, этот устаревший и закрытый PR и этот открытый PR, кажется, что caffe отлично умеет принимать метки. Правильно ли это?
-
Будет ли построение такой сети требовать использования нескольких нейронов (внутренний продукт → relu → внутренний продукт) и слоев softmax, как в страница 13 настоящего документа; или Caffe ip и softmax в настоящее время поддерживают несколько размеров ярлыков?
-
Когда я передаю свои метки в сеть, пример которой иллюстрирует правильный подход (если не оба)?:
например. Кошка ест яблоко Примечание: синтаксис Python, но я использую источник С++.
Столбец 0 - класс находится во вводе;
Столбец 1 - Класс не вводится
[[1,0], # Apple
[0,1], # Baseball
[1,0], # Cat
[0,1]] # Dog
или
Столбец 0 - Класс находится на входе
[[1], # Apple
[0], # Baseball
[1], # Cat
[0]] # Dog
Если что-то не имеет ясности, пожалуйста, дайте мне знать, и я создам живописные примеры вопросов, которые я задаю.
Ответы
Ответ 1
Хороший вопрос. Я считаю, что здесь нет единого "канонического" ответа, и вы можете найти несколько разных подходов к решению этой проблемы. Я сделаю все возможное, чтобы показать один из возможных способов. Это немного отличается от заданного вами вопроса, поэтому я переформулирую проблему и предложим решение.
Проблема:, учитывая входное изображение и набор классов C
, укажите для каждого класса, если он изображен на изображении или нет.
Входы: во время обучения, входы представляют собой пары изображений и двоичный вектор C
-dim, указывающий для каждого класса классов C
, если он присутствует на изображении или нет.
Ouput: для изображения, выведите двоичный вектор C
-dim (тот же, что и вторая форма, предложенная в вашем вопросе).
Создание caffe выполняет работу:. Чтобы выполнить эту работу, нам нужно изменить верхние слои сети, используя другую потерю.
Но сначала, давайте понять, как обычно используется кофе, а затем изучать необходимые изменения.
Теперь все происходит: изображение подается в сеть, проходит через уровни conv/pooling/... и, наконец, проходит через слой "InnerProduct"
с выходами C
. Эти предсказания C
входят в слой "Softmax"
, который блокирует все, кроме самого доминирующего класса. После выделения выделенного класса "SoftmaxWithLoss"
проверяет, что выделенный прогнозируемый класс соответствует первому классу истинности.
Что вам нужно: проблема с существующим подходом - это слой "Softmax"
, который в основном выбирает один класс. Я предлагаю вам заменить его слоем "Sigmoid"
, который отображает каждый из выходов C
в индикатор того, присутствует ли этот конкретный класс в изображении. Для обучения вам следует использовать "SigmoidCrossEntropyLoss"
вместо слоя "SoftmaxWithLoss"
.
Ответ 2
Поскольку одно изображение может иметь несколько ярлыков. Самый интуитивный способ - рассматривать эту проблему как проблему с бинарной классификацией C независимо, где C - общее количество различных классов. Поэтому легко понять, что @Shai сказал:
добавьте слой "Sigmoid", который отображает каждый из выходов C в индикатор того, присутствует ли этот конкретный класс в изображении, и должен использовать "SigmoidCrossEntropyLoss" вместо слоя "SoftmaxWithloss". Потеря представляет собой сумму этих C SigmoidCrossEntropyLoss.