+ All Categories
Home > Engineering > Genetic programming with clojure.spec and Beyond

Genetic programming with clojure.spec and Beyond

Date post: 14-Apr-2017
Category:
Upload: carin-meier
View: 926 times
Download: 0 times
Share this document with a friend
138
Genetic Programming and Beyond with clojure.spec Carin Meier(@gigasquid)- Cognitect
Transcript
Page 1: Genetic programming with clojure.spec and Beyond

Genetic Programming and Beyond with clojure.specCarin Meier(@gigasquid)- Cognitect

Page 2: Genetic programming with clojure.spec and Beyond

I'm so excited to be here!

Page 3: Genetic programming with clojure.spec and Beyond
Page 4: Genetic programming with clojure.spec and Beyond
Page 5: Genetic programming with clojure.spec and Beyond

PerspectiveSeeing things in a different way

Page 6: Genetic programming with clojure.spec and Beyond

Java Developermany years

Page 7: Genetic programming with clojure.spec and Beyond

Everything is an object

Page 8: Genetic programming with clojure.spec and Beyond
Page 9: Genetic programming with clojure.spec and Beyond
Page 10: Genetic programming with clojure.spec and Beyond

Different way of thinkingModeling the world in a functional way

Page 11: Genetic programming with clojure.spec and Beyond
Page 13: Genetic programming with clojure.spec and Beyond

Four Tribes of Programmers» Explorers

» Alchemists

» Wrestlers

» Detectives

Page 14: Genetic programming with clojure.spec and Beyond

Four Tribes of ProgrammersExplorers

Those who get excited about discovering a new algorithm or tool.

Page 15: Genetic programming with clojure.spec and Beyond

Four Tribes of ProgrammersExplorersGem Collectors

Bring beautiful things back from their discoveries

Page 16: Genetic programming with clojure.spec and Beyond

Four Tribes of ProgrammersExplorersMappers

Describe and chart the new lands

Page 17: Genetic programming with clojure.spec and Beyond

Four Tribes of ProgrammersAlchemists

Those who get excited about finding connections between different areas of programming or other fields that no one had seen before.

Pour one into another and explode!

Page 18: Genetic programming with clojure.spec and Beyond

Four Tribes of ProgrammersWrestlers

Those who enjoy the scale of programming.

They thrive on true big data, speed, and handling things at scale that would make other people faint

Page 19: Genetic programming with clojure.spec and Beyond

Four Tribes of ProgrammersDetectives

Those who find enjoyment in diving into the deep, detailed aspects of programming.

Understanding things at a 200X magnification.

Page 20: Genetic programming with clojure.spec and Beyond

Belong to One or Many

» Explorers

» Alchemists

» Wrestlers

» Detectives

Page 21: Genetic programming with clojure.spec and Beyond

Alchemist

Page 22: Genetic programming with clojure.spec and Beyond

Seek IntegrationI am a big “integration always proponent"

Page 23: Genetic programming with clojure.spec and Beyond

Integration

“Take risks at the edge of scholarship and seek integration.Most forays won’t yield anything, but some certainly will.”M Gazzaniga (Split Brain) leader of cognitive neuroscience

Page 24: Genetic programming with clojure.spec and Beyond

Combine clojure.spec with things I'm interested in

Page 25: Genetic programming with clojure.spec and Beyond

Clojure.specGenetic Programming

Page 26: Genetic programming with clojure.spec and Beyond

Why Clojure.spec?» Allows you to describe data and create a spec

» Allows you to validate data against the spec

» Allows you to generate data from the spec

Page 27: Genetic programming with clojure.spec and Beyond

Describe Data and Create Spec

foo is a integer

(require '[clojure.spec :as s]);; => nil(s/def ::foo int?);; => :user/foo

Page 28: Genetic programming with clojure.spec and Beyond

Validate Data against a Spec

Is this data a valid foo ?

(s/valid? ::foo 1);; => true

(s/valid? ::foo "hi");; => false

Page 29: Genetic programming with clojure.spec and Beyond

Validate Data against a Spec

Is this data a valid foo ?Why Not?

(s/explain ::foo "hi");;=> val: "hi" fails spec: :user/foo predicate: int?

Page 30: Genetic programming with clojure.spec and Beyond

Generate Data from a Spec

Can you give me some example data?

(s/exercise ::foo 1);; => ([-1 -1])

Page 31: Genetic programming with clojure.spec and Beyond
Page 32: Genetic programming with clojure.spec and Beyond

What is Genetic Programming?Evolving creatures through breeding and mutating

Page 33: Genetic programming with clojure.spec and Beyond

What is Genetic Programming?The creatures are PROGRAMS!

Page 34: Genetic programming with clojure.spec and Beyond

Our ExperimentGiven some dataUse genetic programming to evolve a spec program to describe it

Page 35: Genetic programming with clojure.spec and Beyond

Spec Creatures Eat Data["hi" true 5 10 "boo"]

Page 36: Genetic programming with clojure.spec and Beyond

Spec Creatures» program = spec

» score

{:program (s/cat :0 int? :1 string?) :score 0}

Page 37: Genetic programming with clojure.spec and Beyond

How to Score a CreatureHow much of the data can the spec consume without errors?

Page 38: Genetic programming with clojure.spec and Beyond

Perfect Score(s/explain-data (s/cat :0 int? :1 string?) [1 "hi"]);=> nil

Page 39: Genetic programming with clojure.spec and Beyond

Not Perfect ScoreUse explain-data to figure it out

(s/explain-data (s/cat :0 int? :1 string?) [1 true])

;=> #:clojure.spec{:problems [{:path [:1] :pred string? :val true :via [] :in [1]}]}

Page 40: Genetic programming with clojure.spec and Beyond

How to Score a Creature» Perfect match = 100

» Anything less is how far in the sequence it was valid

Page 41: Genetic programming with clojure.spec and Beyond

Creating a Creature

Page 42: Genetic programming with clojure.spec and Beyond

Creating a CreatureUse the power of Clojure!Code is Data

Page 43: Genetic programming with clojure.spec and Beyond

Creature Creation Controls» All start with s/cat

» Allowed preds

» integer?

» string?

» boolean?

» even?

» odd?

Page 44: Genetic programming with clojure.spec and Beyond

Creature Creation Controls» Allow composition

» s/+

» s/*

» s/and

» s/or

Page 45: Genetic programming with clojure.spec and Beyond

Creature Creation Controlsprobability knobs

(def seq-prob 0.3)(def nest-prob 0.00)(def max-depth 4)(def and-or-prob 0.85)

Page 46: Genetic programming with clojure.spec and Beyond

Creature Create!(make-random-cat 3);=> (clojure.spec/cat :0 (s/and integer? odd?) :1 integer? :2 boolean?)

Page 47: Genetic programming with clojure.spec and Beyond

Creature Create!Make an initial population

(defn initial-population [popsize max-cat-length] (for [i (range popsize)] {:program (make-random-cat (inc (rand-int max-cat-length)))}))

Page 48: Genetic programming with clojure.spec and Beyond

So Now What?How do they evolve?

Page 49: Genetic programming with clojure.spec and Beyond

Mutate

Page 50: Genetic programming with clojure.spec and Beyond

Mutate a Creature

» Walk the creatures program

» Choose a program segment with a probability

» Swap out the piece for newly generated segment

Page 51: Genetic programming with clojure.spec and Beyond

Mutate Creature!(mutate {:program '(clojure.spec/cat :0 (s/and integer? odd?) :1 integer?)})

;=> {:program (clojure.spec/cat :0 (s/or (s/and integer? even?)) :1 integer?)}

Page 52: Genetic programming with clojure.spec and Beyond

What about Breeding?

Page 53: Genetic programming with clojure.spec and Beyond
Page 54: Genetic programming with clojure.spec and Beyond

CrossoverTakes two creatures and swaps a node from one creature to another

Page 55: Genetic programming with clojure.spec and Beyond

Crossover» Use the walk function to select at a random

probability the crossover node from the first creature

» Insert it into the second creature's program at another random spot

Page 56: Genetic programming with clojure.spec and Beyond

Crosover!(crossover {:program '(clojure.spec/cat :0 (s/and integer? odd?) :1 integer?)} {:program '(clojure.spec/cat :0 string? :1 boolean?)})

;=> {:program (clojure.spec/cat :0 (s/and integer? odd?) :1 boolean?)}

Page 57: Genetic programming with clojure.spec and Beyond

We can now» Create Creatures

» Score Creatures

» Change Creatures with Mutation

» Breed Creatures with other Creatures

Page 58: Genetic programming with clojure.spec and Beyond

Evolution Process

Page 59: Genetic programming with clojure.spec and Beyond

Evolution Process» Create initial population

» Rank them

» Take the top two best ones and carry them over (this is known as elitism)

» Create the next generation from selecting creatures for crossover and mutation

» Repeat!

Page 60: Genetic programming with clojure.spec and Beyond

How do you select them?

Page 61: Genetic programming with clojure.spec and Beyond

How do you select them?Good Question

Page 62: Genetic programming with clojure.spec and Beyond

How do you select them?Tournament selectionbut there are many other ways too

Page 63: Genetic programming with clojure.spec and Beyond

Tournament Selection» Pick n creatures from the whole population

» Among those, pick the best scored one

This will allow diversity in our population that is needed for proper evolution

Page 64: Genetic programming with clojure.spec and Beyond

Ready to EvolveMake a function that has inputs

population size how many generations tournament size test data

Ends with creature that is perfect fit or max generations

(defn perfect-fit [creatures] (first (filter #(= 100 (:score %)) creatures)))

Page 65: Genetic programming with clojure.spec and Beyond

Moment of Truth

Page 66: Genetic programming with clojure.spec and Beyond

Evolve(def creature-specs (evolve 100 100 7 ["hi" true 5 10 "boo"]))

Page 67: Genetic programming with clojure.spec and Beyond

Evolve(def creature-specs (evolve 100 100 7 ["hi" true 5 10 "boo"]))

(perfect-fit creature-specs)

Page 68: Genetic programming with clojure.spec and Beyond

Evolve(def creature-specs (evolve 100 100 7 ["hi" true 5 10 "boo"]))

(perfect-fit creature-specs)

;=>{:program (clojure.spec/cat :0 string? ; :1 boolean? ; :2 (s/and integer? odd?) ; :3 integer? ; :4 string?) ; :score 100}

Page 69: Genetic programming with clojure.spec and Beyond

Yay!We Did it - but wait...

Page 70: Genetic programming with clojure.spec and Beyond

Our generated creature is a spec

Page 71: Genetic programming with clojure.spec and Beyond

Specs can generate data

Page 72: Genetic programming with clojure.spec and Beyond

Specs can generate data (s/exercise (eval (:program (perfect-fit creature-specs))) 5);; ([("" true -1 -1 "") {:0 "", :1 true, :2 -1, :3 -1, :4 ""}];; [("D" false -1 -1 "G") {:0 "D", :1 false, :2 -1, :3 -1, :4 "G"}];; [("12" false -1 0 "l0") {:0 "12", :1 false, :2 -1, :3 0, :4 "l0"}];; [("" false -1 -2 "") {:0 "", :1 false, :2 -1, :3 -2, :4 ""}];; [("2" false 1 0 "Jro") {:0 "2", :1 false, :2 1, :3 0, :4 "Jro"}])

Page 73: Genetic programming with clojure.spec and Beyond

We can use that generated data to generate more specs!

Page 74: Genetic programming with clojure.spec and Beyond
Page 75: Genetic programming with clojure.spec and Beyond

Genetic Programming Summary

Page 76: Genetic programming with clojure.spec and Beyond

Genetic Programming Summary» Start with a way to generate random creatures

» Have a way to evaluate their fitness

» Create a way to change them for the next generations using

» Mutation

» Crossover

Page 77: Genetic programming with clojure.spec and Beyond

Genetic Programming Summary» Have an evolution process

» Create an initial population

» Rank them

» Create the next generation using selection techniques and mutation/ crossovers

» Don’t forget about diversity

Page 78: Genetic programming with clojure.spec and Beyond
Page 79: Genetic programming with clojure.spec and Beyond

Clojure.spec is really coolWhat other things can it do?

Page 80: Genetic programming with clojure.spec and Beyond

Could We Use it to Make Code Smarter?

Page 81: Genetic programming with clojure.spec and Beyond

Wouldn't it be great if a program could recover from an error and heal itself

Page 82: Genetic programming with clojure.spec and Beyond

This code would be able to rise above the mistakes of its humble programmer and make itself better

Page 83: Genetic programming with clojure.spec and Beyond

Self Healing Code

Page 84: Genetic programming with clojure.spec and Beyond
Page 85: Genetic programming with clojure.spec and Beyond

Clojure.specSelf Healing Code

Page 86: Genetic programming with clojure.spec and Beyond

Self Healing Code IngredientsThe paper Towards Design for Self-healing outlines a few main ingredients that we will need

Page 87: Genetic programming with clojure.spec and Beyond

Self Healing Code Ingredients

» Failure Detection - This one is pretty straight forward. We need to detect the problem in order to fix it.

» Fault Diagnosis - Once the failure has been detected, we need to be able to figure out exactly what the problem was so that we can find a solution.

Page 88: Genetic programming with clojure.spec and Beyond

Self Healing Code Ingredients

» Fault Healing - This involves the act of finding a solution and fixing the problem.

» Validation - Some sort of testing that the solution does indeed solve the problem.

Page 89: Genetic programming with clojure.spec and Beyond

Now we have ingredientsHow do we self heal?

Page 90: Genetic programming with clojure.spec and Beyond

Horizontal Donor Code Transfer

Page 91: Genetic programming with clojure.spec and Beyond

MIT developed a system called CodePhage

Page 92: Genetic programming with clojure.spec and Beyond

CodePhage» Inspired from the biological world with horizontal

gene transfer of genetic material between different organisms.

» In it they use a horizontal code transfer system that fixes software errors by transferring correct code from a set of donor application

Page 93: Genetic programming with clojure.spec and Beyond

Cool! Can we do that in Clojure?

Page 94: Genetic programming with clojure.spec and Beyond

» Clojure - has macros that let code modify itself

» clojure.spec - gives code the ability to describe itself

» clojure.spec - let's code share these specs with other code with its global registry

» clojure.spec - gives us the ability to generate example data from the specs

Page 95: Genetic programming with clojure.spec and Beyond

Self Healing Clojure Experiment

» write a small report program

» function called report

» made up of three helper functions.

» takes in a list of earnings and outputs a string summary of the average.

Page 96: Genetic programming with clojure.spec and Beyond

Self Healing Clojure Experiment

(defn report [earnings] (-> earnings (clean-bad-data) (calc-average) (display-report)))

Page 97: Genetic programming with clojure.spec and Beyond

Self Healing Clojure Experiment

(defn report [earnings] (-> earnings (clean-bad-data) (calc-average) (display-report)))

Divide by zero error waiting in calc-average!!!

Page 98: Genetic programming with clojure.spec and Beyond

Our Goal» (should we choose to accept the mission)

On the error, use clojure.spec to find a matching replacement function from a set of donor candidates.

Page 99: Genetic programming with clojure.spec and Beyond

The Setupreport function - dive in

(defn report [earnings] (-> earnings (clean-bad-data) (calc-average) (display-report)))

Page 100: Genetic programming with clojure.spec and Beyond

clean-bad-data

It takes in a vector of anything and filters out only those elements that are numbers.

(defn clean-bad-data [earnings] (filter number? earnings))

Page 101: Genetic programming with clojure.spec and Beyond

clean-bad-data specsspec the input

earnings will be a vector, (for the params) with another vector of anything.

(s/def ::earnings (s/cat :elements (s/coll-of any?)))

Page 102: Genetic programming with clojure.spec and Beyond

clean-bad-data specsspec the output

Custom generator - which will constrain the generator to just returning the value [[1 2 3 4 5]] as its example data* will explain why later

(s/def ::cleaned-earnings (s/with-gen (s/cat :clean-elements (s/coll-of number?)) #(gen/return [[1 2 3 4 5]]))

Page 103: Genetic programming with clojure.spec and Beyond

clean-bad-data specsexample of running the function with specs

(clean-bad-data [1 2 "cat" 3]);=>(1 2 3)

Page 104: Genetic programming with clojure.spec and Beyond

clean-bad-data specsexample of running exercise on it

(s/exercise ::cleaned-earnings 1);=> ([[[1 2 3 4 5]] {:clean-elements [1 2 3 4 5]}])

Page 105: Genetic programming with clojure.spec and Beyond

spec calc-average function with vital/fatal flaw

(defn calc-average [earnings] (/ (apply + earnings) (count earnings)))

(s/def ::average number?)

(s/fdef calc-average :args ::cleaned-earnings :ret ::average)

Page 106: Genetic programming with clojure.spec and Beyond

display-report function

(s/def ::report-format string?)

(defn display-report [avg] (str "The average is " avg))

(s/fdef display-report :args ::average :ret ::report-format)

Page 107: Genetic programming with clojure.spec and Beyond

report function

(defn report [earnings] (-> earnings (clean-bad-data) (calc-average) (display-report)))

(s/fdef report :args ::earnings :ret ::report-format)

Page 108: Genetic programming with clojure.spec and Beyond

Ready for Test Drive

Page 109: Genetic programming with clojure.spec and Beyond

Ready for Test Drive(report [1 2 3 4 5]);=> "The average is 3"

And the fatal flaw:

(report []);=> EXCEPTION! Divide by zero

Page 110: Genetic programming with clojure.spec and Beyond

We have our problem setupNow... the Donor Candidates

Page 111: Genetic programming with clojure.spec and Beyond

Donor CandidatesIn another namespace there will be a number of functions all speced out

Page 112: Genetic programming with clojure.spec and Beyond

Donor CandidatesSome will match the spec for our failing function, some will not

Page 113: Genetic programming with clojure.spec and Beyond

Donor CandidatesBad Matches

» bad-calc-average - matches spec but wrong answer value

» bad-calc-average2 - good value but returns string

» adder - not spec match

Page 114: Genetic programming with clojure.spec and Beyond

Donor CandidatesGood Match better calc average

(s/def ::numbers (s/cat :elements (s/coll-of number?)))(s/def ::result number?)

(defn better-calc-average [earnings] (if (empty? earnings) 0 (/ (apply + earnings) (count earnings))))

Page 115: Genetic programming with clojure.spec and Beyond

We have the setupWe have the donor candidatesNow what is the process?

Page 116: Genetic programming with clojure.spec and Beyond

The Self Healing Process

Page 117: Genetic programming with clojure.spec and Beyond

The Self Healing Process» Try the report function and catch any exceptions.

» If we get an exception, look through the stack trace and find the failing function name.

» Retrieve the failing function's spec from the spec registry

Page 118: Genetic programming with clojure.spec and Beyond

The Self Healing Process» Look for potential replacement matches in the

donor candidates

» Check the orig function's and the donor's :args spec and make sure that they are both valid for the failing input

Page 119: Genetic programming with clojure.spec and Beyond

The Self Healing Process» Check the orig function's and the donor's :ret

spec and make sure that they are both valid for the failing input

» Call spec exercise for the original function and get a seed value. Check that the candidate function's result when called with the seed value is the same result when called with the original function.

Page 120: Genetic programming with clojure.spec and Beyond

The Self Healing Process» If a donor match is found, then redefine the

failing function as new function. Then call the top level report form again, this time using the healed good function.

» Return the result!

Page 121: Genetic programming with clojure.spec and Beyond

Code it up in a function with-healing

Page 122: Genetic programming with clojure.spec and Beyond

Try it out!!

First we call the report function with a non-empty vector.

(healing/with-healing (report [1 2 3 4 5 "a" "b"]));=>"The average is 3"

Page 123: Genetic programming with clojure.spec and Beyond

Now the big test...

Page 124: Genetic programming with clojure.spec and Beyond

(healing/with-healing (report []))

; ERROR in function self-healing.core/calc-average ; Divide by zero -- looking for replacement; Retreiving spec information for function ; {:args :self-healing.core/cleaned-earnings; :ret :self-healing.core/average, :fn nil}; Checking candidates better-calc-average ; adder bad-calc-average bad-calc-average2); ----------

Page 125: Genetic programming with clojure.spec and Beyond

; **Looking at candidate better-calc-average; ****Comparing args :numbers :cleaned-earnings with input [[]]; ****Comparing seed [[1 2 3 4 5]] with new function; ****Result: old 3 new 3; Found a matching candidate replacement;; Replacing with candidate match better-calc-average; ----------; Calling function again; Healed function result is: The average is 0;=>"The average is 0"

Page 126: Genetic programming with clojure.spec and Beyond

Since the function is now healed we can call it again and it won't have the same issue.

(healing/with-healing (report []));=>"The average is 0"

Page 127: Genetic programming with clojure.spec and Beyond

Success!

Page 128: Genetic programming with clojure.spec and Beyond

Self Healing Summary» Very simple - didn't do validation on fn of spec

» Only checked one seed value from exercise but could have done much more - 10 or 100

» We neglected to use the built in feature of spec to check functions that would have found the divide by zero before it happened

Page 129: Genetic programming with clojure.spec and Beyond

Self Healing Summary» clojure.spec rocks

» clojure.spec adds another dimension to how we can solve problems in self-healing

Page 130: Genetic programming with clojure.spec and Beyond

Code is out on Github

» https://github.com/gigasquid/self-healing

» https://github.com/gigasquid/genetic-programming-spec

Page 131: Genetic programming with clojure.spec and Beyond

Taking a Step Back

Page 132: Genetic programming with clojure.spec and Beyond

We've just scratched the surface on how clojure.spec can be used

Page 133: Genetic programming with clojure.spec and Beyond

To All My Fellow Explorers, Alchemists, Wrestlers, and Detectives

Page 134: Genetic programming with clojure.spec and Beyond

Clojure.spec has opened the doors wide to new and exciting areas

Page 135: Genetic programming with clojure.spec and Beyond

Challenge to youClojure.spec + ? = win

Page 136: Genetic programming with clojure.spec and Beyond

Thank you!

Page 137: Genetic programming with clojure.spec and Beyond

Pic Credits

Cardboard Box City

Cat in box

Forest

heart

tribe

evolution

mad scientist

gold

Page 138: Genetic programming with clojure.spec and Beyond

dna

programmer

test drive

cooking


Recommended