Как получить размер ядра и шаг из объекта PyCaffe Layer

Я хотел бы иметь возможность извлекать все размеры ядра и шаги для каждого из слоев объединения и свертки в сети pycaffe. Это кажется возможным, поскольку я вижу, что он используется в функции рисования (см. строку 94 здесь https://github.com/BVLC/caffe/blob/daf013931b31ed9c95250a89d09b7220badbcefe/python/caffe/draw.py)

К сожалению, когда я пытаюсь использовать этот синтаксис таким образом:

net = caffe.Net(model_def,      # defines the structure of the model
                model_weights,  # contains the trained weights
                caffe.TEST)     # use test mode (e.g., don't perform dropout)
# For each layer
for layer_name, layer in net.layer_dict.iteritems():
    if layer.type == 'Convolution':
          print layer.type
          print layer.convolution_param.kernel_size[0] if len(layer.convolution_param.kernel_size) else 1

Я получаю следующую ошибку:

Convolution
AttributeError: 'Layer' object has no attribute 'convolution_param'

Это странно, потому что я явно частично прав, так как layer.type работает правильно, так как я могу успешно выполнить проверку и только попытаться извлечь параметры свертки для слоя свертки. Что происходит не так? Когда я пытаюсь увидеть, что это за «слой» объекта, я вижу это:

<caffe._caffe.Layer object at 0x7fe3a2fad050>

Это означает, что на самом деле это объект слоя PyCaffe. Я везде искал ссылку на класс PyCaffe Layer, но ничего не придумал. Кто-нибудь знает хорошую ссылку или как правильно извлечь информацию о ядре и шаге?


person Kantthpel    schedule 19.05.2017    source источник
comment
В draw.py я вижу цикл по атрибуту layer, а не layer_dict (строка 153: for layer in caffe_net.layer). Вы пробовали сделать это таким образом?   -  person kostek    schedule 19.05.2017
comment
Спасибо за ваше предложение. Я попытался сделать следующее: для слоя в net.layer: print layer.type Но получил следующую ошибку: AttributeError: объект «Net» не имеет атрибута «слой».   -  person Kantthpel    schedule 19.05.2017
comment
ХОРОШО. Вы не можете получить доступ к этим атрибутам, потому что объект, который у вас есть с вызовом caffe.Net(), не является caffe.proto.caffe_pb2.NetParameter, который используется в drawp.py. Вы, вероятно, должны получить эту информацию от BLOB-объектов. Проверьте это сообщение в блоге: christopher5106.github.io/deep/learning/2015/09/04/   -  person kostek    schedule 19.05.2017
comment
Хм, понятно. К сожалению, я не могу получить информацию о шаге или заполнении из больших двоичных объектов, поскольку размеры больших двоичных объектов предоставляют мне только количество выходов и количество каналов. Есть ли способ получить caffe.proto.caffe_pb2.NetParameter, который используется в draw.py?   -  person Kantthpel    schedule 19.05.2017
comment
А, я вижу, что net.params['conv'][0] содержит параметры веса, которые позволяют получить размер ядра. Теперь проблема заключается в том, как получить сверточный шаг, а также размер ядра и шаг для объединения слоев...   -  person Kantthpel    schedule 19.05.2017
comment
Как вы хорошо заметили, внутренние параметры каждого слоя не отображаются из кода С++ в интерфейс Python.   -  person Shai    schedule 19.05.2017


Ответы (1)


Следуя указаниям kostek, я смог извлечь нужные параметры, прочитав prototxt отдельно как файл caffe.proto.caffe_pb2.NetParameter. Код для этого можно найти ниже:

from caffe.proto import caffe_pb2
from google.protobuf import text_format

new_format_model_def = '/models/vgg16-caffe/new_format_VGG_ILSVRC_16_layers_deploy.prototxt'
parsible_net = caffe_pb2.NetParameter()
text_format.Merge(open(new_format_model_def).read(), parsible_net)
print parsible_net.layer

print '[kernel, stride, pad]'
for layer in parsible_net.layer:
    if layer.type == 'Convolution':
          print '======='
          print layer.name
          kernel = layer.convolution_param.kernel_size[0] if len(layer.convolution_param.kernel_size) else 1
          stride = layer.convolution_param.stride[0] if len(layer.convolution_param.stride) else 1
          pad    = layer.convolution_param.pad[0] if len(layer.convolution_param.pad) else 0
          print '['+str(kernel)+str(stride)+str(pad)+']'
    if layer.type == 'Pooling':
          print '======='
          print layer.name
          kernel = layer.pooling_param.kernel_size
          stride = layer.pooling_param.stride
          pad    = layer.pooling_param.pad
          print '['+str(kernel)+str(stride)+str(pad)+']'
person Kantthpel    schedule 19.05.2017