Skip to content

Commit

Permalink
bring new caffe changes into h2o-3
Browse files Browse the repository at this point in the history
  • Loading branch information
mstensmo authored and arnocandel committed Apr 1, 2017
1 parent 8cab7ed commit 62d724b
Show file tree
Hide file tree
Showing 4 changed files with 283 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public class DeepWaterCaffeIntegrationTest extends DeepWaterAbstractIntegrationT
@BeforeClass
public static void checkBackend() { Assume.assumeTrue(DeepWater.haveBackend(DeepWaterParameters.Backend.caffe)); };

@Ignore
@Test
public void run() throws Exception {
/*
Expand Down Expand Up @@ -73,12 +74,6 @@ public void run() throws Exception {
1234,
true // GPU
);
model.learning_rate(.01f);
model.momentum(.9f);

model.start();
System.out.println("Press enter");
// System.in.read();

System.out.println("Train");

Expand All @@ -94,15 +89,8 @@ public void run() throws Exception {
model.predict(ps);
}

model.saveModel("graph");
model.saveParam("params");
model.loadParam("params");

// // Monitor training
// final long start = System.nanoTime();
// double time = (System.nanoTime() - start) / 1e9;
// long processed = 0;
// int ps = (int) (processed / time);
// String text = (int) time + "s, " + processed + " (" + (ps) + "/s) ";
}
model.saveModel("/tmp/graph");
model.saveParam("/tmp/params");
model.loadParam("/tmp/params");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ public void delete(BackendModel m) {
@Override
public BackendModel buildNet(ImageDataSet dataset, RuntimeOptions opts, BackendParams bparms, int num_classes, String name) {
if (name.equals("MLP")) {
// TODO: add non-MLP Models such as lenet, inception_bn, etc.
int[] hidden = (int[]) bparms.get("hidden");
int[] sizes = new int[hidden.length + 2];
sizes[0] = dataset.getWidth();
Expand All @@ -33,8 +32,8 @@ public BackendModel buildNet(ImageDataSet dataset, RuntimeOptions opts, BackendP
System.err.println("Ignoring device_id");
double[] hdr = new double[sizes.length];
if (bparms.get("input_dropout_ratio") != null)
hdr[0] = (double)bparms.get("input_dropout_ratio");
double[] bphdr = (double[])bparms.get("hidden_dropout_ratios");
hdr[0] = (double) bparms.get("input_dropout_ratio");
double[] bphdr = (double[]) bparms.get("hidden_dropout_ratios");
if (bphdr != null)
System.arraycopy(bphdr, 0, hdr, 1, bphdr.length);
String[] layers = new String[sizes.length];
Expand All @@ -50,7 +49,19 @@ public BackendModel buildNet(ImageDataSet dataset, RuntimeOptions opts, BackendP
opts.getSeed(),
opts.useGPU()
);
} else throw new UnsupportedOperationException("Only MLP is supported for now for Caffe.");
} else {
return new DeepwaterCaffeModel(
name,
new int[] {
(Integer) bparms.get("mini_batch_size"),
dataset.getChannels(),
dataset.getWidth(),
dataset.getHeight()
},
opts.getSeed(),
opts.useGPU()
);
}
}

// graph (model definition) only
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,49 +11,48 @@
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;

import deepwater.backends.BackendModel;
import hex.genmodel.algos.deepwater.caffe.nano.Deepwater;
import hex.genmodel.algos.deepwater.caffe.nano.Deepwater.Cmd;

public class DeepwaterCaffeModel implements BackendModel {
private int _batch_size;
private int[] _sizes; // neurons per layer
private String[] _types; // layer types
private double[] _dropout_ratios;
private float _learning_rate;
private float _momentum;
private int[] _input_shape = new int[0];
private int[] _sizes = new int[0]; // neurons per layer
private String[] _types = new String[0]; // layer types
private double[] _dropout_ratios = new double[0];
private long _seed;
private boolean _useGPU;
private boolean _useDocker = true;
private boolean _useDocker = false;
private String _graph = "";

private Process _process;
private static final ThreadLocal<ByteBuffer> _buffer = new ThreadLocal<>();

public DeepwaterCaffeModel(int batch_size, int[] sizes, String[] types, double[] dropout_ratios, long seed, boolean useGPU) {
_batch_size = batch_size;
public DeepwaterCaffeModel(int batch_size, int[] sizes,
String[] types, double[] dropout_ratios,
long seed, boolean useGPU) {
_input_shape = new int[] {batch_size, 1, 1, sizes[0]};
_sizes = sizes;
_types = types;
_dropout_ratios = dropout_ratios;
_seed = seed;
_useGPU = useGPU;
}

public void learning_rate(float val) {
if (_process != null)
throw new RuntimeException("Already started");
_learning_rate = val;
start();
}

public void momentum(float val) {
if (_process != null)
throw new RuntimeException("Already started");
_momentum = val;
}
public DeepwaterCaffeModel(String graph, int[] input_shape, long seed, boolean useGPU) {
_graph = graph;
_input_shape = input_shape;
_seed = seed;
_useGPU = useGPU;

//
start();
}

private void checkStarted() {
private void start() {
if (_process == null) {
if (_useDocker) {
boolean ok = false;
Expand All @@ -80,49 +79,42 @@ private void checkStarted() {

Cmd cmd = new Cmd();
cmd.type = Deepwater.Create;
// proto.graph = _graph; // TODO
cmd.batchSize = _batch_size;
cmd.solverType = "SGD";
cmd.graph = _graph;
cmd.inputShape = _input_shape;
cmd.solverType = "Adam";
cmd.sizes = _sizes;
cmd.types = _types;
cmd.dropoutRatios = _dropout_ratios;
cmd.learningRate = _learning_rate;
cmd.momentum = _momentum;
cmd.learningRate = .01f;
cmd.momentum = .99f;
cmd.randomSeed = _seed;
cmd.useGpu = _useGPU;
call(cmd);
}
}

public void start() {
checkStarted();
}

public void saveModel(String model_path) {
checkStarted();
Cmd cmd = new Cmd();
cmd.type = Deepwater.SaveGraph;
cmd.path = model_path;
call(cmd);
}

public void saveParam(String param_path) {
checkStarted();
Cmd cmd = new Cmd();
cmd.type = Deepwater.Save;
cmd.path = param_path;
call(cmd);
}

public void loadParam(String param_path) {
checkStarted();
Cmd cmd = new Cmd();
cmd.type = Deepwater.Load;
cmd.path = param_path;
call(cmd);
}

static void copy(float[] data, byte[] buff) {
private static void copy(float[] data, byte[] buff) {
if (data.length * 4 != buff.length)
throw new RuntimeException();
ByteBuffer buffer = _buffer.get();
Expand All @@ -135,7 +127,7 @@ static void copy(float[] data, byte[] buff) {
buffer.get(buff);
}

static void copy(float[][] buffs, Cmd cmd) {
private static void copy(float[][] buffs, Cmd cmd) {
cmd.data = new byte[buffs.length][];
for (int i = 0; i < buffs.length; i++) {
cmd.data[i] = new byte[buffs[i].length * 4];
Expand All @@ -144,24 +136,26 @@ static void copy(float[][] buffs, Cmd cmd) {
}

public void train(float[] data, float[] label) {
checkStarted();
Cmd cmd = new Cmd();
cmd.type = Deepwater.Train;
if (data.length != _batch_size * _sizes[0])
cmd.inputShape = _input_shape;
int len = _input_shape[0] * _input_shape[1] * _input_shape[2] * _input_shape[3];
if (data.length != len)
throw new RuntimeException();
if (label.length != _batch_size)
if (label.length != _input_shape[0])
throw new RuntimeException();
float[][] buffs = new float[][] {data, label};
copy(buffs, cmd);
call(cmd);
}

public float[] predict(float[] data) {
checkStarted();
Cmd cmd = new Cmd();
cmd.type = Deepwater.Predict;
if (data.length != _batch_size * _sizes[0])
throw new RuntimeException();
cmd.inputShape = _input_shape;
// int len = _input_shape[0] * _input_shape[1] * _input_shape[2] * _input_shape[3];
// if (data.length != len)
// throw new RuntimeException(data.length + " vs " + len);
float[][] buffs = new float[][] {data};
copy(buffs, cmd);
cmd = call(cmd);
Expand All @@ -173,6 +167,7 @@ public float[] predict(float[] data) {
buffer.clear();
buffer.put(cmd.data[0]);
float[] res = new float[cmd.data[0].length / 4];
buffer.flip();
buffer.asFloatBuffer().get(res);
return res;
}
Expand Down Expand Up @@ -214,7 +209,7 @@ private void startDocker(String image, boolean gpu) throws IOException {
String tmp = System.getProperty("java.io.tmpdir");
opts += " -v " + tmp + ":" + tmp;
s = gpu ? "nvidia-docker" : "docker";
s += " run " + opts + " " + image + " python /h2o-docker/caffe/backend.py";
s += " run " + opts + " " + image + " python3 /h2o-docker/caffe/backend.py";
pb = new ProcessBuilder(s.split(" "));
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
_process = pb.start();
Expand All @@ -224,8 +219,8 @@ private void startDocker(String image, boolean gpu) throws IOException {
private void startRegular() throws IOException {
String home = System.getProperty("user.home");
String pwd = home + "/h2o-docker/caffe";
ProcessBuilder pb = new ProcessBuilder("python backend.py".split(" "));
pb.environment().put("PYTHONPATH", home + "/caffe/python");
ProcessBuilder pb = new ProcessBuilder("python3 backend.py".split(" "));
pb.environment().put("PYTHONPATH", home + "/caffe/python:" + home + "/protobuf/python");
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
pb.directory(new File(pwd));
_process = pb.start();
Expand Down
Loading

0 comments on commit 62d724b

Please sign in to comment.