MOSES for Noobs
This page will attempt to explain how to use MOSES in an even simpler way than described on the MOSES Tutorial page. If you feel this tutorial is too simple for you, please check that page.
This page has the following prerequisites:
Since the examples on the slighly more advanced MOSES Tutorial page may be hard to grasp without understanding what multiplex and parity problems are, I thought we'd start with something extremely simple, such as regression (a measure of the relation between the mean value of one variable (e.g. output) and corresponding values of other variables (e.g. time and cost)).
With regression, MOSES attempts to find a program that approximates a set of data as closely as possible. A common example is trying to find a program that will be able to calculate a good price for a house that needs to be sold, based on some input parameters such as number of bedrooms, the year it was built, size of the garden, etc.
Since that's a bit daunting for now, we're going to start with a stupidly simple dataset.
First let's explain how to structure a dataset for use in MOSES.
Creating a really simple dataset
We're going to see if MOSES can generate a program where input equals output. So if we input 1, we want it to output 1. If we input 5, we want it to output 5. This is terribly uninteresting, but it's the easiest way to explain the log file it generates and the general structure of the steps you need to take.
First we need to create a text file with data for MOSES to process. In the default format, columns represent features and rows represent observations.
Open a text editor, and enter the following lines:
TARGET,INPUT 1,1 2,2 3,3 4,4 5,5 6,6 7,7
Save the file in a location that you know how to enter as a parameter when we start the MOSES program, let's say we call it 'inout.txt'
The first row gives us column labels (TARGET,INPUT), which makes the output a little easier to understand.
The first column (TARGET) is the so called 'target feature' that the generated program will attempt to 'fit', or approximate. The columns after that are input features - values MOSES can use as input in the programs it is generating in order to approximate the target feature.
Running MOSES on the dataset
Depending on how you configured and installed MOSES (see this page) you may have to run it from varying locations. Worst case - you have to run it from your build directory (opencog/build/opencog/learning/moses/main, or in the old folder structure bin/opencog/learning/moses/main). Let's assume you started in your build or bin folder:
And then you can run the MOSES program as follows
./moses -i inout.txt -m43 -W1 (or try dropping the ./
./moses -i inout.txt -m43 -W1)
-i is used to supply an input file, which is the parameter after that.
-m43 tells it to stop after 43 fitness function evaluations. For now think of it as the number of programs it tries to 'score', based on the distance between their desired output (the first column in our file, the target feature) and their actual output (the output generated by that version of the COMBO program MOSES has evolved).
43 turns out to be the minimum number to reach a program with a perfect score. Feel free to decrease the number, which will give you programs that approximate the target feature less well, or increase the number, which makes the program run longer with the same result.
-W1 tells it to use the column labels we provided in the output programs, so we can understand them better.
Understanding the output
The output should be something like:
0 $INPUT -91 1 -140 0 -203 -1 -560 *(-1 $INPUT)
Each line first gives a score for how well the generated program approximates the target feature (0 is perfect, anything lower is worse). Behind the score it will output the COMBO program it used to achieve the score.
The highest scoring program is on the first line. The 0 indicates there is 0 distance between the target feature we wanted the program to approximate and the actual output of this program. The $INPUT indicates that the COMBO program consists of nothing more than the first input feature, the second column in our data file.
The other lines show other programs COMBO generated, ranked by how well they approximate the target feature. Programs that simply output a static value of 1, 0 or -1 score -91, -140 and -203 respectively.
The last line shows a program which multiplies (*) the first input feature ($INPUT) by -1. As we can see, it scores quite badly, -560. In the output, operators are displayed first, followed by their parameters. This may seem un-intuitive at first, but it's actually quite easy to get used to.
Understanding the log file
Sometimes it may be useful to look at the log file to understand what MOSES tried to do. Since we are generating almost the simplest possible program here, the log file should be quite short. For aesthetic reasons, the timestamps at the beginning of each line have been removed.
The files start with some generic logging data:
Using config file found at: moses version 3.6.0 Command line: ./moses -i inout.txt -m43 hostname: ubuntu
Then it tells us some things about the file. Here we can see that MOSES attempts to determine the type of data in the records (line 4 below), with the last value being the target value (our first columns), also shown in line 5. The word 'contin' is short for continous, meaning numbers, as opposed to discrete, which would indicate boolean values.
Read data file inout.txt Number of rows in tables = 7 Inferred arity = 1 Inferred data signature ->(contin contin) Inferred output type: contin
Alphabet size = 9 output = contin
BScore complexity ratio = 3.5
Inferred target score = 0 Subtract -0.0001 (minimum significant improvement) from the target score to deal with float imprecision = 0.0001 Cache composite scores
MOSES starts, max_evals=43 max_gens=-1 max_time=2147483647
The next section is just comments that explain the output table that follows.
Stats: # Stats: # Stats are tab-separated, ready for graphing. Stats: # You can also use the script parse_log.py to extract a CSV file given a moses log file. Column explanation: Stats: # Stats: # gen is the generation number. Stats: # num_evals is the number of scoring function evaluations so far. Stats: # elapsed is the wall-clock time, in seconds, since start. Stats: # metapop_size is the size of the metapopulation. Stats: # best_score is the highest raw score seen, of all exemplars. Stats: # complexity is in bits, of the highest-composite score exemplar. Stats: # field_set_size is the ESTIMATED number of bits in all the knobs. Stats: # optim_steps is the number of steps the optimizer took. Stats: # over_budget is bool, T if search exceeded scoring func eval budget. Stats: # Stats: # gen num_evals elapsed metapop_size best_score complexity field_set_size optim_steps over_budget
Start knob building, rep size=1 complexity=1 After knob building, rep size=57 complexity=5 Total number of field specs: 18 Number of disc knobs mapped: 0 Number of contin knobs mapped: 18 Field set, in bytes: 1768 One instance, in bytes: 36 [2013-03-14 09:07:18:527] [INFO] Demes: # deme_count iteration total_steps total_evals microseconds new_instances num_instances inst_RAM num_evals has_improved best_weighted_score delta_weighted best_raw delta_raw complexity [2013-03-14 09:07:18:527] [INFO] Demes: 1 1 1 1 112 1 1 3.43323e-05 1 1 -140.286 3.40282e+38 -140 3.40282e+38 1 [2013-03-14 09:07:18:532] [INFO] Demes: 1 2 2 37 4843 36 37 0.00127029 37 1 -0.285714 140 0 140 1 [2013-03-14 09:07:18:533] [INFO] Demes: 1 3 3 43 964 6 43 0.00147629 43 0 -0.285714 0 0 0 1 Expansion 1 done Total number of evaluations so far: 43 The following candidate(s) have the best score [score=0, complexity=1, complexity penalty=0.2857142984867095947265625, diversity penalty=0] 1 Stats: 1 43 0 5 0 1 41 3 1 MOSES ends Best candidates: 0 $1 -91 1 -140 0 -203 -1 -560 *(-1 $1) Cache composite scores hits=38 misses=6
Since the regression tutorial above isn't complete yet, you could have a look at MOSES for Noobs - Logic Gates.
- Q: What does it mean to 'to find a program' in 'MOSES attempts to find a program that approximates a set of data as closely as possible'?
A program, in MOSES, is a combo program. A combo program is represented as a tree of operators, variables and values. Nodes in the tree may be constants (bits, integers, real numbers, etc.), boolean operators (and, or, etc.), arithmetical operators (+, -, *, etc.), functions (sin, cos, etc.) or logical expressions (if...then...else, etc.), and so on. Arguments to an n-ary function are denoted with '$', so that would be the arguments. Thus, for example, is a program that takes argument (a float pt. number), multiplies it by 0.5, and checks to see if it is greater than zero. The result of this compare is or-ed ( -ed) with argument (a boolean). Although programs may be explicit, as in this example, a program can also be understood to be a representation, together with a particular set of knob settings, as explained in the MOSES terminology page.
- Then please leave them here.
- Q: Where do the logs appear? (they don't seem to be appending to moses.log)
- Q: How much of COMBO does one need to understand in order to proceed with MOSES? What basic concepts would be good to understand?
- Q: I don't really get the basic expressions section of the COMBO Programming Language wiki page - is there a more verbose explanation of COMBO?