Fix handling of false boolean input values; continue development of valiant problem

This commit is contained in:
Lee Spector 2020-12-07 20:19:59 -05:00
parent 14f63f880b
commit bb916c2ad3
3 changed files with 207 additions and 291 deletions

View File

@ -1,7 +1,14 @@
(ns propeller.problems.valiant) (ns propeller.problems.valiant
(:require [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter]
[propeller.push.state :as state]))
(defn train-and-test-data (def num-vars 100) ;1000)
[num-vars num-inputs num-train num-test] (def num-inputs 50) ;500)
(def num-train 500) ;5000)
(def num-test 200)
(def train-and-test-data
(let [input-indices (take num-inputs (shuffle (range num-vars))) (let [input-indices (take num-inputs (shuffle (range num-vars)))
rand-vars (fn [] (vec (repeatedly num-vars #(< (rand) 0.5)))) rand-vars (fn [] (vec (repeatedly num-vars #(< (rand) 0.5))))
even-parity? (fn [vars] even-parity? (fn [vars]
@ -16,150 +23,38 @@
:outputs (map even-parity? test-inputs)}})) :outputs (map even-parity? test-inputs)}}))
(def instructions (def instructions
(list :in1 (vec (concat (for [i (range num-inputs)] (keyword (str "in" i)))
:integer_add (take num-inputs
:integer_subtract (cycle [:boolean_and
:integer_mult :boolean_or
:integer_quot :boolean_not
:integer_eq
:exec_dup
:exec_if :exec_if
'close 'close])))))
0
1))
boolean_and boolean_or boolean_not exec_if (defn error-function
([argmap individual]
;============== NOTE NOTE NOTE ================= (error-function argmap individual :train))
; This file has note been updated for Clojush 2.0, and will likely not work ([argmap individual subset]
;============== NOTE NOTE NOTE ================= (let [program (genome/plushy->push (:plushy individual) argmap)
; data (get train-and-test-data subset)
;(ns clojush.problems.boolean.valiant inputs (:inputs data)
; (:use [clojush.pushgp.pushgp] correct-outputs (:outputs data)
; [clojush.pushstate] outputs (map (fn [input]
; [clojush.random] (state/peek-stack
; [clojush.interpreter] (interpreter/interpret-program
; [clojure.math.numeric-tower])) program
; (assoc state/empty-state
;(def numvars 100) ;1000) :input (zipmap (for [i (range (count input))]
;(def numinputs 50) ;500) (keyword (str "in" i)))
;(def numcases 500) ;5000) input))
; (:step-limit argmap))
;(def input-indices :boolean))
; (vec (take numinputs (shuffle (range numvars))))) inputs)
; errors (map #(if (= %1 %2) 0 1)
;(def cases correct-outputs
; (vec (repeatedly numcases outputs)]
; (fn [] (let [vars (vec (repeatedly numvars #(< (lrand) 0.5)))] (assoc individual
; [vars (even? (count (filter #(= % true) :behaviors outputs
; (map #(nth vars %) :errors errors
; input-indices))))]))))) :total-error #?(:clj (apply +' errors)
; :cljs (apply + errors))))))
;(println "input-indices:" input-indices)
;
;;; ugly way to define all of the input instructions, since I haven't fully
;;; grokked Clojure macros
;
;(def n-hack (atom 0))
;
;(defn define-input [n]
; (reset! n-hack n)
; (eval `(define-registered ~(symbol (str "input" @n-hack))
; (fn [state#]
; (push-item (nth (first (:auxiliary state#)) ~(+ @n-hack))
; :boolean
; state#)))))
;
;(dotimes [n numvars] (define-input n))
;
;;; this gives the instructions: (registered-for-type "input")
;
;(defn rp [prog state] (run-push prog state true))
;
;(defn valiant-fitness
; [individual]
; (assoc individual
; :errors
; (doall (for [c (range numcases)]
; (let [[inputs answer] (nth cases c)
; output (->> (make-push-state)
; (push-item inputs :auxiliary)
; (run-push (:program individual))
; ;(rp (:program individual))
; (top-item :boolean))]
; ;(println "output" output "answer" answer)
; (if (= output answer) 0 1))))))
;
;;input-indices
;
;;(reduce + (valiant-fitness '(input1 input4 input0 input7 input9 boolean_and boolean_and boolean_and boolean_and)))
;
;;; oversized-offspring-fail-to-random? -- take fail to random code from here and use right
;;; parameters
;;(in-ns 'clojush.pushgp.genetic-operators)
;;(defn crossover
;; "Returns a copy of parent1 with a random subprogram replaced with a random
;; subprogram of parent2."
;; [parent1 parent2 max-points]
;; (let [new-program (case (lrand-int 2)
;; 0 (insert-code-at-point
;; (:program parent1)
;; (select-node-index (:program parent1))
;; (code-at-point (:program parent2)
;; (select-node-index (:program parent2))))
;; 1 (list (random-code 10 @global-atom-generators) 'exec_if (:program parent1) (:program parent2)))]
;; (if (> (count-points new-program) max-points)
;; ;parent1
;; (make-individual :program (random-code 10 @global-atom-generators) :history (:history parent1)
;; :ancestors (if global-maintain-ancestors
;; (cons (:program parent1) (:ancestors parent1))
;; (:ancestors parent1)))
;; (make-individual :program new-program :history (:history parent1)
;; :ancestors (if global-maintain-ancestors
;; (cons (:program parent1) (:ancestors parent1))
;; (:ancestors parent1))))))
;;(in-ns 'experimental.valiant)
;;;
;;; Probabilistic Pseudo Hillclimbing (persistence)
;;;
;
;;(def argmap
;; {:error-function valiant-fitness
;; :atom-generators (concat (vec (registered-for-type "input"))
;; ;)
;; (apply concat
;; (repeat 25
;; '(boolean_and boolean_or boolean_not exec_if))))
;; :use-lexicase-selection true
;; :max-points 40000
;; :max-genome-size-in-initial-program 10
;; :population-size 100
;; :evalpush-limit 10000
;; :mutation-probability 0.4
;; :mutation-max-points 50
;; ;:crossover-probability 0.4
;; :simplification-probability 0.2
;; :reproduction-simplifications 1
;; ;:deletion-mutation-probability 0.2
;; :boolean-gsxover-probability 0.4
;; :boolean-gsxover-new-code-max-points 10
;; :parent-reversion-probability 0.95
;; ;:decimation-ratio 0.01
;; ;:use-single-thread true
;; })
;
;(def argmap
; {:error-function valiant-fitness
; :atom-generators (concat (vec (registered-for-type "input"))
; ;)
; (apply concat
; (repeat 25
; '(boolean_and boolean_or boolean_not exec_if))))
; :max-points 4000
; :max-genome-size-in-initial-program 100
; :population-size 100
; :evalpush-limit 2000
; :genetic-operator-probabilities {[:alternation :uniform-mutation] 1.0} ;Somewhat equivalent to normal Push's ULTRA operator
; :alignment-deviation 20
; ;:use-single-thread true
; })

View File

@ -16,8 +16,9 @@
;; stack. ;; stack.
(defn handle-input-instruction (defn handle-input-instruction
[state instruction] [state instruction]
(if-let [input (instruction (:input state))] (if (contains? (:input state) instruction)
(state/push-to-stack state :exec input) (let [input (instruction (:input state))]
(state/push-to-stack state :exec input))
(throw #?(:clj (Exception. (str "Undefined instruction " instruction)) (throw #?(:clj (Exception. (str "Undefined instruction " instruction))
:cljs (js/Error :cljs (js/Error
(str "Undefined instruction " instruction)))))) (str "Undefined instruction " instruction))))))

View File

@ -5,150 +5,170 @@
[propeller.variation :as variation] [propeller.variation :as variation]
[propeller.problems.simple-regression :as regression] [propeller.problems.simple-regression :as regression]
[propeller.problems.string-classification :as string-classif] [propeller.problems.string-classification :as string-classif]
propeller.problems.valiant
[propeller.push.core :as push] [propeller.push.core :as push]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
[propeller.push.state :as state] [propeller.push.state :as state]
[propeller.push.utils.helpers :refer [get-stack-instructions]])) [propeller.push.utils.helpers :refer [get-stack-instructions]]))
#_(interpreter/interpret-program ;#_(interpreter/interpret-program
'(1 2 :integer_add) state/empty-state 1000) ; '(1 2 :integer_add) state/empty-state 1000)
;
#_(interpreter/interpret-program ;#_(interpreter/interpret-program
'(3 3 :integer_eq :exec_if (1 "yes") (2 "no")) ; '(3 3 :integer_eq :exec_if (1 "yes") (2 "no"))
state/empty-state ; state/empty-state
1000) ; 1000)
;
#_(interpreter/interpret-program ;#_(interpreter/interpret-program
'(:in1 :string_reverse 1 :string_take "?" :string_eq :exec_if ; '(:in1 :string_reverse 1 :string_take "?" :string_eq :exec_if
(:in1 " I am asking." :string_concat) ; (:in1 " I am asking." :string_concat)
(:in1 " I am saying." :string_concat)) ; (:in1 " I am saying." :string_concat))
(assoc state/empty-state :input {:in1 "Can you hear me?"}) ; (assoc state/empty-state :input {:in1 "Can you hear me?"})
1000) ; 1000)
;
#_(interpreter/interpret-program ;#_(interpreter/interpret-program
'(:in1 :string_reverse 1 :string_take "?" :string_eq :exec_if ; '(:in1 :string_reverse 1 :string_take "?" :string_eq :exec_if
(:in1 " I am asking." :string_concat) ; (:in1 " I am asking." :string_concat)
(:in1 " I am saying." :string_concat)) ; (:in1 " I am saying." :string_concat))
(assoc state/empty-state :input {:in1 "I can hear you."}) ; (assoc state/empty-state :input {:in1 "I can hear you."})
1000) ; 1000)
;
#_(genome/plushy->push ;#_(genome/plushy->push
(genome/make-random-plushy (get-stack-instructions #{:float :integer :exec :boolean}) 20)) ; (genome/make-random-plushy (get-stack-instructions #{:float :integer :exec :boolean}) 20))
;
#_(gp/gp {:instructions propeller.problems.software.number-io/instructions ;#_(gp/gp {:instructions propeller.problems.software.number-io/instructions
:error-function propeller.problems.software.number-io/error-function ; :error-function propeller.problems.software.number-io/error-function
:max-generations 500 ; :max-generations 500
:population-size 500 ; :population-size 500
:max-initial-plushy-size 100 ; :max-initial-plushy-size 100
:step-limit 200 ; :step-limit 200
:parent-selection :lexicase ; :parent-selection :lexicase
:tournament-size 5 ; :tournament-size 5
:umad-rate 0.1 ; :umad-rate 0.1
:variation {:umad 0.5 :crossover 0.5} ; :variation {:umad 0.5 :crossover 0.5}
:elitism false}) ; :elitism false})
;
#_(gp/gp {:instructions propeller.problems.simple-regression/instructions ;#_(gp/gp {:instructions propeller.problems.simple-regression/instructions
:error-function propeller.problems.simple-regression/error-function ; :error-function propeller.problems.simple-regression/error-function
:max-generations 500 ; :max-generations 500
:population-size 500 ; :population-size 500
:max-initial-plushy-size 100 ; :max-initial-plushy-size 100
:step-limit 200 ; :step-limit 200
:parent-selection :tournament ; :parent-selection :tournament
:tournament-size 5 ; :tournament-size 5
:umad-rate 0.01 ; :umad-rate 0.01
:variation {:umad 1.0 ; :variation {:umad 1.0
:crossover 0.0} ; :crossover 0.0}
:elitism false}) ; :elitism false})
;
#_(gp/gp {:instructions propeller.problems.simple-regression/instructions ;#_(gp/gp {:instructions propeller.problems.simple-regression/instructions
:error-function propeller.problems.simple-regression/error-function ; :error-function propeller.problems.simple-regression/error-function
:max-generations 500 ; :max-generations 500
:population-size 500 ; :population-size 500
:max-initial-plushy-size 100 ; :max-initial-plushy-size 100
:step-limit 200 ; :step-limit 200
:parent-selection :tournament ; :parent-selection :tournament
:tournament-size 5 ; :tournament-size 5
:umad-rate 0.1 ; :umad-rate 0.1
:variation {:umad 1.0 ; :variation {:umad 1.0
:crossover 0.0} ; :crossover 0.0}
:elitism false}) ; :elitism false})
;
;
#_(gp/gp {:instructions propeller.problems.simple-regression/instructions ;#_(gp/gp {:instructions propeller.problems.simple-regression/instructions
:error-function propeller.problems.simple-regression/error-function ; :error-function propeller.problems.simple-regression/error-function
:max-generations 500 ; :max-generations 500
:population-size 500 ; :population-size 500
:max-initial-plushy-size 100 ; :max-initial-plushy-size 100
:step-limit 200 ; :step-limit 200
:parent-selection :lexicase ; :parent-selection :lexicase
:tournament-size 5 ; :tournament-size 5
:umad-rate 0.1 ; :umad-rate 0.1
:variation {:umad 1.0 ; :variation {:umad 1.0
:crossover 0.0} ; :crossover 0.0}
:elitism false}) ; :elitism false})
;
#_(gp/gp {:instructions propeller.problems.simple-regression/instructions ;#_(gp/gp {:instructions propeller.problems.simple-regression/instructions
:error-function propeller.problems.simple-regression/error-function ; :error-function propeller.problems.simple-regression/error-function
:max-generations 500 ; :max-generations 500
:population-size 500 ; :population-size 500
:max-initial-plushy-size 100 ; :max-initial-plushy-size 100
:step-limit 200 ; :step-limit 200
:parent-selection :lexicase ; :parent-selection :lexicase
:tournament-size 5 ; :tournament-size 5
:umad-rate 0.1 ; :umad-rate 0.1
:diploid-flip-rate 0.1 ; :diploid-flip-rate 0.1
:variation {:umad 0.8 ; :variation {:umad 0.8
:diploid-flip 0.2} ; :diploid-flip 0.2}
:elitism false ; :elitism false
:diploid true}) ; :diploid true})
;
;
#_(gp/gp {:instructions propeller.problems.software.smallest/instructions ;#_(gp/gp {:instructions propeller.problems.software.smallest/instructions
:error-function propeller.problems.software.smallest/error-function ; :error-function propeller.problems.software.smallest/error-function
:max-generations 500 ; :max-generations 500
:population-size 500 ; :population-size 500
:max-initial-plushy-size 100 ; :max-initial-plushy-size 100
:step-limit 200 ; :step-limit 200
:parent-selection :lexicase ; :parent-selection :lexicase
:tournament-size 5 ; :tournament-size 5
:umad-rate 0.1 ; :umad-rate 0.1
:diploid-flip-rate 0.1 ; :diploid-flip-rate 0.1
:variation {;:umad 0.8 ; :variation {;:umad 0.8
;:diploid-flip 0.2 ; ;:diploid-flip 0.2
:umad 1
}
:elitism false
:diploid false})
#_(gp/gp {:instructions propeller.problems.software.smallest/instructions
:error-function propeller.problems.software.smallest/error-function
:max-generations 500
:population-size 500
:max-initial-plushy-size 200 ;100
:step-limit 200
:parent-selection :lexicase
:tournament-size 5
:umad-rate 0.1
:diploid-flip-rate 0.1
:variation {:umad 0.8
:diploid-flip 0.2
; :umad 1 ; :umad 1
; }
; :elitism false
; :diploid false})
;
;#_(gp/gp {:instructions propeller.problems.software.smallest/instructions
; :error-function propeller.problems.software.smallest/error-function
; :max-generations 500
; :population-size 500
; :max-initial-plushy-size 200 ;100
; :step-limit 200
; :parent-selection :lexicase
; :tournament-size 5
; :umad-rate 0.1
; :diploid-flip-rate 0.1
; :variation {:umad 0.8
; :diploid-flip 0.2
; ;:umad 1
; }
; :elitism false
; :diploid true})
;
;
;(gp/gp {:instructions propeller.problems.string-classification/instructions
; :error-function propeller.problems.string-classification/error-function
; :max-generations 500
; :population-size 500
; :max-initial-plushy-size 100
; :step-limit 200
; :parent-selection :lexicase
; :tournament-size 5
; :umad-rate 0.1
; :diploid-flip-rate 0.1
; :variation {:umad 0.8
; :diploid-flip 0.2
; }
; :elitism false
; :diploid true})
(gp/gp {:instructions propeller.problems.valiant/instructions
:error-function propeller.problems.valiant/error-function
:max-generations 500
:population-size 500
:max-initial-plushy-size 1000
:step-limit 2000
:parent-selection :lexicase
:tournament-size 5
:umad-rate 0.001
:diploid-flip-rate 0.001
:variation {:umad 0.5
:diploid-flip 0.5
} }
:elitism false :elitism false
:diploid true}) :diploid true})
#_(gp/gp {:instructions propeller.problems.string-classification/instructions
:error-function propeller.problems.string-classification/error-function
:max-generations 500
:population-size 500
:max-initial-plushy-size 100
:step-limit 200
:parent-selection :lexicase
:tournament-size 5
:umad-rate 0.1
:diploid-flip-rate 0.1
:variation {:umad 0.8
:diploid-flip 0.2
}
:elitism false
:diploid true})