Running Clojush

#Running Clojush

(added by @lspector): This topic serves as a pointer to the Clojush README file, which documents how to run the Clojush implementation of the PushGP genetic programming system.

It can also be used to post additional Clojush documentation, and to ask/answer questions about Clojush.

(original first post documentation, by @mcphee):

Generating CSV output

  • :print-csv-logs true turns on CSV output. This can generate a ton of data very quickly, so use with care.
  • :csv-columns '[:generation :location :parent-uuids :genetic-operators :push-program-size :plush-genome-size :push-program :plush-genome :total-error :test-case-errors]' lets you specify which columns you want to print out. If you leave something (e.g., :push-program) out of this list, then that won’t be output. Some of these are particularly big (e.g., :plush-genome and `:push-program), so leaving them out can cut down on the size of the logs.
  • :csv-log-filename '"data0.csv"' specifies the name of the CSV output file. Since this argument needs to be a string (and not a symbol), you need the weird double quotes (one for the shell, one for Clojure).
1 Like

A question, probably for @thelmuth: How do we tell Clojush we want to capture all the ancestry info in a CSV file? I’m sure it’s a simple argument to the lein run … command, but I’m not immediately seeing it. Thanks.

No worries – I figured it out by hacking through some ALF files from previous runs. :stuck_out_tongue_winking_eye: I’ve put that info in the wiki entry at the top of this as well.

I edited the last bullet with what I remember is the reason for the weird double quotes.

I’ll add this to my list of Orientation topics to flesh out when I have time.

Thanks! That explanation seems weird to me, though. I thought all command line arguments came into Clojure as strings by default. Does Clojush do some munging that changes that, and then this is necessary to undo that?

Exactly. If you think about it, we pass arguments like true and :lexicase and 1000 to the command line, and they’re treated not as strings, but as booleans, keywords, and integers respectively. I don’t know exactly what voodoo happens behind the scenes, but it means we need to quote strings if we want them to turn into strings. Probably some sort of read/eval type thing.

1 Like

Can anyone (@lspector? @thelmuth? @anyone?) remind me how to use the Clojush code to auto-simplify a program? I know folks helped us figure that out last fall, but it doesn’t look like I wrote anything down, and searching here and my mail spool isn’t turning anything up.

Oh, and I want to run this starting from a genome, not a program, which appears to complicate things.

Help? :blush:

Thanks. :stuck_out_tongue_winking_eye:

You need an error function, which gets complicated if you’re using one of the software problems, since they use different training cases each time they are initialized. You can create a new error function which will use new training cases easily enough, which may or may not be good enough for your application depending on what you’re trying to simplify. For example, with the Count Odds problem, the following creates an error function:

(count-odds-error-function count-odds-data-domains)

After that, its pretty easy. I grabbed a genome from a run and simplified it using the following:

(use 'clojush.translate)
(use 'clojush.simplification)

(def genome '({:instruction integer_lt, :close 0} {:instruction integer_mod, :close 0} {:instruction integer_add, :close 0} {:instruction exec_yankdup, :close 0} {:instruction vector_integer_eq, :close 1} {:instruction exec_stackdepth, :close 0} {:instruction boolean_dup, :close 1} {:instruction vector_integer_contains, :close 0} {:instruction exec_pop, :close 0} {:instruction exec_flush, :close 1} {:instruction vector_integer_nth, :close 0} {:instruction boolean_swap, :close 0} {:instruction vector_integer_shove, :close 4} {:instruction in1, :close 1} {:instruction vector_integer_concat, :close 0} {:instruction boolean_yankdup, :close 0} {:instruction vector_integer_rot, :close 0} {:instruction boolean_yank, :close 0} {:instruction vector_integer_subvec, :close 0} {:instruction integer_min, :close 0} {:instruction integer_gte, :close 0} {:instruction in1, :close 0} {:instruction integer_rot, :close 0} {:instruction exec_stackdepth, :close 0} {:instruction integer_sub, :close 0} {:instruction integer_rot, :close 0} {:instruction vector_integer_emptyvector, :close 0} {:instruction vector_integer_emptyvector, :close 0} {:instruction vector_integer_dup, :close 0} {:instruction -644, :close 0} {:instruction integer_yank, :close 0} {:instruction boolean_flush, :close 0} {:instruction integer_min, :close 0} {:instruction integer_dup, :close 0} {:instruction integer_stackdepth, :close 1} {:instruction integer_div, :close 0} {:instruction integer_mult, :close 0} {:instruction vector_integer_nth, :close 0} {:instruction exec_dup, :close 0} {:instruction vector_integer_eq, :close 0} {:instruction vector_integer_pop, :close 0} {:instruction exec_do*vector_integer, :close 0} {:instruction integer_add, :close 0} {:instruction vector_integer_first, :close 2} {:instruction boolean_yankdup, :close 0} {:instruction in1, :close 0} {:instruction boolean_pop, :close 3} {:instruction integer_dec, :close 0} {:instruction boolean_and, :close 0} {:instruction in1, :close 0} {:instruction integer_shove, :close 0} {:instruction in1, :close 0} {:instruction vector_integer_yank, :close 2} {:instruction 3, :close 0} {:instruction exec_k, :close 0} {:instruction integer_sub, :close 0} {:instruction integer_mult, :close 0} {:instruction integer_add, :close 0} {:instruction boolean_stackdepth, :close 1} {:instruction in1, :close 1} {:instruction vector_integer_concat, :close 0} {:instruction exec_while, :close 0} {:instruction exec_do*vector_integer, :close 0} {:instruction vector_integer_occurrencesof, :close 2} {:instruction in1, :close 0} {:instruction vector_integer_last, :close 0} {:instruction in1, :close 0} {:instruction vector_integer_yank, :close 1} {:instruction 1, :close 0} {:instruction exec_yankdup, :close 0} {:instruction vector_integer_reverse, :close 0} {:instruction integer_mult, :close 0} {:instruction vector_integer_nth, :close 0} {:instruction integer_add, :close 1} {:instruction boolean_invert_second_then_and, :close 1} {:instruction vector_integer_indexof, :close 0} {:instruction vector_integer_replacefirst, :close 0} {:instruction boolean_not, :close 0} {:instruction exec_while, :close 0} {:instruction integer_swap, :close 0} {:instruction boolean_yank, :close 0} {:instruction tagged_383, :close 0} {:instruction exec_stackdepth, :close 0} {:instruction vector_integer_swap, :close 0} {:instruction vector_integer_concat, :close 0} {:instruction exec_while, :close 0} {:instruction exec_do*vector_integer, :close 0} {:instruction tagged_441, :close 2} {:instruction boolean_invert_second_then_and, :close 0} {:instruction vector_integer_nth, :close 0} {:instruction boolean_eq, :close 2} {:instruction vector_integer_first, :close 0} {:instruction in1, :close 0} {:instruction integer_empty, :close 1} {:instruction exec_pop, :close 0} {:instruction vector_integer_emptyvector, :close 0} {:instruction boolean_flush, :close 1} {:instruction 2, :close 1} {:instruction exec_stackdepth, :close 0} {:instruction integer_pop, :close 0} {:instruction integer_mod, :close 0} {:instruction in1, :close 1} {:instruction boolean_pop, :close 0} {:instruction vector_integer_dup, :close 0} {:instruction integer_mult, :close 0} {:instruction boolean_invert_second_then_and, :close 0} {:instruction integer_empty, :close 0} {:instruction vector_integer_empty, :close 0} {:instruction integer_mult, :close 1} {:instruction integer_add, :close 0} {:instruction integer_sub, :close 1} {:instruction -644, :close 1} {:instruction boolean_flush, :close 0} {:instruction vector_integer_swap, :close 0} {:instruction exec_do*times, :close 1} {:instruction exec_swap, :close 2} {:instruction 4, :close 3} {:instruction vector_integer_conj, :close 0} {:instruction integer_yank, :close 1} {:instruction vector_integer_length, :close 0} {:instruction boolean_flush, :close 0} {:instruction integer_mod, :close 1} {:instruction vector_integer_pop, :close 0} {:instruction boolean_or, :close 0} {:instruction boolean_empty, :close 2})

(def program (translate-plush-genome-to-push-program {:genome genome} ;translate takes an individual or a map containing a `:genome`
                                                     {:max-points 10000})) ;it also takes the max-points, which is used to make sure the program doesn't get too big. Feel free to just set this to a big number unless you think it might effect the translation.

(auto-simplify-from-program program
                            (count-odds-error-function count-odds-data-domains)
                            500  ;number of simplification steps
                            true ;whether to print a report every X generations
                            100) ;X = number of generations after which to report

Let me know if any of that is unclear!