holehouse.org Blog Machine learning notes

08: Neural Networks - Representation

Neural networks - Overview and summary

Why do we need neural networks?

Example: Problems where n is large - computer vision

Neurons and the brain

Model representation 1

Artificial neural network - representation of a neurone

Neural networks - notation

a1(2)=g(Θ10(1)x0+Θ11(1)x1+Θ12(1)x2+Θ13(1)x3) a2(2)=g(Θ20(1)x0+Θ21(1)x1+Θ22(1)x2+Θ23(1)x3) a3(2)=g(Θ30(1)x0+Θ31(1)x1+Θ32(1)x2+Θ33(1)x3) hΘ(x)=a1(3)=g(Θ10(2)a0(2)+Θ11(2)a1(2)+Θ12(2)a2(2)+Θ13(2)a3(2)) The three layer-2 activations, then the hypothesis computed from them. Each is a logistic unit over the previous layer plus its bias term.

Model representation II

Here we'll look at how to carry out the computation efficiently through a vectorized implementation. We'll also consider

why NNs are good and how we can use them to learn complex non-linear things

a1(2)=g(Θ10(1)x0+Θ11(1)x1+Θ12(1)x2+Θ13(1)x3) a2(2)=g(Θ20(1)x0+Θ21(1)x1+Θ22(1)x2+Θ23(1)x3) a3(2)=g(Θ30(1)x0+Θ31(1)x1+Θ32(1)x2+Θ33(1)x3) hΘ(x)=a1(3)=g(Θ10(2)a0(2)+Θ11(2)a1(2)+Θ12(2)a2(2)+Θ13(2)a3(2)) The three layer-2 activations, then the hypothesis computed from them. Each is a logistic unit over the previous layer plus its bias term.
x=[x0x1x2x3]z(2)=[z1(2)z2(2)z3(2)]
x = np.array([1, 0.5, -1.2, 0.8])   # x0 = 1 plus three features
Theta1 = np.array([[ 0.1, -0.4,  0.6,  0.2],   # [3 x 4]: three hidden units,
                   [-0.3,  0.5, -0.1,  0.7],   # each seeing all four inputs
                   [ 0.2,  0.1,  0.3, -0.5]])

z2 = Theta1 @ x                       # [3]  - one z per hidden unit
a2 = g(z2)                            # [3]  - their activations
a2 = np.concatenate(([1], a2))        # [4]  - add the bias unit a0 = 1

The two vectorized steps above, as code: one matrix multiply computes every hidden unit's z at once, one call to g turns them into activations.

hΘ(x)=g(Θ10(2)a0(2)+Θ11(2)a1(2)+Θ12(2)a2(2)+Θ13(2)a3(2)) a0(2) is the bias unit, added to a(2) to make it a 4x1 vector — it is picked out in red on the original slide.

Neural networks learning its own features

Neural network example - computing a complex, nonlinear function of the input

y = x1 XOR x2

x1 XNOR x2

Where XNOR = NOT (x1 XOR x2)

Neural Network example 1: AND function

hΘ(x) = g(−30 + 20x1 + 20x2)
x1x2 hΘ(x)
00g(−30) ≈ 0
01g(−10) ≈ 0
10g(−10) ≈ 0
11g(10) ≈ 1

Only (1,1) gives a positive output — so hΘ(x) ≈ x1 AND x2.

import numpy as np

def g(z):   # the sigmoid, as everywhere else
    return 1 / (1 + np.exp(-z))

Theta = np.array([-30, 20, 20])   # the weights drawn on the network above

for x1, x2 in [(0, 0), (0, 1), (1, 0), (1, 1)]:
    h = g(Theta @ np.array([1, x1, x2]))
    # h -> 0.000, 0.000, 0.000, 1.000 : only (1,1) fires

The AND table above, computed. The weights push the sigmoid deep into saturation, so the outputs are 0 and 1 to three decimal places.

Neural Network example 2: NOT function

Neural Network example 3: XNOR function

Combining the three gates: a1(2) = x1 AND x2, a2(2) = (NOT x1) AND (NOT x2), hΘ(x) = a1(2) OR a2(2)
x1x2 a1(2)a2(2) hΘ(x)
00011
01000
10000
11101

The output is 1 exactly when the inputs agree — XNOR — which a single logistic unit cannot express. Gate weights: AND (−30, 20, 20), NOR (10, −20, −20), OR (−10, 20, 20).

Theta1 = np.array([[-30,  20,  20],   # row 1: AND
                   [ 10, -20, -20]])  # row 2: (NOT x1) AND (NOT x2)
Theta2 = np.array([-10, 20, 20])      # output layer: OR

def forward(x1, x2):
    a1 = np.array([1, x1, x2])              # input plus bias
    a2 = g(Theta1 @ a1)                     # both gates at once
    return g(Theta2 @ np.concatenate(([1], a2)))

[round(forward(x1, x2)) for x1, x2 in [(0, 0), (0, 1), (1, 0), (1, 1)]]
# [1, 0, 0, 1]  - XNOR, from two layers of logistic units

The whole XNOR network, forward-propagated. Layer 1 computes the two gates, layer 2 ORs them together — a non-linear function no single logistic unit can express.

Neural network intuition - handwritten digit classification

Multiclass classification