Создание пользовательского слоя Caffe в python
После разбора многих ссылок на создание слоев Caffe в Python я все еще испытываю трудности с пониманием нескольких концепций. Может ли кто-нибудь прояснить их?
Что мне еще не хватает:
-
setup()
метод: что мне здесь делать? Почему в примере я должен сравнить длину "нижнего" парама с "2"? Почему это должно быть 2? Кажется, это не размер партии, потому что это произвольно? И дно, насколько я понимаю, является блобом, а затем первым измерением является размер партии?
-
reshape()
метод: поскольку я понимаю, что "нижний" входной параметр является блобом ниже уровня, а "верхний" параметр - это капля верхнего слоя, и мне нужно изменить верхний слой в соответствии с формой вывода моих вычислений с помощью прямого прохода, Но почему мне нужно делать это каждый проход вперед, если эти фигуры не меняются от прохода до прохода, меняются только веса?
-
reshape
и forward
методы имеют 0 индексов для "верхнего" входного параметра. Зачем мне использовать top[0].data=...
или top[0].input=...
вместо top.data=...
и top.input=...
? О чем этот индекс? Если мы не используем другую часть этого верхнего списка, почему это так разоблачено? Я могу заподозрить его или совпадение с С++, но было бы хорошо знать точно.
-
reshape()
, строка с:
if bottom[0].count != bottom[1].count
что я здесь делаю? почему его размерность еще раз? И что я здесь пересчитываю? Почему обе части blobs (0 и 1) должны быть равны по количеству некоторых членов (count
)?
-
forward()
, который я определяю по этой строке:
self.diff[...] = bottom[0].data - bottom[1].data
Когда он используется после прямого пути, если я его определяю? Можем ли мы использовать
diff = bottom[0].data - bottom[1].data
вместо этого считать потерю позже в этом методе, не присваивая self
, или его выполнение с определенной целью?
-
backward()
метод: что это о: for i in range(2):
? Почему снова диапазон составляет 2?
-
backward()
, параметр propagate_down
: почему он определен? Я имею в виду, если его True, градиент должен быть назначен bottom[X].diff
, как я вижу, но почему кто-то вызовет метод, который ничего не сделает с помощью propagate_down = False
, если он просто ничего не делает и все еще едет внутри?
Прошу прощения, если эти вопросы слишком очевидны, я просто не смог найти хорошее руководство, чтобы понять их и просить о помощи здесь.
Ответы
Ответ 1
Вы задали здесь много вопросов, я дам вам несколько моментов и указаний, которые, я надеюсь, прояснят вам вопросы. Я не буду однозначно отвечать на все ваши вопросы.
Кажется, что вас больше всего смущает разница между блобом и уровнем ввода/вывода. На самом деле, большинство слоев имеют один кадр в качестве входных данных и один кадр в качестве вывода, но это не всегда так. Рассмотрим слой потерь: он имеет два входа: предсказания и метки наземной истины. Таким образом, в этом случае bottom
представляет собой вектор длины 2 (!), Где bottom[0]
является (4-D) блобом, представляющим предсказания, а bottom[1]
является еще одним блобом с метками. Таким образом, при построении такого слоя вы должны убедиться, что у вас есть точно (жестко закодированные) 2 входных капли (см., Например, ExactNumBottomBlobs()
в AccuracyLayer
определение).
То же самое можно сказать и для top
blobs: действительно, в большинстве случаев для каждого слоя есть один top
, но это не всегда так (см., например, AccuracyLayer
). Следовательно, top
также является вектором 4-D blobs, по одному для каждого слоя top
. В большинстве случаев в этом векторе будет один элемент, но иногда вы можете найти более одного.
Я считаю, что это охватывает ваши вопросы 1,3,4 и 6.
Как и в reshape()
(Q.2), эта функция не вызывается при каждом переходе вперед, она вызывается только тогда, когда сеть настроена на распределение пространства для входов/выходов и параметров.
Иногда вам может потребоваться изменить размер ввода для вашей сети (например, для сетей обнаружения), тогда вам нужно вызвать reshape()
для всех слоев сети для размещения нового размера ввода.
Что касается параметра propagate_down
(Q.7): поскольку слой может иметь более одного bottom
, вам, в принципе, потребуется передать градиент всем bottom
во время backprop. Однако каково значение градиента для дна label
слоя потерь? Бывают случаи, когда вы не хотите распространять все bottom
s: для этого используется этот флаг. (здесь с уровнем потерь с тремя bottom
, которые ожидают градиента для всех из них).
Для получения дополнительной информации см. этот "Python"
уровень учебника.
Ответ 2
Почему это должно быть 2?
Этот конкретный смысл говорит об эвклидовом слое потерь. Потери евклидова - это средняя квадратическая ошибка между векторами 2. Следовательно, на входном блоке должно быть 2 вектора. Длина каждого вектора должна быть одинаковой, поскольку она является разницей по элементам. Вы можете увидеть эту проверку в методе изменить.
Спасибо.