Harrison, A.M., & Trafton, J.G. (2009) Gaze-following and awareness of another’s perspective in chimpanzees. 10th International Conference on Cognitive Modeling.
Cognitive Science and Traditional AI
I just finished a little article on the motivation and methods of dumbing down game AIs. It’s particularly interesting in that it makes for a good case in point regarding how cognitive science and traditional AI differ.
The article starts off by commenting on the challenges of less-than-perfect AIs, which is interesting in its own right. Traditional AI is often concerned with the optimal, deterministic, and efficient solutions to a given scenario. As a cognitive psychologist, I’m more concerned with the solution that best matches human performance. And it is this focus on human-like performance that dumbing down the AIs is all about.
The first possible resolution presented (and summarily dismissed) is to reduce the amount of computation performed. This rarely works as it results in completely idiotic behavior that even novices would be loath to exhibit. From a cognitive modeling standpoint, novice/expert distinctions are primarily represented as knowledge base, skill, and learning differences - but the total computational time is relatively unaffected. Novices are novices not because they can’t think as long and as hard about a problem, but because they lack the relevant strategies, experience, and learned optimizations.
Instead, the author argues, AIs should “throw the game” in a subtle but significant way (i.e. make a simple mistake at a pivotal point). This is actually fairly easy to do assuming you have an adequate representation of the scenario, and computer games are virtually always blessed with omniscience. What’s most interesting is that this is effectively scaffolding in the Vygotskian sense, with the AI opponent acting as a guide in the player’s skill development. If the AI is aware of the skill-level of the player (and not in the gross easy/medium/hard sense), perhaps through a model tracing mechanism, it can tune its behavior dynamically to provide just enough challenge. A technique that has been used in cognitive tutors for quite some time now.
The author also points out the utility (and failings) of reducing the accuracy of the AI’s information. This particular issue has always stuck in my craw as a gamer and as a psychologist. Perfect information is an illusion that can only exist in low-fidelity approximations of a system. Ratchet up that fidelity and the inherent noise in the system starts to become evident. Humans are quite at home with uncertainty (or we just ignore it entirely at the perceptual level). One of the easiest ways to dumb down an AI is to give it the same limitations that we have, but don’t impose new artificial limitations. It’s not about probabilistically ignoring the opponent’s last move, but rather not letting it see past the fog of war in the first place. Don’t add small random noise to the pool shot trajectory, rather make it line up the shot as we do, with perceptual tricks & extrapolated imaginal geometries.
Cognitive science would dumb down the AI not by introducing noise, clever game throwing, or similar crippling, but by introducing the same limitations that humans possess. The limitations of perception, action, memory, attention, and skill are what make us the adaptable agents that we are. All of this is just as a point of comparison. Cognitive modeling is still more research than application (with some notable exceptions). However, I can see a near-term future where game developers focus on developing human-like opponents not through clever programming, but through an actual focus on how the human actually plays.
ACT-R’s manual-motor system (derived from EPIC) is really starting to show its limitation as we push on it within the embodied robotics domain. I’ve commented elsewhere regarding the a more general implementation of a motor system (not just hands), but that has been falling short. While the future certainly holds radical changes for the perceptual/motor systems, there is still the need for short-term fixes that don’t radically change the architecture.
One such fix that I’ve been playing with recently has been compound motor commands. In jACT-R (and ACT-R proper), motor commands are described by the motor/manual module and their execution is handled by the underlying device. This limits the modeler to those commands and they must be managed at the production level. Typically this requires some measure of goal involvement, as reflex-style productions (i.e. no goal, imaginal, or retrieval) often don’t carry sufficient information to evaluate their appropriateness. Compound motor commands address this by allowing modelers to define their own motor commands that delegate to the primitive commands available. These compound commands can be added to the motor buffer (which will actually contain them), allowing reflex-style productions to merely match the contents of the motor buffer to control the flow of motor execution.
Pursue-command
The following compound command takes a configural identifier, which allows it to reference a specific spatial representation in the configural buffer. It uses this information to direct turn and walk commands (provided by PlayerStageInterface) in order to approach the target.
(chunk-type pursue-target-command (:include compound-motor-command)
( configural-id nil ) ;; who’s our target
( distance-tolerance 0.2 );; get w/in 20cm of target
( angular-tolerance 5 ) ;; get the target w/in 10 deg arc
( state busy ) ;; command, not module state
( remove-on-complete t ) ;; when complete -motor
( no-configural-is-error nil )) ;;empty configural buffer should be an error
There are then seven simple reflex-style productions that turn and move the model towards the target. That set even includes an error recovery (which is incredibly important if you’re actually acting in an environment):
(p pursue-target-attempt-recovery
=motor>
isa pursue-target-command
?motor>
state error ;; module, not command
==>
=motor>
state error ;; command, not module
+motor>
isa walk
distance -0.25 ;;jump back
)
This reusable compound command and its productions are used in multiple models by merely making a +motor request after verifying that the motor buffer is empty and free:
(p pursuit-attend-succeeded-match
=goal>
isa pursue
step searching
target =target
=visual>
isa visual-object
token =target
=configural>
isa configural
identifier =target
center-bearing =bearing
?motor>
- state busy
buffer empty
==>
+motor>
isa pursue-target-command
configural-id =target
=configural>
=visual>
+goal>
isa forage
)
This mechanism carries with it a handful of useful characteristics beyond giving modelers a higher-level of motor control and abstraction.
Perception-Action Loops
With the exception of the mouse movement command, all motor commands in ACT-R are decoupled from perception. At the lowest level this is a good thing (albeit a challenge: using radians to control key targets for fingers?). However, there is ample evidence that perception and action are tightly coupled. The previous example establishes an explicit link between a to-be-monitored percept and an action. A similar mechanism could be used for the monitoring used to control steering in driving. I’m currently working on similar commands to keep our new robots continuously fixated on the object of visual-attention, complete with moving eyes, head, and body. When our visual system is able to recognize the robot’s own hands, guided reaching becomes a difference reduction problem between the hand’s and target’s spatial representations.
Parameterized commands
The previous example uses two slot-based parameters to control the execution of the compound command. To the extent that they are propagated to the underlying primitive commands, ACT-R’s underlying learning mechanisms present possible avenues for a model to move from motor babbling to more precise control.
Further Separation of Concerns
One of my underlying principles in modeling is to separate out concerns. One aspect of this is trimming productions and goal states to their bare minimum, permitting greater composition of subsequent productions. Another aspect is the generalization of model components to maximize reuse. Compound commands permit the motor system to access limited state information (i.e. what spatial percept to track), offloading it from the goal or task state structures, simultaneously simplifying and increasing reusability.
This quick modification has dramatically simplified our modeling in complex, embodied environments. It is, in principle, consistent with canonical ACT-R. The only change necessary is to allow the motor buffer to contain a chunk (as it currently does not). In terms of short-term fixes, this has some serious bang-for-the-buck.
This change has already been made in the current release of jACT-R, should anyone want to play with them.
Kennedy, W.G., Bugajska, M.D., Harrison, A.M., & Trafton, J.G. (2009) “Like-me” Simulation as an Effective and Cognitively Plausible Basis for Social Robotics. International journal of social robotics. (Paper)
The past month has seen me up to my eye-balls in spatial modeling. I’ve been blasting out models and exploring parameter spaces. I’ve been doing all of this to get an ACT-R/S paper out the door (crazy, I know). I’ve got a single model that can accomplish two different spatial tasks across two different experiments. However, fitting the two simultaneously looks impossible. Inevitably this is due to mistakes with the model and the theory, but how much of each?
Is it a serious theoretical failing that I can’t zero-parameter fit the second experiment? Given how often modelers twiddle parameters between experiments, I doubt this. However, I’m proposing an entirely new module - new functionality. The burden of proof required for such an addition pushes me towards trying to do even more - perhaps too much.
After much head-bashing (it feels so good when you stop), and discussion, I’ve decided to split the paper in two. Submit the first experiment/model ASAP, and let the model and theory issues surrounding the second percolate for a few months. While this doesn’t meet my module-imposed higher-standards, it does have the added benefit of being penetrable to readers. The first experiment was short, sweet, with a cleanly modeled explanation. It makes an ideal introduction to ACT-R/S. Adding the second experiment (with judgments of relative direction) would have been far too much for all but the most extreme spatial modeler (as many of those as there are).
I just have to try to put the second experiment out of my mind until the writing is done… easier said than done.
Recently I finished (in so much as any software I develop is actually ever finished) a tool that allows bulk jACT-R model runs to be submitted to a remote server. All in all, it was an amazingly painless experience made possible by ECF, a protocol neutral communications library in the latest release of Eclipse. To be completely honest, while I’ve had dreams about this tool for a long time, it wasn’t until I saw the webinar for ECF that I realized just how feasible this project was.
What follows are my thoughts and impressions on using ECF. Before I begin, let me include this disclaimer: for all things networking, I am self-taught. And like all self-taught men, I had an idiot for a teacher. However, I do have a great deal of experience building networked tools for robotics, modeling and my own edification. Up until this point I have relied upon MINA, another slick networking framework - but one that sticks closer to more traditional networking models.
I’d like to start off with the positive points.
- The use of the IContainer and adapter paradigm makes it really quick to get started using the framework, particularly for those familiar with Eclipse.
- The generic (and serializable) IDs make the tracking of connections absurdly easy (e.g. I use them as map keys to keep track of processing jobs and the clients & servers they are associated with across invocations of the IDE. Quit, start up again, and everything is right back the way it was).
- The discovery api is incredibly simple. Having tried to use zeroconf years back, this is a dramatic improvement.
- Retrieving files via known standard protocols is also a snap (I use it to fetch the archives of the runs and results, with a dynamic Jetty instance to server them). From what I can tell, virtually all container instances support a configurable url file fetch mechanism (file:, http:, scp even).
- The use of channels makes arbitrary messaging (read as: serialized POJO) quick and painless, particularly since most containers support it with relatively little difficulty.
Before I present my gripes, let me just say that the folks behind this project have done an awesome job. It took about a week to get this whole tool up and running. But there were some headaches, mostly due to documentation (availability, when it’s there it’s good) and mental model mismatches.
Clients as Servers
If you want to build a server, you’ll probably look at the “ecf.generic.server” container, thinking that you’ll hook up to it some connection policies, channel handlers and be done with it. Not exactly. The ecf generic server acts as a hub. Your actual server will be a client that connects to the ecf server in order to talk to the actual clients that connect to it as well. I can understand the reasoning here, but this doesn’t map very cleanly onto most conceptions of a server. Looking through the developer mailing list, I see that I’m not the only one who’s gotten a bit confused.
This is magnified by how the generic server handles channel communications. When a client connects to it, it is assigned a unique ID, it will be up to you to determine which IDs correspond to the server-client and the clients-proper.
I am somewhat surprised that there is no IServerContainerAdapter that permits the setting of connection policies and the like. Something that more closely maps onto the traditional concept of a server. Something less general than the ecf generic server that can be extended into something very specific. As it stands, I don’t see a way to quickly build a server that non-ECF clients can access. (But I’m probably wrong).
Services
I love them OSGi services, and ECF is supporting them as well. But I’ll be damned if I could find any of the file sharing services. I don’t know if it’s missing or I’m clueless, but I wasted a couple of hours looking for said services. Fortunately, they, like all good Eclipse citizens, include their source code. In there I discovered that most containers support the url file transfers right out of the gate. Doh!
Where are those container names?
ContainerFactory.getDefault().createContainer(String) is the most document method for creating a new container, yet finding the list of current container names can be a pain (short of PDE extension point search). There is a providers list, but it doesn’t include the names. After digging I finally found it on the eclipse site proper. Since the wiki is actually the first place the ECF project page on Eclipse.org directs you to, stumbling back to the eclipse site again seemed like the wrong path to me. I dunno. If it were me, it would be at the top of the providers list and maintained regularly (“ecf.generic.fileshare” is apparently a vestigial remnant from earlier versions).
Anyway, as I mentioned, these are small gripes for what is an otherwise exceptional piece of work, particularly when you consider all the functionality that this is permitting. Good job, guys.
As usual after a day of writing, I needed to take a break. I decided to watch an old webinar on the Eclipse communications project. Why does a psychologist/roboticist care about a platform specific communications system? Aside from the possibilities of leveraging others work on shared editing, or even chat/IM within the IDE (great for contacting me if you’ve got a question), it also opens the door to more effective distributed model execution.
As cognitive modelers we routinely have to run thousands of model iterations in order to collect enough data to do effective quantitative fits. For simple models, the time cost is negligible, but larger models can serious tax computation resources for quite sometime. My dissertation experiments lasted around two hours, and the model runs took almost 15 minutes per simulated subject. Given the parameter space I had to explore, it was common for my machine to be bogged down for days on end. My solution at the time was to VNC into other machines in the lab, update the model from SVN, then run a set of parameters. Not the most effective distribution mechanism.
Wouldn’t it be better if you could do all this from the IDE without any hassle? Imagine if you could specify the bulk model executions and then farm it out to a set of machines without any heavy lifting or sacrificing your processor cycles. The combination of OSGi bundles (which all jACT-R models are), Eclipse’s PDE, and ECF makes this possibility a very near reality (p2 will definitely help too as it will make enforcing consistent bundle states much easier).
After watching the webinar I couldn’t resist and started building the pieces. Here’s how the bad-boy will work:
- define the run configuration for the iterative model run
- then select the remote tab which will list all the discovered service capable of accepting the model run (pruned based on dependencies of your model)
- the model and all its dependencies is exported to a zip file and sent to the remote service
- the remote service unpacks, imports and compiles the content (ensuring that all the deps are met and your code will actually run) - it then executes the run configuration
- as the execution progresses, the service transmits the state information back to your IDE (i.e. iteration #, ETA, etc)
- when all is done, it packages up the working directory that the model was run in and sends it back
- this is then expanded into your runs/ directory as if you had executed the bulk run yourself.
This is actually a sloppy implementation of a more general functionality that Eclipse might find useful: transmitting local bundles and invoking them on a remote system.
I’ve got a weekend away from distractions coming up and I think I can get a rough implementation working by then. This will certainly make the bulk monkey runs go so much easier (remote desktop is usable but really just too much of a hassle). Of course, I could use that time to work on the spatial modeling instead.. but that’s too much like real work for a weekend.
I am. I am.
Surprise, surprise, my previous rant was completely unjustified. Turns out it was my own stupid fault. I was programmatically launching player, unfortunately I forgot to harvest the program’s stdout and stderr. The process’s buffers were flooded. Stooopid Ediot!
But, at least the monkey sims can run for much longer now. And not a moment too soon as the robot lab is rapidly filling with interns. (It’s such a nice change of pace to no longer be on the bottom of the totem pole)
Frackin’ other peoples’ code *
I love division of labor, it saves us all from having to reinvent the wheel.. but sometimes it just drives me insane.
I’ve hooked up player/stage through a java client, enabling jACT-R (and the monkey models) to interact in the simulated robotic environment. For sometime now I’ve had a bug where stage would freeze after around four minutes of simulated time. I initially thought it was due to my unorthodox use of the client (the threading model in the client is a tad weak), so I reverted it back to the normal usage and the simulations were now running past four minutes with no problem. Yay, problem fixed!
Nope. Now it dead locks around 6 minutes. So maybe it’s a problem with stage? Lo and behold, someone else was encountering a similar problem. The recommended fix? Upgrade to playerstage 2.1, which is, of course, not support by the client yet and no one has posted any word on an ETA.
I am able to detect when it occurs, which lead me to believe that I’d be able to disconnect the clients and reconnect. Unfortunately, the only way to resurrect stage at this point is to completely kill the socket owning process. My only option is to not only disconnect the clients, but then force quit stage and restart it.. Ick!
I think it’s time to work on something else for a little while.
* This is not meant as a disparagement of anyone’s work, rather just me venting. I fully acknowledge that the same statements could be- (and probably have been-) applied to my own work.





