ENCP / CNNdroid

Open Source Library for GPU-Accelerated Execution of Trained Deep Convolutional Neural Networks on Android
MIT License
539 stars 181 forks source link

Convert Caffe Net to CNNdroid faild #36

Open yungs2017 opened 6 years ago

yungs2017 commented 6 years ago

There is my Net file of Caffe (prototext file)

name: "face_12c" input: "X" input_dim: 1 input_dim: 3 input_dim: 12 input_dim: 12

layer { name: "conv1" type: "Convolution" bottom: "X" top: "conv1" convolution_param { num_output: 10 kernel_size: 3 } } layer { name: "relu1" type: "PReLU" bottom: "conv1" top: "conv1" } layer { name: "pool1" type: "Pooling" bottom: "conv1" top: "pool1" pooling_param { pool: MAX kernel_size: 2 stride: 2 } }

When I use the script 'SavePycaffeModelInMessagePack.py' to convert it to CNNdroid file, it make errors Getting parameters: conv1 Getting parameters: relu1 Traceback (most recent call last): File "SavePycaffeModelInMessagePack.py", line 55, in <module> params = get_params(net) File "SavePycaffeModelInMessagePack.py", line 41, in get_params net_params[key] = [net.params[key][0].data, net.params[key][1].data] IndexError: Index out of range I have read the document and make sure there was no wrong for the parameters. There seems to be something wrong when it converted the relu1 layer. So, how to solve this problem?

latifisalar commented 6 years ago

Hi,

Unfortunately, Parametric ReLU layer is not implemented on the CNNdroid. So, the conversion script doesn't have any idea about what kind of parameter it has and fails to convert the Caffe model. If you want, I can help you to add this functionality to your library. We need to update the library and also the conversion script.

Thanks, Salar

lvzcl commented 5 years ago

@yungs2017 ,I face the same problem and I have no solution to change the source code, can you tell me how to solve it? Thanks!

latifisalar commented 5 years ago

Do you also want to add PReLU layer?

lvzcl commented 5 years ago

@latifisalar yes, I want to add PRelu layer, but I don't know how to realize it in the source code, can you give me some suggestions?

latifisalar commented 5 years ago

Here are the modifications that are necessary:

  1. You need to add PReLU layer functionality in CNNdroid/CNNdroid Source Package/java/layers/NonLinear.java: NonLinear.java is dedicated for non-linear activation functions, so you can add the PReLU functionality besides ReLU function. Here is the overview of required changes:

    • Line 4: Add import messagepack.ParamUnpacker;
    • Line 8: Define new parameters for PReLU:
    private String paramFilePath;           // name of the file which specifies alpha parameter
    private ParamUnpacker paramUnpacker;    // for extracting the alpha from the parameters file
    private float alpha;        //alpha parameter for PReLU
    - Line 12: Add PReLU in enumeration.
    - Line 16: Define a new constructor similar to ReLU one with the added alpha input:
    public NonLinear(String name, NonLinearType nonLinearType, String paramFilePath) {
        this.name = name;
        this.nonLinearType = nonLinearType;
        this.paramFilePath = paramFilePath;
    
        this.paramUnpacker = new ParamUnpacker();
        Object[] objects = paramUnpacker.unpackerFunction(paramFilePath, new Class[]{float.class});
        alpha = (float) objects[0];
    }
    • Line 27: Add the corresponding case in switch.
    • Line 42 & 63: Add similar functions for PReLU with the parametric functionality.
  2. You also need to add PReLU layer parsing in CNNdroid/CNNdroid Source Package/java/network/CNNdroid.java: CNNdroid.java is dedicated to parse NetFile and construct network compute flow. Here is the overview of required changes:

    • Line 455: Add the following if statement for PReLU:
      else if (type.equalsIgnoreCase("PReLU")) {
          String parametersFile = null;
          for (int i = 0; i < args.size(); ++i) {
              String tempArg = args.get(i);
              String tempValue = values.get(i);
              if (tempArg.equalsIgnoreCase("parameters_file"))
                  parametersFile = tempValue;
              else
                  return false;
          }
          if (parametersFile == null)
              return false;
          NonLinear nl = new NonLinear(name, NonLinear.NonLinearType.<YOUR_PReLU_DEFINITION_in_ENUM>, parametersFile);
          lastLayer = nl;
          layers.add(nl);
          return true;
      }
  3. Update the CNNdroid/Parameter Generation Scripts/SavePycaffeModelInMessagePack.py to save PReLU parameter in messagepack.

Let me know if you have question regarding any of the steps. I can also add the optimized implementation in a couple of weeks when I have more free time.

lvzcl commented 5 years ago

Thanks for your reply!