Thomas Piacentini
← Atelier

Exercice Python

Backpropagation through a two-layer MLP

Texte original · anglais40 min

Backpropagation computes the gradient of the loss with respect to every weight of a network. You run the forward pass once, keep the values that the backward pass needs, and then apply the chain rule from the loss back to the input. In this problem, you write both passes for a network with two sigmoid layers and a mean squared error loss.

Task

Write three functions.

  1. mlp_forward(x, params) runs the network on a batch and returns (output, cache).
  2. mse_loss(predicted, target) returns the mean squared error.
  3. mlp_backward(params, cache, target) returns the gradient of the loss with respect to each parameter.

The forward pass for a batch x of shape (N, n_in) is:

z_1 = x W_1 + b_1, \quad a_1 = \sigma(z_1), \quad z_2 = a_1 W_2 + b_2, \quad a_2 = \sigma(z_2)

Here \sigma(z) = 1 / (1 + e^{-z}) is the sigmoid. The output is a_2. The bias vectors add to every row.

The loss is the mean over all N \cdot n_{out} entries:

L = \frac{1}{N \, n_{out}} \sum_{i,j} (a_{2,ij} - y_{ij})^2

The cache is your own choice. It can be any Python object. The checks pass the cache from your mlp_forward to your mlp_backward and do not read it.

Input and output

Name Type Shape Meaning
x float array (N, n_in) one row for each example
params dict of float arrays see below the parameters of the network
params["W1"] float array (n_in, n_hidden) the weights of the hidden layer
params["b1"] float array (n_hidden,) the bias of the hidden layer
params["W2"] float array (n_hidden, n_out) the weights of the output layer
params["b2"] float array (n_out,) the bias of the output layer
predicted float array (N, n_out) the output of mlp_forward
target float array (N, n_out) the target values, from 0 to 1
cache any the second value that your mlp_forward returns
  • mlp_forward returns a tuple (output, cache). output is a float array of shape (N, n_out).
  • mse_loss returns a Python float.
  • mlp_backward returns a dict with the keys "W1", "b1", "W2" and "b2". Each value is a float array with the shape of that parameter. It is the partial derivative of L with respect to that parameter.

Constraints

  • 1 <= N <= 64, 1 <= n_in, n_hidden, n_out <= 16.
  • Weights and inputs can be large. A pre-activation can be 1000 or more. No output or gradient can be NaN or infinite.
  • Do not change x, target or the arrays in params.
  • Use numpy only.

Examples

python
x = np.array([[0.0, 1.0], [1.0, 0.0]])
params = {
    "W1": np.array([[0.5, -0.5, 1.0], [0.25, 0.75, -1.0]]),
    "b1": np.array([0.0, 0.1, -0.1]),
    "W2": np.array([[1.0], [-1.0], [0.5]]),
    "b2": np.array([0.2]),
}
target = np.array([[1.0], [0.0]])
output, cache = mlp_forward(x, params)
loss = mse_loss(output, target)
grads = mlp_backward(params, cache, target)
text
output
[[0.5464852 ]
 [0.68495157]]
loss
0.33741716
grads["W2"]
[[ 0.02881637]
 [-0.01942579]
 [ 0.07701337]]
grads["b2"]
[0.03540898]
grads["W1"]
[[ 0.03473536 -0.03551239  0.01518726]
 [-0.02766515  0.0235782  -0.01053007]]
grads["b1"]
[ 0.0070702  -0.01193419  0.0046572 ]
Code et livrables 13
Ce que vous en retenez

Enregistré dans votre carnet sur cet appareil.

Sources et limites

Les repères de lecture sont déclaratifs. Les résultats de tests sont enregistrés séparément ; ils valent pour les cas exécutés.

AI Engineering from Scratch · 3f9715c · MIT

Télécharger ce fichier ↓