This next line of code will then create a pooling layer.
It's max-pooling because we're
going to take the maximum value.
We're saying it's a two-by-two pool,
so for every four pixels,
the biggest one will survive as shown earlier.
We then add another convolutional layer,
and another max-pooling layer so that the network can
learn another set of
convolutions on top of the existing one,
and then again, pool to reduce the size.
So, by the time the image gets to
the flatten to go into the dense layers,
it's already much smaller.
It's being quartered, and then quartered again.
So, its content has been greatly simplified,
the goal being that the convolutions will
filter it to the features that determine the output.
A really useful method on
the model is the model.summary method.
This allows you to inspect the layers of the model,
and see the journey of
the image through the convolutions,
and here is the output.
It's a nice table showing us the layers,
and some details about them including the output shape.
It's important to keep an eye on the output shape column.
When you first look at this,
it can be a little bit confusing and feel like a bug.
After all, isn't the data 28 by 28,
so y is the output, 26 by 26.
The key to this is remembering that
the filter is a three by three filter.
Consider what happens when you start scanning
through an image starting on the top left.
So, for example with this image of the dog on the right,
you can see zoomed into
the pixels at its top left corner.
You can't calculate the filter for
the pixel in the top left,
because it doesn't have any neighbors
above it or to its left.
In a similar fashion,
the next pixel to the right won't work
either because it doesn't have any neighbors above it.
So, logically, the first pixel that you
can do calculations on is this one,
because this one of course has
all eight neighbors that a three by three filter needs.
This when you think about it,
means that you can't use
a one pixel margin all around the image,
so the output of the convolution
will be two pixels smaller on x,
and two pixels smaller on y.
If your filter is five-by-five for similar reasons,
your output will be four smaller on x,
and four smaller on y.
So, that's y with a three by three filter,
our output from the 28 by 28 image,
is now 26 by 26,
we've removed that one pixel on x and y,
and each of the borders.
So, next is the first of the max-pooling layers.
Now, remember we specified it to be two-by-two,
thus turning four pixels into one,
and having our x and y.
So, now our output gets reduced from 26 by 26,
to 13 by 13.
The convolutions will then operate on that,
and of course, we lose the one pixel margin as before,
so we're down to 11 by 11,
add another two-by-two max-pooling
to have this rounding down,
and went down, down to five-by-five images.
So, now our dense neural network is the same as before,
but it's being fed with five-by-five images
instead of 28 by 28 ones.
But remember, it's not just one compress
five-by-five image instead of the original 28 by 28,
there are a number of convolutions
per image that we specified,
in this case 64.
So, there are 64 new images
of five-by-five that had been fed in.
Flatten that out and you have
25 pixels times 64, which is 1600.
So, you can see that the new flattened layer
has 1,600 elements in it,
as opposed to the 784 that you had previously.
This number is impacted by the parameters that you
set when defining the convolutional 2D layers.
Later when you experiment,
you'll see what the impact of setting
what other values for the number of convolutions will be,
and in particular, you can see what happens when
you're feeding less than 784 over all pixels in.
Training should be faster,
but is there a sweet spot where it's more accurate?
Well, let's switch to the workbook,
and we can try it out for ourselves.