ML Study Hub

Home / MLP / Week 11

Week 11 · Neural networks in sklearn

Official syllabus line: Neural networks models in scikit-learn
About 80 minEnd Term material (see exam radar)BSCS2008 · Ashish Tendulkar
Before you start: MLP weeks 5 and 7 (classification, multiclass). MLT week 12 for the theory of neurons, softmax and backpropagation.
Watch first: the animated story of this weekAbout 1-2 minutes of real 3D animation with a friendly voice. Pause any time.
Read the words of the video
  1. Imagine a special room filled with tiny voters, like little decision-makers. They each take some information, "squish" it, and then vote on an outcome. This "room of tiny voters" is what a neural network is! It helps computers learn to classify things, like telling cats from dogs.
  2. Scikit-learn helps build this room of voters for you. You decide its shape: how many rows of voters and how many in each row. You also pick the "squish" they use, and how long to patiently train them. Then, the computer adjusts all connections to make it smart.
  3. Let's count network parts! If you have 20 features for input, and two hidden layers with 30 and 10 voters, leading to 4 output classes, you'll have specific connections. For example, between the first two layers, there are 20 times 30 weights plus 30 biases. This gives a total of 984 adjustable parameters.
  4. Remember, "squish" functions create non-linearity, which is super important! If your network is too good on training data but bad on new data, you're overfitting. To fix this, increase "alpha" or use early stopping. Always set a "random state" for consistent results. Keep practicing, you've got this!

The one-minute story

Think of it like this

In MLT week 12 you met the room of tiny voters. scikit-learn's MLPClassifier and MLPRegressor build that room for you with a single line of code. ("MLP" here means multi-layer perceptron, which is another name for a plain neural network, and has nothing to do with this course being called MLP!)

You decide the shape of the room (how many rows of voters, how many in each row), the squish each voter uses, and how patiently the training should run. scikit-learn then adjusts every weight by backpropagation, shows you the loss falling epoch by epoch, and stops when it stops improving.

The skills this week: reading the shape of the network from the code, counting its parameters, picking sensible dials, and noticing the same old villains: overfitting (cure: alpha, early stopping) and unscaled data.

By the end of this week you can:

  • train MLPClassifier / MLPRegressor and read coefs_, intercepts_, n_layers_, n_iter_, loss_curve_;
  • set hidden_layer_sizes, activation, solver, alpha, max_iter, early_stopping;
  • count parameters and know the output activation for each task;
  • explain what happens with no non-linearity and with too few hidden units.

Words you need

Words you need
  • Hidden layer - a layer between input and output. hidden_layer_sizes=(100,) means one hidden layer of 100 neurons.
  • Activation - the non-linear squish: 'relu' (default), 'tanh', 'logistic' (sigmoid), 'identity' (no squish).
  • Solver - the optimiser: 'adam' (default), 'sgd', 'lbfgs'.
  • Epoch - one pass over the training data. max_iter counts epochs for adam and sgd.
  • alpha - the L2 regularisation strength (like ridge). Larger alpha = more regularisation.
  • Loss curve - the training loss after every epoch.

Idea 1: The API

from sklearn.neural_network import MLPClassifier, MLPRegressor
mlp = MLPClassifier(hidden_layer_sizes=(100,), activation="relu", solver="adam",
                    alpha=0.0001, batch_size="auto", learning_rate_init=0.001,
                    max_iter=200, early_stopping=False, random_state=42)

Those are (almost) the defaults. The ones to remember:

ParameterDefaultNotes
hidden_layer_sizes(100,)a tuple: one number per hidden layer. (50, 50) = two hidden layers of 50
activation'relu'applies to hidden layers only
solver'adam'good default; 'lbfgs' is quick for small data; 'sgd' adds momentum options
alpha0.0001L2 penalty
batch_size'auto'min⁡(200, n)\min(200,\,n)
learning_rate_init0.001for adam and sgd
max_iter200maximum epochs (a ConvergenceWarning means it was not enough)
tol, n_iter_no_change1e-4, 10stop if the loss stops improving by tol for 10 epochs
early_stoppingFalsehold out validation_fraction=0.1 and stop when the validation score stops improving
random_stateNoneset it: the start is random, so results vary between runs

You do not specify the input or output layer sizes: they are read from the data (number of features, number of classes). The output activation is chosen for you and stored in out_activation_:

TaskOutput activation
multiclass classificationsoftmax
binary or multilabel classificationlogistic (sigmoid)
regression (MLPRegressor)identity

Idea 2: A real run on digits

The 1797 digit images (64 pixels each), standardised, 75/25 split, with the default network (one hidden layer of 100 ReLU neurons):

mlp = make_pipeline(StandardScaler(), MLPClassifier(random_state=42, max_iter=300))
mlp.fit(X_train, y_train)
test accuracy 0.980     train accuracy 1.000
n_iter_ = 147    n_layers_ = 3    n_outputs_ = 10    out_activation_ = 'softmax'

(n_layers_ counts input + hidden + output layers: 1+1+1=31+1+1=3.) Inspect the learned numbers:

[c.shape for c in mlp[-1].coefs_]        # [(64, 100), (100, 10)]   one weight matrix per layer
[b.shape for b in mlp[-1].intercepts_]   # [(100,), (10,)]          one bias vector per layer

Counting parameters (it is the sum over layers of m×n+nm\times n+n):

64×100+100⏟6500+100×10+10⏟1010=7510\underbrace{64\times100+100}_{6500}+\underbrace{100\times10+10}_{1010}=\mathbf{7510}

For hidden_layer_sizes=(50, 50) the shapes become [(64,50), (50,50), (50,10)] and the count is (3200+50)+(2500+50)+(500+10)=6310(3200+50)+(2500+50)+(500+10)=\mathbf{6310}, with n_layers_=4.

loss_curve_ has one entry per epoch (147 here) and falls from about 2.52 to 0.0055: plot it to watch training. predict_proba(X) returns an (m,10)(m,10) array whose rows sum to 1 (softmax).

Idea 3: The dials, with evidence

Change (digits, scaled)Test accuracyWhat it shows
default, (100,)0.980train accuracy 1.0: it fits the training data perfectly
(2,) only 2 hidden units0.587underfits: too small a bottleneck to represent 10 digits
alpha=1.0 (strong L2)0.982train 1.0, test slightly up: regularisation helps a little
activation="identity" (no non-linearity)0.964collapses to a linear model; worse, even if the problem is almost linear
early_stopping=True0.960stopped after 39 epochs; validation_scores_ and best_validation_score_ (0.985) are recorded

Lessons:

  • Capacity: too few hidden units underfit; many units can overfit. Tune the architecture with cross-validation.
  • alpha is the regulariser: larger = simpler weights = less overfitting. (And early_stopping=True is another regulariser.)
  • With activation="identity" the whole network is a single linear map, no matter how many layers: this is what "introducing non-linearity" fixes. To make a network non-linear, use a non-linear activation ('relu', 'tanh', 'logistic').
  • Scale your inputs. Networks train much better when inputs are standardised or in [0,1][0,1]. (The digit pixels are all between 0 and 16 so the unscaled run still reached 0.978; with features on very different scales the gap is large.)
  • Results change between runs because the start is random (random_state). For reproducible results set it.

Idea 4: Other points

  • Binary classification gives n_outputs_=1, out_activation_='logistic', and the last weight matrix has shape (n_hidden, 1).
  • MLPRegressor has an identity output; scale the target too when it is large.
  • partial_fit is available (on adam and sgd): for classification pass classes= the first time. Training in chunks like this is not the same as a full-epoch fit; our 3-pass demo only reached 0.53.
  • Hyperparameters to tune: hidden_layer_sizes, alpha, learning_rate_init, activation. Use GridSearchCV with the pipeline name: {"mlpclassifier__hidden_layer_sizes": [(50,), (100,), (50, 50)], "mlpclassifier__alpha": [1e-4, 1e-2]}.
  • scikit-learn's MLP is fine for small and medium data. For big images or text use a deep-learning library (PyTorch, TensorFlow/Keras) with GPUs.
  • Neural nets are non-convex: different starts can land in different minima.

Solved examples

Solved example: 1. Count the parameters

Question. MLPClassifier(hidden_layer_sizes=(30, 10)) is trained on 20 features and 4 classes. Give the shapes of coefs_ and the total number of parameters.

Solution. Layers: 20→30→10→420\to30\to10\to4. coefs_ shapes: (20,30), (30,10), (10,4)(20,30),\,(30,10),\,(10,4). Parameters: (600+30)+(300+10)+(40+4)=630+310+44=984(600+30)+(300+10)+(40+4)=630+310+44=\mathbf{984}. n_layers_ =4=4.

Solved example: 2. Which activation introduces non-linearity?

Question. An MLPClassifier has activation="identity". Does adding more hidden layers help?

Solution. No. With identity activations, any number of layers collapses to one linear map, so it can only draw straight boundaries, no more powerful than logistic regression. Use relu/tanh/logistic for non-linearity.

Solved example: 3. Reading the loss curve

Question. loss_curve_ is [2.3, 1.1, 0.6, 0.4, 0.40001, 0.40000, ...] and training stops with n_iter_=15 although max_iter=200. Why?

Solution. The loss improved by less than tol for n_iter_no_change (10) epochs in a row, so training was declared converged. If n_iter_ had equalled max_iter you would instead see a ConvergenceWarning, and you should raise max_iter or scale the data.

Your turn

Your turn: 1. Parameter count

Inputs: 10 features. hidden_layer_sizes=(8,). 3 classes. How many parameters?

Need a hint?

10→8→310\to8\to3.

Show the full solution

(10×8+8)+(8×3+3)=88+27=115(10\times8+8)+(8\times3+3)=88+27=\mathbf{115}.

Your turn: 2. Read the shape

coefs_ shapes are [(5, 12), (12, 12), (12, 2)]. How many hidden layers, features, hidden units per layer, and outputs?

Need a hint?

Each tuple is (input size, output size).

Show the full solution

5 features; 2 hidden layers of 12 units each; 2 outputs (so a 2-class multiclass-style output, or 2 labels). n_layers_ =4=4.

Your turn: 3. Which dial?

Your MLP has train accuracy 100% and test 90%. Name two dials to change.

Need a hint?

Overfitting.

Show the full solution

Increase alpha (more L2), use early_stopping=True, or reduce hidden_layer_sizes. (Also: more data.)

Your turn: 4. Output layer

For (a) a 5-class problem, (b) predicting house price, (c) a yes/no problem, which output activation does MLP* use?

Need a hint?

Use the table.

Show the full solution

(a) softmax, (b) identity, (c) logistic.

Your turn: 5. True or false

(a) hidden_layer_sizes=(100,) means 100 hidden layers. (b) The default solver is adam. (c) activation is applied to the output layer. (d) Results are identical between runs without random_state.

Need a hint?

Read the table again.

Show the full solution

(a) False: one hidden layer of 100 neurons. (b) True. (c) False: hidden layers only (the output activation is automatic). (d) False: random initialisation.

Exam radar

Exam radar

MLP End Term: "You're designing an MLPClassifier for an image recognition task ... which element introduces non-linearity?" (the activation function), "which of these settings gives the lowest overfitting?" (more alpha, early stopping), "what is hidden_layer_sizes=(50, 50)?" and parameter counts / coefs_ shapes.

From MLT: neural networks in 16 End Term papers, activation functions in 19, ReLU in 11, architecture in 18.

Watch out - real exam trap
  • hidden_layer_sizes is a tuple of hidden sizes only; the input and output sizes are automatic. (100) without the comma is just the number 100: write (100,).
  • n_layers_ counts input + hidden + output.
  • Identity activation = no non-linearity.
  • Count the biases too.
  • max_iter counts epochs, not weight updates.
  • Set random_state for repeatable results.

Quick quiz

Quick quiz

MLPClassifier(hidden_layer_sizes=(64, 32)) creates how many hidden layers?

  • 1
  • 2
  • 3
  • 96
The tuple has two entries, so there are two hidden layers (of 64 and 32 neurons).

Which element of a neural network introduces non-linearity?

  • the learning rate
  • the bias
  • the activation function
  • the batch size
Without non-linear activations the network is just a linear model.

Which setting is a way to reduce overfitting in MLPClassifier?

  • early_stopping=True or a larger alpha
  • a smaller alpha and more hidden units
  • activation set to identity
  • removing the scaler
Early stopping and L2 regularisation (alpha) restrain overfitting.

Select all TRUE statements. (select all that apply)

  • The default activation for hidden layers is relu.
  • Multiclass output uses softmax.
  • n_layers_ counts only the hidden layers.
  • max_iter counts mini-batches.
n_layers_ includes input and output, and max_iter counts epochs.

Recap

Remember this
  • MLPClassifier/Regressor: hidden_layer_sizes=(100,), activation='relu', solver='adam', alpha=1e-4, max_iter=200 (epochs), early_stopping=False. Set random_state; scale inputs.
  • Output activation is automatic: softmax (multiclass), logistic (binary), identity (regression).
  • coefs_ / intercepts_; parameters =∑(mn+n)=\sum(mn+n); digits default: 7510.
  • Overfit →\to raise alpha, early stop, shrink the network. Too few units →\to underfit. Identity activation →\to linear model.
Formulas to keep
  • Parameters: ∑ℓ(mℓnℓ+nℓ)\sum_\ell(m_\ell n_\ell+n_\ell) over layers; n_layers_ = input + hidden + output
  • Defaults: hidden_layer_sizes=(100,), activation="relu", solver="adam", alpha=1e-4, learning_rate_init=1e-3, max_iter=200, tol=1e-4, n_iter_no_change=10
Connected weeks (learn them together)

Practise with real exam questions

These come straight from past papers (with the real figures and the official answer key). Open 14 real questions on this week   All End Term papers