A small autoencoder works on greyscale strips: each strip is a list of pixel brightnesses between 0 and 1. The encoder squeezes the strip down to a code of numbers, the decoder rebuilds the strip from that code alone, and the reconstruction loss scores how good the copy is.
Encoder: one layer, ReLU. enc_w is a list of rows, one per code number, and each row holds weights, one per pixel. enc_b holds biases. Code number is
where is enc_w[j][i] and is enc_b[j].
Decoder: one layer, sigmoid. dec_w is a list of rows, one per rebuilt pixel, and each row holds weights, one per code number. dec_b holds biases. Rebuilt pixel is
where is dec_w[i][j] and is dec_b[i].
Reconstruction loss. Subtract, square, then average over every pixel:
Task: write autoencode(x, enc_w, enc_b, dec_w, dec_b) and return a tuple (code, rebuilt, loss):
code: the list of code numbers,rebuilt: the list of rebuilt pixels,loss: a single number.Round every returned number to 4 decimal places. Round only at the end: compute the loss from the unrounded rebuilt pixels.
Notice what the loss compares against. There is no label anywhere: the target is the input itself.