Fit a sine curve with a tanh network

TrainMedium35 min10 checksBudget 1500 stepsTarget: held-out mean squared error 0.01

regressionmlptanhmse

Problem

A network with one hidden layer of tanh units can bend a straight line into a smooth curve. In this task you train a 1-16-1 tanh network to fit \sin(x) from noisy samples. The checks then compare the trained network with the true curve at new points that your code never sees.

Task

Write two functions.

  1. train(x, y, rng) trains a network and returns the trained model.
  2. predict(model, x) returns the network output for each value in x.

The data comes from make_sine(n, rng) in support.py. Each x is uniform from -\pi to \pi, and y = \sin(x) + \varepsilon with Gaussian noise of standard deviation 0.1.

Use 1 input, 16 tanh hidden units and 1 linear output: \hat y = \tanh(x W_1 + b_1) W_2 + b_2. Train it on the mean squared error \frac{1}{N} \sum_i (\hat y_i - y_i)^2 with full-batch gradient descent. Adam reaches the target with the least tuning.

During training, call report(step, loss) from practice_check once for each update step. The first step is 0. The page draws these values as a live loss curve, and the checks count them.

Input and output

NameTypeShapeMeaning
xfloat array(N,)the training inputs, from -\pi to \pi
yfloat array(N,)the noisy targets
rngnp.random.Generatorthe only source of random numbers
modelanythe value that train returns
  • train returns the model. The model can be any Python value, for example a list of weight arrays.
  • predict returns a float array of shape (M,) for an input of shape (M,).

Constraints

  • Budget: at most 1500 update steps, so at most 1500 calls to report.
  • Target: a mean squared error of at most 0.01 against the true curve \sin(x), at 2000 new values of x from -\pi to \pi. This page does not give their seed.
  • Take every random number from rng. The same seed must give the same model.
  • Do not change x or y, and do not change their shape.
  • predict must work for one value, shape (1,).
  • Use numpy only. One full submit has a limit of 20 seconds.

Examples

pythonx, y = make_sine(200, np.random.default_rng(0))
model = train(x, y, np.random.default_rng(1))
predict(model, np.array([0.0, np.pi / 2, -np.pi / 2]))
text[-0.0165  1.0418 -1.0157]

The output is rounded to 4 decimals. The true values are 0, 1 and minus 1. The reference uses Adam with the learning rate 0.01. Its first reported loss is 4.2061 and its last is 0.0101, after 1500 steps. The noise alone gives a mean squared error of 0.0106 on these 200 points, so a training loss far below 0.01 means that the network fits the noise.

Provided code: support.py

Your code and the checks import this module with from support import .... You do not change it.

import numpy as np


def make_sine(n, rng, noise=0.1):
    x = rng.uniform(-np.pi, np.pi, size=n)
    y = np.sin(x) + rng.normal(scale=noise, size=n)
    return x, y

Hints

4 hints

    Solution and notes

    Locked

    Pass every check with Submit to open the reference solution and the notes.

    Run it on your computer

    Clone the repository, install numpy and run the same checks in a terminal:

    python3 scripts/practice/run.py train-sine-regression my_answer.py
    python3 scripts/practice/run.py train-sine-regression my_answer.py --examples

    Start my_answer.py from starter.py.

    Your code

    Python loads on the first run

    Your code is saved in this browser as you type. On a phone you can read and edit the code, but the checks are easier to use on a desktop.

    Keyboard shortcuts
    Ctrl Enter
    Run the examples
    Ctrl Shift Enter
    Submit
    Tab / Shift Tab
    Indent or outdent the lines
    Esc then Tab
    Move the focus out of the editor
    Alt H
    Show the next hint

    On a Mac, use Cmd in place of Ctrl.

    Select Run to check the examples, or Submit to run every check.