Return-Path: X-Original-To: apmail-horn-dev-archive@minotaur.apache.org Delivered-To: apmail-horn-dev-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id E4B2119167 for ; Tue, 26 Apr 2016 03:46:32 +0000 (UTC) Received: (qmail 63127 invoked by uid 500); 26 Apr 2016 03:46:32 -0000 Delivered-To: apmail-horn-dev-archive@horn.apache.org Received: (qmail 63082 invoked by uid 500); 26 Apr 2016 03:46:32 -0000 Mailing-List: contact dev-help@horn.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@horn.incubator.apache.org Delivered-To: mailing list dev@horn.incubator.apache.org Received: (qmail 63061 invoked by uid 99); 26 Apr 2016 03:46:32 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd4-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 26 Apr 2016 03:46:32 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd4-us-west.apache.org (ASF Mail Server at spamd4-us-west.apache.org) with ESMTP id C13E8C0D7F for ; Tue, 26 Apr 2016 03:46:31 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd4-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -3.221 X-Spam-Level: X-Spam-Status: No, score=-3.221 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-0.001] autolearn=disabled Received: from mx1-lw-us.apache.org ([10.40.0.8]) by localhost (spamd4-us-west.apache.org [10.40.0.11]) (amavisd-new, port 10024) with ESMTP id jRTph278oN3K for ; Tue, 26 Apr 2016 03:46:24 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx1-lw-us.apache.org (ASF Mail Server at mx1-lw-us.apache.org) with SMTP id 73EDF5FB0A for ; Tue, 26 Apr 2016 03:46:23 +0000 (UTC) Received: (qmail 62966 invoked by uid 99); 26 Apr 2016 03:46:22 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 26 Apr 2016 03:46:22 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id B552ADFC55; Tue, 26 Apr 2016 03:46:22 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: edwardyoon@apache.org To: dev@horn.incubator.apache.org Date: Tue, 26 Apr 2016 03:46:22 -0000 Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: [1/4] incubator-horn git commit: Code refactoring 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 instanceList = new ArrayList(); + + 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 testInstances = new ArrayList(); + testInstances.addAll(instanceList.subList(instanceList.size() - 100, + instanceList.size())); + List 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 instanceList = new ArrayList(); + List trainingInstances = null; + List 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(); + 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 trainingParameters = new HashMap(); + 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 instanceList = new ArrayList(); + List trainingInstances = null; + List 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(); + 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 trainingParameters = new HashMap(); + 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 groundTruthList = new ArrayList(); - line = null; - while ((line = groundTruthReader.readLine()) != null) { - groundTruthList.add(Double.parseDouble(line)); - } - groundTruthReader.close(); - - BufferedReader resultReader = new BufferedReader(new FileReader( - RESULT_PATH)); - List resultList = new ArrayList(); - 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> { - - @Override - public void setup(HamaConfiguration conf) { - } - - @Override - public void forward( - Iterable> messages) - throws IOException { - double sum = 0; - for (Synapse m : messages) { - sum += m.getInput() * m.getWeight(); - } - sum += (bias * theta); - this.feedforward(new Sigmoid().apply(sum)); - } - - @Override - public void backward( - Iterable> messages) - throws IOException { - for (Synapse 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> x = new ArrayList>(); - x.add(new Synapse(new DoubleWritable( - 1.0), new DoubleWritable(0.5))); - x.add(new Synapse(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(new DoubleWritable( - -0.1274), new DoubleWritable(-1.2))); - n.backward(x); - assertEquals(-0.006688234848481696, n.getUpdate()); - } - -}