func TestNeuronAddOutlinkRecurrent(t *testing.T) { ng.SeedRandom() madeNonRecurrentLink := false madeRecurrentLink := false for i := 0; i < 100; i++ { xnorCortex := BasicCortex() neuron := xnorCortex.NeuronUUIDMap()["hidden-neuron1"] numOutlinksBefore := len(neuron.Outbound) ok, mutateResult := NeuronAddOutlinkRecurrent(neuron) if !ok { continue } outboundConnection := mutateResult.(*ng.OutboundConnection) numOutlinksAfter := len(neuron.Outbound) assert.Equals(t, numOutlinksBefore+1, numOutlinksAfter) if neuron.IsConnectionRecurrent(outboundConnection) { // the first time we make a nonRecurrentInlink, // test the network out if madeRecurrentLink == false { // make sure the network actually works examples := ng.XnorTrainingSamples() fitness := xnorCortex.Fitness(examples) assert.True(t, fitness >= 0) } madeRecurrentLink = true } else { // the first time we make a nonRecurrentInlink, // test the network out if madeNonRecurrentLink == false { // make sure the network doesn't totally break examples := ng.XnorTrainingSamples() fitness := xnorCortex.Fitness(examples) assert.True(t, fitness >= 0) } madeNonRecurrentLink = true } } assert.True(t, madeNonRecurrentLink) assert.True(t, madeRecurrentLink) }
func RunPopulationTrainer(pt *nv.PopulationTrainer) bool { population := getInitialPopulation() scape := getScape() fitPopulation, succeeded := pt.Train(population, scape, nv.NewNullRecorder()) if succeeded { logg.LogTo("MAIN", "Successfully trained!") fittestCortex := fitPopulation[0] logg.LogTo("MAIN", "Fitness: %v", fittestCortex.Fitness) filename := fmt.Sprintf("/tmp/checkerlution-%v.json", time.Now().Unix()) logg.LogTo("MAIN", "Saving Cortex to %v", filename) cortex := fittestCortex.Cortex cortex.MarshalJSONToFile(filename) // verify it can now solve the training set verified := cortex.Verify(ng.XnorTrainingSamples()) if !verified { logg.LogTo("MAIN", "Failed to verify neural net") succeeded = false } } if !succeeded { logg.LogTo("MAIN", "Failed to train neural net") } return succeeded }
func TestNeuronAddInlinkRecurrent(t *testing.T) { madeNonRecurrentInlink := false madeRecurrentInlink := false for i := 0; i < 100; i++ { xnorCortex := ng.XnorCortex() neuron := xnorCortex.NeuronUUIDMap()["output-neuron"] ok, mutateResult := NeuronAddInlinkRecurrent(neuron) if !ok { continue } inboundConnection := mutateResult.(*ng.InboundConnection) if neuron.IsInboundConnectionRecurrent(inboundConnection) { // the first time we make a nonRecurrentInlink, // test the network out if madeRecurrentInlink == false { // make sure the network actually works examples := ng.XnorTrainingSamples() fitness := xnorCortex.Fitness(examples) assert.True(t, fitness >= 0) } madeRecurrentInlink = true } else { // the first time we make a nonRecurrentInlink, // test the network out if madeNonRecurrentInlink == false { // make sure the network doesn't totally break examples := ng.XnorTrainingSamples() fitness := xnorCortex.Fitness(examples) assert.True(t, fitness >= 0) } madeNonRecurrentInlink = true } } assert.True(t, madeNonRecurrentInlink) assert.True(t, madeRecurrentInlink) }
func TestOutspliceNonRecurrent(t *testing.T) { ng.SeedRandom() numOutspliced := 0 numIterations := 100 for i := 0; i < numIterations; i++ { cortex := BasicCortex() numNeuronsBefore := len(cortex.Neurons) neuronLayerMapBefore := cortex.NeuronLayerMap() ok, mutateResult := OutspliceNonRecurrent(cortex) neuron := mutateResult.(*ng.Neuron) if !ok { continue } else { numOutspliced += 1 } assert.True(t, neuron.ActivationFunction != nil) numNeuronsAfter := len(cortex.Neurons) assert.Equals(t, numNeuronsAfter, numNeuronsBefore+1) // should have 1 outbound and inbound assert.Equals(t, len(neuron.Inbound), 1) assert.Equals(t, len(neuron.Outbound), 1) // should be no recurrent connections assert.Equals(t, len(neuron.RecurrentInboundConnections()), 0) assert.Equals(t, len(neuron.RecurrentOutboundConnections()), 0) // should have one more layer (this makes an assumption // about the BasicCortex architecture) numLayersBefore := len(neuronLayerMapBefore) numLayersAfter := len(cortex.NeuronLayerMap()) assert.Equals(t, numLayersAfter, numLayersBefore+1) // run network make sure it runs examples := ng.XnorTrainingSamples() fitness := cortex.Fitness(examples) assert.True(t, fitness >= 0) } assert.True(t, numOutspliced > 0) }
func RunTopologyMutatingTrainer() bool { ng.SeedRandom() // training set examples := ng.XnorTrainingSamples() // create netwwork with topology capable of solving XNOR cortex := ng.BasicCortex() // verify it can not yet solve the training set (since training would be useless in that case) verified := cortex.Verify(examples) if verified { panic("neural net already trained, nothing to do") } shc := &nv.StochasticHillClimber{ FitnessThreshold: ng.FITNESS_THRESHOLD, MaxIterationsBeforeRestart: 20000, MaxAttempts: 10, WeightSaturationRange: []float64{-10000, 10000}, } tmt := &nv.TopologyMutatingTrainer{ MaxAttempts: 100, MaxIterationsBeforeRestart: 5, StochasticHillClimber: shc, } cortexTrained, succeeded := tmt.TrainExamples(cortex, examples) if succeeded { logg.LogTo("MAIN", "Successfully trained net: %v", ng.JsonString(cortexTrained)) // verify it can now solve the training set verified = cortexTrained.Verify(examples) if !verified { logg.LogTo("MAIN", "Failed to verify neural net") succeeded = false } } if !succeeded { logg.LogTo("MAIN", "Failed to train neural net") } return succeeded }
func TestAddNeuronNonRecurrent(t *testing.T) { ng.SeedRandom() numUnableToAdd := 0 numIterations := 100 for i := 0; i < numIterations; i++ { cortex := BasicCortex() numNeuronsBefore := len(cortex.Neurons) ok, mutateResult := AddNeuronNonRecurrent(cortex) if !ok { numUnableToAdd += 1 continue } neuron := mutateResult.(*ng.Neuron) assert.True(t, neuron.ActivationFunction != nil) numNeuronsAfter := len(cortex.Neurons) addedNeuron := numNeuronsAfter == numNeuronsBefore+1 assert.True(t, addedNeuron) if !addedNeuron { break } // should have 1 outbound and inbound assert.Equals(t, len(neuron.Inbound), 1) assert.Equals(t, len(neuron.Outbound), 1) // should be no recurrent connections assert.Equals(t, len(neuron.RecurrentInboundConnections()), 0) assert.Equals(t, len(neuron.RecurrentOutboundConnections()), 0) // run network make sure it runs examples := ng.XnorTrainingSamples() fitness := cortex.Fitness(examples) assert.True(t, fitness >= 0) } assert.True(t, numUnableToAdd <= (numIterations/3)) }
func DisabledTestUnmarshalCortexFitness(t *testing.T) { ng.SeedRandom() logg.LogKeys["DEBUG"] = true logg.LogKeys["NEURGO"] = true // this test is disabled by default since it can take a long time // this was a real net that was evolved by the topological mutator // before it went through the memetic step. // jsonString := `{"NodeId":{"UUID":"cortex","NodeType":"CORTEX","LayerIndex":0},"Sensors":[{"NodeId":{"UUID":"sensor","NodeType":"SENSOR","LayerIndex":0},"VectorLength":2,"Outbound":[{"NodeId":{"UUID":"neuron","NodeType":"NEURON","LayerIndex":0.25}},{"NodeId":{"UUID":"todo=394057419","NodeType":"NEURON","LayerIndex":0.25}}]}],"Neurons":[{"NodeId":{"UUID":"neuron","NodeType":"NEURON","LayerIndex":0.25},"Bias":0,"Inbound":[{"NodeId":{"UUID":"sensor","NodeType":"SENSOR","LayerIndex":0},"Weights":[20,20]}],"Outbound":[{"NodeId":{"UUID":"todo=3342881449","NodeType":"NEURON","LayerIndex":0.375}}],"ActivationFunction":{"Name":"sigmoid"}},{"NodeId":{"UUID":"todo=3342881449","NodeType":"NEURON","LayerIndex":0.375},"Bias":-0.36421027459743627,"Inbound":[{"NodeId":{"UUID":"neuron","NodeType":"NEURON","LayerIndex":0.25},"Weights":[1.8610633947514623]},{"NodeId":{"UUID":"todo=394057419","NodeType":"NEURON","LayerIndex":0.25},"Weights":[0.45355591271633067]}],"Outbound":[{"NodeId":{"UUID":"actuator","NodeType":"ACTUATOR","LayerIndex":0.5}}],"ActivationFunction":{"Name":"sigmoid"}},{"NodeId":{"UUID":"todo=394057419","NodeType":"NEURON","LayerIndex":0.25},"Bias":0.4665982575854781,"Inbound":[{"NodeId":{"UUID":"sensor","NodeType":"SENSOR","LayerIndex":0},"Weights":[0.6618610678776169,3.065256532332561]}],"Outbound":[{"NodeId":{"UUID":"todo=3342881449","NodeType":"NEURON","LayerIndex":0.375}}],"ActivationFunction":{"Name":"tanh"}}],"Actuators":[{"NodeId":{"UUID":"actuator","NodeType":"ACTUATOR","LayerIndex":0.5},"VectorLength":1,"Inbound":[{"NodeId":{"UUID":"todo=3342881449","NodeType":"NEURON","LayerIndex":0.375},"Weights":null}]}]}` jsonString2 := `{"NodeId":{"UUID":"cortex","NodeType":"CORTEX","LayerIndex":0},"Sensors":[{"NodeId":{"UUID":"sensor","NodeType":"SENSOR","LayerIndex":0},"VectorLength":2,"Outbound":[{"NodeId":{"UUID":"neuron","NodeType":"NEURON","LayerIndex":0.25}},{"NodeId":{"UUID":"todo=8550407276","NodeType":"NEURON","LayerIndex":0.25}}]}],"Neurons":[{"NodeId":{"UUID":"neuron","NodeType":"NEURON","LayerIndex":0.25},"Bias":0,"Inbound":[{"NodeId":{"UUID":"sensor","NodeType":"SENSOR","LayerIndex":0},"Weights":[20,20]}],"Outbound":[{"NodeId":{"UUID":"todo=6014372025","NodeType":"NEURON","LayerIndex":0.375}}],"ActivationFunction":{"Name":"sigmoid"}},{"NodeId":{"UUID":"todo=6014372025","NodeType":"NEURON","LayerIndex":0.375},"Bias":1.216286900747618,"Inbound":[{"NodeId":{"UUID":"neuron","NodeType":"NEURON","LayerIndex":0.25},"Weights":[1.767095335462158]},{"NodeId":{"UUID":"todo=8550407276","NodeType":"NEURON","LayerIndex":0.25},"Weights":[1.0905530851150242]}],"Outbound":[{"NodeId":{"UUID":"actuator","NodeType":"ACTUATOR","LayerIndex":0.5}}],"ActivationFunction":{"Name":"sigmoid"}},{"NodeId":{"UUID":"todo=8550407276","NodeType":"NEURON","LayerIndex":0.25},"Bias":-0.23064534306604623,"Inbound":[{"NodeId":{"UUID":"sensor","NodeType":"SENSOR","LayerIndex":0},"Weights":[-2.069786342256813,-2.0791073119872916]}],"Outbound":[{"NodeId":{"UUID":"todo=6014372025","NodeType":"NEURON","LayerIndex":0.375}}],"ActivationFunction":{"Name":"sigmoid"}}],"Actuators":[{"NodeId":{"UUID":"actuator","NodeType":"ACTUATOR","LayerIndex":0.5},"VectorLength":1,"Inbound":[{"NodeId":{"UUID":"todo=6014372025","NodeType":"NEURON","LayerIndex":0.375},"Weights":null}]}]}` jsonBytes := []byte(jsonString2) cortex := &ng.Cortex{} err := json.Unmarshal(jsonBytes, cortex) if err != nil { log.Fatal(err) } assert.True(t, err == nil) shc := &StochasticHillClimber{ FitnessThreshold: ng.FITNESS_THRESHOLD, MaxIterationsBeforeRestart: 20000, MaxAttempts: 10, } examples := ng.XnorTrainingSamples() cortexTrained, succeeded := shc.TrainExamples(cortex, examples) assert.True(t, succeeded) // verify it can now solve the training set verified := cortexTrained.Verify(examples) assert.True(t, verified) fitness := cortexTrained.Fitness(examples) log.Printf("Final fitness: %v", fitness) }
func TestAddNeuronRecurrent(t *testing.T) { ng.SeedRandom() numAdded := 0 numIterations := 100 for i := 0; i < numIterations; i++ { cortex := BasicCortex() numNeuronsBefore := len(cortex.Neurons) ok, mutateResult := AddNeuronRecurrent(cortex) neuron := mutateResult.(*ng.Neuron) if !ok { continue } else { numAdded += 1 } assert.True(t, neuron != nil) assert.True(t, neuron.ActivationFunction != nil) numNeuronsAfter := len(cortex.Neurons) addedNeuron := numNeuronsAfter == numNeuronsBefore+1 if !addedNeuron { logg.LogPanic("AddNeuronRecurrent %v did not add exactly one neuron. before: %v after: %v", i, numNeuronsBefore, numNeuronsAfter) } // run network make sure it runs examples := ng.XnorTrainingSamples() fitness := cortex.Fitness(examples) assert.True(t, fitness >= 0) } assert.True(t, numAdded > 0) }
func RunStochasticHillClimber() { ng.SeedRandom() // training set -- todo: examples := ng.XnorTrainingSamples() examples := ng.XnorTrainingSamples() // create netwwork with topology capable of solving XNOR cortex := ng.XnorCortexUntrained() // verify it can not yet solve the training set (since training would be useless in that case) verified := cortex.Verify(examples) if verified { panic("neural net already trained, nothing to do") } shc := &nv.StochasticHillClimber{ FitnessThreshold: ng.FITNESS_THRESHOLD, MaxIterationsBeforeRestart: 2000, MaxAttempts: 2000, WeightSaturationRange: []float64{-100 * math.Pi, 100 * math.Pi}, } cortexTrained, _, succeeded := shc.TrainExamples(cortex, examples) if !succeeded { panic("could not train neural net") } // verify it can now solve the training set verified = cortexTrained.Verify(examples) if !verified { panic("could not verify neural net") } logg.LogTo("DEBUG", "trained cortex: %v", cortexTrained) logg.Log("done") }
func getScape() nv.Scape { return XnorScapeTwoPlayer{ examples: ng.XnorTrainingSamples(), } }
func TestNeuronAddInlinkNonRecurrent(t *testing.T) { ng.SeedRandom() madeNonRecurrentInlink := false madeRecurrentInlink := false firstTime := true // since it's stochastic, repeat the operation many times and make // sure that it always produces expected behavior for i := 0; i < 100; i++ { xnorCortex := ng.XnorCortex() sensor := xnorCortex.Sensors[0] neuron := xnorCortex.NeuronUUIDMap()["output-neuron"] hiddenNeuron1 := xnorCortex.NeuronUUIDMap()["hidden-neuron1"] targetLayerIndex := hiddenNeuron1.NodeId.LayerIndex // add a new neuron at the same layer index as the hidden neurons hiddenNeuron3 := &ng.Neuron{ ActivationFunction: ng.EncodableSigmoid(), NodeId: ng.NewNeuronId("hidden-neuron3", targetLayerIndex), Bias: -30, } hiddenNeuron3.Init() xnorCortex.Neurons = append(xnorCortex.Neurons, hiddenNeuron3) weights := randomWeights(sensor.VectorLength) sensor.ConnectOutbound(hiddenNeuron3) hiddenNeuron3.ConnectInboundWeighted(sensor, weights) ok, mutateResult := NeuronAddInlinkNonRecurrent(neuron) if !ok { continue } inboundConnection := mutateResult.(*ng.InboundConnection) if neuron.IsInboundConnectionRecurrent(inboundConnection) { madeRecurrentInlink = true } else { madeNonRecurrentInlink = true } if firstTime == true { // only two possibilities - the hiddenNeuron3 or the // sensor. if it was the sensor, then the hiddenNeuron3 // is "dangliing" and so lets connect it if inboundConnection.NodeId.UUID == "sensor" { weights2 := randomWeights(1) hiddenNeuron3.ConnectOutbound(neuron) neuron.ConnectInboundWeighted(hiddenNeuron3, weights2) } // run network make sure it runs examples := ng.XnorTrainingSamples() fitness := xnorCortex.Fitness(examples) assert.True(t, fitness >= 0) firstTime = false } } assert.True(t, madeNonRecurrentInlink) assert.False(t, madeRecurrentInlink) }
func TestOutspliceRecurrent(t *testing.T) { logg.LogKeys["TEST"] = true logg.LogKeys["NEURVOLVE"] = true ng.SeedRandom() numOutspliced := 0 numOutsplicedWithNewLayer := 0 numOutsplicedWithExistingLayer := 0 numIterations := 100 for i := 0; i < numIterations; i++ { cortex := BasicCortexRecurrent() // run network make sure it runs examplesBefore := ng.XnorTrainingSamples() fitnessBefore := cortex.Fitness(examplesBefore) assert.True(t, fitnessBefore >= 0) // recreate network cortex = BasicCortexRecurrent() numNeuronsBefore := len(cortex.Neurons) neuronLayerMapBefore := cortex.NeuronLayerMap() ok, mutateResult := OutspliceRecurrent(cortex) neuron := mutateResult.(*ng.Neuron) if !ok { continue } else { numOutspliced += 1 } assert.True(t, neuron.ActivationFunction != nil) numNeuronsAfter := len(cortex.Neurons) assert.Equals(t, numNeuronsAfter, numNeuronsBefore+1) // should have 1 outbound and inbound assert.Equals(t, len(neuron.Inbound), 1) assert.Equals(t, len(neuron.Outbound), 1) // increment counter if layer added numLayersBefore := len(neuronLayerMapBefore) numLayersAfter := len(cortex.NeuronLayerMap()) if numLayersAfter == numLayersBefore+1 { numOutsplicedWithNewLayer += 1 } else { numOutsplicedWithExistingLayer += 1 } // run network make sure it runs examples := ng.XnorTrainingSamples() fitness := cortex.Fitness(examples) assert.True(t, fitness >= 0) } assert.True(t, numOutspliced > 0) assert.True(t, numOutsplicedWithNewLayer > 0) assert.True(t, numOutsplicedWithExistingLayer > 0) }