// Locality test func testRepr(initFunc func(maxDep int) *node.Node, mutateFunc func(float64, *node.Node), paintFunc func(*node.Node, *imgut.Image)) (avgErr, varErr float64) { // Create storage for the images indImage := imgut.Create(IMG_W, IMG_H, imgut.MODE_RGB) tmpImage := imgut.Create(IMG_W, IMG_H, imgut.MODE_RGB) // Build random individuals randomIndividuals := make([]*node.Node, N) // For each individual var totErrorSum float64 = 0 var totErrorSqr float64 = 0 for _, i := range randomIndividuals { // Initialize it i = initFunc(MAX_D) // Render it to an image (it will be garbage) indImage.Clear() paintFunc(i, indImage) // Average error for this individual var indErrorSum float64 = 0 var indErrorSqr float64 = 0 for k := 0; k < M; k++ { // Copy the individual j := i.Copy() // Mutate the individual mutateFunc(1, j) // Render it to another image tmpImage.Clear() paintFunc(j, tmpImage) // Compute distance dist := imgut.PixelRMSE(indImage, tmpImage) // Accumulate distance indErrorSum += dist indErrorSqr += dist * dist } // Compute average error indErrorAvg := indErrorSum / float64(M) // Compute variance indErrorVar := indErrorSqr/float64(M) - (indErrorAvg * indErrorAvg) fmt.Println(" Individual avg error and variance:", indErrorAvg, indErrorVar) // Accumulate error totErrorSum += indErrorAvg totErrorSqr += indErrorAvg * indErrorAvg } // Compute average error of the averages avgErr = totErrorSum / float64(N) // Compute variance of the averages varErr = totErrorSqr/float64(N) - (avgErr * avgErr) fmt.Println("Total error and var:", avgErr, varErr) return }
func TestRMSE(t *testing.T) { rand.Seed(time.Now().UTC().UnixNano()) // Create a white image img1 := imgut.Create(10, 1, imgut.MODE_RGBA) img1.FillRect(0, 0, 10, 1, 1.0, 1.0, 1.0) // Create a black image img2 := imgut.Create(10, 1, imgut.MODE_RGBA) img2.FillRect(0, 0, 10, 1, 0.0, 0.0, 0.0) //path := "/home/akiross/Dropbox/Dottorato/TeslaPhD/GoGP/rmse_test_image.png" //img2.WritePNG(path) // Compare RMSEs rmseVec := fitnessRMSE(img1, img2) rmseImg := fitnessRMSEImage(img1, img2) t.Log("Vec RMSE", rmseVec, rmseImg) }
func TestPrimitives(t *testing.T) { x := MakeIdentityX() y := MakeIdentityY() c5 := MakeConstant(0.5) e := MakeEphimeral("MakeRand", func() *Primitive { v := rand.Float64() return MakeConstant(NumericOut(v)) }) sum := MakeBinary("Sum", func(a, b NumericOut) NumericOut { return a + b }) sub := MakeBinary("Sub", func(a, b NumericOut) NumericOut { return a - b }) mul := MakeBinary("Mul", func(a, b NumericOut) NumericOut { return a * b }) cos := MakeUnary("Cos", func(a NumericOut) NumericOut { return NumericOut(math.Cos(float64(a))) }) spl := MakeTernary("Spl", func(a, b, c NumericOut) NumericOut { if a > 0.5 { return b } else { return c } }) sub = sub sum = sum mul = mul cos = cos spl = spl e, x, y, c5 = e, x, y, c5 expr := spl.Run(x, y, x) t.Log(expr) img := imgut.Create(100, 100, imgut.MODE_RGBA) // We have to compile the nodes exec := expr.Run().(*Primitive) // Apply the function // exec(0 0, float64(img.W), float64(img.H), img) var call imgut.PixelFunc = func(x, y float64) float64 { return float64(exec.Eval(NumericIn(x), NumericIn(y))) } img.FillMathBounds(call) img.WritePNG("test_expr_repr.png") t.Fail() }
func (ind *Individual) Copy() ga.Individual { tmpImg := imgut.Create(ind.set.ImgTarget.W, ind.set.ImgTarget.H, ind.set.ImgTarget.ColorSpace) return &Individual{ind.Node.Copy(), ind.fitness, ind.fitIsValid, ind.set, tmpImg} }
func (ind *Individual) Initialize() { ind.Node = ind.set.GenFunc(ind.set.MaxDepth) ind.ImgTemp = imgut.Create(ind.set.ImgTarget.W, ind.set.ImgTarget.H, ind.set.ImgTarget.ColorSpace) }
func (c *Configuration) RandomSolution() hc.Solution { n := node.MakeTreeHalfAndHalf(c.MaxDepth, c.Functionals, c.Terminals) tmpImg := imgut.Create(c.ImgTarget.W, c.ImgTarget.H, c.ImgTarget.ColorSpace) return &Solution{n, tmpImg, c} }
func (s *Solution) Copy() hc.Solution { tmpImg := imgut.Create(s.Conf.ImgTarget.W, s.Conf.ImgTarget.H, s.Conf.ImgTarget.ColorSpace) return &Solution{s.Node.Copy(), tmpImg, s.Conf} }
func Evolve(calcMaxDepth func(*imgut.Image) int, fun, ter []gp.Primitive, drawfun func(*base.Individual, *imgut.Image)) { startTime := time.Now() // Setup options fs := flag.NewFlagSet(os.Args[0], flag.ExitOnError) numGen := fs.Int("g", 100, "Number of generations") popSize := fs.Int("p", 1000, "Size of population") saveInterval := fs.Int("n", 25, "Generations interval between two snapshot saves") tournSize := fs.Int("T", 3, "Tournament size") pCross := fs.Float64("C", 0.8, "Crossover probability") pMut := fs.Float64("M", 0.1, "Bit mutation probability") quiet := fs.Bool("q", false, "Quiet mode") fElite := fs.Bool("el", false, "Enable elite individual") fInitFull := fs.Bool("full", true, "Enable full initialization") fInitGrow := fs.Bool("grow", true, "Enable grow initialization") fInitRamped := fs.Bool("ramp", true, "Enable ramped initialization") fMutSin := fs.Bool("ms", false, "Enable Single Mutation") fMutNod := fs.Bool("mn", false, "Enable Node Mutation") fMutSub := fs.Bool("mt", false, "Enable Subtree Mutation") fMutAre := fs.Bool("ma", false, "Enable Area Mutation") fMutLsubt := fs.Bool("mlt", false, "Enable Level-Subtree Mutation") fMutLoc := fs.Bool("ml", false, "Enable Local Mutation") fSelect := fs.String("sel", "torun", "Pick selection method (tourn, rmad, irmad)") fMultiMut := fs.Bool("mM", false, "Enable multiple mutations") fFitness := fs.String("fit", "rmse", "Pick fitness function (rmse, mse, rmsed, ssim)") //advStats := fs.Bool("stats", false, "Enable advanced statistics") //nps := fs.Bool("nps", false, "Disable population snapshot (no-pop-snap)") targetPath := fs.String("t", "", "Target image (PNG) path") var basedir, basename string cpuProfile := fs.String("cpuprofile", "", "Write CPU profile to file") fs.Usage = func() { fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0]) fs.PrintDefaults() fmt.Fprintf(os.Stderr, " basedir (string) to be used for saving logs and files\n") fmt.Fprintf(os.Stderr, " basename (string) to be used for saving logs and files\n") } fs.Parse(os.Args[1:]) // Check if the argument args := fs.Args() if len(args) != 2 { fs.Usage() fmt.Fprintf(os.Stderr, "\nBasename/basedir parameter not specified\n") return } else { basedir = args[0] basename = args[1] } sta := stats.Create(basedir, basename) // Build settings var settings base.Settings // Primitives to use settings.Functionals = fun settings.Terminals = ter // Draw function to use settings.Draw = drawfun settings.Ramped = *fInitRamped if settings.Ramped { fmt.Println("Using ramped initialization") } // Pick initialization method based on flags var genFuncBit func(minH, maxH int, funcs, terms []gp.Primitive) *node.Node if *fInitFull && !*fInitGrow { fmt.Println("Using init strategy: full") genFuncBit = node.MakeTreeFull // Initialize tree using full } else if !*fInitFull && *fInitGrow { fmt.Println("Using init strategy: balanced grow") genFuncBit = node.MakeTreeGrowBalanced // Initialize using grow } else { fmt.Println("Using init strategy: half-and-half") genFuncBit = node.MakeTreeHalfAndHalf // Initialize using both (half and half) } settings.GenFunc = func(maxDep int) *node.Node { t := genFuncBit(0, maxDep, fun, ter) // /* TODO */ sistemare la minH s := settings if _, ok := s.IntCounters[tree_init_depth]; !ok { s.IntCounters[tree_init_depth] = new(counter.IntCounter) } s.IntCounters[tree_init_depth].Count(node.Depth(t)) return t } // Build statistic map settings.Statistics = make(map[string]*sequence.SequenceStats) settings.Counters = make(map[string]*counter.BoolCounter) settings.IntCounters = make(map[string]*counter.IntCounter) // Names of extra statistics statsKeys := []string{} countersKeys := []string{} intCountersKeys := []string{} intCountersKeys = append(intCountersKeys, tree_init_depth) if *fMutSin { countersKeys = append(countersKeys, mut_single_event, mut_single_improv, mut_single_node_leaves) intCountersKeys = append(intCountersKeys, mut_single_node_depth, mut_single_node_repld) } if *fMutNod { countersKeys = append(countersKeys, mut_multi_event, mut_multi_improv, mut_multi_node_leaves) intCountersKeys = append(intCountersKeys, mut_multi_node_depth, mut_multi_node_repld) } if *fMutSub { countersKeys = append(countersKeys, mut_tree_event, mut_tree_improv, mut_tree_node_leaves) intCountersKeys = append(intCountersKeys, mut_tree_node_depth, mut_tree_node_repld) } if *fMutAre { countersKeys = append(countersKeys, mut_area_event, mut_area_improv, mut_area_node_leaves) intCountersKeys = append(intCountersKeys, mut_area_node_depth, mut_area_node_repld) } if *fMutLsubt { countersKeys = append(countersKeys, mut_lsubt_event, mut_lsubt_improv, mut_lsubt_improv) intCountersKeys = append(intCountersKeys, mut_lsubt_node_depth, mut_lsubt_node_repld) } if *fMutLoc { countersKeys = append(countersKeys, mut_local_event, mut_local_improv) // intCountersKeys = append(intCountersKeys, "mut_local_") TODO } if *fMultiMut { intCountersKeys = append(intCountersKeys, mut_count_multi) } if *cpuProfile != "" { f, err := os.Create(*cpuProfile) if err != nil { fmt.Println("ERROR", err) panic("Cannot create cpuprofile") } pprof.StartCPUProfile(f) defer pprof.StopCPUProfile() } // Load the target var err error settings.ImgTarget, err = imgut.Load(*targetPath) if err != nil { fmt.Fprintln(os.Stderr, "ERROR: Cannot load image", *targetPath) panic("Cannot load image") } if !*quiet { fmt.Println("Image format RGB?", settings.ImgTarget.ColorSpace == imgut.MODE_RGB, settings.ImgTarget.ColorSpace) } // Compute the right value of maxDepth settings.MaxDepth = calcMaxDepth(settings.ImgTarget) if !*quiet { fmt.Println("For area of", settings.ImgTarget.W*settings.ImgTarget.H, "pixels, max depth is", settings.MaxDepth) } // Create temporary surface, of same size and mode //settings.ImgTemp = imgut.Create(settings.ImgTarget.W, settings.ImgTarget.H, settings.ImgTarget.ColorSpace) // Create temporary surface for the entire population pImgCols := int(math.Ceil(math.Sqrt(float64(*popSize)))) pImgRows := int(math.Ceil(float64(*popSize) / float64(pImgCols))) imgTempPop := imgut.Create(pImgCols*settings.ImgTarget.W, pImgRows*settings.ImgTarget.H, settings.ImgTarget.ColorSpace) // Define the operators settings.CrossOver = makeCrossover(&settings) settings.Mutate = makeMultiMutation(&settings, *fMultiMut, *fMutSin, *fMutNod, *fMutSub, *fMutAre, *fMutLsubt, *fMutLoc) // Fitness if *fFitness == "mse" { settings.FitFunc = base.MakeFitMSE(settings.ImgTarget) } else if *fFitness == "rmsed" { statsKeys = append(statsKeys, "fit-delta-rmse") settings.FitFunc = base.MakeFitEdge(settings.ImgTarget, settings.Statistics) } else if *fFitness == "ssim" { settings.FitFunc = base.MakeFitSSIM(settings.ImgTarget) } else { statsKeys = append(statsKeys, "fit-delta-rmse") settings.FitFunc = base.MakeFitRMSE(settings.ImgTarget) } // Selection ts := *tournSize if *fSelect == "rmad" { settings.Select = base.MakeSelectRMAD(ts, ts*ts, settings.BetterThan) } else if *fSelect == "irmad" { settings.Select = base.MakeSelectIRMAD(ts, ts*ts, settings.BetterThan) } else { settings.Select = base.MakeSelectTourn(ts, settings.BetterThan) } // Seed rng if !*quiet { fmt.Println("Number of CPUs", runtime.NumCPU()) runtime.GOMAXPROCS(runtime.NumCPU()) fmt.Println("CPUs limits", runtime.GOMAXPROCS(0)) } // Build population pop := new(base.Population) pop.Set = &settings //pop.TournSize = *tournSize pop.Initialize(*popSize) // Save initial population FIXME it's for debugging /* for i := range pop.Pop { pop.Pop[i].Draw(imgTemp) imgTemp.WritePNG(fmt.Sprintf("pop_ind_%v.png", i)) } */ // Number of parallel generators to setup pipelineSize := 1 // Was 4 FIXME but there are statistics used in parallel and not ready for concurrent access // Containers for pipelined operators chXo := make([]<-chan ga.PipelineIndividual, pipelineSize) chMut := make([]<-chan ga.PipelineIndividual, pipelineSize) // Save best individual, for elitism var elite ga.Individual = nil // Save time before starting //genTime := time.Now() // Loop until max number of generation is reached for g := 0; g < *numGen; g++ { // Compute fitness for every individual with no fitness fitnessEval := pop.Evaluate() fitnessEval = fitnessEval // //if !*quiet { // fmt.Println("Generation ", g, "fit evals", fitnessEval, time.Since(genTime)) // genTime = time.Now() //} // Compute various statistics sta.Observe(pop) // Statistics and samples if g%*saveInterval == 0 { snapName, snapPopName := sta.SaveSnapshot(pop, *quiet, countersKeys, statsKeys, intCountersKeys) // Save best individual if false { pop.BestIndividual().Fitness() pop.BestIndividual().(*base.Individual).ImgTemp.WritePNG(snapName) } // Save best individual code // pop.BestIndividual().(*base.Individual).Draw(settings.ImgTemp) // settings.ImgTemp.WritePNG(snapName) // Save pop images pop.Draw(imgTempPop, pImgCols, pImgRows) imgTempPop.WritePNG(snapPopName) } // Setup parallel pipeline selectionSize := len(pop.Pop) // int(float64(len(pop.Pop))*0.3)) if you want to randomly generate new individuals chSel := ga.GenSelect(pop, selectionSize, float32(g)/float32(*numGen), elite) for i := 0; i < pipelineSize; i++ { chXo[i] = ga.GenCrossover(chSel, *pCross) chMut[i] = ga.GenMutate(chXo[i], *pMut) } var sel []ga.PipelineIndividual = ga.Collector(ga.FanIn(chMut...), selectionSize) // Replace old population and compute statistics for i := range sel { pop.Pop[i] = sel[i].Ind.(*base.Individual) sta.ObserveCrossoverFitness(sel[i].CrossoverFitness, sel[i].InitialFitness) sta.ObserveMutationFitness(sel[i].MutationFitness, sel[i].CrossoverFitness) } // When elitism is activated, get best individual if *fElite { elite = pop.BestIndividual() } // Build new individuals //base.RampedFill(pop, len(sel), len(pop.Pop)) } fitnessEval := pop.Evaluate() fitnessEval = fitnessEval // Population statistics sta.Observe(pop) //if !*quiet { // fmt.Println("Generation", *numGen, "fit evals", fitnessEval) // fmt.Println("Best individual", pop.BestIndividual()) //} snapName, snapPopName := sta.SaveSnapshot(pop, *quiet, countersKeys, statsKeys, intCountersKeys) // Save best individual if false { pop.BestIndividual().Fitness() pop.BestIndividual().(*base.Individual).ImgTemp.WritePNG(snapName) } // pop.BestIndividual().(*base.Individual).Draw(settings.ImgTemp) // settings.ImgTemp.WritePNG(snapName) // Save pop images pop.Draw(imgTempPop, pImgCols, pImgRows) imgTempPop.WritePNG(snapPopName) if !*quiet { fmt.Println("Best individual:") fmt.Println(pop.BestIndividual()) } elapsedTime := time.Since(startTime) fmt.Println("Execution took %s", elapsedTime) /* bestName := fmt.Sprintf("%v/best/%v.png", basedir, basename) if !*quiet { fmt.Println("Saving best individual in", bestName) fmt.Println(pop.BestIndividual()) } pop.BestIndividual().(*base.Individual).Draw(settings.ImgTemp) settings.ImgTemp.WritePNG(bestName) */ }