horn-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From edwardy...@apache.org
Subject [1/4] incubator-horn git commit: Code refactoring
Date Tue, 26 Apr 2016 03:46:22 GMT
Repository: incubator-horn
Updated Branches:
  refs/heads/master 277773c0a -> ac8eaf8e1


http://git-wip-us.apache.org/repos/asf/incubator-horn/blob/ac8eaf8e/src/test/java/org/apache/horn/core/TestSmallLayeredNeuralNetwork.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/horn/core/TestSmallLayeredNeuralNetwork.java b/src/test/java/org/apache/horn/core/TestSmallLayeredNeuralNetwork.java
new file mode 100644
index 0000000..7e4328f
--- /dev/null
+++ b/src/test/java/org/apache/horn/core/TestSmallLayeredNeuralNetwork.java
@@ -0,0 +1,642 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.horn.core;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.io.SequenceFile;
+import org.apache.hama.HamaConfiguration;
+import org.apache.hama.commons.io.VectorWritable;
+import org.apache.hama.commons.math.DenseDoubleMatrix;
+import org.apache.hama.commons.math.DenseDoubleVector;
+import org.apache.hama.commons.math.DoubleMatrix;
+import org.apache.hama.commons.math.DoubleVector;
+import org.apache.hama.ml.util.DefaultFeatureTransformer;
+import org.apache.hama.ml.util.FeatureTransformer;
+import org.apache.horn.core.AbstractLayeredNeuralNetwork.LearningStyle;
+import org.apache.horn.core.AbstractLayeredNeuralNetwork.TrainingMethod;
+import org.apache.horn.funcs.FunctionFactory;
+import org.junit.Test;
+import org.mortbay.log.Log;
+
+/**
+ * Test the functionality of SmallLayeredNeuralNetwork.
+ * 
+ */
+public class TestSmallLayeredNeuralNetwork extends MLTestBase {
+
+  @Test
+  public void testReadWrite() {
+    LayeredNeuralNetwork ann = new LayeredNeuralNetwork();
+    ann.addLayer(2, false,
+        FunctionFactory.createDoubleFunction("IdentityFunction"));
+    ann.addLayer(5, false,
+        FunctionFactory.createDoubleFunction("IdentityFunction"));
+    ann.addLayer(1, true,
+        FunctionFactory.createDoubleFunction("IdentityFunction"));
+    ann.setCostFunction(FunctionFactory
+        .createDoubleDoubleFunction("SquaredError"));
+    double learningRate = 0.2;
+    // ann.setLearningRate(learningRate);
+    double momentumWeight = 0.5;
+    // ann.setMomemtumWeight(momentumWeight);
+    double regularizationWeight = 0.05;
+    //ann.setRegularizationWeight(regularizationWeight);
+    // intentionally initialize all weights to 0.5
+    DoubleMatrix[] matrices = new DenseDoubleMatrix[2];
+    matrices[0] = new DenseDoubleMatrix(5, 3, 0.2);
+    matrices[1] = new DenseDoubleMatrix(1, 6, 0.8);
+    ann.setWeightMatrices(matrices);
+    ann.setLearningStyle(LearningStyle.UNSUPERVISED);
+    
+    FeatureTransformer defaultFeatureTransformer = new DefaultFeatureTransformer();
+    ann.setFeatureTransformer(defaultFeatureTransformer);
+    
+
+    // write to file
+    String modelPath = "/tmp/testSmallLayeredNeuralNetworkReadWrite";
+    ann.setModelPath(modelPath);
+    try {
+      ann.writeModelToFile();
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+
+    // read from file
+    LayeredNeuralNetwork annCopy = new LayeredNeuralNetwork(new HamaConfiguration(), modelPath);
+    assertEquals(annCopy.getClass().getSimpleName(), annCopy.getModelType());
+    assertEquals(modelPath, annCopy.getModelPath());
+    // assertEquals(learningRate, annCopy.getLearningRate(), 0.000001);
+    // assertEquals(momentumWeight, annCopy.getMomemtumWeight(), 0.000001);
+    //assertEquals(regularizationWeight, annCopy.getRegularizationWeight(),
+    //    0.000001);
+    assertEquals(TrainingMethod.GRADIENT_DESCENT, annCopy.getTrainingMethod());
+    assertEquals(LearningStyle.UNSUPERVISED, annCopy.getLearningStyle());
+
+    // compare weights
+    DoubleMatrix[] weightsMatrices = annCopy.getWeightMatrices();
+    for (int i = 0; i < weightsMatrices.length; ++i) {
+      DoubleMatrix expectMat = matrices[i];
+      DoubleMatrix actualMat = weightsMatrices[i];
+      for (int j = 0; j < expectMat.getRowCount(); ++j) {
+        for (int k = 0; k < expectMat.getColumnCount(); ++k) {
+          assertEquals(expectMat.get(j, k), actualMat.get(j, k), 0.000001);
+        }
+      }
+    }
+    
+    FeatureTransformer copyTransformer = annCopy.getFeatureTransformer();
+    assertEquals(defaultFeatureTransformer.getClass().getName(), copyTransformer.getClass().getName());
+  }
+
+  @Test
+  /**
+   * Test the forward functionality.
+   */
+  public void testOutput() {
+    // first network
+    LayeredNeuralNetwork ann = new LayeredNeuralNetwork();
+    ann.addLayer(2, false,
+        FunctionFactory.createDoubleFunction("IdentityFunction"));
+    ann.addLayer(5, false,
+        FunctionFactory.createDoubleFunction("IdentityFunction"));
+    ann.addLayer(1, true,
+        FunctionFactory.createDoubleFunction("IdentityFunction"));
+    ann.setCostFunction(FunctionFactory
+        .createDoubleDoubleFunction("SquaredError"));
+    // ann.setLearningRate(0.1);
+    // intentionally initialize all weights to 0.5
+    DoubleMatrix[] matrices = new DenseDoubleMatrix[2];
+    matrices[0] = new DenseDoubleMatrix(5, 3, 0.5);
+    matrices[1] = new DenseDoubleMatrix(1, 6, 0.5);
+    ann.setWeightMatrices(matrices);
+
+    double[] arr = new double[] { 0, 1 };
+    DoubleVector training = new DenseDoubleVector(arr);
+    DoubleVector result = ann.getOutput(training);
+    assertEquals(1, result.getDimension());
+    // assertEquals(3, result.get(0), 0.000001);
+
+    // second network
+    LayeredNeuralNetwork ann2 = new LayeredNeuralNetwork();
+    ann2.addLayer(2, false, FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann2.addLayer(3, false, FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann2.addLayer(1, true, FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann2.setCostFunction(FunctionFactory
+        .createDoubleDoubleFunction("SquaredError"));
+    // ann2.setLearningRate(0.3);
+    // intentionally initialize all weights to 0.5
+    DoubleMatrix[] matrices2 = new DenseDoubleMatrix[2];
+    matrices2[0] = new DenseDoubleMatrix(3, 3, 0.5);
+    matrices2[1] = new DenseDoubleMatrix(1, 4, 0.5);
+    ann2.setWeightMatrices(matrices2);
+
+    double[] test = { 0, 0 };
+    double[] result2 = { 0.807476 };
+
+    DoubleVector vec = ann2.getOutput(new DenseDoubleVector(test));
+    assertArrayEquals(result2, vec.toArray(), 0.000001);
+
+    LayeredNeuralNetwork ann3 = new LayeredNeuralNetwork();
+    ann3.addLayer(2, false, FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann3.addLayer(3, false, FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann3.addLayer(1, true, FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann3.setCostFunction(FunctionFactory
+        .createDoubleDoubleFunction("SquaredError"));
+    // ann3.setLearningRate(0.3);
+    // intentionally initialize all weights to 0.5
+    DoubleMatrix[] initMatrices = new DenseDoubleMatrix[2];
+    initMatrices[0] = new DenseDoubleMatrix(3, 3, 0.5);
+    initMatrices[1] = new DenseDoubleMatrix(1, 4, 0.5);
+    ann3.setWeightMatrices(initMatrices);
+
+    double[] instance = { 0, 1 };
+    DoubleVector output = ann3.getOutput(new DenseDoubleVector(instance));
+    assertEquals(0.8315410, output.get(0), 0.000001);
+  }
+
+  @Test
+  public void testXORlocal() {
+    LayeredNeuralNetwork ann = new LayeredNeuralNetwork();
+    ann.addLayer(2, false, FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann.addLayer(3, false, FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann.addLayer(1, true, FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann.setCostFunction(FunctionFactory
+        .createDoubleDoubleFunction("SquaredError"));
+    // ann.setLearningRate(0.5);
+    // ann.setMomemtumWeight(0.0);
+
+    int iterations = 50000; // iteration should be set to a very large number
+    double[][] instances = { { 0, 1, 1 }, { 0, 0, 0 }, { 1, 0, 1 }, { 1, 1, 0 } };
+    for (int i = 0; i < iterations; ++i) {
+      DoubleMatrix[] matrices = null;
+      for (int j = 0; j < instances.length; ++j) {
+        matrices = ann.trainByInstance(new DenseDoubleVector(instances[j
+            % instances.length]));
+        ann.updateWeightMatrices(matrices);
+      }
+    }
+
+    for (int i = 0; i < instances.length; ++i) {
+      DoubleVector input = new DenseDoubleVector(instances[i]).slice(2);
+      // the expected output is the last element in array
+      double result = instances[i][2];
+      double actual = ann.getOutput(input).get(0);
+      if (result < 0.5 && actual >= 0.5 || result >= 0.5 && actual < 0.5) {
+        Log.info("Neural network failes to lear the XOR.");
+      }
+    }
+
+    // write model into file and read out
+    String modelPath = "/tmp/testSmallLayeredNeuralNetworkXORLocal";
+    ann.setModelPath(modelPath);
+    try {
+      ann.writeModelToFile();
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+    LayeredNeuralNetwork annCopy = new LayeredNeuralNetwork(new HamaConfiguration(), modelPath);
+    // test on instances
+    for (int i = 0; i < instances.length; ++i) {
+      DoubleVector input = new DenseDoubleVector(instances[i]).slice(2);
+      // the expected output is the last element in array
+      double result = instances[i][2];
+      double actual = annCopy.getOutput(input).get(0);
+      if (result < 0.5 && actual >= 0.5 || result >= 0.5 && actual < 0.5) {
+        Log.info("Neural network failes to lear the XOR.");
+      }
+    }
+  }
+
+  @Test
+  public void testXORWithMomentum() {
+    LayeredNeuralNetwork ann = new LayeredNeuralNetwork();
+    ann.addLayer(2, false, FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann.addLayer(3, false, FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann.addLayer(1, true, FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann.setCostFunction(FunctionFactory
+        .createDoubleDoubleFunction("SquaredError"));
+    // ann.setLearningRate(0.6);
+    // ann.setMomemtumWeight(0.3);
+
+    int iterations = 2000; // iteration should be set to a very large number
+    double[][] instances = { { 0, 1, 1 }, { 0, 0, 0 }, { 1, 0, 1 }, { 1, 1, 0 } };
+    for (int i = 0; i < iterations; ++i) {
+      for (int j = 0; j < instances.length; ++j) {
+        ann.trainOnline(new DenseDoubleVector(instances[j % instances.length]));
+      }
+    }
+
+    for (int i = 0; i < instances.length; ++i) {
+      DoubleVector input = new DenseDoubleVector(instances[i]).slice(2);
+      // the expected output is the last element in array
+      double result = instances[i][2];
+      double actual = ann.getOutput(input).get(0);
+      if (result < 0.5 && actual >= 0.5 || result >= 0.5 && actual < 0.5) {
+        Log.info("Neural network failes to lear the XOR.");
+      }
+    }
+
+    // write model into file and read out
+    String modelPath = "/tmp/testSmallLayeredNeuralNetworkXORLocalWithMomentum";
+    ann.setModelPath(modelPath);
+    try {
+      ann.writeModelToFile();
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+    LayeredNeuralNetwork annCopy = new LayeredNeuralNetwork(new HamaConfiguration(), modelPath);
+    // test on instances
+    for (int i = 0; i < instances.length; ++i) {
+      DoubleVector input = new DenseDoubleVector(instances[i]).slice(2);
+      // the expected output is the last element in array
+      double result = instances[i][2];
+      double actual = annCopy.getOutput(input).get(0);
+      if (result < 0.5 && actual >= 0.5 || result >= 0.5 && actual < 0.5) {
+        Log.info("Neural network failes to lear the XOR.");
+      }
+    }
+  }
+
+  @Test
+  public void testXORLocalWithRegularization() {
+    LayeredNeuralNetwork ann = new LayeredNeuralNetwork();
+    ann.addLayer(2, false, FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann.addLayer(3, false, FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann.addLayer(1, true, FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann.setCostFunction(FunctionFactory
+        .createDoubleDoubleFunction("SquaredError"));
+    // ann.setLearningRate(0.7);
+    // ann.setMomemtumWeight(0.5);
+    //ann.setRegularizationWeight(0.002);
+
+    int iterations = 5000; // iteration should be set to a very large number
+    double[][] instances = { { 0, 1, 1 }, { 0, 0, 0 }, { 1, 0, 1 }, { 1, 1, 0 } };
+    for (int i = 0; i < iterations; ++i) {
+      for (int j = 0; j < instances.length; ++j) {
+        ann.trainOnline(new DenseDoubleVector(instances[j % instances.length]));
+      }
+    }
+
+    for (int i = 0; i < instances.length; ++i) {
+      DoubleVector input = new DenseDoubleVector(instances[i]).slice(2);
+      // the expected output is the last element in array
+      double result = instances[i][2];
+      double actual = ann.getOutput(input).get(0);
+      if (result < 0.5 && actual >= 0.5 || result >= 0.5 && actual < 0.5) {
+        Log.info("Neural network failes to lear the XOR.");
+      }
+    }
+
+    // write model into file and read out
+    String modelPath = "/tmp/testSmallLayeredNeuralNetworkXORLocalWithRegularization";
+    ann.setModelPath(modelPath);
+    try {
+      ann.writeModelToFile();
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+    LayeredNeuralNetwork annCopy = new LayeredNeuralNetwork(new HamaConfiguration(), modelPath);
+    // test on instances
+    for (int i = 0; i < instances.length; ++i) {
+      DoubleVector input = new DenseDoubleVector(instances[i]).slice(2);
+      // the expected output is the last element in array
+      double result = instances[i][2];
+      double actual = annCopy.getOutput(input).get(0);
+      if (result < 0.5 && actual >= 0.5 || result >= 0.5 && actual < 0.5) {
+        Log.info("Neural network failes to lear the XOR.");
+      }
+    }
+  }
+
+  @Test
+  public void testTwoClassClassification() {
+    // use logistic regression data
+    String filepath = "src/test/resources/logistic_regression_data.txt";
+    List<double[]> instanceList = new ArrayList<double[]>();
+
+    try {
+      BufferedReader br = new BufferedReader(new FileReader(filepath));
+      String line = null;
+      while ((line = br.readLine()) != null) {
+        String[] tokens = line.trim().split(",");
+        double[] instance = new double[tokens.length];
+        for (int i = 0; i < tokens.length; ++i) {
+          instance[i] = Double.parseDouble(tokens[i]);
+        }
+        instanceList.add(instance);
+      }
+      br.close();
+    } catch (FileNotFoundException e) {
+      e.printStackTrace();
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+
+    zeroOneNormalization(instanceList, instanceList.get(0).length - 1);
+    
+    int dimension = instanceList.get(0).length - 1;
+
+    // divide dataset into training and testing
+    List<double[]> testInstances = new ArrayList<double[]>();
+    testInstances.addAll(instanceList.subList(instanceList.size() - 100,
+        instanceList.size()));
+    List<double[]> trainingInstances = instanceList.subList(0,
+        instanceList.size() - 100);
+
+    LayeredNeuralNetwork ann = new LayeredNeuralNetwork();
+    // ann.setLearningRate(0.001);
+    // ann.setMomemtumWeight(0.1);
+    //ann.setRegularizationWeight(0.01);
+    ann.addLayer(dimension, false,
+        FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann.addLayer(dimension, false,
+        FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann.addLayer(dimension, false,
+        FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann.addLayer(1, true, FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann.setCostFunction(FunctionFactory
+        .createDoubleDoubleFunction("CrossEntropy"));
+
+    long start = new Date().getTime();
+    int iterations = 1000;
+    for (int i = 0; i < iterations; ++i) {
+      for (double[] trainingInstance : trainingInstances) {
+        ann.trainOnline(new DenseDoubleVector(trainingInstance));
+      }
+    }
+    long end = new Date().getTime();
+    Log.info(String.format("Training time: %fs\n",
+        (double) (end - start) / 1000));
+
+    double errorRate = 0;
+    // calculate the error on test instance
+    for (double[] testInstance : testInstances) {
+      DoubleVector instance = new DenseDoubleVector(testInstance);
+      double expected = instance.get(instance.getDimension() - 1);
+      instance = instance.slice(instance.getDimension() - 1);
+      double actual = ann.getOutput(instance).get(0);
+      if (actual < 0.5 && expected >= 0.5 || actual >= 0.5 && expected < 0.5) {
+        ++errorRate;
+      }
+    }
+    errorRate /= testInstances.size();
+
+    Log.info(String.format("Relative error: %f%%\n", errorRate * 100));
+  }
+  
+  @Test
+  public void testLogisticRegression() {
+    this.testLogisticRegressionDistributedVersion();
+    this.testLogisticRegressionDistributedVersionWithFeatureTransformer();
+  }
+
+  public void testLogisticRegressionDistributedVersion() {
+    // write data into a sequence file
+    String tmpStrDatasetPath = "/tmp/logistic_regression_data";
+    Path tmpDatasetPath = new Path(tmpStrDatasetPath);
+    String strDataPath = "src/test/resources/logistic_regression_data.txt";
+    String modelPath = "/tmp/logistic-regression-distributed-model";
+
+    Configuration conf = new Configuration();
+    List<double[]> instanceList = new ArrayList<double[]>();
+    List<double[]> trainingInstances = null;
+    List<double[]> testInstances = null;
+
+    try {
+      FileSystem fs = FileSystem.get(new URI(tmpStrDatasetPath), conf);
+      fs.delete(tmpDatasetPath, true);
+      if (fs.exists(tmpDatasetPath)) {
+        fs.createNewFile(tmpDatasetPath);
+      }
+
+      BufferedReader br = new BufferedReader(new FileReader(strDataPath));
+      String line = null;
+      int count = 0;
+      while ((line = br.readLine()) != null) {
+        String[] tokens = line.trim().split(",");
+        double[] instance = new double[tokens.length];
+        for (int i = 0; i < tokens.length; ++i) {
+          instance[i] = Double.parseDouble(tokens[i]);
+        }
+        instanceList.add(instance);
+      }
+      br.close();
+      
+      zeroOneNormalization(instanceList, instanceList.get(0).length - 1);
+      
+      // write training data to temporal sequence file
+      SequenceFile.Writer writer = new SequenceFile.Writer(fs, conf,
+          tmpDatasetPath, LongWritable.class, VectorWritable.class);
+      int testSize = 150;
+
+      Collections.shuffle(instanceList);
+      testInstances = new ArrayList<double[]>();
+      testInstances.addAll(instanceList.subList(instanceList.size() - testSize,
+          instanceList.size()));
+      trainingInstances = instanceList.subList(0, instanceList.size()
+          - testSize);
+
+      for (double[] instance : trainingInstances) {
+        DoubleVector vec = new DenseDoubleVector(instance);
+        writer.append(new LongWritable(count++), new VectorWritable(vec));
+      }
+      writer.close();
+    } catch (FileNotFoundException e) {
+      e.printStackTrace();
+    } catch (IOException e) {
+      e.printStackTrace();
+    } catch (URISyntaxException e) {
+      e.printStackTrace();
+    }
+
+    // create model
+    int dimension = 8;
+    LayeredNeuralNetwork ann = new LayeredNeuralNetwork();
+    // ann.setLearningRate(0.7);
+    // ann.setMomemtumWeight(0.5);
+    //ann.setRegularizationWeight(0.1);
+    ann.addLayer(dimension, false,
+        FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann.addLayer(dimension, false,
+        FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann.addLayer(dimension, false,
+        FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann.addLayer(1, true, FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann.setCostFunction(FunctionFactory
+        .createDoubleDoubleFunction("CrossEntropy"));
+    ann.setModelPath(modelPath);
+
+    long start = new Date().getTime();
+    Map<String, String> trainingParameters = new HashMap<String, String>();
+    trainingParameters.put("tasks", "5");
+    trainingParameters.put("training.max.iterations", "2000");
+    trainingParameters.put("training.batch.size", "300");
+    trainingParameters.put("convergence.check.interval", "1000");
+    //ann.train(new HamaConfiguration(), tmpDatasetPath, trainingParameters);
+
+    long end = new Date().getTime();
+
+    // validate results
+    double errorRate = 0;
+    // calculate the error on test instance
+    for (double[] testInstance : testInstances) {
+      DoubleVector instance = new DenseDoubleVector(testInstance);
+      double expected = instance.get(instance.getDimension() - 1);
+      instance = instance.slice(instance.getDimension() - 1);
+      double actual = ann.getOutput(instance).get(0);
+      if (actual < 0.5 && expected >= 0.5 || actual >= 0.5 && expected < 0.5) {
+        ++errorRate;
+      }
+    }
+    errorRate /= testInstances.size();
+
+    Log.info(String.format("Training time: %fs\n",
+        (double) (end - start) / 1000));
+    Log.info(String.format("Relative error: %f%%\n", errorRate * 100));
+  }
+
+  public void testLogisticRegressionDistributedVersionWithFeatureTransformer() {
+    // write data into a sequence file
+    String tmpStrDatasetPath = "/tmp/logistic_regression_data_feature_transformer";
+    Path tmpDatasetPath = new Path(tmpStrDatasetPath);
+    String strDataPath = "src/test/resources/logistic_regression_data.txt";
+    String modelPath = "/tmp/logistic-regression-distributed-model-feature-transformer";
+
+    Configuration conf = new Configuration();
+    List<double[]> instanceList = new ArrayList<double[]>();
+    List<double[]> trainingInstances = null;
+    List<double[]> testInstances = null;
+
+    try {
+      FileSystem fs = FileSystem.get(new URI(tmpStrDatasetPath), conf);
+      fs.delete(tmpDatasetPath, true);
+      if (fs.exists(tmpDatasetPath)) {
+        fs.createNewFile(tmpDatasetPath);
+      }
+
+      BufferedReader br = new BufferedReader(new FileReader(strDataPath));
+      String line = null;
+      int count = 0;
+      while ((line = br.readLine()) != null) {
+        String[] tokens = line.trim().split(",");
+        double[] instance = new double[tokens.length];
+        for (int i = 0; i < tokens.length; ++i) {
+          instance[i] = Double.parseDouble(tokens[i]);
+        }
+        instanceList.add(instance);
+      }
+      br.close();
+      
+      zeroOneNormalization(instanceList, instanceList.get(0).length - 1);
+      
+      // write training data to temporal sequence file
+      SequenceFile.Writer writer = new SequenceFile.Writer(fs, conf,
+          tmpDatasetPath, LongWritable.class, VectorWritable.class);
+      int testSize = 150;
+
+      Collections.shuffle(instanceList);
+      testInstances = new ArrayList<double[]>();
+      testInstances.addAll(instanceList.subList(instanceList.size() - testSize,
+          instanceList.size()));
+      trainingInstances = instanceList.subList(0, instanceList.size()
+          - testSize);
+
+      for (double[] instance : trainingInstances) {
+        DoubleVector vec = new DenseDoubleVector(instance);
+        writer.append(new LongWritable(count++), new VectorWritable(vec));
+      }
+      writer.close();
+    } catch (FileNotFoundException e) {
+      e.printStackTrace();
+    } catch (IOException e) {
+      e.printStackTrace();
+    } catch (URISyntaxException e) {
+      e.printStackTrace();
+    }
+
+    // create model
+    int dimension = 8;
+    LayeredNeuralNetwork ann = new LayeredNeuralNetwork();
+    // ann.setLearningRate(0.7);
+    // ann.setMomemtumWeight(0.5);
+    //ann.setRegularizationWeight(0.1);
+    ann.addLayer(dimension, false,
+        FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann.addLayer(dimension, false,
+        FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann.addLayer(dimension, false,
+        FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann.addLayer(1, true, FunctionFactory.createDoubleFunction("Sigmoid"));
+    ann.setCostFunction(FunctionFactory
+        .createDoubleDoubleFunction("CrossEntropy"));
+    ann.setModelPath(modelPath);
+    
+    FeatureTransformer featureTransformer = new DefaultFeatureTransformer();
+    
+    ann.setFeatureTransformer(featureTransformer);
+
+    long start = new Date().getTime();
+    Map<String, String> trainingParameters = new HashMap<String, String>();
+    trainingParameters.put("tasks", "5");
+    trainingParameters.put("training.max.iterations", "2000");
+    trainingParameters.put("training.batch.size", "300");
+    trainingParameters.put("convergence.check.interval", "1000");
+    //ann.train(new HamaConfiguration(), tmpDatasetPath, trainingParameters);
+
+    long end = new Date().getTime();
+
+    // validate results
+    double errorRate = 0;
+    // calculate the error on test instance
+    for (double[] testInstance : testInstances) {
+      DoubleVector instance = new DenseDoubleVector(testInstance);
+      double expected = instance.get(instance.getDimension() - 1);
+      instance = instance.slice(instance.getDimension() - 1);
+      instance = featureTransformer.transform(instance);
+      double actual = ann.getOutput(instance).get(0);
+      if (actual < 0.5 && expected >= 0.5 || actual >= 0.5 && expected < 0.5) {
+        ++errorRate;
+      }
+    }
+    errorRate /= testInstances.size();
+
+    Log.info(String.format("Training time: %fs\n",
+        (double) (end - start) / 1000));
+    Log.info(String.format("Relative error: %f%%\n", errorRate * 100));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-horn/blob/ac8eaf8e/src/test/java/org/apache/horn/core/TestSmallLayeredNeuralNetworkMessage.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/horn/core/TestSmallLayeredNeuralNetworkMessage.java b/src/test/java/org/apache/horn/core/TestSmallLayeredNeuralNetworkMessage.java
new file mode 100644
index 0000000..a0c66d2
--- /dev/null
+++ b/src/test/java/org/apache/horn/core/TestSmallLayeredNeuralNetworkMessage.java
@@ -0,0 +1,173 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.horn.core;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FSDataInputStream;
+import org.apache.hadoop.fs.FSDataOutputStream;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hama.commons.math.DenseDoubleMatrix;
+import org.apache.hama.commons.math.DoubleMatrix;
+import org.apache.horn.core.ParameterMessage;
+import org.junit.Test;
+
+/**
+ * Test the functionalities of SmallLayeredNeuralNetworkMessage.
+ * 
+ */
+public class TestSmallLayeredNeuralNetworkMessage {
+
+  @Test
+  public void testReadWriteWithoutPrev() {
+    double error = 0.22;
+    double[][] matrix1 = new double[][] { { 0.1, 0.2, 0.8, 0.5 },
+        { 0.3, 0.4, 0.6, 0.2 }, { 0.5, 0.6, 0.1, 0.5 } };
+    double[][] matrix2 = new double[][] { { 0.8, 1.2, 0.5 } };
+    DoubleMatrix[] matrices = new DoubleMatrix[2];
+    matrices[0] = new DenseDoubleMatrix(matrix1);
+    matrices[1] = new DenseDoubleMatrix(matrix2);
+
+    boolean isConverge = false;
+
+    ParameterMessage message = new ParameterMessage(
+        error, isConverge, matrices, null);
+    Configuration conf = new Configuration();
+    String strPath = "/tmp/testReadWriteSmallLayeredNeuralNetworkMessage";
+    Path path = new Path(strPath);
+    try {
+      FileSystem fs = FileSystem.get(new URI(strPath), conf);
+      FSDataOutputStream out = fs.create(path);
+      message.write(out);
+      out.close();
+
+      FSDataInputStream in = fs.open(path);
+      ParameterMessage readMessage = new ParameterMessage(
+          0, isConverge, null, null);
+      readMessage.readFields(in);
+      in.close();
+      assertEquals(error, readMessage.getTrainingError(), 0.000001);
+      assertFalse(readMessage.isConverge());
+      DoubleMatrix[] readMatrices = readMessage.getCurMatrices();
+      assertEquals(2, readMatrices.length);
+      for (int i = 0; i < readMatrices.length; ++i) {
+        double[][] doubleMatrices = ((DenseDoubleMatrix) readMatrices[i])
+            .getValues();
+        double[][] doubleExpected = ((DenseDoubleMatrix) matrices[i])
+            .getValues();
+        for (int r = 0; r < doubleMatrices.length; ++r) {
+          assertArrayEquals(doubleExpected[r], doubleMatrices[r], 0.000001);
+        }
+      }
+
+      DoubleMatrix[] readPrevMatrices = readMessage.getPrevMatrices();
+      assertNull(readPrevMatrices);
+
+      // delete
+      fs.delete(path, true);
+    } catch (IOException e) {
+      e.printStackTrace();
+    } catch (URISyntaxException e) {
+      e.printStackTrace();
+    }
+  }
+
+  @Test
+  public void testReadWriteWithPrev() {
+    double error = 0.22;
+    boolean isConverge = true;
+
+    double[][] matrix1 = new double[][] { { 0.1, 0.2, 0.8, 0.5 },
+        { 0.3, 0.4, 0.6, 0.2 }, { 0.5, 0.6, 0.1, 0.5 } };
+    double[][] matrix2 = new double[][] { { 0.8, 1.2, 0.5 } };
+    DoubleMatrix[] matrices = new DoubleMatrix[2];
+    matrices[0] = new DenseDoubleMatrix(matrix1);
+    matrices[1] = new DenseDoubleMatrix(matrix2);
+
+    double[][] prevMatrix1 = new double[][] { { 0.1, 0.1, 0.2, 0.3 },
+        { 0.2, 0.4, 0.1, 0.5 }, { 0.5, 0.1, 0.5, 0.2 } };
+    double[][] prevMatrix2 = new double[][] { { 0.1, 0.2, 0.5, 0.9 },
+        { 0.3, 0.5, 0.2, 0.6 }, { 0.6, 0.8, 0.7, 0.5 } };
+
+    DoubleMatrix[] prevMatrices = new DoubleMatrix[2];
+    prevMatrices[0] = new DenseDoubleMatrix(prevMatrix1);
+    prevMatrices[1] = new DenseDoubleMatrix(prevMatrix2);
+
+    ParameterMessage message = new ParameterMessage(
+        error, isConverge, matrices, prevMatrices);
+    Configuration conf = new Configuration();
+    String strPath = "/tmp/testReadWriteSmallLayeredNeuralNetworkMessageWithPrev";
+    Path path = new Path(strPath);
+    try {
+      FileSystem fs = FileSystem.get(new URI(strPath), conf);
+      FSDataOutputStream out = fs.create(path);
+      message.write(out);
+      out.close();
+
+      FSDataInputStream in = fs.open(path);
+      ParameterMessage readMessage = new ParameterMessage(
+          0, isConverge, null, null);
+      readMessage.readFields(in);
+      in.close();
+
+      assertTrue(readMessage.isConverge());
+
+      DoubleMatrix[] readMatrices = readMessage.getCurMatrices();
+      assertEquals(2, readMatrices.length);
+      for (int i = 0; i < readMatrices.length; ++i) {
+        double[][] doubleMatrices = ((DenseDoubleMatrix) readMatrices[i])
+            .getValues();
+        double[][] doubleExpected = ((DenseDoubleMatrix) matrices[i])
+            .getValues();
+        for (int r = 0; r < doubleMatrices.length; ++r) {
+          assertArrayEquals(doubleExpected[r], doubleMatrices[r], 0.000001);
+        }
+      }
+
+      DoubleMatrix[] readPrevMatrices = readMessage.getPrevMatrices();
+      assertEquals(2, readPrevMatrices.length);
+      for (int i = 0; i < readPrevMatrices.length; ++i) {
+        double[][] doubleMatrices = ((DenseDoubleMatrix) readPrevMatrices[i])
+            .getValues();
+        double[][] doubleExpected = ((DenseDoubleMatrix) prevMatrices[i])
+            .getValues();
+        for (int r = 0; r < doubleMatrices.length; ++r) {
+          assertArrayEquals(doubleExpected[r], doubleMatrices[r], 0.000001);
+        }
+      }
+
+      // delete
+      fs.delete(path, true);
+    } catch (IOException e) {
+      e.printStackTrace();
+    } catch (URISyntaxException e) {
+      e.printStackTrace();
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-horn/blob/ac8eaf8e/src/test/java/org/apache/horn/examples/MultiLayerPerceptronTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/horn/examples/MultiLayerPerceptronTest.java b/src/test/java/org/apache/horn/examples/MultiLayerPerceptronTest.java
new file mode 100644
index 0000000..fd24c4f
--- /dev/null
+++ b/src/test/java/org/apache/horn/examples/MultiLayerPerceptronTest.java
@@ -0,0 +1,177 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.horn.examples;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URI;
+
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.io.SequenceFile;
+import org.apache.hama.Constants;
+import org.apache.hama.HamaCluster;
+import org.apache.hama.HamaConfiguration;
+import org.apache.hama.commons.io.VectorWritable;
+import org.apache.hama.commons.math.DenseDoubleVector;
+import org.apache.hama.commons.math.DoubleVector;
+import org.apache.horn.core.HornJob;
+import org.apache.horn.core.LayeredNeuralNetwork;
+
+/**
+ * Test the functionality of NeuralNetwork Example.
+ */
+public class MultiLayerPerceptronTest extends HamaCluster {
+  private HamaConfiguration conf;
+  private FileSystem fs;
+  private String MODEL_PATH = "/tmp/neuralnets.model";
+  private String RESULT_PATH = "/tmp/neuralnets.txt";
+  private String SEQTRAIN_DATA = "/tmp/test-neuralnets.data";
+
+  public MultiLayerPerceptronTest() {
+    conf = new HamaConfiguration();
+    conf.set("bsp.master.address", "localhost");
+    conf.setBoolean("hama.child.redirect.log.console", true);
+    conf.setBoolean("hama.messenger.runtime.compression", true);
+    assertEquals("Make sure master addr is set to localhost:", "localhost",
+        conf.get("bsp.master.address"));
+    conf.set("bsp.local.dir", "/tmp/hama-test");
+    conf.set(Constants.ZOOKEEPER_QUORUM, "localhost");
+    conf.setInt(Constants.ZOOKEEPER_CLIENT_PORT, 21810);
+    conf.set("hama.sync.client.class",
+        org.apache.hama.bsp.sync.ZooKeeperSyncClientImpl.class
+            .getCanonicalName());
+  }
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    fs = FileSystem.get(conf);
+  }
+
+  @Override
+  public void tearDown() throws Exception {
+    super.tearDown();
+  }
+
+  public void testNeuralnetsLabeling() throws IOException {
+    this.neuralNetworkTraining();
+
+    String featureDataPath = "src/test/resources/neuralnets_classification_test.txt";
+    try {
+      LayeredNeuralNetwork ann = new LayeredNeuralNetwork(conf,
+          MODEL_PATH);
+
+      // process data in streaming approach
+      FileSystem fs = FileSystem.get(new URI(featureDataPath), conf);
+      BufferedReader br = new BufferedReader(new InputStreamReader(
+          fs.open(new Path(featureDataPath))));
+
+      String line = null;
+      line = null;
+
+      // compare results with ground-truth
+      BufferedReader groundTruthReader = new BufferedReader(new FileReader(
+          "src/test/resources/neuralnets_classification_label.txt"));
+
+      double correct = 0;
+      int samples = 0;
+      while ((line = br.readLine()) != null) {
+        if (line.trim().length() == 0) {
+          continue;
+        }
+        String[] tokens = line.trim().split(",");
+        double[] vals = new double[tokens.length];
+        for (int i = 0; i < tokens.length; ++i) {
+          vals[i] = Double.parseDouble(tokens[i]);
+        }
+        DoubleVector instance = new DenseDoubleVector(vals);
+        DoubleVector result = ann.getOutput(instance);
+        double actual = result.toArray()[0];
+        double expected = Double.parseDouble(groundTruthReader.readLine());
+
+        LOG.info("evaluated: " + actual + ", expected: " + expected);
+        if (actual < 0.5 && expected < 0.5 || actual >= 0.5 && expected >= 0.5) {
+          ++correct;
+        }
+        samples++;
+      }
+
+      groundTruthReader.close();
+      br.close();
+
+      LOG.info("## Precision: " + (correct / samples));
+      assertTrue((correct / samples) > 0.5);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+    } finally {
+      fs.delete(new Path(RESULT_PATH), true);
+      fs.delete(new Path(MODEL_PATH), true);
+      fs.delete(new Path(SEQTRAIN_DATA), true);
+    }
+  }
+
+  @SuppressWarnings("deprecation")
+  private void neuralNetworkTraining() {
+    String strTrainingDataPath = "src/test/resources/neuralnets_classification_training.txt";
+    int featureDimension = 8;
+    int labelDimension = 1;
+
+    Path sequenceTrainingDataPath = new Path(SEQTRAIN_DATA);
+    try {
+      SequenceFile.Writer writer = new SequenceFile.Writer(fs, conf,
+          sequenceTrainingDataPath, LongWritable.class, VectorWritable.class);
+      BufferedReader br = new BufferedReader(
+          new FileReader(strTrainingDataPath));
+      String line = null;
+      // convert the data in sequence file format
+      while ((line = br.readLine()) != null) {
+        String[] tokens = line.split(",");
+        double[] vals = new double[tokens.length];
+        for (int i = 0; i < tokens.length; ++i) {
+          vals[i] = Double.parseDouble(tokens[i]);
+        }
+        writer.append(new LongWritable(), new VectorWritable(
+            new DenseDoubleVector(vals)));
+      }
+      writer.close();
+      br.close();
+    } catch (IOException e1) {
+      e1.printStackTrace();
+    }
+
+    try {
+      HornJob ann = MultiLayerPerceptron.createJob(conf, MODEL_PATH,
+          SEQTRAIN_DATA, 0.4, 0.2, 0.01, featureDimension, labelDimension,
+          1000, 2);
+
+      long startTime = System.currentTimeMillis();
+      if (ann.waitForCompletion(true)) {
+        LOG.info("Job Finished in " + (System.currentTimeMillis() - startTime)
+            / 1000.0 + " seconds");
+      }
+
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-horn/blob/ac8eaf8e/src/test/java/org/apache/horn/examples/NeuralNetworkTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/horn/examples/NeuralNetworkTest.java b/src/test/java/org/apache/horn/examples/NeuralNetworkTest.java
deleted file mode 100644
index 932b17a..0000000
--- a/src/test/java/org/apache/horn/examples/NeuralNetworkTest.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.horn.examples;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.hadoop.fs.FileSystem;
-import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.io.LongWritable;
-import org.apache.hadoop.io.SequenceFile;
-import org.apache.hama.Constants;
-import org.apache.hama.HamaCluster;
-import org.apache.hama.HamaConfiguration;
-import org.apache.hama.commons.io.VectorWritable;
-import org.apache.hama.commons.math.DenseDoubleVector;
-import org.apache.hama.commons.math.DoubleVector;
-import org.apache.horn.bsp.HornJob;
-import org.apache.horn.bsp.SmallLayeredNeuralNetwork;
-
-/**
- * Test the functionality of NeuralNetwork Example.
- * 
- */
-public class NeuralNetworkTest extends HamaCluster {
-  private HamaConfiguration conf;
-  private FileSystem fs;
-  private String MODEL_PATH = "/tmp/neuralnets.model";
-  private String RESULT_PATH = "/tmp/neuralnets.txt";
-  private String SEQTRAIN_DATA = "/tmp/test-neuralnets.data";
-
-  public NeuralNetworkTest() {
-    conf = new HamaConfiguration();
-    conf.set("bsp.master.address", "localhost");
-    conf.setBoolean("hama.child.redirect.log.console", true);
-    conf.setBoolean("hama.messenger.runtime.compression", true);
-    assertEquals("Make sure master addr is set to localhost:", "localhost",
-        conf.get("bsp.master.address"));
-    conf.set("bsp.local.dir", "/tmp/hama-test");
-    conf.set(Constants.ZOOKEEPER_QUORUM, "localhost");
-    conf.setInt(Constants.ZOOKEEPER_CLIENT_PORT, 21810);
-    conf.set("hama.sync.client.class",
-        org.apache.hama.bsp.sync.ZooKeeperSyncClientImpl.class
-            .getCanonicalName());
-  }
-
-  @Override
-  protected void setUp() throws Exception {
-    super.setUp();
-    fs = FileSystem.get(conf);
-  }
-
-  @Override
-  public void tearDown() throws Exception {
-    super.tearDown();
-  }
-
-  public void testNeuralnetsLabeling() throws IOException {
-    this.neuralNetworkTraining();
-
-    String featureDataPath = "src/test/resources/neuralnets_classification_test.txt";
-    try {
-      SmallLayeredNeuralNetwork ann = new SmallLayeredNeuralNetwork(conf,
-          MODEL_PATH);
-
-      // process data in streaming approach
-      FileSystem fs = FileSystem.get(new URI(featureDataPath), conf);
-      BufferedReader br = new BufferedReader(new InputStreamReader(
-          fs.open(new Path(featureDataPath))));
-      Path outputPath = new Path(RESULT_PATH);
-      if (fs.exists(outputPath)) {
-        fs.delete(outputPath, true);
-      }
-      BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
-          fs.create(outputPath)));
-
-      String line = null;
-
-      while ((line = br.readLine()) != null) {
-        if (line.trim().length() == 0) {
-          continue;
-        }
-        String[] tokens = line.trim().split(",");
-        double[] vals = new double[tokens.length];
-        for (int i = 0; i < tokens.length; ++i) {
-          vals[i] = Double.parseDouble(tokens[i]);
-        }
-        DoubleVector instance = new DenseDoubleVector(vals);
-        DoubleVector result = ann.getOutput(instance);
-        double[] arrResult = result.toArray();
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < arrResult.length; ++i) {
-          sb.append(arrResult[i]);
-          if (i != arrResult.length - 1) {
-            sb.append(",");
-          } else {
-            sb.append("\n");
-          }
-        }
-        bw.write(sb.toString());
-      }
-
-      br.close();
-      bw.close();
-
-      // compare results with ground-truth
-      BufferedReader groundTruthReader = new BufferedReader(new FileReader(
-          "src/test/resources/neuralnets_classification_label.txt"));
-      List<Double> groundTruthList = new ArrayList<Double>();
-      line = null;
-      while ((line = groundTruthReader.readLine()) != null) {
-        groundTruthList.add(Double.parseDouble(line));
-      }
-      groundTruthReader.close();
-
-      BufferedReader resultReader = new BufferedReader(new FileReader(
-          RESULT_PATH));
-      List<Double> resultList = new ArrayList<Double>();
-      while ((line = resultReader.readLine()) != null) {
-        resultList.add(Double.parseDouble(line));
-      }
-      resultReader.close();
-      int total = resultList.size();
-      double correct = 0;
-      for (int i = 0; i < groundTruthList.size(); ++i) {
-        double actual = resultList.get(i);
-        double expected = groundTruthList.get(i);
-        LOG.info("evaluated: " + actual + ", expected: " + expected);
-        if (actual < 0.5 && expected < 0.5 || actual >= 0.5 && expected >= 0.5) {
-          ++correct;
-        }
-      }
-
-      LOG.info("## Precision: " + (correct / total));
-      assertTrue((correct / total) > 0.5);
-
-    } catch (Exception e) {
-      e.printStackTrace();
-    } finally {
-      fs.delete(new Path(RESULT_PATH), true);
-      fs.delete(new Path(MODEL_PATH), true);
-      fs.delete(new Path(SEQTRAIN_DATA), true);
-    }
-  }
-
-  @SuppressWarnings("deprecation")
-  private void neuralNetworkTraining() {
-    String strTrainingDataPath = "src/test/resources/neuralnets_classification_training.txt";
-    int featureDimension = 8;
-    int labelDimension = 1;
-
-    Path sequenceTrainingDataPath = new Path(SEQTRAIN_DATA);
-    try {
-      SequenceFile.Writer writer = new SequenceFile.Writer(fs, conf,
-          sequenceTrainingDataPath, LongWritable.class, VectorWritable.class);
-      BufferedReader br = new BufferedReader(
-          new FileReader(strTrainingDataPath));
-      String line = null;
-      // convert the data in sequence file format
-      while ((line = br.readLine()) != null) {
-        String[] tokens = line.split(",");
-        double[] vals = new double[tokens.length];
-        for (int i = 0; i < tokens.length; ++i) {
-          vals[i] = Double.parseDouble(tokens[i]);
-        }
-        writer.append(new LongWritable(), new VectorWritable(
-            new DenseDoubleVector(vals)));
-      }
-      writer.close();
-      br.close();
-    } catch (IOException e1) {
-      e1.printStackTrace();
-    }
-
-    try {
-      HornJob ann = MultiLayerPerceptron.createJob(conf, MODEL_PATH,
-          SEQTRAIN_DATA, 0.4, 0.2, 0.01, featureDimension, labelDimension,
-          1000, 2);
-
-      long startTime = System.currentTimeMillis();
-      if (ann.waitForCompletion(true)) {
-        LOG.info("Job Finished in "
-            + (System.currentTimeMillis() - startTime) / 1000.0 + " seconds");
-      }
-      
-    } catch (Exception e) {
-      e.printStackTrace();
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-horn/blob/ac8eaf8e/src/test/java/org/apache/horn/trainer/TestNeuron.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/horn/trainer/TestNeuron.java b/src/test/java/org/apache/horn/trainer/TestNeuron.java
deleted file mode 100644
index b5f6bfc..0000000
--- a/src/test/java/org/apache/horn/trainer/TestNeuron.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.horn.trainer;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.apache.hadoop.io.DoubleWritable;
-import org.apache.hama.HamaConfiguration;
-import org.apache.horn.bsp.Neuron;
-import org.apache.horn.bsp.Synapse;
-import org.apache.horn.funcs.Sigmoid;
-
-public class TestNeuron extends TestCase {
-  private static double learningRate = 0.1;
-  private static double bias = -1;
-  private static double theta = 0.8;
-
-  public static class MyNeuron extends
-      Neuron<Synapse<DoubleWritable, DoubleWritable>> {
-
-    @Override
-    public void setup(HamaConfiguration conf) {
-    }
-
-    @Override
-    public void forward(
-        Iterable<Synapse<DoubleWritable, DoubleWritable>> messages)
-        throws IOException {
-      double sum = 0;
-      for (Synapse<DoubleWritable, DoubleWritable> m : messages) {
-        sum += m.getInput() * m.getWeight();
-      }
-      sum += (bias * theta);
-      this.feedforward(new Sigmoid().apply(sum));
-    }
-
-    @Override
-    public void backward(
-        Iterable<Synapse<DoubleWritable, DoubleWritable>> messages)
-        throws IOException {
-      for (Synapse<DoubleWritable, DoubleWritable> m : messages) {
-        // Calculates error gradient for each neuron
-        double gradient = new Sigmoid().applyDerivative(this.getOutput()) * (m.getDelta() * m.getWeight());
-
-        // Propagates to lower layer
-        backpropagate(gradient);
-
-        // Weight corrections
-        double weight = learningRate * this.getOutput() * m.getDelta();
-        this.push(weight);
-      }
-    }
-
-  }
-
-  public void testProp() throws IOException {
-    List<Synapse<DoubleWritable, DoubleWritable>> x = new ArrayList<Synapse<DoubleWritable, DoubleWritable>>();
-    x.add(new Synapse<DoubleWritable, DoubleWritable>(new DoubleWritable(
-        1.0), new DoubleWritable(0.5)));
-    x.add(new Synapse<DoubleWritable, DoubleWritable>(new DoubleWritable(
-        1.0), new DoubleWritable(0.4)));
-
-    MyNeuron n = new MyNeuron();
-    n.forward(x);
-    assertEquals(0.5249791874789399, n.getOutput());
-
-    x.clear();
-    x.add(new Synapse<DoubleWritable, DoubleWritable>(new DoubleWritable(
-        -0.1274), new DoubleWritable(-1.2)));
-    n.backward(x);
-    assertEquals(-0.006688234848481696, n.getUpdate());
-  }
-
-}


Mime
View raw message