A Dense Layer and the Forward Pass
One neuron can only do so much with an input. Connecting several neurons lets us calculate different combinations of the same measurements, then pass those outputs to another layer.
14 sections · 15 questions · 3 coding challenges
The arrow keys move between sections too.
What Could Several Neurons Notice That One Cannot?
BOTIE
Work on multilayer networks made this possibility useful by learning internal representations, rather than requiring a person to specify every intermediate feature. Rumelhart, Hinton and Williams' 1986 backpropagation paper showed hidden units developing features relevant to the task while the network learned from its output errors.
In a dense layer, every output unit receives all the incoming values, but each has its own weights and bias. One can respond to one combination while another responds to a different combination. Their outputs become the next layer's inputs. Nonlinear activations matter here: without them, stacking these linear combinations would still amount to a single affine transformation.
Sources for this history
Several Neurons Read the Same Example
One neuron gives one response to an observation. We may want several different responses, each reading the same measurements in its own way.
A dense layer places several neurons beside one another and gives every neuron the same input vector.
Keep the input observation together
The row contains one observation's measurements. Its entries retain their meanings and order as they travel through the layer.
Input row
- Height
- Body mass
Matrix multiplication organizes the parallel neurons
The numerical calculation performs the same weighted-sum operation for each neuron. A matrix stores those weights in a consistent arrangement.
The full example traces one row through several layers before introducing batch shapes and matrix notation.
Explore the full example
Follow one example through the neurons. Compare each neuron's inputs, score, and activated output before following the next layer.
Each neuron prints z, its weighted sum plus bias, and a, that score after its activation function. The next column reads the a values and nothing else.
| x₁ | x₂ | bias | |
|---|---|---|---|
| h₁ | |||
| h₂ | |||
| h₃ |
| h₁ | h₂ | h₃ | bias | |
|---|---|---|---|---|
| y |
Part 1. Many Neurons, One Row
1. Three neurons reading the same two numbers
Take one person from the crowd the classification pages keep returning to, written in standard units so that (1, 2) means one deviation taller than average and two deviations heavier. The neurons page hands that row to one neuron and gets one number back. Hand the same row to three neurons at once and three numbers come back, and that is the whole of what a layer adds.
Nothing about any neuron has changed. Each still holds one weight per input and a bias, forms its score, applies its activation function, and passes on the output.
…
The three scores
All three neurons read the same input, (1, 2), but each has its own weights. Their biases are zero. Calculate their scores separately before applying the rectifier.
neuron 1: 1 × 1 + 1 × 2 + 0 = 3
neuron 2: 1 × 1 + (−1) × 2 + 0 = −1
neuron 3: (−1) × 1 + 1 × 2 + 0 = 1
ReLU(3, −1, 1) = (3, 0, 1)The next layer receives the three outputs as one row. Switching to sigmoid keeps the scores unchanged but changes their outputs.
sigmoid(3, −1, 1) ≈ (0.9526, 0.2689, 0.7311)Keep in mind
2. Why the widths inside a layer cannot disagree
Because every neuron in the layer is handed the same row, a neuron expecting a different number of inputs is not an odd member of the group, it is one that can never be fed. Give the layer a neuron holding two weights and another holding three and there is no row that satisfies both.
So the width a layer reads is a fact about the group, settled when the group is formed, and a group that cannot agree on it is refused at construction rather than discovered when a row arrives. I tried it, and the refusal reads “every neuron in a layer reads the same row, so they must agree on its width, got [2, 3]”.
a layer of m neurons over n inputs holds exactly n weights in every neuronThe neurons page already made the count of weights the input width, since a dot product with a row of another length is undefined. A layer inherits that and adds one rule on top, that all of its members hold the same count. That rule is the first link in a chain that ends with a whole network’s shape being decidable before any data exists, which Part 4 is about.
Keep in mind
3. The width answered owes nothing to the width read
Three neurons answer with three numbers whether they read two inputs or two hundred, so the width a layer answers with is how many neurons it holds, and nothing about the row it reads bears on it. The two widths are separate choices. The first is forced by whatever feeds the layer; the second is free, and choosing it is what designing a network mostly consists of.
reads (n,) answers (m,) here (2,) and (3,)Widening a layer changes what the next layer must expect and changes nothing about what this one accepts, which is why a network’s shape is a chain of separate equalities rather than one number carried the whole way through. On the playground the hidden layer reads (2,) and answers (3,), and the output layer reads (3,) and answers (1,), and the second pair is a consequence of the first only at its left end.
Keep in mind
4. Counting the parameters
A dense layer has one weight for every input-output connection and one bias per output neuron. Count the two layers separately.
hidden layer = 2 inputs × 3 neurons + 3 biases = 9
output layer = 3 inputs × 1 neuron + 1 bias = 4
network total = 9 + 4 = 13The playground reports the same total.
parameters in a layer = m · n + m
hidden 3 · 2 + 3 = 9
output 1 · 3 + 1 = 4
network 13Thirteen numbers is small enough to write out, and the point of doing so is that nothing else exists. There is no stored answer anywhere in a layer, only these numbers and the two lines of arithmetic that Part 2 writes down. Change a cell in the playground and every node re-prints, because nothing from the last pass is kept that a new one could reuse.
On the crowd
Both networks in Part 5 read two measurements and produce one answer. The first has one hidden layer of six neurons; the second has two hidden layers of three. Count weights and biases layer by layer.
one hidden layer: (2 × 6 + 6) + (6 × 1 + 1) = 25
two hidden layers: (2 × 3 + 3) + (3 × 3 + 3) + (3 × 1 + 1) = 25They have the same parameter count. That lets us compare the effects of their different arrangements without also changing how many parameters they can learn.
Keep in mind
Part 2. The Matrix Form
5. Stacking the weight rows into a matrix
Each hidden neuron’s weights are a row of two numbers, and three such rows stacked one under another are a matrix with three rows and two columns. Nothing has been computed yet; the three neurons’ weights have only been written down together. But written that way, the three dot products the last section formed one at a time are one matrix multiply, the linear algebra primer’s, and the three biases are one vector added afterwards.
z = W x + b
W = [ 1 1 ] x = [ 1 ] b = [ 0 ] z = [ 3 ]
[ 1 −1 ] [ 2 ] [ 0 ] [ −1 ]
[ −1 1 ] [ 0 ] [ 1 ]…
Row two of the multiply
Choose the second neuron. Its row of W lights up beside the input vector. That row performs the same calculation we worked through in section 1.
z₂ = 1 × 1 + (−1) × 2 + 0 = −1Each matrix row computes one neuron’s score. Matrix multiplication collects those separate calculations into one operation.
Keep in mind
6. Why the matrix has the shape it has
The shape of W is (neurons, inputs), and both the order and the reason for it are worth having straight, because the transposed convention is common and reads differently. A row of W is a neuron, so reading across a row gives one neuron’s weights in input order, and the number of rows is the width the layer answers with. A column of W is an input, so reading down a column gives every neuron’s weight on that one input, and the number of columns is the width the layer reads.
W is (m, n) W x is (m, n)(n, 1) = (m, 1)The multiply conforms exactly when the matrix’s column count equals the row’s length, which is section 2’s agreement about width said in the primer’s vocabulary. The hidden layer’s W is (3, 2) and reads a row of two; the output layer’s is (1, 3) and reads the three hidden outputs. Each neuron is kept as its own object, because the neuron is the unit that was learned about, and the matrix is assembled once when the layer is built, so a pass is one multiply per layer rather than a loop over neurons.
Keep in mind
7. A block of people in one multiply
One person is one row. Three people are three rows stacked into a block, and the same matrix multiply handles all of them in one call, because multiplying a block by the transposed weight matrix forms every person’s dot product with every neuron at once. The block that comes out has one row per person still, and one column per neuron, so a layer keeps the people axis and replaces the other axis with its own width.
Z = X Wᵀ + b (rows, n)(n, m) = (rows, m)The transpose is bookkeeping and not a new operation. A matrix product pairs each row of its left factor with each column of its right factor. The people are the rows of X, and section 5 wrote the neurons as the rows of W, so W is turned on its side to put each neuron’s weights in a column. The entry in row i and column j of the product is then person i’s dot product with neuron j, the same score section 1 formed for one person and one neuron.
The bias vector is added to every row alike, because a neuron’s bias does not depend on which person it is reading. Nothing in one row of Z depends on any other row of X, so a block is not a new kind of input. It is several separate passes that happen to share one call.
A block’s first axis is always the people. Each layer keeps that axis and replaces the other with its own width, so three people stay three rows all the way up.
Three people through the two layers
The tall heavy person (1, 2), someone exactly average at (0, 0), and someone a deviation shorter and half a deviation heavier at (−1, 0.5) go in as a block of shape (3, 2). The hidden layer answers a (3, 3) block whose rows are (3, 0, 1), (0, 0, 0) and (0, 0, 1.5), since the third person’s scores were (−0.5, −1.5, 1.5) and the rectifier kept only the last, and the output layer answers a (3, 1) block holding 5, 0 and 3.
The first person is the row worked in section 1. The third person’s row of each block is the same arithmetic on different inputs.
person (−1, 0.5)
neuron 1: 1 × (−1) + 1 × 0.5 = −0.5 ReLU → 0
neuron 2: 1 × (−1) + (−1) × 0.5 = −1.5 ReLU → 0
neuron 3: (−1) × (−1) + 1 × 0.5 = 1.5 ReLU → 1.5
output: 1 × 0 + (−1) × 0 + 2 × 1.5 = 3The average person scores zero at every neuron, because every bias is zero.
The third button sends a row three numbers wide. The request lets it through on purpose, so that the layer meets it, and the layer refuses it with “this layer reads (2,), got a block arranged (3,)”. That sentence is quoted word for word, and Part 4 says why it is phrased in terms of an arrangement rather than a count.
Keep in mind
8. The activation function is applied one entry at a time
After the multiply, each neuron transforms only its own score, so the activation function is applied to every entry of z on its own and the result has z’s shape. That is what lets a whole layer share one activation function applied to one block in a single call, and it is why softmax is not among the four activation functions here, since softmax reads a whole row of scores to answer any one of them, which the neurons page sets out.
a = f(z), entry by entry
rectifier (3, −1, 1) → (3, 0, 1)
sigmoid (3, −1, 1) → (0.9526, 0.2689, 0.7311)
tangent (3, −1, 1) → (0.9951, −0.7616, 0.7616)Each neuron carries its own activation function, so nothing in the mathematics stops a layer from mixing them, and a layer whose first neuron is straight and whose second is a sigmoid is accepted; I checked, and it answers (3, 0.2689) at the row. A uniform layer is a fact about ordinary practice rather than a law, and it is the case a vectorised pass can exploit, since one activation function over a whole block is one call where a mixed layer needs one per column.
Keep in mind
Check yourself
Questions on Parts 1 and 2
Question 1 of 5
A layer holds three neurons, and each neuron holds two weights and a bias. What does the layer read, and what does it answer with?
Part 3. The Forward Pass
9. What one layer keeps from a pass
A layer asked about a row answers with more than the row it hands on. It keeps three blocks together, the block it read, the scores it formed, and the outputs it answered with, and it keeps them as one object so that the three cannot be separated or mispaired. The scores and the outputs share a shape, since the same entry in each describes the same neuron on the same person, and the inputs share the row count.
…
On the running row the hidden layer’s response holds inputs (1, 2), scores (3, −1, 1) and outputs (3, 0, 1), and the output layer’s holds inputs (3, 0, 1), score 5 and output 5. The response reports two facts about itself besides, how many rows went through and how many neurons answered, which are the two axes of its blocks.
Keep in mind
10. The chain, each layer reading what the one beneath answered
The forward pass is section 5’s two lines applied once per layer, with one rule joining them. The first layer reads the person, every later layer reads what the layer beneath answered, and the last layer’s outputs are the network’s answer. Written as matrices, with a subscript for the layer, the whole of the running network is four lines.
z₁ = W₁ x + b₁ h = f₁(z₁)
z₂ = W₂ h + b₂ y = f₂(z₂)The four lines at the row
The hidden scores are (3, −1, 1). ReLU turns them into (3, 0, 1), which become the output neuron’s inputs. Its weights are (1, −1, 2) and its bias is zero.
output score = 1 × 3 + (−1) × 0 + 2 × 1 + 0 = 5
identity(5) = 5The second connection contributes nothing because it multiplies a zero, which is why the playground draws it faint. Changing the hidden activation to sigmoid makes that input nonzero and changes the final answer.
sigmoid hidden outputs ≈ (0.9526, 0.2689, 0.7311)
final output ≈ 1 × 0.9526 − 0.2689 + 2 × 0.7311 ≈ 2.1457Using the hyperbolic tangent for the hidden activation gives a final output of about 3.2798.
One response is kept per layer and the whole list handed back, with the last layer’s outputs reachable directly so that an ordinary caller never indexes into the list at all. A deeper network is the same alternation continued, an affine map, an activation function, an affine map, an activation function, for as many layers as were stacked.
Keep in mind
11. Why the scores are kept, and the inputs too
A forward pass on its own would need only the outputs. The scores are kept because training needs the slope of each activation function at the point where the activation function was evaluated, and that point is the score, not the output. Under the rectifier the output 0 of the second hidden neuron could have come from a score of −1 or −100, and its slope is zero either way, but under the sigmoid the slope at a score of −1 is one number and at −100 another, and from an output alone the score would have to be recovered by running the layer again.
The inputs are kept for the same reason, since the correction owed to a layer’s weights multiplies by what the layer read, and the forward pass is the only thing that knows it.
kept per layer: inputs, scores, outputs
read forward: outputs only
read backward: all threeThe backpropagation page is where those three blocks are spent, walking the same row back down this same network, and it is not repeated here. What belongs here is only the design decision that makes it a plain reversed loop rather than a reconstruction of what each layer once read. An earlier version of this design kept only the scores and outputs, and the backward walk had to rebuild the list of inputs by shifting the outputs down one and pushing the caller’s row on the front, which was rebuilding something the forward pass had known and thrown away.
Keep in mind
12. Why a pass says why it is happening
A dense layer does the same arithmetic whether the network is learning or answering, and so do a convolution and a pooling window. Two layers do not. A dropout layer damages its own answers on purpose while learning, and a batch normalisation layer standardises by the batch in front of it while learning and by remembered statistics while answering.
So every pass here states its purpose, predicting or training, and hands it to every layer whether or not the layer reads it, so that a layer which starts caring later does not change the interface for the rest.
purpose ∈ {predicting, training} the default is predictingThe default is predicting, and the direction is chosen deliberately. Forgetting to say training costs a slightly slower descent; forgetting to say predicting would make every answer the model gives a matter of luck. The playground says its passes ran for predicting, which it states out loud even though it is the default, and the dropout page is where the other value earns its keep.
Keep in mind
13. Two routes to one answer, and how far apart they are
The definition of a layer is a loop, ask each neuron in turn, and the matrix multiply is that loop written as one call. Both are kept, the multiply for every fit and the loop as an observed route for anyone who wants to see one neuron’s arithmetic, and a test asserts that they agree, because a fast path and a slow path with nothing between them are two implementations rather than one calculation read two ways.
They agree to within floating point and not to the last bit, since the multiply sums the products in a different order than a loop does.
A score printed in amber differs from its neighbour in the last digit or two. The gap is the order the products were summed in and nothing else.
Measured
On the running network, two and three inputs wide, the two routes agree exactly, a gap of 0. On a seeded layer of eight neurons reading eight inputs the largest gap in the scores is 4.4 × 10⁻¹⁶, and on sixty-four neurons reading sixty-four inputs, 4,160 parameters, it is 7.1 × 10⁻¹⁵ in the scores and 5.3 × 10⁻¹⁵ in the outputs.
A dot product of sixty-four terms summed in two different orders parts in the fifteenth decimal place, and the scores in the table beneath the sliders differ only in their last digit or two.
Keep in mind
Part 4. Shapes and the Join
14. A shape is a pair of tuples, not a pair of numbers
A dense layer knows two things about itself before any data arrives, the width it reads and the width it answers with, and each is recorded as a tuple of extents rather than as a number. For a dense layer the tuple has one entry, (2,) or (3,), and the distinction looks pedantic. It stops being pedantic the moment a layer answers with something arranged, a convolution handing on a stack of pictures, say.
A dense layer reading a row that holds exactly as many numbers still cannot read it, because a row and a stack of pictures are different arrangements of the same count, and a check that compared counts would wave that mismatch through as an agreement.
dense reads (2,) answers (3,)
convolution reads (1, 28, 28) answers (8, 26, 26)
8 · 26 · 26 = 5408 = (5408,) as a count, and not as an arrangementA count says how many numbers there are and a tuple says how they are arranged, and the shape guarantee page is where that difference bites, with a flatten layer as the bridge. On this page every tuple has one entry, and the refusals still print the tuples, because a refusal that printed “5408 and 5408” on the case the check exists to catch would send a reader looking for a bug in the check rather than for the missing layer.
Keep in mind
15. Two layers join when one answers what the other reads
Two layers fit together when the one above reads exactly what the one beneath answers, and that is a sentence about two shapes, so it belongs to the shape rather than to whichever loop is assembling a network. The two boxes below state their four widths and nothing else. Set them, and the verdict comes back with no row sent, in the same words a real mismatch would produce hours into a training run if nobody had checked first.
above follows beneath ⇔ beneath.answers == above.readsNo row was sent. The verdict came from the four widths alone, and a red sentence is the refusal itself, word for word.
Only the seam is checked. The left box’s reads and the right box’s answers are the network’s two ends, which the data and the task decide, and a layer reading eight and answering five joins one reading five and answering eight without complaint, since the seam between them holds.
Keep in mind
16. The whole chain is checked at construction, and the seam is named
An answer nobody is obliged to read is not a guarantee. A caller can ask whether two layers join, discard the answer, and discover the disagreement inside a matrix multiply later. So the check is not left to the caller. A stack of layers refuses to exist unless every seam holds, and a stack that has been built is one whose shape is already known to be sound, so no forward pass anywhere re-establishes it.
The check is a walk down a list of integers, two comparisons for three layers, and it costs nothing that could be measured.
A chain of three
Layers reading 2 and answering 3, reading 3 and answering 4, reading 4 and answering 1 make a stack that reads (2,) and answers (1,) across two seams, holding thirty parameters. Change the last layer to read 5 and the stack refuses to be built, with “layer 1 answers with (4,) and layer 2 reads (5,)”. Break the first seam as well and it is the first that is named, since the walk stops at the first seam that fails.
The thirty is section 4’s count taken once per layer, and the two seams are the two places where one layer’s answering width has to equal the next layer’s reading width.
parameters = (2 × 3 + 3) + (3 × 4 + 4) + (4 × 1 + 1) = 9 + 16 + 5 = 30
seam 0 to 1: answers (3,) reads (3,) holds
seam 1 to 2: answers (4,) reads (4,) holds
with the last layer reading 5
seam 1 to 2: answers (4,) reads (5,) refused›Why the check belongs to an object
A rule spanning several values belongs to an object that enforces it in its constructor, so that a value of that type cannot exist in a broken state. That is the same reason a feature set validates its columns together and a layer validates its neurons’ widths together. A free check function has to be remembered by every caller, and a constructor that refuses does not.
Keep in mind
17. Only the two ends are the data's business
A stack that exists has a shape of its own, the first layer’s reads paired with the last layer’s answers, and the playground prints it as (2,) → (1,). Everything between those two ends is internal, already agreed, and nobody else’s business. The data supplies two facts. The first layer’s width has to match how many measurements a person carries, and the last layer’s has to match what the task wants back, one number for a regression or a yes-or-no decision, one per class otherwise.
stack reads (2,) ← two measurements per person
stack answers (1,) → one number per personThe first of those is checked by the first layer itself the moment a block arrives, which is the refusal section 7 provoked with a row of width three. Nothing downstream checks anything, because every interior seam was settled when the stack was built. And a mismatch the widths cannot see stays invisible, since a row handed over with height and weight swapped has the right width and is scored wrongly with nothing raised.
I sent (2, 1) through the running network and it answered 2 where (1, 2) answers 5. The weights carry no names and match inputs by position, so the order is the contract, and this is documented rather than defended.
Keep in mind
Check yourself
Questions on Parts 3 and 4
Question 1 of 5
At the running row the hidden outputs under the rectifier are (3, 0, 1), and the output neuron holds weights (1, −1, 2) and no bias under the identity. What does the network answer?
Part 5. Width and Depth
18. Two layers without a nonlinear activation are one layer
Before asking what a second layer buys, ask what it buys when only affine operations occur between the two. Set both activation functions to the identity and the four lines of section 10 substitute into one, a single affine map from the person straight to the answer with matrix W₂ W₁ and bias W₂ b₁ + b₂.
y = W₂ (W₁ x + b₁) + b₂ = (W₂ W₁) x + (W₂ b₁ + b₂)The collapsed map at the row
Multiply the output weight row by the hidden weight matrix. This combines the two affine transformations into a single weight row. All biases are zero in this example.
combined weights = (1 − 1 − 2, 1 + 1 + 2) = (−2, 4)
output at (1, 2) = (−2) × 1 + 4 × 2 = 6Set both activation functions to identity in the playground. The stack and the combined transformation both return six.
With identity activations, both layers together perform one affine transformation from two inputs to one output. They use thirteen parameters to express something that needs only three. Adding more affine layers does not change that limitation. A nonlinear activation between layers allows the network to represent functions outside that class.
Keep in mind
Two affine transformations combine into one. A nonlinear activation between them is what allows additional layers to expand the kinds of function the network can represent. Identity is also an activation function, but it does not provide that expansion.
19. What one rectifier folds, and what a layer of them carves
A ReLU neuron has two regimes: it outputs zero when its score is negative, and it outputs its score when the score is positive. With two inputs, the change between regimes happens along a straight line where the score is zero.
The output layer combines several such responses. The resulting score is affine within each region of the input plane, with its slope able to change where a hidden neuron switches regime. Its zero contour can therefore contain multiple straight segments. This is what a piecewise-linear decision boundary means.
y = Σⱼ vⱼ · max(0, wⱼ · x + bⱼ) + c
unit j is flat where wⱼ · x + bⱼ < 0 and tilted where it is not…
Weights are in standard units, so a weight on height of 5 means one deviation of height, 15.6 centimetres, moves the unit’s score by five. The decision boundary can change direction where a hidden neuron switches between zero output and its score.
Three creases on the crowd
The best run at three units, from seed 2, calls every one of the twenty-five people correctly at a loss of 0.0725, and its three creases have weights (−5.912, −2.63), (−4.088, −2.577) and (5.092, 2.849) on standardised height and weight, with biases −1.853, −0.069 and −0.528. All three run across the plane at similar angles, and the boundary between the two shaded regions turns only where it meets one of them.
At two units there are two creases and the boundary cannot close around the children in the middle, and the best run leaves four adults wrongly called.
Keep in mind
Each hidden ReLU introduces a line where its response changes from zero to its score. Combining neurons lets the output score use different slopes in different regions. More units provide more possible changes, although training must still find useful weights.
20. Width on the crowd, measured
A sufficiently wide network with suitable nonlinear activations can approximate continuous functions on a bounded input domain. That existence result does not tell us which widths will train successfully on this particular dataset. I compared six widths and six starting seeds, using fifteen hundred epochs at a fixed learning rate. A fitted logistic classifier provides a reference.
Training thirty-six networks…
| hidden units | parameters | starts calling everyone | mean accuracy over six starts | best start's loss |
|---|---|---|---|---|
| 1 | 5 | 0 of 6 | 0.707 | 0.3606 |
| 2 | 9 | 0 of 6 | 0.840 | 0.2711 |
| 3 | 13 | 1 of 6 | 0.887 | 0.0725 |
| 4 | 17 | 2 of 6 | 0.913 | 0.0548 |
| 6 | 25 | 4 of 6 | 0.960 | 0.0388 |
| 8 | 33 | 6 of 6 | 1.000 | 0.0347 |
Rectifier hidden layers on the crowd, learning rate 0.5, 1500 epochs, six seeds each. The straight boundary calls 17 of 25, an accuracy of 0.68.
The best one-unit run classifies twenty-one of the twenty-five people correctly. A single ReLU followed by an affine output and a threshold still gives a half-plane decision region, or a constant prediction. Its higher accuracy than this fitted logistic reference does not demonstrate a more complex boundary; the training objectives and resulting fitted boundaries can differ.
One of the six starts leaves that unit inactive for every person and reaches only 0.52 accuracy. Two units reach 0.84 from every start. Three classify everyone correctly from one start; four do so from two starts, six from four and eight from all six. In these runs, extra width improves the reliability of finding a successful fit.
Keep in mind
21. Width against depth at twenty-five parameters
Section 4 showed that one hidden layer of six neurons and two hidden layers of three have the same twenty-five parameters. The deeper network’s second layer reads features already transformed by the first. Its activation regions, viewed in the original input coordinates, need not be separated by single straight lines.
This can make depth useful for representing some functions compactly. It does not guarantee easier training or better accuracy at a fixed parameter count. On this crowd, the deeper arrangement was less reliable.
Training eighteen networks…
| architecture | parameters | starts calling everyone | mean accuracy | loss when everyone is called |
|---|---|---|---|---|
| 2 → 6 → 1 | 25 | 4 of 6 | 0.960 | 0.0388 to 0.0577 |
| 2 → 3 → 3 → 1 | 25 | 2 of 6 | 0.887 | 0.0045 and 0.0060 |
| 2 → 6 → 6 → 1 | 67 | 6 of 6 | 1.000 | 0.0013 to 0.0037 |
The same loop, the same six seeds. Loss is the average log loss over the twenty-five people at the end of the run.
The wide model classifies everyone correctly from four starts, while the deeper model does so from two. In the deeper model’s worst run, two of its three second-layer neurons are inactive for the whole crowd and accuracy is 0.76.
When the deeper model succeeds, its best log loss is 0.0045, compared with 0.0388 for the wide model. Both predict the correct classes, but the deeper run assigns them higher probabilities. Two layers of six succeed from every tested start, with losses below 0.004. These outcomes describe this training experiment, not a universal advantage of width or depth.
Keep in mind
22. What the guarantee promises and what the loop finds
The universal approximation results promise that a network exists. Every number in the two tables above is about whether this loop, from this start, found it, and the gap between the two is the honest content of the section. Three units suffice for this crowd, since seed 2 proves it, and five of the six starts at three units did not get there.
One of the six starts at eight units ended with a unit dead for everyone, contributing a constant, and it still called every person correctly with the seven that were left, at a loss of 0.0813 against the 0.0347 of the best start.
a network exists ≠ this walk from this start arrivesThe dead units are the rectifier’s own hazard, the neurons page’s dead side met in a layer. A unit whose score is at or below zero for every person answers zero to all of them, its slope is zero everywhere it is evaluated, and nothing on any row can tell it what to do, so it stays where it is for the rest of the run. Whether it dies depends on the start, which is why the count is reported per seed. Everything after this page that is not a layer, momentum, better initialisation, normalisation between layers, is machinery for making the walk arrive somewhere good more often, and the training page runs the loop itself.
Keep in mind
Part 6. Implementation and Failure Contracts
23. What a complete implementation states
A dense layer's implementation must make its arrangements explicit before a forward pass. The reader needs to know which coordinate every weight multiplies and where every result goes.
- State the input and output shapes. Every neuron must have one weight per input coordinate.
- Fix the neuron order and the matrix convention. Here the weight matrix has neurons as rows and inputs as columns.
- Keep the batch axis separate from each example's shape. A response retains the inputs, scores, and activated outputs from the same pass.
- Specify the activation rule. This implementation can use different activations for different neurons and does not change its behavior with pass purpose.
A layer stack checks the shape at every join when it is constructed. If a join is invalid, the error identifies the adjacent layers and their arrangements. Its overall shape then runs from the first layer's input to the last layer's output.
24. Failure contracts
Every row below was probed. The playground’s request refuses some of these at the door, with its own bounds, before the layer is reached, and where that happens the row says what the layer itself does when asked directly.
| the edge | the behaviour |
|---|---|
| a layer with no neurons | refused, ‘a layer needs at least one neuron’; a layer answering nothing has no width for the next layer to agree with. |
| neurons of different widths in one layer | refused, ‘every neuron in a layer reads the same row, so they must agree on its width, got [2, 3]’. |
| a layer of one neuron | accepted; it reads (2,) and answers (1,), and is the neurons page’s model wearing a layer. |
| a stack with no layers | refused, ‘a stack needs at least one layer’; there is no network to describe. |
| a stack of one layer | accepted; it has no seams and its shape is the layer’s own. |
| a seam that does not hold | refused at construction, naming the seam and both arrangements, before any row exists. |
| a block with no rows | refused, ‘a layer needs at least one row to respond to’; the request refuses it a layer earlier. |
| a block of one row | accepted; one person is the ordinary case, and a layer has no notion of a dataset. |
| a row of the wrong width | refused by the first layer, ‘this layer reads (2,), got a block arranged (3,)’, and nothing downstream is reached. |
| a single row handed over flat, not as a block | refused, ‘a layer reads a block whose first axis is the rows, got 1 dimensions’. |
| a three-dimensional block into a dense layer | refused as an arrangement mismatch, ‘this layer reads (2,), got a block arranged (2, 1)’, which is the shape page’s case. |
| a non-finite value in a row | refused, ‘inputs must contain only finite values’; it cannot be written in a request at all, since JSON cannot spell it. |
| text in a row | refused, ‘inputs must be readable as a float array’. |
| integers, or booleans, in a row | accepted and coerced, so true reads as 1; documented rather than defended. |
| a non-finite weight or bias | refused when the neuron is built, in words, before any layer holds it. |
| an overflow produced inside a layer | accepted by the layer that produced it and refused by the next, ‘inputs must contain only finite values’, one seam later than it began; a response does not scan its own outputs, by decision. |
| mixed activation functions in one layer | accepted, and answers (3, 0.2689) at the row with a straight first neuron and a sigmoid second. |
| softmax requested as an activation function | refused; it is not on the list and cannot be, since it reads a row. |
| a width of zero, or a boolean, as an extent | refused, ‘n_inputs extents must be at least 1, got 0’ and ‘n_inputs must be whole numbers, not bools’, because true would otherwise read as a width of one. |
| a step handed no gradient | refused, ‘a dense layer has parameters and needs a gradient to step by’; absence is for layers with nothing to learn. |
| new parameters of the wrong shape | refused, ‘this layer’s weights are (3, 2), got (2, 3)’, so a transposed matrix cannot be installed quietly. |
| a row with its columns swapped | not detectable; (2, 1) answers 2 where (1, 2) answers 5, with nothing raised. Positional weights are the contract. Documented rather than defended. |
| unfitted use | nothing to refuse; a layer is built complete from its neurons and has no fit of its own. Fitting is the training page’s job. |
| a weight beyond a million, a block of more than six rows, a chain of more than six layers, or a width beyond eight | refused at the door as a request larger than the page allows, with the limit named. |
Two rows deserve a second look. The overflow row is a decision rather than an omission, since a layer’s response is built once per layer per call, and scanning every block on the way out as well as on the way in would double the check for a value that finite inputs and finite weights can still produce, so it is caught one seam later, where the next layer scans what it is given.
And the swapped-columns row is the price of a unit that reads unnamed coordinates from the layer beneath it. Past the first layer there are no names to check against, so the first layer cannot have them either, and the order a caller assembles a row in is the whole of the agreement.
Check yourself
Questions on Parts 5 and 6
Question 1 of 5
With both activation functions set to the identity, what do the running network’s thirteen parameters express?
Try it with Botie
Build with Botie
Write and run Python