diff --git a/src/test/java/com/syncleus/grail/neural/backprop/ActionTriggerXor3InputTest.java b/src/test/java/com/syncleus/grail/neural/backprop/ActionTriggerXor3InputTest.java
index 44fa804b1f3a87a5cf73ee58d234ce6c0fc3d67c..73120c1d3909b1d1c4a2dfb483f5d3dff6fa3c96 100644
--- a/src/test/java/com/syncleus/grail/neural/backprop/ActionTriggerXor3InputTest.java
+++ b/src/test/java/com/syncleus/grail/neural/backprop/ActionTriggerXor3InputTest.java
@@ -10,6 +10,8 @@ import java.lang.reflect.UndeclaredThrowableException;
 import java.util.*;
 
 public class ActionTriggerXor3InputTest {
+    private static final ActivationFunction ACTIVATION_FUNCTION = new SineActivationFunction();
+
     @Test
     public void testXor() {
         final FramedTransactionalGraph<?> graph = BlankGraphFactory.makeTinkerGraph();
@@ -27,6 +29,8 @@ public class ActionTriggerXor3InputTest {
         newHiddenNeurons.add(ActionTriggerXor3InputTest.createNeuron(graph, "hidden"));
         newHiddenNeurons.add(ActionTriggerXor3InputTest.createNeuron(graph, "hidden"));
         final BackpropNeuron newOutputNeuron = ActionTriggerXor3InputTest.createNeuron(graph, "output");
+        final BackpropNeuron biasNeuron = ActionTriggerXor3InputTest.createNeuron(graph, "bias");
+        biasNeuron.setSignal(1.0);
 
         //connect all input neurons to hidden neurons
         for( final BackpropNeuron inputNeuron : newInputNeurons ) {
@@ -39,13 +43,9 @@ public class ActionTriggerXor3InputTest {
             graph.addEdge(null, hiddenNeuron.asVertex(), newOutputNeuron.asVertex(), "signals", BackpropSynapse.class);
 
             //create bias neuron
-            final BackpropNeuron biasNeuron = ActionTriggerXor3InputTest.createNeuron(graph, "bias");
-            biasNeuron.setSignal(1.0);
             graph.addEdge(null, biasNeuron.asVertex(), hiddenNeuron.asVertex(), "signals", BackpropSynapse.class);
         }
         //create bias neuron for output neuron
-        final BackpropNeuron biasNeuron = ActionTriggerXor3InputTest.createNeuron(graph, "bias");
-        biasNeuron.setSignal(1.0);
         graph.addEdge(null, biasNeuron.asVertex(), newOutputNeuron.asVertex(), "signals", BackpropSynapse.class);
 
         //
@@ -82,6 +82,10 @@ public class ActionTriggerXor3InputTest {
             newEdge.setTriggerPriority(0);
             newEdge.setTriggerAction("backpropagate");
         }
+        //also connect it to all the bias neurons
+        final PrioritySerialTriggerEdge biasTriggerBackpropEdge = graph.addEdge(null, backpropInputTrigger.asVertex(), biasNeuron.asVertex(), "triggers", PrioritySerialTriggerEdge.class);
+        biasTriggerBackpropEdge.setTriggerPriority(0);
+        biasTriggerBackpropEdge.setTriggerAction("backpropagate");
 
         //create backpropagation trigger for the hidden layer
         final PrioritySerialTrigger backpropHiddenTrigger = ActionTriggerXor3InputTest.createPrioritySerialTrigger(graph);
@@ -93,7 +97,7 @@ public class ActionTriggerXor3InputTest {
             newEdge.setTriggerAction("backpropagate");
         }
 
-        //finally chain the hidden layers back propagation to the input layers trigger
+        //chain the hidden layers back propagation to the input layers trigger
         final PrioritySerialTriggerEdge chainTriggerBackpropEdge = graph.addEdge(null, backpropHiddenTrigger.asVertex(), backpropInputTrigger.asVertex(), "triggers", PrioritySerialTriggerEdge.class);
         chainTriggerBackpropEdge.setTriggerPriority(1000);
         chainTriggerBackpropEdge.setTriggerAction("actionTrigger");
@@ -105,7 +109,7 @@ public class ActionTriggerXor3InputTest {
         // Graph is constructed, just need to train and test our network now.
         //
 
-        for(int i = 0; i < 1000; i++) {
+        for(int i = 0; i < 10000; i++) {
             ActionTriggerXor3InputTest.train(graph, 1.0, 1.0, 1.0, -1.0);
             ActionTriggerXor3InputTest.train(graph, -1.0, 1.0, 1.0, -1.0);
             ActionTriggerXor3InputTest.train(graph, 1.0, -1.0, 1.0, -1.0);
@@ -114,6 +118,8 @@ public class ActionTriggerXor3InputTest {
             ActionTriggerXor3InputTest.train(graph, -1.0, 1.0, -1.0, 1.0);
             ActionTriggerXor3InputTest.train(graph, 1.0, -1.0, -1.0, 1.0);
             ActionTriggerXor3InputTest.train(graph, -1.0, -1.0, -1.0, -1.0);
+            if( i%50 == 0 && ActionTriggerXor3InputTest.calculateError(graph) < 0.1 )
+                break;
         }
         Assert.assertTrue(ActionTriggerXor3InputTest.propagate(graph, 1.0, 1.0, 1.0) < 0.0);
         Assert.assertTrue(ActionTriggerXor3InputTest.propagate(graph, -1.0, 1.0, 1.0) < 0.0);
@@ -125,7 +131,33 @@ public class ActionTriggerXor3InputTest {
         Assert.assertTrue(ActionTriggerXor3InputTest.propagate(graph, -1.0, -1.0, -1.0) < 0.0);
     }
 
-    private static final ActivationFunction activationFunction = new SineActivationFunction();
+    private static double calculateError(FramedTransactionalGraph<?> graph) {
+        double actual = ActionTriggerXor3InputTest.propagate(graph, 1.0, 1.0, 1.0);
+        double error = Math.abs(actual + 1.0) / Math.abs(actual);
+
+        actual = ActionTriggerXor3InputTest.propagate(graph, -1.0, 1.0, 1.0);
+        error += Math.abs(actual + 1.0) / 2.0;
+
+        actual = ActionTriggerXor3InputTest.propagate(graph, 1.0, -1.0, 1.0);
+        error += Math.abs(actual + 1.0) / 2.0;
+
+        actual = ActionTriggerXor3InputTest.propagate(graph, 1.0, 1.0, -1.0);
+        error += Math.abs(actual + 1.0) / 2.0;
+
+        actual = ActionTriggerXor3InputTest.propagate(graph, 1.0, -1.0, -1.0);
+        error += Math.abs(actual - 1.0) / 2.0;
+
+        actual = ActionTriggerXor3InputTest.propagate(graph, -1.0, 1.0, -1.0);
+        error += Math.abs(actual - 1.0) / 2.0;
+
+        actual = ActionTriggerXor3InputTest.propagate(graph, -1.0, -1.0, 1.0);
+        error += Math.abs(actual - 1.0) / 2.0;
+
+        actual = ActionTriggerXor3InputTest.propagate(graph, -1.0, -1.0, -1.0);
+        error += Math.abs(actual + 1.0) / 2.0;
+
+        return error / 8.0;
+    }
 
     private static void train(final FramedTransactionalGraph<?> graph, final double input1, final double input2, final double input3, final double expected) {
         ActionTriggerXor3InputTest.propagate(graph, input1, input2, input3);
@@ -133,7 +165,7 @@ public class ActionTriggerXor3InputTest {
         final Iterator<BackpropNeuron> outputNeurons = graph.getVertices("layer", "output", BackpropNeuron.class).iterator();
         final BackpropNeuron outputNeuron = outputNeurons.next();
         Assert.assertTrue(!outputNeurons.hasNext());
-        outputNeuron.setDeltaTrain((expected - outputNeuron.getSignal()) * activationFunction.activateDerivative(outputNeuron.getActivity()) );
+        outputNeuron.setDeltaTrain((expected - outputNeuron.getSignal()) * ACTIVATION_FUNCTION.activateDerivative(outputNeuron.getActivity()));
         graph.commit();
 
         final Iterator<PrioritySerialTrigger> backpropTriggers = graph.getVertices("triggerPointer", "backpropagate", PrioritySerialTrigger.class).iterator();
diff --git a/src/test/java/com/syncleus/grail/neural/backprop/SimpleOrTest.java b/src/test/java/com/syncleus/grail/neural/backprop/SimpleOrTest.java
index b0144243b1b93c1d372edea4fc0a34ee96d65135..79cc09a4c205017375321ef2782f6c2c2595ceea 100644
--- a/src/test/java/com/syncleus/grail/neural/backprop/SimpleOrTest.java
+++ b/src/test/java/com/syncleus/grail/neural/backprop/SimpleOrTest.java
@@ -7,7 +7,10 @@ import org.junit.*;
 import java.util.*;
 
 public class SimpleOrTest {
-   @Test
+
+    private static final ActivationFunction ACTIVATION_FUNCTION = new SineActivationFunction();
+
+    @Test
     public void testOr() {
         final FramedTransactionalGraph<?> graph = BlankGraphFactory.makeTinkerGraph();
 
@@ -26,11 +29,13 @@ public class SimpleOrTest {
         graph.addEdge(null, biasNeuron.asVertex(), newOutputNeuron.asVertex(), "signals", BackpropSynapse.class);//.asEdge().setProperty("type", "BackpropSynapse");
         graph.commit();
 
-        for(int i = 0; i < 1000; i++) {
+        for(int i = 0; i < 10000; i++) {
             SimpleOrTest.train(graph, -1.0, 1.0, 1.0);
             SimpleOrTest.train(graph, 1.0, -1.0, 1.0);
             SimpleOrTest.train(graph, 1.0, 1.0, 1.0);
             SimpleOrTest.train(graph, -1.0, -1.0, -1.0);
+            if( i%50 == 0 && SimpleOrTest.calculateError(graph) < 0.2 )
+                break;
         }
 
         Assert.assertTrue("expected >0.0, got: " + SimpleOrTest.propagate(graph, 1.0, 1.0), SimpleOrTest.propagate(graph, 1.0, 1.0) > 0.0);
@@ -39,7 +44,21 @@ public class SimpleOrTest {
         Assert.assertTrue("expected >0.0, got: " + SimpleOrTest.propagate(graph, -1.0, 1.0), SimpleOrTest.propagate(graph, -1.0, 1.0) > 0.0);
     }
 
-    private static final ActivationFunction activationFunction = new SineActivationFunction();
+    private static double calculateError(FramedTransactionalGraph<?> graph) {
+        double actual = SimpleOrTest.propagate(graph, 1.0, 1.0);
+        double error = Math.abs(actual - 1.0) / 2.0;
+
+        actual = SimpleOrTest.propagate(graph, -1.0, -1.0);
+        error += Math.abs(actual + 1.0) / 2.0;
+
+        actual = SimpleOrTest.propagate(graph, 1.0, -1.0);
+        error += Math.abs(actual - 1.0) / 2.0;
+
+        actual = SimpleOrTest.propagate(graph, -1.0, 1.0);
+        error += Math.abs(actual - 1.0) / 2.0;
+
+        return error/4.0;
+    }
 
     private static void train(final FramedTransactionalGraph<?> graph, final double input1, final double input2, final double expected) {
         SimpleOrTest.propagate(graph, input1, input2);
@@ -47,7 +66,7 @@ public class SimpleOrTest {
         final Iterator<BackpropNeuron> outputNeurons = graph.getVertices("layer", "output", BackpropNeuron.class).iterator();
         final BackpropNeuron outputNeuron = outputNeurons.next();
         Assert.assertTrue(!outputNeurons.hasNext());
-        outputNeuron.setDeltaTrain((expected - outputNeuron.getSignal()) * activationFunction.activateDerivative(outputNeuron.getActivity()) );
+        outputNeuron.setDeltaTrain((expected - outputNeuron.getSignal()) * ACTIVATION_FUNCTION.activateDerivative(outputNeuron.getActivity()));
         graph.commit();
 
         final Iterator<BackpropNeuron> inputNeurons = graph.getVertices("layer", "input", BackpropNeuron.class).iterator();
diff --git a/src/test/java/com/syncleus/grail/neural/backprop/SimpleXor2InputTest.java b/src/test/java/com/syncleus/grail/neural/backprop/SimpleXor2InputTest.java
index d4a7f1af5c7a7a4ce45d4574a5813c3a8fdd7db1..08bd7d3f8618a1c12f3d6a47bc7c37c556eef7c2 100644
--- a/src/test/java/com/syncleus/grail/neural/backprop/SimpleXor2InputTest.java
+++ b/src/test/java/com/syncleus/grail/neural/backprop/SimpleXor2InputTest.java
@@ -7,6 +7,8 @@ import org.junit.*;
 import java.util.*;
 
 public class SimpleXor2InputTest {
+    private static final ActivationFunction ACTIVATION_FUNCTION = new HyperbolicTangentActivationFunction();
+
     @Test
     public void testXor() {
         final FramedTransactionalGraph<?> graph = BlankGraphFactory.makeTinkerGraph();
@@ -22,6 +24,10 @@ public class SimpleXor2InputTest {
         final BackpropNeuron newOutputNeuron = SimpleXor2InputTest.createNeuron(graph, "output");
         newOutputNeuron.setActivationFunctionClass(HyperbolicTangentActivationFunction.class);
         newOutputNeuron.setLearningRate(0.09);
+        final BackpropNeuron biasNeuron = SimpleXor2InputTest.createNeuron(graph, "bias");
+        biasNeuron.setSignal(1.0);
+        biasNeuron.setActivationFunctionClass(HyperbolicTangentActivationFunction.class);
+        biasNeuron.setLearningRate(0.09);
 
         //connect all input neurons to hidden neurons
         for( BackpropNeuron inputNeuron : newInputNeurons ) {
@@ -41,25 +47,19 @@ public class SimpleXor2InputTest {
             hiddenNeuron.setLearningRate(0.09);
 
             //create bias neuron
-            final BackpropNeuron biasNeuron = SimpleXor2InputTest.createNeuron(graph, "bias");
-            biasNeuron.setSignal(1.0);
-            biasNeuron.setActivationFunctionClass(HyperbolicTangentActivationFunction.class);
-            biasNeuron.setLearningRate(0.09);
             graph.addEdge(null, biasNeuron.asVertex(), hiddenNeuron.asVertex(), "signals", BackpropSynapse.class);
         }
         //create bias neuron for output neuron
-        final BackpropNeuron biasNeuron = SimpleXor2InputTest.createNeuron(graph, "bias");
-        biasNeuron.setSignal(1.0);
-        biasNeuron.setLearningRate(0.09);
-        biasNeuron.setActivationFunctionClass(HyperbolicTangentActivationFunction.class);
         graph.addEdge(null, biasNeuron.asVertex(), newOutputNeuron.asVertex(), "signals", BackpropSynapse.class);
         graph.commit();
 
-        for(int i = 0; i < 1000; i++) {
+        for(int i = 0; i < 10000; i++) {
             SimpleXor2InputTest.train(graph, -1.0, 1.0, 1.0);
             SimpleXor2InputTest.train(graph, 1.0, -1.0, 1.0);
             SimpleXor2InputTest.train(graph, 1.0, 1.0, -1.0);
             SimpleXor2InputTest.train(graph, -1.0, -1.0, -1.0);
+            if( i%50 == 0 && SimpleXor2InputTest.calculateError(graph) < 0.1 )
+                break;
         }
         Assert.assertTrue(SimpleXor2InputTest.propagate(graph, 1.0, 1.0) < 0.0);
         Assert.assertTrue(SimpleXor2InputTest.propagate(graph, -1.0, -1.0) < 0.0);
@@ -67,7 +67,21 @@ public class SimpleXor2InputTest {
         Assert.assertTrue(SimpleXor2InputTest.propagate(graph, -1.0, 1.0) > 0.0);
     }
 
-    private static final ActivationFunction activationFunction = new SineActivationFunction();
+    private static double calculateError(FramedTransactionalGraph<?> graph) {
+        double actual = SimpleXor2InputTest.propagate(graph, 1.0, 1.0);
+        double error = Math.abs(actual + 1.0) / 2.0;
+
+        actual = SimpleXor2InputTest.propagate(graph, -1.0, -1.0);
+        error += Math.abs(actual + 1.0) / 2.0;
+
+        actual = SimpleXor2InputTest.propagate(graph, 1.0, -1.0);
+        error += Math.abs(actual - 1.0) / 2.0;
+
+        actual = SimpleXor2InputTest.propagate(graph, -1.0, 1.0);
+        error += Math.abs(actual - 1.0) / 2.0;
+
+        return error/4.0;
+    }
 
     private static void train(final FramedTransactionalGraph<?> graph, final double input1, final double input2, final double expected) {
         SimpleXor2InputTest.propagate(graph, input1, input2);
@@ -75,7 +89,7 @@ public class SimpleXor2InputTest {
         final Iterator<BackpropNeuron> outputNeurons = graph.getVertices("layer", "output", BackpropNeuron.class).iterator();
         final BackpropNeuron outputNeuron = outputNeurons.next();
         Assert.assertTrue(!outputNeurons.hasNext());
-        outputNeuron.setDeltaTrain((expected - outputNeuron.getSignal()) * activationFunction.activateDerivative(outputNeuron.getActivity()) );
+        outputNeuron.setDeltaTrain((expected - outputNeuron.getSignal()) * ACTIVATION_FUNCTION.activateDerivative(outputNeuron.getActivity()));
         graph.commit();
 
         final Iterator<BackpropNeuron> hiddenNeurons = graph.getVertices("layer", "hidden", BackpropNeuron.class).iterator();
@@ -94,10 +108,6 @@ public class SimpleXor2InputTest {
 
         final Iterator<BackpropNeuron> biasNeurons = graph.getVertices("layer", "bias", BackpropNeuron.class).iterator();
         biasNeurons.next().backpropagate();
-        biasNeurons.next().backpropagate();
-        biasNeurons.next().backpropagate();
-        biasNeurons.next().backpropagate();
-        biasNeurons.next().backpropagate();
         Assert.assertTrue(!biasNeurons.hasNext());
         graph.commit();
     }
diff --git a/src/test/java/com/syncleus/grail/neural/backprop/SimpleXor3InputTest.java b/src/test/java/com/syncleus/grail/neural/backprop/SimpleXor3InputTest.java
index df052b0b7285ef3c409a4e633d3559b2f2248b57..9e48852dc9bbb252703a1c76c3cf1d1e87af3ca5 100644
--- a/src/test/java/com/syncleus/grail/neural/backprop/SimpleXor3InputTest.java
+++ b/src/test/java/com/syncleus/grail/neural/backprop/SimpleXor3InputTest.java
@@ -8,6 +8,8 @@ import org.junit.*;
 import java.util.*;
 
 public class SimpleXor3InputTest {
+    private static final ActivationFunction activationFunction = new SineActivationFunction();
+
     @Test
     public void testXor() {
         final FramedTransactionalGraph<?> graph = BlankGraphFactory.makeTinkerGraph();
@@ -21,6 +23,8 @@ public class SimpleXor3InputTest {
         newHiddenNeurons.add(SimpleXor3InputTest.createNeuron(graph, "hidden"));
         newHiddenNeurons.add(SimpleXor3InputTest.createNeuron(graph, "hidden"));
         final BackpropNeuron newOutputNeuron = SimpleXor3InputTest.createNeuron(graph, "output");
+        final BackpropNeuron biasNeuron = SimpleXor3InputTest.createNeuron(graph, "bias");
+        biasNeuron.setSignal(1.0);
 
         //connect all input neurons to hidden neurons
         for( BackpropNeuron inputNeuron : newInputNeurons ) {
@@ -32,18 +36,14 @@ public class SimpleXor3InputTest {
         for( BackpropNeuron hiddenNeuron : newHiddenNeurons ) {
             graph.addEdge(null, hiddenNeuron.asVertex(), newOutputNeuron.asVertex(), "signals", BackpropSynapse.class);
 
-            //create bias neuron
-            final BackpropNeuron biasNeuron = SimpleXor3InputTest.createNeuron(graph, "bias");
-            biasNeuron.setSignal(1.0);
+            //create bias connection
             graph.addEdge(null, biasNeuron.asVertex(), hiddenNeuron.asVertex(), "signals", BackpropSynapse.class);
         }
         //create bias neuron for output neuron
-        final BackpropNeuron biasNeuron = SimpleXor3InputTest.createNeuron(graph, "bias");
-        biasNeuron.setSignal(1.0);
         graph.addEdge(null, biasNeuron.asVertex(), newOutputNeuron.asVertex(), "signals", BackpropSynapse.class);
         graph.commit();
 
-        for(int i = 0; i < 1000; i++) {
+        for(int i = 0; i < 10000 ; i++) {
             SimpleXor3InputTest.train(graph, 1.0, 1.0, 1.0, -1.0);
             SimpleXor3InputTest.train(graph, -1.0, 1.0, 1.0, -1.0);
             SimpleXor3InputTest.train(graph, 1.0, -1.0, 1.0, -1.0);
@@ -52,6 +52,8 @@ public class SimpleXor3InputTest {
             SimpleXor3InputTest.train(graph, -1.0, 1.0, -1.0, 1.0);
             SimpleXor3InputTest.train(graph, 1.0, -1.0, -1.0, 1.0);
             SimpleXor3InputTest.train(graph, -1.0, -1.0, -1.0, -1.0);
+            if( i%50 == 0 && SimpleXor3InputTest.calculateError(graph) < 0.1 )
+                break;
         }
         Assert.assertTrue(SimpleXor3InputTest.propagate(graph, 1.0, 1.0, 1.0) < 0.0);
         Assert.assertTrue(SimpleXor3InputTest.propagate(graph, -1.0, 1.0, 1.0) < 0.0);
@@ -63,7 +65,33 @@ public class SimpleXor3InputTest {
         Assert.assertTrue(SimpleXor3InputTest.propagate(graph, -1.0, -1.0, -1.0) < 0.0);
     }
 
-    private static final ActivationFunction activationFunction = new SineActivationFunction();
+    private static double calculateError(FramedTransactionalGraph<?> graph) {
+        double actual = SimpleXor3InputTest.propagate(graph, 1.0, 1.0, 1.0);
+        double error = Math.abs(actual + 1.0) / Math.abs(actual);
+
+        actual = SimpleXor3InputTest.propagate(graph, -1.0, 1.0, 1.0);
+        error += Math.abs(actual + 1.0) / 2.0;
+
+        actual = SimpleXor3InputTest.propagate(graph, 1.0, -1.0, 1.0);
+        error += Math.abs(actual + 1.0) / 2.0;
+
+        actual = SimpleXor3InputTest.propagate(graph, 1.0, 1.0, -1.0);
+        error += Math.abs(actual + 1.0) / 2.0;
+
+        actual = SimpleXor3InputTest.propagate(graph, 1.0, -1.0, -1.0);
+        error += Math.abs(actual - 1.0) / 2.0;
+
+        actual = SimpleXor3InputTest.propagate(graph, -1.0, 1.0, -1.0);
+        error += Math.abs(actual - 1.0) / 2.0;
+
+        actual = SimpleXor3InputTest.propagate(graph, -1.0, -1.0, 1.0);
+        error += Math.abs(actual - 1.0) / 2.0;
+
+        actual = SimpleXor3InputTest.propagate(graph, -1.0, -1.0, -1.0);
+        error += Math.abs(actual + 1.0) / 2.0;
+
+        return error/8.0;
+    }
 
     private static void train(final FramedTransactionalGraph<?> graph, final double input1, final double input2, final double input3, final double expected) {
         SimpleXor3InputTest.propagate(graph, input1, input2, input3);
@@ -90,9 +118,6 @@ public class SimpleXor3InputTest {
 
         final Iterator<BackpropNeuron> biasNeurons = graph.getVertices("layer", "bias", BackpropNeuron.class).iterator();
         biasNeurons.next().backpropagate();
-        biasNeurons.next().backpropagate();
-        biasNeurons.next().backpropagate();
-        biasNeurons.next().backpropagate();
         Assert.assertTrue(!biasNeurons.hasNext());
         graph.commit();
     }