comparison thesis/cortex.org @ 452:f339e3d5cc8c

finish draft of chapter 3.
author Robert McIntyre <rlm@mit.edu>
date Wed, 26 Mar 2014 22:17:42 -0400
parents 0a4362d1f138
children 6db37c4aa1ee
comparison
equal deleted inserted replaced
451:0a4362d1f138 452:f339e3d5cc8c
209 #+caption: Body-centerd actions are best expressed in a body-centered 209 #+caption: Body-centerd actions are best expressed in a body-centered
210 #+caption: language. This code detects when the worm has curled into a 210 #+caption: language. This code detects when the worm has curled into a
211 #+caption: full circle. Imagine how you would replicate this functionality 211 #+caption: full circle. Imagine how you would replicate this functionality
212 #+caption: using low-level pixel features such as HOG filters! 212 #+caption: using low-level pixel features such as HOG filters!
213 #+name: grand-circle-intro 213 #+name: grand-circle-intro
214 #+begin_listing clojure 214 #+attr_latex: [htpb]
215 #+begin_listing clojure
215 #+begin_src clojure 216 #+begin_src clojure
216 (defn grand-circle? 217 (defn grand-circle?
217 "Does the worm form a majestic circle (one end touching the other)?" 218 "Does the worm form a majestic circle (one end touching the other)?"
218 [experiences] 219 [experiences]
219 (and (curled? experiences) 220 (and (curled? experiences)
398 :touch (touch! model) 399 :touch (touch! model)
399 :proprioception (proprioception! model) 400 :proprioception (proprioception! model)
400 :muscles (movement! model)})) 401 :muscles (movement! model)}))
401 #+end_src 402 #+end_src
402 #+end_listing 403 #+end_listing
403 404
404 ** Embodiment factors action recognition into managable parts 405 ** Embodiment factors action recognition into managable parts
405 406
406 Using empathy, I divide the problem of action recognition into a 407 Using empathy, I divide the problem of action recognition into a
407 recognition process expressed in the language of a full compliment 408 recognition process expressed in the language of a full compliment
408 of senses, and an imaganitive process that generates full sensory 409 of senses, and an imaganitive process that generates full sensory
434 #+caption: of sensory experience, and only uses proprioceptive data. Even 435 #+caption: of sensory experience, and only uses proprioceptive data. Even
435 #+caption: this simple predicate, however, is automatically frame 436 #+caption: this simple predicate, however, is automatically frame
436 #+caption: independent and ignores vermopomorphic differences such as 437 #+caption: independent and ignores vermopomorphic differences such as
437 #+caption: worm textures and colors. 438 #+caption: worm textures and colors.
438 #+name: curled 439 #+name: curled
439 #+begin_listing clojure 440 #+attr_latex: [htpb]
441 #+begin_listing clojure
440 #+begin_src clojure 442 #+begin_src clojure
441 (defn curled? 443 (defn curled?
442 "Is the worm curled up?" 444 "Is the worm curled up?"
443 [experiences] 445 [experiences]
444 (every? 446 (every?
449 #+end_listing 451 #+end_listing
450 452
451 #+caption: Program for summarizing the touch information in a patch 453 #+caption: Program for summarizing the touch information in a patch
452 #+caption: of skin. 454 #+caption: of skin.
453 #+name: touch-summary 455 #+name: touch-summary
454 #+begin_listing clojure 456 #+attr_latex: [htpb]
457
458 #+begin_listing clojure
455 #+begin_src clojure 459 #+begin_src clojure
456 (defn contact 460 (defn contact
457 "Determine how much contact a particular worm segment has with 461 "Determine how much contact a particular worm segment has with
458 other objects. Returns a value between 0 and 1, where 1 is full 462 other objects. Returns a value between 0 and 1, where 1 is full
459 contact and 0 is no contact." 463 contact and 0 is no contact."
474 #+caption: uses a summary of the tactile information from the underbelly 478 #+caption: uses a summary of the tactile information from the underbelly
475 #+caption: of the worm, and is only true if every segment is touching the 479 #+caption: of the worm, and is only true if every segment is touching the
476 #+caption: floor. Note that this function contains no references to 480 #+caption: floor. Note that this function contains no references to
477 #+caption: proprioction at all. 481 #+caption: proprioction at all.
478 #+name: resting 482 #+name: resting
479 #+begin_listing clojure 483 #+attr_latex: [htpb]
484 #+begin_listing clojure
480 #+begin_src clojure 485 #+begin_src clojure
481 (def worm-segment-bottom (rect-region [8 15] [14 22])) 486 (def worm-segment-bottom (rect-region [8 15] [14 22]))
482 487
483 (defn resting? 488 (defn resting?
484 "Is the worm resting on the ground?" 489 "Is the worm resting on the ground?"
493 #+caption: Program for detecting whether the worm is curled up into a 498 #+caption: Program for detecting whether the worm is curled up into a
494 #+caption: full circle. Here the embodied approach begins to shine, as 499 #+caption: full circle. Here the embodied approach begins to shine, as
495 #+caption: I am able to both use a previous action predicate (=curled?=) 500 #+caption: I am able to both use a previous action predicate (=curled?=)
496 #+caption: as well as the direct tactile experience of the head and tail. 501 #+caption: as well as the direct tactile experience of the head and tail.
497 #+name: grand-circle 502 #+name: grand-circle
498 #+begin_listing clojure 503 #+attr_latex: [htpb]
504 #+begin_listing clojure
499 #+begin_src clojure 505 #+begin_src clojure
500 (def worm-segment-bottom-tip (rect-region [15 15] [22 22])) 506 (def worm-segment-bottom-tip (rect-region [15 15] [22 22]))
501 507
502 (def worm-segment-top-tip (rect-region [0 15] [7 22])) 508 (def worm-segment-top-tip (rect-region [0 15] [7 22]))
503 509
523 #+caption: wiggling this way also gives the worm an opportunity to learn 529 #+caption: wiggling this way also gives the worm an opportunity to learn
524 #+caption: and recognize ``frustrated wiggling'', where the worm tries to 530 #+caption: and recognize ``frustrated wiggling'', where the worm tries to
525 #+caption: wiggle but can't. Frustrated wiggling is very visually different 531 #+caption: wiggle but can't. Frustrated wiggling is very visually different
526 #+caption: from actual wiggling, but this definition gives it to us for free. 532 #+caption: from actual wiggling, but this definition gives it to us for free.
527 #+name: wiggling 533 #+name: wiggling
528 #+begin_listing clojure 534 #+attr_latex: [htpb]
535 #+begin_listing clojure
529 #+begin_src clojure 536 #+begin_src clojure
530 (defn fft [nums] 537 (defn fft [nums]
531 (map 538 (map
532 #(.getReal %) 539 #(.getReal %)
533 (.transform 540 (.transform
563 all the worm's senses. 570 all the worm's senses.
564 571
565 #+caption: Use the action predicates defined earlier to report on 572 #+caption: Use the action predicates defined earlier to report on
566 #+caption: what the worm is doing while in simulation. 573 #+caption: what the worm is doing while in simulation.
567 #+name: report-worm-activity 574 #+name: report-worm-activity
568 #+begin_listing clojure 575 #+attr_latex: [htpb]
576 #+begin_listing clojure
569 #+begin_src clojure 577 #+begin_src clojure
570 (defn debug-experience 578 (defn debug-experience
571 [experiences text] 579 [experiences text]
572 (cond 580 (cond
573 (grand-circle? experiences) (.setText text "Grand Circle") 581 (grand-circle? experiences) (.setText text "Grand Circle")
681 mistake. 689 mistake.
682 690
683 #+caption: Program to convert an experience vector into a 691 #+caption: Program to convert an experience vector into a
684 #+caption: proprioceptively binned lookup function. 692 #+caption: proprioceptively binned lookup function.
685 #+name: bin 693 #+name: bin
686 #+begin_listing clojure 694 #+attr_latex: [htpb]
695 #+begin_listing clojure
687 #+begin_src clojure 696 #+begin_src clojure
688 (defn bin [digits] 697 (defn bin [digits]
689 (fn [angles] 698 (fn [angles]
690 (->> angles 699 (->> angles
691 (flatten) 700 (flatten)
739 748
740 #+caption: Program to calculate empathy by tracing though \Phi-space 749 #+caption: Program to calculate empathy by tracing though \Phi-space
741 #+caption: and finding the longest (ie. most coherent) interpretation 750 #+caption: and finding the longest (ie. most coherent) interpretation
742 #+caption: of the data. 751 #+caption: of the data.
743 #+name: longest-thread 752 #+name: longest-thread
744 #+begin_listing clojure 753 #+attr_latex: [htpb]
754 #+begin_listing clojure
745 #+begin_src clojure 755 #+begin_src clojure
746 (defn longest-thread 756 (defn longest-thread
747 "Find the longest thread from phi-index-sets. The index sets should 757 "Find the longest thread from phi-index-sets. The index sets should
748 be ordered from most recent to least recent." 758 be ordered from most recent to least recent."
749 [phi-index-sets] 759 [phi-index-sets]
781 fill in the gaps. 791 fill in the gaps.
782 792
783 #+caption: Fill in blanks in sensory experience by replicating the most 793 #+caption: Fill in blanks in sensory experience by replicating the most
784 #+caption: recent experience. 794 #+caption: recent experience.
785 #+name: infer-nils 795 #+name: infer-nils
786 #+begin_listing clojure 796 #+attr_latex: [htpb]
797 #+begin_listing clojure
787 #+begin_src clojure 798 #+begin_src clojure
788 (defn infer-nils 799 (defn infer-nils
789 "Replace nils with the next available non-nil element in the 800 "Replace nils with the next available non-nil element in the
790 sequence, or barring that, 0." 801 sequence, or barring that, 0."
791 [s] 802 [s]
802 813
803 ** Efficient action recognition with =EMPATH= 814 ** Efficient action recognition with =EMPATH=
804 815
805 To use =EMPATH= with the worm, I first need to gather a set of 816 To use =EMPATH= with the worm, I first need to gather a set of
806 experiences from the worm that includes the actions I want to 817 experiences from the worm that includes the actions I want to
807 recognize. The =generate-phi-space= program (listint 818 recognize. The =generate-phi-space= program (listing
808 \ref{generate-phi-space} runs the worm through a series of 819 \ref{generate-phi-space} runs the worm through a series of
809 exercices and gatheres those experiences into a vector. The 820 exercices and gatheres those experiences into a vector. The
810 =do-all-the-things= program is a routine expressed in a simple 821 =do-all-the-things= program is a routine expressed in a simple
811 muscle contraction script language for automated worm control. 822 muscle contraction script language for automated worm control. It
823 causes the worm to rest, curl, and wiggle over about 700 frames
824 (approx. 11 seconds).
812 825
813 #+caption: Program to gather the worm's experiences into a vector for 826 #+caption: Program to gather the worm's experiences into a vector for
814 #+caption: further processing. The =motor-control-program= line uses 827 #+caption: further processing. The =motor-control-program= line uses
815 #+caption: a motor control script that causes the worm to execute a series 828 #+caption: a motor control script that causes the worm to execute a series
816 #+caption: of ``exercices'' that include all the action predicates. 829 #+caption: of ``exercices'' that include all the action predicates.
817 #+name: generate-phi-space 830 #+name: generate-phi-space
818 #+attr_latex: [!H] 831 #+attr_latex: [htpb]
819 #+begin_listing clojure 832 #+begin_listing clojure
820 #+begin_src clojure 833 #+begin_src clojure
821 (def do-all-the-things 834 (def do-all-the-things
822 (concat 835 (concat
823 curl-script 836 curl-script
824 [[300 :d-ex 40] 837 [[300 :d-ex 40]
841 #+end_listing 854 #+end_listing
842 855
843 #+caption: Use longest thread and a phi-space generated from a short 856 #+caption: Use longest thread and a phi-space generated from a short
844 #+caption: exercise routine to interpret actions during free play. 857 #+caption: exercise routine to interpret actions during free play.
845 #+name: empathy-debug 858 #+name: empathy-debug
846 #+begin_listing clojure 859 #+attr_latex: [htpb]
860 #+begin_listing clojure
847 #+begin_src clojure 861 #+begin_src clojure
848 (defn init [] 862 (defn init []
849 (def phi-space (generate-phi-space)) 863 (def phi-space (generate-phi-space))
850 (def phi-scan (gen-phi-scan phi-space))) 864 (def phi-scan (gen-phi-scan phi-space)))
851 865
889 action predicates as the real sensory experience. 903 action predicates as the real sensory experience.
890 904
891 #+caption: Determine how closely empathy approximates actual 905 #+caption: Determine how closely empathy approximates actual
892 #+caption: sensory data. 906 #+caption: sensory data.
893 #+name: test-empathy-accuracy 907 #+name: test-empathy-accuracy
894 #+begin_listing clojure 908 #+attr_latex: [htpb]
909 #+begin_listing clojure
895 #+begin_src clojure 910 #+begin_src clojure
896 (def worm-action-label 911 (def worm-action-label
897 (juxt grand-circle? curled? wiggling?)) 912 (juxt grand-circle? curled? wiggling?))
898 913
899 (defn compare-empathy-with-baseline [matches] 914 (defn compare-empathy-with-baseline [matches]
929 73%. This is based on very limited worm experience. By training the 944 73%. This is based on very limited worm experience. By training the
930 worm for longer, the accuracy dramatically improves. 945 worm for longer, the accuracy dramatically improves.
931 946
932 #+caption: Program to generate \Phi-space using manual training. 947 #+caption: Program to generate \Phi-space using manual training.
933 #+name: manual-phi-space 948 #+name: manual-phi-space
949 #+attr_latex: [htpb]
934 #+begin_listing clojure 950 #+begin_listing clojure
935 #+begin_src clojure 951 #+begin_src clojure
936 (defn init-interactive [] 952 (defn init-interactive []
937 (def phi-space 953 (def phi-space
938 (let [experiences (atom [])] 954 (let [experiences (atom [])]
947 #+end_src 963 #+end_src
948 #+end_listing 964 #+end_listing
949 965
950 After about 1 minute of manual training, I was able to achieve 95% 966 After about 1 minute of manual training, I was able to achieve 95%
951 accuracy on manual testing of the worm using =init-interactive= and 967 accuracy on manual testing of the worm using =init-interactive= and
952 =test-empathy-accuracy=. The ability of the system to infer sensory 968 =test-empathy-accuracy=. The majority of errors are near the
953 states is truly impressive. 969 boundaries of transitioning from one type of action to another.
970 During these transitions the exact label for the action is more open
971 to interpretation, and dissaggrement between empathy and experience
972 is more excusable.
954 973
955 ** Digression: bootstrapping touch using free exploration 974 ** Digression: bootstrapping touch using free exploration
975
976 In the previous section I showed how to compute actions in terms of
977 body-centered predicates which relied averate touch activation of
978 pre-defined regions of the worm's skin. What if, instead of recieving
979 touch pre-grouped into the six faces of each worm segment, the true
980 topology of the worm's skin was unknown? This is more similiar to how
981 a nerve fiber bundle might be arranged. While two fibers that are
982 close in a nerve bundle /might/ correspond to two touch sensors that
983 are close together on the skin, the process of taking a complicated
984 surface and forcing it into essentially a circle requires some cuts
985 and rerragenments.
986
987 In this section I show how to automatically learn the skin-topology of
988 a worm segment by free exploration. As the worm rolls around on the
989 floor, large sections of its surface get activated. If the worm has
990 stopped moving, then whatever region of skin that is touching the
991 floor is probably an important region, and should be recorded.
992
993 #+caption: Program to detect whether the worm is in a resting state
994 #+caption: with one face touching the floor.
995 #+name: pure-touch
996 #+begin_listing clojure
997 #+begin_src clojure
998 (def full-contact [(float 0.0) (float 0.1)])
999
1000 (defn pure-touch?
1001 "This is worm specific code to determine if a large region of touch
1002 sensors is either all on or all off."
1003 [[coords touch :as touch-data]]
1004 (= (set (map first touch)) (set full-contact)))
1005 #+end_src
1006 #+end_listing
1007
1008 After collecting these important regions, there will many nearly
1009 similiar touch regions. While for some purposes the subtle
1010 differences between these regions will be important, for my
1011 purposes I colapse them into mostly non-overlapping sets using
1012 =remove-similiar= in listing \ref{remove-similiar}
1013
1014 #+caption: Program to take a lits of set of points and ``collapse them''
1015 #+caption: so that the remaining sets in the list are siginificantly
1016 #+caption: different from each other. Prefer smaller sets to larger ones.
1017 #+name: remove-similiar
1018 #+begin_listing clojure
1019 #+begin_src clojure
1020 (defn remove-similar
1021 [coll]
1022 (loop [result () coll (sort-by (comp - count) coll)]
1023 (if (empty? coll) result
1024 (let [[x & xs] coll
1025 c (count x)]
1026 (if (some
1027 (fn [other-set]
1028 (let [oc (count other-set)]
1029 (< (- (count (union other-set x)) c) (* oc 0.1))))
1030 xs)
1031 (recur result xs)
1032 (recur (cons x result) xs))))))
1033 #+end_src
1034 #+end_listing
1035
1036 Actually running this simulation is easy given =CORTEX='s facilities.
1037
1038 #+caption: Collect experiences while the worm moves around. Filter the touch
1039 #+caption: sensations by stable ones, collapse similiar ones together,
1040 #+caption: and report the regions learned.
1041 #+name: learn-touch
1042 #+begin_listing clojure
1043 #+begin_src clojure
1044 (defn learn-touch-regions []
1045 (let [experiences (atom [])
1046 world (apply-map
1047 worm-world
1048 (assoc (worm-segment-defaults)
1049 :experiences experiences))]
1050 (run-world world)
1051 (->>
1052 @experiences
1053 (drop 175)
1054 ;; access the single segment's touch data
1055 (map (comp first :touch))
1056 ;; only deal with "pure" touch data to determine surfaces
1057 (filter pure-touch?)
1058 ;; associate coordinates with touch values
1059 (map (partial apply zipmap))
1060 ;; select those regions where contact is being made
1061 (map (partial group-by second))
1062 (map #(get % full-contact))
1063 (map (partial map first))
1064 ;; remove redundant/subset regions
1065 (map set)
1066 remove-similar)))
1067
1068 (defn learn-and-view-touch-regions []
1069 (map view-touch-region
1070 (learn-touch-regions)))
1071 #+end_src
1072 #+end_listing
1073
1074 The only thing remining to define is the particular motion the worm
1075 must take. I accomplish this with a simple motor control program.
1076
1077 #+caption: Motor control program for making the worm roll on the ground.
1078 #+caption: This could also be replaced with random motion.
1079 #+name: worm-roll
1080 #+begin_listing clojure
1081 #+begin_src clojure
1082 (defn touch-kinesthetics []
1083 [[170 :lift-1 40]
1084 [190 :lift-1 19]
1085 [206 :lift-1 0]
1086
1087 [400 :lift-2 40]
1088 [410 :lift-2 0]
1089
1090 [570 :lift-2 40]
1091 [590 :lift-2 21]
1092 [606 :lift-2 0]
1093
1094 [800 :lift-1 30]
1095 [809 :lift-1 0]
1096
1097 [900 :roll-2 40]
1098 [905 :roll-2 20]
1099 [910 :roll-2 0]
1100
1101 [1000 :roll-2 40]
1102 [1005 :roll-2 20]
1103 [1010 :roll-2 0]
1104
1105 [1100 :roll-2 40]
1106 [1105 :roll-2 20]
1107 [1110 :roll-2 0]
1108 ])
1109 #+end_src
1110 #+end_listing
1111
1112
1113 #+caption: The small worm rolls around on the floor, driven
1114 #+caption: by the motor control program in listing \ref{worm-roll}.
1115 #+name: worm-roll
1116 #+ATTR_LaTeX: :width 12cm
1117 [[./images/worm-roll.png]]
1118
1119
1120 #+caption: After completing its adventures, the worm now knows
1121 #+caption: how its touch sensors are arranged along its skin. These
1122 #+caption: are the regions that were deemed important by
1123 #+caption: =learn-touch-regions=. Note that the worm has discovered
1124 #+caption: that it has six sides.
1125 #+name: worm-touch-map
1126 #+ATTR_LaTeX: :width 12cm
1127 [[./images/touch-learn.png]]
1128
1129 While simple, =learn-touch-regions= exploits regularities in both
1130 the worm's physiology and the worm's environment to correctly
1131 deduce that the worm has six sides. Note that =learn-touch-regions=
1132 would work just as well even if the worm's touch sense data were
1133 completely scrambled. The cross shape is just for convienence. This
1134 example justifies the use of pre-defined touch regions in =EMPATH=.
956 1135
957 * Contributions 1136 * Contributions
958 1137
959 1138
960 1139