如何从 PyCaffe Layer 对象获取内核大小和步幅

How to get kernel size and stride from PyCaffe Layer object

我希望能够提取 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 工作正常,因为我能够成功进行检查并且只尝试提取卷积层的卷积参数。出了什么问题?当我试图查看 "layer" 是什么类型的对象时,我看到了这个:

<caffe._caffe.Layer object at 0x7fe3a2fad050>

所以这意味着它实际上是一个 PyCaffe 图层对象。我到处寻找 PyCaffe Layer class 参考,但没有想出任何东西。有谁知道一个好的参考或如何正确提取内核和跨步信息?

在 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)+']'