{# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. #}
Caffe lets you define custom layers with Python. Python layers are obviously much slower than their C++ counterparts, but are easy to write and test quickly since using them doesn't require recompilation. DIGITS moves some files around for you so that you can specify different Python layers for each network.
The BVLC and DIGITS documentation online has detailed information and tutorials about how to use these layers. Some of that information has been re-created here for your convenience.
First, you'll need to create a Python file which defines one or more layers. As an example, here is a layer which re-creates the functionality of the standard Accuracy layer using JSON-encoded parameters:
import caffe import json class AccuracyLayer(caffe.Layer): def setup(self, bottom, top): if hasattr(self, 'param_str') and self.param_str: params = json.loads(self.param_str) else: params = {} self.top_k = params.get('top_k', 1) def reshape(self, bottom, top): top[0].reshape(1) def forward(self, bottom, top): # Renaming for clarity predictions = bottom[0].data ground_truth = bottom[1].data num_correct = 0.0 # NumPy magic - get top K predictions for each datum top_predictions = (-predictions).argsort()[:, :self.top_k] for batch_index, predictions in enumerate(top_predictions): if ground_truth[batch_index] in predictions: num_correct += 1 # Accuracy is averaged over the batch top[0].data[0] = num_correct / len(ground_truth) def backward(self, top, propagate_down, bottom): pass
NOTE: The uploaded file will be renamed to digits_python_layers.py, discarding the original filename.
To add the layer to your network, include this prototxt snippet in your custom network definition:
layer { name: "accuracy" type: "Python" bottom: "pred" # These blob names may differ in your network bottom: "label" top: "accuracy" python_param { module: "digits_python_layers" # File name layer: "AccuracyLayer" # Class name param_str: "{\"top_k\": 1}" } include { stage: "val" } }