Mercurial > cortex
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 |