Deep House Architecture / What we are building
A deep network for house price stacks more than one hidden layer. Here: three features in, two ReLU hidden layers (4 neurons each), then one linear output that guesses a dollar price.
Same Layer idea as
Neural Networks — just one more hop in the middle.
This page builds the model and runs a forward pass only. Training comes later on the trail.
- Hidden layer
- A middle layer of neurons with an activation (ReLU here). Each neuron sees the previous layer’s outputs and produces a new vector. We use two of them so patterns can compose.
- Linear output
- The last neuron has no ReLU. Price is unbounded — it can be any real number, including large positives.
- Forward
- One trip input → H1 → H2 → price. No weight updates. Just a prediction from the current weights.
Build model
Architecture for HOUSES
Five tiny listings. Features are [sqft, beds, age]. Target is the sale price.
The net is 3 → 4 (ReLU) → 4 (ReLU) → 1 (linear).
Square footage is thousands; we scale inputs so training does not explode
(scale divides sqft by 1000 and age by 10 before the first layer).
| sqft | beds | age | price |
|---|---|---|---|
| 1200 | 2 | 15 | 245_000 |
| 1800 | 3 | 8 | 310_000 |
| 2200 | 4 | 3 | 420_000 |
| 900 | 2 | 40 | 180_000 |
| 1500 | 3 | 10 | 295_000 |
- in play
Same HOUSES vector you used in linear regression and single-neuron lessons — only the depth ahead is new.
Solution in TypeScript
Layer is the same building block as the XOR net: ReLU or linear, random small weights, forward returns outputs and pre-activations.
DeepHouseNet wires H1 → H2 → out. Seed 37 keeps every printed number on this trail reproducible.
Square footage is thousands; we scale inputs so training does not explode.
type Vector = number[];
type Matrix = number[][]; // rows = neurons, cols = inputs
function relu(x: number): number {
return Math.max(0, x);
}
/** Square footage is thousands; we scale inputs so training does not explode. */
function scale(features: Vector): Vector {
return [features[0] / 1000, features[1], features[2] / 10];
}
/** Mulberry32 — fixed seed so this lesson’s numbers are reproducible. */
function mulberry32(seed: number): () => number {
return () => {
seed |= 0;
seed = (seed + 0x6d2b79f5) | 0;
let t = Math.imul(seed ^ (seed >>> 15), 1 | seed);
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
};
}
class Layer {
weights: Matrix;
biases: Vector;
activation: "relu" | "linear";
constructor(
inputSize: number,
outputSize: number,
activation: "relu" | "linear",
rnd: () => number,
) {
this.activation = activation;
this.weights = Array.from({ length: outputSize }, () =>
Array.from({ length: inputSize }, () => rnd() * 0.5 - 0.25),
);
this.biases = Array(outputSize).fill(0);
}
forward(inputs: Vector): { outputs: Vector; preActivations: Vector } {
const preActivations: Vector = [];
const outputs: Vector = [];
for (let j = 0; j < this.weights.length; j++) {
let sum = this.biases[j];
for (let i = 0; i < inputs.length; i++) {
sum += inputs[i] * this.weights[j][i];
}
preActivations.push(sum);
outputs.push(this.activation === "relu" ? relu(sum) : sum);
}
return { outputs, preActivations };
}
}
/**
* Deep house net: 3 → 4 (ReLU) → 4 (ReLU) → 1 (linear price).
* Seed 37: two HOUSES rows flip different H1 neurons (same weights).
*/
class DeepHouseNet {
h1: Layer;
h2: Layer;
out: Layer;
constructor(seed = 37) {
const rnd = mulberry32(seed);
this.h1 = new Layer(3, 4, "relu", rnd);
this.h2 = new Layer(4, 4, "relu", rnd);
this.out = new Layer(4, 1, "linear", rnd);
}
forward(features: Vector): number {
const x = scale(features); // sqft/1000, age/10
const a = this.h1.forward(x);
const b = this.h2.forward(a.outputs);
const o = this.out.forward(b.outputs);
return o.outputs[0];
}
}
const HOUSES: [Vector, number][] = [
[[1200, 2, 15], 245_000],
[[1800, 3, 8], 310_000],
[[2200, 4, 3], 420_000],
[[ 900, 2, 40], 180_000],
[[1500, 3, 10], 295_000],
];
const net = new DeepHouseNet();
const features = HOUSES[4][0]; // [1500, 3, 10]
console.log(features, "→", net.forward(features).toFixed(3));
// ≈ 0.006 — nowhere near 295_000. Weights are random; we have not trained yet.[1500, 3, 10] prints something like ≈ 0.006 — not 295_000.
The architecture can express prices; it has not learned them yet. Next lesson walks the forward numbers; later lessons train.Next
Trail
Deep Learning overview → Deep House Architecture → Forward Pass Through Depth.