6

Is there a relatively simple way to extract weights in Python from one of the many pretrained models in Caffe Zoo WITHOUT CAFFE (nor pyCaffe)? i.e. parsing .caffemodel to hdf5/numpy or whatever format that can be read by Python?

All the answers I found use C++ code with caffe classes or Pycaffe. I have looked at pycaffe's code it looks like you really need caffe to make sense of the binary is that the only solution?

Shai
  • 111,146
  • 38
  • 238
  • 371
jeandut
  • 2,471
  • 4
  • 29
  • 56
  • Were you able to use caffe-tensorflow converter (https://github.com/ethereon/caffe-tensorflow). to extract weights from a caffe model? I recently ran into the same problem: I'd like to use weight of a pre-trained model to fine tune my own model via python (I'm using keras+tensorflow). However the pre-trained model I'd like to use only has caffemodel... – Ruby Oct 21 '16 at 04:03
  • Yes this kaffe thing is working great if it is not working for you for some reasons you can still go to mrry repo on github and look at his vgg16 caffe to tensorflow code it is pretty straightforward to do the conversion if you have built pycaffe. – jeandut Oct 21 '16 at 11:35
  • Thank you! Vgg16 is what I'm looking at. – Ruby Oct 22 '16 at 01:10
  • hdf5 tools comes handy to view and extract weights from the model file. The .caffemodel file can be opened through this tools and there is a option to dump the weights in binary format as well. – ShreeVidhya Mar 19 '20 at 11:54

4 Answers4

7

I had to resolve that exact issue just now. Assuming you have a .caffemodel (binary proto format), it turns out to be quite simple.

  1. Download the latest caffe.proto

  2. Compile into python library: protoc --python_out=. caffe.proto

  3. Import and parse

The sample code below

import numpy as np
import sys, os
import argparse
import caffe_pb2 as cq

f = open('VGG_ILSVRC_16_layers.caffemodel', 'r')
cq2 = cq.NetParameter()
cq2.ParseFromString(f.read())
f.close()
print "name 1st layer: " + cq2.layers[0].name 

produces for me:

name 1st layer: conv1_1

Obviously you can extract anything else you want from your object. I just printed the name of my first layer as an example. Also, your model may be expressing the layers in either the layers array (deprecated) or the layer (no 's') array, but you get the gist.

Lolo
  • 3,935
  • 5
  • 40
  • 50
  • 1
    I tried it and find it should be `cq2.layer` rather than `cq2.layers` – one Aug 09 '18 at 11:56
  • @Alpha See the last line I had in my response already: it depends whether the layers you have are specified using the deprecated layers field or the new layer field. Frankly, this layer vs. layers name is a mess. – Lolo Aug 16 '18 at 20:27
  • 1
    FYI I had to use `open(..., 'rb')` to make this work – Nole Apr 05 '20 at 22:46
4

Nowadays, caffe can save the weights in two formats: BINARYPROTO, or HDF5. Binary weights files with extension .caffemodel are in BINARYPROTO format, while extension .caffemodel.h5 are in HDF5 format. Since the HDF5 format was introduced to caffe recently, I expect most models you currently encounter in the "model zoo" to be in the more "traditional" BINARYPROTO format.

If the weights are in stored in HDF5 format, you might be able to pick through them using h5py package.

However, the BINARYPROTO format is based on a binary serialization of google protocol buffer format that is defined by caffe.proto. I am no expert in protocol buffers, but I suspect you will have a really hard time deciphering the binary file without explicitly "compiling" the caffe.proto protobuf definition files (which is part of caffe build).

I suppose the easiest way to pick into the weights is by installing caffe and using its python/C++ interface. Why don't you just do that?

Shai
  • 111,146
  • 38
  • 238
  • 371
  • I did not know caffe started to use hdf5 I know of h5py and it is great I have been using it a lot since I found out about it. Yeah I guess seeing the answers it must not be easy to parse google protocol buffer or at least I do not have the knwoledge to do so. Thanks for your answer I am gonna try finding some new model with .h5 extension or I will use pycaffe if there is no escape to it. – jeandut Jun 02 '16 at 07:54
  • .@Shai - If I parse the log generated by `Caffe`, then I get `learning rate` and `loss`. If these don't change for every new run of `Caffe`, is it fair to conclude that `weights` stored in `.caffemodel` for different runs are exactly same? – Chetan Arvind Patil Feb 13 '18 at 05:08
  • @ChetanArvindPatil why should they be the same? even if the loss is the same it does not necessarily mean the*gradients* are zero. – Shai Feb 13 '18 at 05:40
3

As it so happens, ethereon made a wonderful library called caffe-tensorflow to convert caffe models to Tensorflow code, but that is not all! It also allows the user to convert .caffemodel files to .npy files without having to build pycaffe! It tests if caffe was built and if not it falls back to a pure google protobuf implementation.

chris
  • 1,831
  • 18
  • 33
jeandut
  • 2,471
  • 4
  • 29
  • 56
2

I don't understand why you want to do that without caffe/pycaffe, perhaps you are tired of deploying caffe on new machine ? But since caffemodel is special binary data type of caffe, using others' tool doesn't make life easier.

If you do insist to do this, there is another framework : Mocha on Julia, which provides a method to extracting caffemodel to hdf5. I hope this could help you.

Lyken
  • 628
  • 6
  • 11
  • 1
    It is indeed Caffe's install that is a bit scary, I have just installed it on my personnal computer and built pycaffe but never tested the installation (apart from succedding to write import caffe without error messages). Furthermore I am using few other frameworks and could use the free space. I will take a look into Mocha on Julia however I bet you have to install Julia...It is a pity there is no simple way to hack it through with pure python. – jeandut Jun 02 '16 at 07:51
  • Thanks for your answer though ! – jeandut Jun 02 '16 at 07:52