Skip to content

Instantly share code, notes, and snippets.

@escorciav
Last active August 27, 2018 04:25
Show Gist options
  • Save escorciav/cf192bc51b21dae0f634 to your computer and use it in GitHub Desktop.
Save escorciav/cf192bc51b21dae0f634 to your computer and use it in GitHub Desktop.
python_layer in caffe

These files complete the example presented by @shelmaher about python layer in caffe. I just add extra files to run his example.

Usage

  1. Setup your enviroment variable, see details in setenv.sh. Basically, the module that you want to run must be in your PYTHONPATH.
  2. Run forward.sh

Requirements

  1. caffe with pycaffe
name: 'EuclideanExample'
layer {
type: 'DummyData'
name: 'x'
top: 'x'
dummy_data_param {
shape: { dim: 10 dim: 3 dim: 2 }
data_filler: { type: 'gaussian' }
}
}
layer {
type: 'DummyData'
name: 'y'
top: 'y'
dummy_data_param {
shape: { dim: 10 dim: 3 dim: 2 }
data_filler: { type: 'gaussian' }
}
}
# include InnerProduct layers for parameters
# so the net will need backward
layer {
type: 'InnerProduct'
name: 'ipx'
top: 'ipx'
bottom: 'x'
inner_product_param {
num_output: 10
weight_filler { type: 'xavier' }
}
}
layer {
type: 'InnerProduct'
name: 'ipy'
top: 'ipy'
bottom: 'y'
inner_product_param {
num_output: 10
weight_filler { type: 'xavier' }
}
}
layer {
type: 'Python'
name: 'loss'
top: 'loss'
bottom: 'ipx'
bottom: 'ipy'
python_param {
# the module name -- usually the filename -- that needs to be in $PYTHONPATH
module: 'pyloss'
# the layer name -- the class name in the module
layer: 'EuclideanLossLayer'
}
# set loss weight so Caffe knows this is a loss layer
loss_weight: 1
}
#!/usr/bin/env sh
TOOLS=../caffe/build/tools
$TOOLS/caffe train --solver=solver.prototxt --log_dir=.
import caffe
import numpy as np
class EuclideanLossLayer(caffe.Layer):
def setup(self, bottom, top):
# check input pair
if len(bottom) != 2:
raise Exception("Need two inputs to compute distance.")
def reshape(self, bottom, top):
# check input dimensions match
if bottom[0].count != bottom[1].count:
raise Exception("Inputs must have the same dimension.")
# difference is shape of inputs
self.diff = np.zeros_like(bottom[0].data, dtype=np.float32)
# loss output is scalar
top[0].reshape(1)
def forward(self, bottom, top):
self.diff[...] = bottom[0].data - bottom[1].data
top[0].data[...] = np.sum(self.diff**2) / bottom[0].num / 2.
def backward(self, top, propagate_down, bottom):
for i in range(2):
if not propagate_down[i]:
continue
if i == 0:
sign = 1
else:
sign = -1
bottom[i].diff[...] = sign * self.diff / bottom[i].num
# Usage: . setenv.sh OR source setenv.sh
# Get project dir
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
# Add example to PYTHONPATH
export PYTHONPATH=$PYTHONPATH:$DIR/data/python.layer.example
# The train/test net protocol buffer definition
net: "euclid.prototxt"
test_iter: 0
# Carry out testing every 1000 training iterations.
test_interval: 1000
# The base learning rate, momentum and the weight decay of the network.
base_lr: 0.001
momentum: 0.9
weight_decay: 0.004
# The learning rate policy
lr_policy: "fixed"
# Display every iteration
display: 1
# The maximum number of iterations
max_iter: 2
# snapshot intermediate results
snapshot: 2
snapshot_prefix: "/tmp/python_layer"
# solver mode: CPU or GPU
solver_mode: GPU
@fabiosammy
Copy link

For the deploy, i can use this same python class?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment