MADALINE neural network: Complete Guide — Principles, Examples and Python Implementation
Summary
MADALINE (Multiple ADALINE) is one of the first artificial neural networks to use a hidden layer. Introduced by Bernard Widrow and Marcian Hoff in 1960, it relies on the association of multiple ADALINE neurons arranged in parallel, followed by a fixed output unit. Its major contribution lies in the MRI rule (Minimum Rule of Intervention), an elegant learning algorithm that only corrects truly uncertain neurons, thus minimizing disturbances to already acquired knowledge. This guide thoroughly explores the mathematical principles, intuition, and complete Python code of the MADALINE neural network.
Mathematical principle
Architecture of the MADALINE neural network
Unlike a single ADALINE, the MADALINE neural network introduces a hidden layer composed of N ADALINE units operating in parallel:
- Input layer: The input vector x = (x₁, x₂, …, xₙ) is sent to each ADALINE neuron in the hidden layer.
- Hidden layer: N independent ADALINE neurons, each with its own weights wᵢ and its own bias bᵢ. Each neuron computes a net output:
netᵢ = wᵢ · x + bᵢ = Σⱼ wᵢⱼ · xⱼ + bᵢ
The discrete output (sign) of each ADALINE is:
yᵢ = sign(netᵢ) = +1 if netᵢ ≥ 0, −1 otherwise
- Output layer: A fixed function combines the outputs of the N ADALINE neurons. Common strategies are:
- Majority vote: y_output = sign(Σᵢ yᵢ)
- Linear combination: y_output = sign(Σᵢ αᵢ · yᵢ) where the αᵢ are combination weights
- Fixed logic function: AND, OR, or other deterministic logic gates
Widrow-Hoff rule for each ADALINE
Each individual ADALINE neuron in the hidden layer follows the Widrow-Hoff rule (also called the LMS rule — Least Mean Squares):
Δwᵢ = η · (t − netᵢ) · x
where:
– η is the learning rate (0 < η < 1)
– t is the desired target for this neuron (+1 or −1)
– netᵢ is the net (continuous) output before applying the sign
– x is the input vector
This rule minimizes the mean squared error of each neuron via gradient descent, unlike the Perceptron which only updates its weights in case of a classification error.
The MRI rule (Minimum Rule of Intervention) — The heart of learning
The essential contribution of the MADALINE neural network model is the MRI rule (Minimum Rule of Intervention). Instead of updating all ADALINE neurons when the overall output is in error, the MRI rule identifies and corrects only the most “hesitant” neuron:
MRI Algorithm:
- Present an example (x, target d) to the network.
- Each ADALINE i computes its net output netᵢ. If netᵢ ≥ 0, its discrete output is +1; otherwise −1.
- Combine the outputs to obtain the overall output y_output.
- If y_output ≠ d (error):
a. Identify the ADALINE whose net output netᵢ is closest to zero (i.e., |netᵢ| minimal among those whose discrete output is “responsible” for the majority vote). This is the most hesitant neuron.
b. Only this neuron is updated with the Widrow-Hoff rule to force it to flip its output.
c. Recalculate the overall output. If the error persists, identify the next most hesitant neuron and update it. Repeat until correction or exhaustion of neurons. - If y_output = d (no error): no weights are modified.
Why this works: By only touching the most uncertain neuron, we minimize disruption to the other neurons that had a “strong” opinion (net output far from zero). This is the functional equivalent of the minimum surprise principle: we only correct the one who really needs it, without destabilizing the rest of the collective.
Variants RRI and MRI
Widrow proposed three algorithms associated with the MADALINE neural network:
- MRI (Minimum Rule of Intervention): Described above. Selects one neuron at a time and corrects it individually.
- RRI (Random Rule of Intervention): Randomly selects a neuron whose output is compatible with the required inversion, then corrects it. Less deterministic but sometimes useful for avoiding local minima.
- MRI-II: An improved version that allows correcting several neurons simultaneously if necessary, while still respecting the minimum intervention principle.
For this guide, we focus on the original MRI rule, the most elegant and the most taught.
Intuition: the team of experts
Imagine a team of N experts assembled to solve a classification problem. Each expert (ADALINE) examines the data from a slightly different angle — that is, with their own weights wᵢ — and renders a verdict: +1 or −1. The final decision is made by majority vote.
Now imagine the vote yields an incorrect result. How do you correct the team?
Naïve approach (classical network): You ask all the experts to revise their opinion. It’s brutal: the experts who had strong arguments (very positive or very negative net output) also see their knowledge modified, which can destabilize what they had learned well.
MADALINE neural network approach (MRI rule): You identify the most hesitant expert — the one whose verdict was closest to indecision (net output close to zero). You only ask that expert to change their mind. The confident experts retain their positions. This is minimum intervention: you touch as little as possible what was already working.
This analogy explains why the MADALINE neural network often converges faster than a classical multilayer Perceptron: by preserving the knowledge acquired by “self-assured” neurons, learning is more stable and requires fewer iterations.
Complete Python implementation
Solving the XOR problem with a MADALINE neural network
The XOR problem is the classic benchmark: it is not linearly separable, so a single ADALINE or Perceptron fails. With 2 or 3 ADALINE in the hidden layer, the MADALINE neural network can nonetheless solve it.
import numpy as np
class Madaline:
"""
MADALINE neural network — Implementation from scratch.
Hidden layer of N ADALINE with MRI rule.
"""
def __init__(self, n_inputs, n_adalines=3, eta=0.1,
n_iter=1000, threshold=0.0):
self.n_inputs = n_inputs
self.n_adalines = n_adalines
self.eta = eta
self.n_iter = n_iter
self.threshold = threshold
# Each ADALINE has its own weights + bias
np.random.seed(42)
self.weights = np.random.randn(n_adalines, n_inputs) * 0.5
self.biases = np.random.randn(n_adalines) * 0.5
def _net_output(self, x):
"""Net (continuous) output of each ADALINE."""
return np.dot(self.weights, x) + self.biases
def _discrete_output(self, net):
"""Discrete (sign) output of each ADALINE."""
return np.where(net >= self.threshold, 1, -1)
def _combine(self, discrete):
"""Majority vote."""
total = np.sum(discrete)
return 1 if total >= 0 else -1
def _mri_update(self, x, nets, discrete, target):
"""
MRI rule: sort ADALINE by ascending |net|
and correct the most hesitant first.
"""
order = np.argsort(np.abs(nets))
for idx in order:
# Widrow-Hoff rule for this neuron alone
error = target - nets[idx]
self.weights[idx] += self.eta * error * x
self.biases[idx] += self.eta * error
# Check if the majority vote is now correct
new_nets = self._net_output(x)
new_discrete = self._discrete_output(new_nets)
new_output = self._combine(new_discrete)
if new_output == target:
return True # Successful correction
return False
def fit(self, X, y, verbose=True):
"""
Learning with the MRI rule.
X: matrix (n_samples, n_inputs)
y: target vector (n_samples,) values +1 or -1
"""
n_samples = X.shape[0]
self.errors_history = []
for epoch in range(self.n_iter):
epoch_errors = 0
for i in range(n_samples):
nets = self._net_output(X[i])
discrete = self._discrete_output(nets)
output = self._combine(discrete)
if output != y[i]:
epoch_errors += 1
self._mri_update(X[i], nets, discrete, y[i])
self.errors_history.append(epoch_errors)
if verbose and (epoch + 1) % 100 == 0:
print(f"Époque {epoch+1:>4d}/{self.n_iter} "
f"— Erreurs : {epoch_errors}/{n_samples}")
if epoch_errors == 0:
if verbose:
print(f"\nConvergence atteinte à l'époque {epoch+1} !")
break
return self
def predict(self, X):
"""Prediction for a set of samples."""
preds = []
for x in X:
nets = self._net_output(x)
discrete = self._discrete_output(nets)
preds.append(self._combine(discrete))
return np.array(preds)
def score(self, X, y):
"""Accuracy."""
return np.mean(self.predict(X) == y)
# =============================================
# Test on the XOR problem
# =============================================
if __name__ == "__main__":
X_xor = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y_xor = np.array([-1, 1, 1, -1])
print("=" * 60)
print("MADALINE neural network — XOR Problem")
print("=" * 60)
model = Madaline(n_inputs=2, n_adalines=3, eta=0.3, n_iter=2000)
model.fit(X_xor, y_xor, verbose=True)
print("\n" + "=" * 60)
print("Final results:")
print("=" * 60)
for x, t in zip(X_xor, y_xor):
nets = model._net_output(x)
disc = model._discrete_output(nets)
out = model._combine(disc)
mark = "✓" if out == t else "✗"
print(f" Input {list(x)} → nets = {np.round(nets, 3)}, "
f"ADALINE = {disc}, "
f"MADALINE = {out} (exp. {t}) {mark}")
acc = model.score(X_xor, y_xor)
print(f"\nAccuracy on XOR: {acc * 100:.1f}%")
Convergence analysis
The convergence of the MADALINE neural network is based on solid theoretical foundations:
- Correction guarantee: The Widrow-Hoff rule minimizes the mean squared error of each ADALINE. If the problem is linearly separable in the space induced by the hidden layer, convergence is guaranteed.
- Stability: Unlike backpropagation which modifies all weights simultaneously, the MRI rule only touches one neuron at a time, reducing the risk of divergence.
- Speed: The number of iterations needed depends on the number of ADALINE (at least 2 are needed for XOR), the learning rate η, and the complexity of the decision boundary.
Comparison: Multilayer Perceptron vs MADALINE
- Learning algorithm: Backpropagation (MLP) vs MRI / Widrow-Hoff rule (MADALINE)
- Activation function: Sigmoid / ReLU (MLP) vs Binary sign (MADALINE)
- Weight update: All neurons simultaneously (MLP) vs Only the most hesitant ADALINE (MRI)
- Stability: Can diverge without regularization (MLP) vs Very stable: preserves safe weights (MADALINE)
- Convergence: Often faster with ReLU (MLP) vs Slower but more robust (MADALINE)
- Complexity: O(n² per layer) (MLP) vs O(N_adalines × n_inputs) (MADALINE)
- Primary use: Modern deep learning (MLP) vs Hidden-layer binary classification (MADALINE)
Hyperparameters
The MADALINE neural network has four main hyperparameters:
n_adalines (number of ADALINE in hidden layer)
- Role: Determines the network’s capacity to model nonlinear boundaries.
- Typical value: 2 to 10 for simple problems. For XOR, 2 ADALINE are theoretically sufficient, but 3 offer more robustness.
- Empirical rule: The minimum number of ADALINE is the number of linearly separable regions needed to cover the positive class. You can start with 3 and adjust.
eta (learning rate)
- Role: Controls the amplitude of each Widrow-Hoff update.
- Recommended range: 0.01 to 0.5.
- Behavior: A η that is too small leads to slow convergence; a η that is too large can cause oscillations around the optimal solution.
n_iter (maximum number of iterations)
- Role: Upper limit on the number of training epochs.
- Recommended range: 500 to 5,000.
- Early stopping criterion: Learning stops as soon as the error on the training set reaches zero (convergence).
threshold (decision threshold)
- Role: The value from which an ADALINE switches from −1 to +1.
- Default value: 0.0.
- Note: The bias of each ADALINE plays a similar role; the threshold is therefore rarely modified in practice.
Advantages and limitations
Advantages of the MADALINE neural network
- Learning stability: The MRI rule preserves the knowledge of “safe” neurons, reducing the phenomenon of catastrophic forgetting.
- Conceptual simplicity: Each neuron follows the Widrow-Hoff rule, easy to understand and implement, without needing to compute chain gradients (unlike backpropagation).
- No saturation plateau: ADALINE uses continuous net outputs for learning, thus avoiding the sigmoid saturation problem.
- Historical importance: The MADALINE neural network was the first model to demonstrate that a hidden layer could solve non-linearly separable problems, paving the way for modern multi-layer networks.
Limitations of the MADALINE neural network
- Limited capacity: With a single hidden layer and a fixed output function, the MADALINE cannot model functions as complex as a deep MLP with backpropagation.
- No deep generalization: The architecture does not naturally extend to multiple hidden layers, which limits its expressive power.
- Performance on large datasets: The MRI rule, although stable, is slower than mini-batch SGD backpropagation on large datasets.
- Binary: The MADALINE neural network is inherently a binary classifier. Extension to multi-class requires one-vs-rest type strategies.
4 practical use cases
1. Handwritten character recognition (simplified OCR)
The MADALINE neural network can be used to distinguish two specific characters, for example the digits “1” and “7” in binarized images. Each ADALINE in the hidden layer detects a different pattern (vertical bar, diagonal, etc.), and the majority vote provides the final classification.
2. Radar / sonar signal classification
In military and navigation applications, the MADALINE neural network was historically used by Widrow to classify radar echoes as “detected object” or “background noise”. The stability of the MRI rule is crucial in these contexts: you don’t want the system to “forget” what it has learned about clear echoes.
3. Industrial anomaly detection
To monitor an industrial process (temperature, pressure, vibration), the MADALINE neural network can learn “normal” behavior and flag anomalies. Each ADALINE monitors a different aspect of the signal, and minimum intervention ensures that detection remains stable even in the presence of noise.
4. Adaptive speech filtering (echo cancellation)
This was Widrow’s original application: individual ADALINE units act as adaptive filters in a parallel filter bank. The MRI rule allows adjusting only the most uncertain filters, which preserves the overall signal quality while reducing the acoustic echo.
See also
- Deux modules pour bien sécuriser votre navigateur web
- Tester la Primalité de $2n^2 – 1$ en Python : Guide Complet et Optimisé

