Как мне использовать BLOB-объекты в слое Caffe Python и когда происходит их обучение?

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

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

  1. Есть ли какая-либо спецификация, которой должен следовать этот большой двоичный объект, например, ограничения по размерам и т. д.? Независимо от того, что делает мой слой, могу ли я создать BLOB-объект одного измерения и использовать любой элемент BLOB-объекта, по одному, для любых вычислений в слое?
  2. Что означает diff блоба? Насколько я понимаю, diff из bottom — это градиент на текущем слое, а top — на предыдущем слое. Однако что именно происходит здесь?
  3. Когда эти параметры обучаются? Нужно ли это делать вручную в определении слоя?

Я видел примеры в test_python_layer.py, но большинство из них не имеют никаких параметров.


person GoodDeeds    schedule 07.06.2017    source источник
comment
Очень хороший вопрос.   -  person Shai    schedule 08.06.2017


Ответы (1)


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

Чтобы добавить капли (в класс вашего слоя):

def setup(self, bottom, top):
  self.blobs.add_blob(2) # add two blobs
  self.blobs[0].reshape(3, 4)  # first blob is 2D
  self.blobs[0].data[...] = 0 # init 
  self.blobs[1].reshape(10)  # second blob is 1D with 10 elements
  self.blobs[1].data[...] = 1 # init to 1

Каково «значение» каждого параметра и как организовать их в self.blobs, полностью зависит от вас.

Как «обучаются» обучаемые параметры?
Это одна из замечательных особенностей caffe (и других наборов инструментов DNN), вам не нужно об этом беспокоиться!
Что вам нужно сделать? Все, что вам нужно, это вычислить градиент потерь по параметрам и сохранить его в self.blobs[i].diff. Как только градиенты будут обновлены, внутренние компоненты кафе позаботятся об обновлении параметров в соответствии с градиентами/скоростью обучения/моментом/политикой обновления и т. д.
Итак,
у вас должен быть нетривиальный backward метод для вашего слоя

backward(self, top, propagate_down, bottom):
  self.blobs[0].diff[...] = # diff of parameters
  self.blobs[1].diff[...] = # diff for all the blobs

Возможно, вы захотите протестировать свою реализацию слоя после ее завершения.
Взгляните на этот PR для численного теста градиентов.

person Shai    schedule 08.06.2017
comment
Благодарю вас! Если я хочу, чтобы конкретный блоб был фиксированным параметром, а не обучался, я могу установить diff равным 0, верно? - person GoodDeeds; 08.06.2017
comment
@GoodDeeds или установите для этого большого двоичного объекта скорость обучения, равную нулю. см., например, слой BatchNorm - person Shai; 08.06.2017
comment
Я получаю сообщение об ошибке. Я следовал методу создания большого двоичного объекта в соответствии с вашим примером, и я получаю ошибку индекса вне диапазона, когда пытаюсь получить доступ к self.blobs[1]. Такой ошибки нет, если я делаю add_blob(1) дважды, но, возможно, в этом случае есть другая логическая ошибка. Не могли бы вы сказать, почему это может происходить? - person GoodDeeds; 08.06.2017
comment
@GoodDeeds, вероятно, я ошибся в своем ответе. Делайте то, что работает для вас! - person Shai; 08.06.2017
comment
Хорошо, спасибо. Кажется, теперь это работает. Я также запустил код, который вы написали в связанном PR (спасибо!), и столкнулся с той же проблемой, что и в этот комментарий. Значения в моем случае также отличаются в 2 раза. Это проблема с моим слоем или это известная проблема (спрашиваю, потому что об этом сообщалось ранее)? - person GoodDeeds; 08.06.2017
comment
@GoodDeeds это может быть связано с пиаром. еще не было возможности посмотреть - person Shai; 08.06.2017