A Neural Network from Scratch
Stage 1 of 6v1 · 9fecafa6

The Artificial Neuron and Linear Combination

Compute the weighted sum z = Σ(w_i * x_i) + b and validate dimension consistency between inputs and weights.

Project Contract

Your program is a neural computation and training engine that processes commands from standard input in compact JSON format and writes results to standard output, reporting errors to stderr with exit code 1.

The Shipcode runner runs your program using the command declared in shipcode.yml:

challenge: neural-network
run: python3 main.py

First Principles: What is an Artificial Neuron?

To understand modern artificial intelligence, you do not need to start with deep networks containing billions of parameters. Everything starts with a single elementary unit conceived in 1943: the artificial neuronA simplified mathematical model inspired by biological brain cellsView official documentation.

Imagine you are deciding whether to go out for a walk today. Your brain weighs several environmental clues:

  • Is the weather nice? (x1x_1)
  • Is it the weekend? (x2x_2)
  • Do you have pending errands? (x3x_3)

However, not all clues carry equal importance to you. Good weather might be a huge positive factor, while errands might be a negative deterrent. The relative importance of each factor is called its weight (ww).

An artificial neuron models this exact process:

  1. It receives numerical input values (x1,x2,,xnx_1, x_2, \dots, x_n).
  2. It multiplies each input by its corresponding weight (xiwix_i \cdot w_i).
  3. It sums all these weighted multiplications.
  4. It adds an independent baseline value called the bias (bb).

Why is the Bias Necessary?

Without a bias, if all inputs were zero (x=[0,0]x = [0, 0]), the output would always be zero. The bias acts as the neuron's natural baseline tendency before receiving any external stimulus. Geometrically, the bias allows the decision boundary to shift up or down so it is not forced to pass through the origin (0,0)(0, 0).

Mathematical Formulation

The linear combination (commonly denoted as zz) is calculated using the affine sum:

z=i=1n(xiwi)+b=(x1w1)+(x2w2)++(xnwn)+b z = \sum_{i=1}^{n} (x_i \cdot w_i) + b = (x_1 \cdot w_1) + (x_2 \cdot w_2) + \dots + (x_n \cdot w_n) + b

Your Objective in this Stage

When standard input receives an operation with "op": "linear-neuron", your program must process:

{
  "op": "linear-neuron",
  "inputs": [1.0, 2.0],
  "weights": [0.5, -0.5],
  "bias": 0.2
}

Step-by-Step Walkthrough

Using the values from the example above:

  1. Multiply the first input by its weight: 1.0×0.5=0.51.0 \times 0.5 = 0.5.
  2. Multiply the second input by its weight: 2.0×(0.5)=1.02.0 \times (-0.5) = -1.0.
  3. Sum the weighted products: 0.5+(1.0)=0.50.5 + (-1.0) = -0.5.
  4. Add the baseline bias: 0.5+0.2=0.3-0.5 + 0.2 = -0.3.
  5. The final output is z=0.3z = -0.3.

Practical Implementation and Code Advice

In practical model development:

  • In Python: Use the built-in zip(inputs, weights) function to cleanly iterate across both vectors:
    if len(inputs) != len(weights):
        raise ValueError("Mismatched dimensions")
    z = sum(x * w for x, w in zip(inputs, weights)) + bias
    
  • In TypeScript: Use a standard for loop or reduce() starting from bias:
    if (inputs.length !== weights.length) {
      throw new Error("Dimension mismatch");
    }
    const z = inputs.reduce((acc, x, i) => acc + x * weights[i], bias);
    

Debugging Tips

If a test fails:

  • Print inputs, weights, and bias to sys.stderr or console.error to inspect raw values without altering standard output.
  • Make sure bias is added once at the end; it should not be multiplied by any inputs.

Validation and Output Rules

  1. Dimension Consistency: The number of elements in inputs must match weights exactly. If a neuron receives 3 inputs but only has 2 weights, write a message to stderr containing the word error and exit with code 1.
  2. Error Handling and Malformed JSON: If standard input is not valid JSON or the op field is unrecognized, output error to stderr and exit with code 1.
  3. Precision Handling: Round the result to 4 decimal places using the round_value / roundValue function provided in your starter. If the rounded value is an integer (including 0), serialize it as an integer in JSON (for example {"z":0} instead of {"z":0.0}).
  4. Response Format: Emit only the compact JSON object on a single line terminated by a newline:
    { "z": -0.3 }