Character recognition exercise
Click to run World:
Character recognition neural network at
Ancient Brain.
- Clone and edit the world
- First, look at the data set.
Data is loaded into the "mnist" object. View console to explore this object.
Regular array-like structure.
- Examine the code to see how one entry of the array (an array of pixels)
is transformed into an image to display in different sizes on the canvas.
Change the learning
- Turn learning off / slow learning down:
- It is hard to see, because it happens so fast, but the network starts random with random predictions,
but after only a few hundred exemplars it gets pretty good.
- To see that the network starts random, change "do_training" to false.
However this will not do any testing of the training, so we cannot see how good it is.
You need to edit that section to leave the testing in (but no training).
- Alternatively, set TRAINPERSTEP to zero.
- If we do no training, the Network stays random.
Results are random. (Meaning what?)
- Or you can let it learn but slow it down with
TRAINPERSTEP = 1, TESTPERSTEP = 50.
Then it learns slower, and you can see it improve.
- See what happens when you:
- Reduce hidden nodes to 5.
- Reduce hidden nodes to 1.
- Increase hidden nodes to 200.
- Why?
- See what happens when you:
- Change randomWeight to return zero.
- Change randomWeight to return constant.
- Why?
Output vector
Idea 1: Should output be all 100 percent or zero?
- When we are training, we tell it the correct output is one "1" and the rest 0:
let targets = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
targets[label] = 1; // change one output location to 1, the rest stay at 0
- But is that right?
- Say the image is "7".
We tell the network the correct output is:
( 0,0,0,0,0,0,0,1,0,0 )
But should we really expect the network to have zero output for "1" and "9"?
Maybe we should tell the network the correct output should be:
( 0, 0.3, 0,0,0,0,0, 0.9, 0, 0.3 )
- Set up some rules like this and see if it improves.
- Will this help? I do not know.
Idea 2: Other input scheme
Could we try another input scheme?
Here is an idea:
- 2 input nodes per pixel.
-
One node for 0-127 and another node for 128-255
-
So "70" has 70/128 (or some other scheme) in 1st input node,
and 0 in 2nd input node.
-
And "178" has 0 in 1st input node,
and 50/128 (or some other scheme) in 2nd input node.
-
More weights per pixel.
Weights can change independently.
- Would not be hard to set up.
Just a few lines of code when setting up the inputs.
- Will this help? I do not know.
Input vector: Blurring the doodle
To try to improve doodle recognition,
I made a change to make the doodle more like the MNIST images.
The challenge: Improve doodle recognition
- After a long time, the doodle recognition gets to about 60 percent accuracy.
- Can we improve this?