Code and Short Tutorial for Neural Parser
Code
Tutorial
Oct 2018 Tutorial
Get it running
- Grab the tarball, unzip, and untar it.
- I'm running in Ubuntu 14.04, with nest and spinnaker. You should
get those running (or just nest if that's all you want).
- You should be able to test that the system runs by
python testTurnLangNest.py
- Note: the tarball comes set to run in spinnaker. To change this
comment out simulator=spinnaker in nealParams.py.
- This should generate two pkl files in the results directory. You
can convert the pkl files to spike trains by
python printPklFile.py results/parseState.pkl > sent0States.sp
This is a text file of spikes (thus sp), that should end with
neurons 30-37 firing until about 250 ms. (That's the final
parse state of the first (0) sentence).
Explanation of the files.
- All of the python files are for the pynn parser.
- testTurnLangNest.py: this tests the parsing system on
one sentence. By default it is the 0 sentence, but you
can specify another sentence. There are other version for
spinn7 and spinn8; these are for running on spinnaker using
a version from 2017 and 2018 respectively.
- turnStepLang.py: the testTurnLang*.py files use this. It
specifies the language to be parsed, and allocates the
topology. When we want to parse sentences from a different
language, we'll copy this and change it to specify the new
language.
- parseClass.py: this is the base class for parsing. It should
be generic across languages being parsed.
- stateMachineClass.py: the system is parsing a regular language,
which can be defined by a stateMachine. So, this class is used;
it's well tested and should work robustly for sentences.
- nealCoverClass.py: neal is the Neuromophic Embodied
Agents that Learn project. The idea is that we write
agents by combining modules (like this parser). Then we
change one parameter (the simulator), and the system works
on different platforms. Unfortunately some pyNN functions
differ from simulator to simulator. These are included in
nealCoverClass to reduce the amount of branching (e.g.
if simulator == nest) in the modules.
- testLang.py: this is a testfile that runs all of the
sentences.
- printPklFiles.py: a program to convert pkl files generated
from pynn spike saving to spike data.
- runNestTests.sh: automated script for testing nest.
- runSpinn7Tests.sh and runSpinn8Tests.sh automated script for
testing spinnaker.
Make a parser for a new language.
- cp turnStepLang.py turnStep2Lang.py
- cp testTurnLangNest.py testTurnLang2Nest.py
- modify testTurnLang2Nest to import turnStep2Lang instead of
testTurnLang
(just change the import).
It should now run and do just what testTurnLangNest did.
You can do a diff on the translation of the pkl files.
- We're now going to add a sentence to the parser. In
turnStep2Lang, fix up the global variable totalSentences; in the
main set it to 3 (instead of 2).
- This only parses the sentences turn left. and
step forware.because
they are the only sentences we have defined (in turnStep2Lang).
We're going to
define the sentence move backward. We're going to do this
in main after step forward is defined.
- add
parser.addSentence(['move','backward','.'])
moveState = parser.addStateToNewStateOnWord(parser.startState,'move')
moveBackwardState = parser.addStateToNewStateOnWord(moveState,'backward')
moveBackwardFinalState = parser.addStateToNewStateOnWord(moveBackwardState,'.')
-
You've now actually added the sentence, but it's not hooked into the
test. If you call
python testLangOneSentence.py 2
you'll try to parse the new sentence, but it's not defined. If you
look at the parseState.pkl file, you'll see no firing.
- In setupTestSentences, copy the elif (sentence==1) clause
and put the copy below. Modify it so sentence==2, and change
step to move and forward to backward. When you run
python testLangOneSentence.py 2
you should get a complete parse. (the 90-97 neurons
should be firing at the end.)
Run the agent
- The code comes with a simple agent and simple
environment. The Nest versions communicate via text
files. Open up two shells.
rm *.txt (you don't need
to do this the first time, and you might want to be
careful that you've not got some.txt files around you
want.)
In one shell python turnStepWorld.py (This
should bring up a window with a text box; you should type
l (for turn left.) in the window and hit return.)
In
the other shell python turnStepAgent.py.
In each
window you should see some timesteps coming up along with
some words. What is happening is that the world has sent
the agent a command to parse, and then the words. The
agent will make a particular neuron spike and write that
"action" to the file. The world will see the action and
apply it, then print out the state of the agent. (In the
world you can use the print button to get the state too.)
If you do l, you should get the state 270,0,0 in the world
after the parsing is done, meaning the agent is facing at
270 degrees and is in location 0,0. You should be able to
issue multiple commands and have the agent move about.
Modify the agent
- This agent only turns left and moves forward. Let's make it
also move backward.
- cp turnStepWorldNest.py turnStepWorld2Nest.py
- edit turnStepWorld2Nest.py and look for
elif input == 'f'
- cp that line and the line below it changing the 'f' to 'b' (or
whatever you'd like for move backward), and the second
line to
self.toSpinQ.writeSentence([-1,5,6,2])
That is change 3,4 (for step forward) to 5,6 (for move backward).
-1 starts the parse, and 2 is the period.
- turnStepWorld2Nest should run on its own, and with
turnStepAgent (though the b will cause the agent to crash).
- cp turnStepAgentNest.py turnStepAgent2Nest.py
- in turnStepAgent2Nest.py change the import of turnStepLang to
turnStep2Lang. That is include the language that includes
move backward that we made above.
- If you this agent and world (remember to rm *.txt), it should
work for f and l; it parses b, but there is no action, and
once the b is tried, the parse is in a bad state, so other
l and f commands don't work.
- In turnStepAgent2Nest.py, copy the line
connectFinalParseToAction(parser,6,agentActionCells,2) and place it below
changing the new line to
connectFinalParseToAction(parser,9,agentActionCells,3).
This says that the final parse state (the 9th) for move back. should
cause the 3rd action cell to fire. The world already deals with
this appropriately.