Clustering

Clustering#

Clustering seeks to group data into clusters based on their properties and then allow us to predict which cluster a new member belongs.

We’ll use a dataset generator that is part of scikit-learn called make_moons. This generates data that falls into 2 different sets with a shape that looks like half-moons.

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
def generate_data():
    xvec, val = datasets.make_moons(200, noise=0.2)

    # encode the output to be 2 elements
    x = []
    v = []
    for xv, vv in zip(xvec, val):
        x.append(np.array(xv))
        v.append(vv)

    return np.array(x), np.array(v)
x, v = generate_data()

Let’s look at a point and it’s value

print(f"x = {x[0]}, value = {v[0]}")
x = [-0.19114745  1.0553034 ], value = 0

Now let’s plot the data

def plot_data(x, v):
    xpt = [q[0] for q in x]
    ypt = [q[1] for q in x]

    fig, ax = plt.subplots()
    ax.scatter(xpt, ypt, s=40, c=v, cmap="viridis")
    ax.set_aspect("equal")
    return fig
fig = plot_data(x, v)
../_images/cc89d2a3c66f5ebce5c7b518e1ec594cabfa22b78d35ac80701384305fc2e654.png

We want to partition this domain into 2 regions, such that when we come in with a new point, we know which group it belongs to.

First we setup and train our network

from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
from tensorflow.keras.optimizers import RMSprop
2025-02-18 13:19:43.867815: I external/local_xla/xla/tsl/cuda/cudart_stub.cc:32] Could not find cuda drivers on your machine, GPU will not be used.
2025-02-18 13:19:43.871025: I external/local_xla/xla/tsl/cuda/cudart_stub.cc:32] Could not find cuda drivers on your machine, GPU will not be used.
2025-02-18 13:19:43.877568: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:477] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered
WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
E0000 00:00:1739884783.891087    3393 cuda_dnn.cc:8310] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered
E0000 00:00:1739884783.895284    3393 cuda_blas.cc:1418] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered
2025-02-18 13:19:43.911364: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.
To enable the following instructions: AVX2 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.
model = Sequential()
model.add(Dense(50, input_dim=2, activation="relu"))
model.add(Dense(20, activation="relu"))
model.add(Dense(1, activation="sigmoid"))
/opt/hostedtoolcache/Python/3.11.11/x64/lib/python3.11/site-packages/keras/src/layers/core/dense.py:87: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.
  super().__init__(activity_regularizer=activity_regularizer, **kwargs)
2025-02-18 13:19:45.547668: E external/local_xla/xla/stream_executor/cuda/cuda_driver.cc:152] failed call to cuInit: INTERNAL: CUDA error: Failed call to cuInit: UNKNOWN ERROR (303)
rms = RMSprop()
model.compile(loss='binary_crossentropy',
              optimizer=rms, metrics=['accuracy'])
from IPython.display import SVG
from keras.utils import plot_model

plot_model(model, show_shapes=True, dpi=100)
../_images/0848a8cddb93d36618f9034dc87627d1679ac68c7cf23175799db84d5f59b8a1.png

We seem to need a lot of epochs here to get a good result

epochs = 100
results = model.fit(x, v, batch_size=50, epochs=epochs)
Epoch 1/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 1s 639ms/step - accuracy: 0.4200 - loss: 0.7097

4/4 ━━━━━━━━━━━━━━━━━━━━ 1s 6ms/step - accuracy: 0.5093 - loss: 0.6938  
Epoch 2/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - accuracy: 0.7800 - loss: 0.6584

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8227 - loss: 0.6502 
Epoch 3/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8200 - loss: 0.6316

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8033 - loss: 0.6258 
Epoch 4/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8000 - loss: 0.5993

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8107 - loss: 0.6012 
Epoch 5/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8400 - loss: 0.5766

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8360 - loss: 0.5773 
Epoch 6/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8600 - loss: 0.5426

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8527 - loss: 0.5538 
Epoch 7/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - accuracy: 0.9000 - loss: 0.5244

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8513 - loss: 0.5398 
Epoch 8/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8200 - loss: 0.5396

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8340 - loss: 0.5301 
Epoch 9/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8000 - loss: 0.5198

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8267 - loss: 0.5144 
Epoch 10/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - accuracy: 0.8400 - loss: 0.4845

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8420 - loss: 0.4921 
Epoch 11/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9200 - loss: 0.4424

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8767 - loss: 0.4608 
Epoch 12/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.7800 - loss: 0.4923

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8160 - loss: 0.4769 
Epoch 13/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9400 - loss: 0.3933

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8747 - loss: 0.4330 
Epoch 14/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8400 - loss: 0.4376

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8440 - loss: 0.4358 
Epoch 15/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8400 - loss: 0.4375

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8540 - loss: 0.4258 
Epoch 16/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - accuracy: 0.8200 - loss: 0.4161

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8540 - loss: 0.4036 
Epoch 17/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8600 - loss: 0.4097

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8607 - loss: 0.4075 
Epoch 18/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.9400 - loss: 0.3484

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8887 - loss: 0.3768 
Epoch 19/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8800 - loss: 0.3488

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8620 - loss: 0.3776 
Epoch 20/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8800 - loss: 0.3437

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8740 - loss: 0.3638 
Epoch 21/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9200 - loss: 0.3177

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8873 - loss: 0.3487 
Epoch 22/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9200 - loss: 0.2874

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8807 - loss: 0.3463 
Epoch 23/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8400 - loss: 0.3904

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8613 - loss: 0.3640 
Epoch 24/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8400 - loss: 0.3521

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8633 - loss: 0.3489 
Epoch 25/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8000 - loss: 0.4066

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8620 - loss: 0.3469 
Epoch 26/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - accuracy: 0.8600 - loss: 0.4023

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8653 - loss: 0.3502 
Epoch 27/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.7800 - loss: 0.4256

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8347 - loss: 0.3657 
Epoch 28/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9400 - loss: 0.2335

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8953 - loss: 0.3023 
Epoch 29/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9200 - loss: 0.2448

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9007 - loss: 0.2809 
Epoch 30/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9000 - loss: 0.2909

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8840 - loss: 0.3075 
Epoch 31/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9200 - loss: 0.2988

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9000 - loss: 0.2923 
Epoch 32/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9000 - loss: 0.2889

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8927 - loss: 0.2971 
Epoch 33/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9000 - loss: 0.3479

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9000 - loss: 0.3011 
Epoch 34/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9200 - loss: 0.2947

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8907 - loss: 0.3061 
Epoch 35/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9200 - loss: 0.2322

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8927 - loss: 0.2796 
Epoch 36/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - accuracy: 0.8800 - loss: 0.3602

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8953 - loss: 0.3072 
Epoch 37/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9400 - loss: 0.2167

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9033 - loss: 0.2732 
Epoch 38/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9400 - loss: 0.1798

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8953 - loss: 0.2709 
Epoch 39/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - accuracy: 0.8800 - loss: 0.2883

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8887 - loss: 0.2837 
Epoch 40/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8600 - loss: 0.3468

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8920 - loss: 0.2883 
Epoch 41/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8600 - loss: 0.3508

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8767 - loss: 0.3222 
Epoch 42/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 15ms/step - accuracy: 0.9400 - loss: 0.1979

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9053 - loss: 0.2599 
Epoch 43/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8800 - loss: 0.3590

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8800 - loss: 0.3164 
Epoch 44/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9000 - loss: 0.3105

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8853 - loss: 0.3090 
Epoch 45/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - accuracy: 0.9400 - loss: 0.2643

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9033 - loss: 0.2900 
Epoch 46/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8200 - loss: 0.3549

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8747 - loss: 0.3044 
Epoch 47/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - accuracy: 0.9000 - loss: 0.2224

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8947 - loss: 0.2753 
Epoch 48/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8800 - loss: 0.2372

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8900 - loss: 0.2632 
Epoch 49/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9000 - loss: 0.2951

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9060 - loss: 0.2773 
Epoch 50/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9400 - loss: 0.1934

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9107 - loss: 0.2425 
Epoch 51/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8400 - loss: 0.4069

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8787 - loss: 0.3155 
Epoch 52/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 16ms/step - accuracy: 0.9600 - loss: 0.1919

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9213 - loss: 0.2422 
Epoch 53/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - accuracy: 0.9600 - loss: 0.1570

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9253 - loss: 0.2206 
Epoch 54/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9000 - loss: 0.2497

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8987 - loss: 0.2755 
Epoch 55/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - accuracy: 0.9200 - loss: 0.2542

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9013 - loss: 0.2740 
Epoch 56/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9400 - loss: 0.2032

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9100 - loss: 0.2574 
Epoch 57/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8800 - loss: 0.2899

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8873 - loss: 0.2793 
Epoch 58/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8800 - loss: 0.3499

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9000 - loss: 0.2894 
Epoch 59/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8200 - loss: 0.3521

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8760 - loss: 0.2928 
Epoch 60/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9400 - loss: 0.2451

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9093 - loss: 0.2608 
Epoch 61/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9600 - loss: 0.1887

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9173 - loss: 0.2446 
Epoch 62/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8800 - loss: 0.3169

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8953 - loss: 0.2696 
Epoch 63/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8800 - loss: 0.3606

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8927 - loss: 0.2955 
Epoch 64/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9000 - loss: 0.2657

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9033 - loss: 0.2483 
Epoch 65/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8400 - loss: 0.3822

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8773 - loss: 0.3082 
Epoch 66/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - accuracy: 0.8800 - loss: 0.3476

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8960 - loss: 0.2847 
Epoch 67/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - accuracy: 0.9000 - loss: 0.2647

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8940 - loss: 0.2605 
Epoch 68/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - accuracy: 0.9200 - loss: 0.2150

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9080 - loss: 0.2341 
Epoch 69/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - accuracy: 0.9200 - loss: 0.2098

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9027 - loss: 0.2482 
Epoch 70/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - accuracy: 0.9200 - loss: 0.2153

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8960 - loss: 0.2565 
Epoch 71/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - accuracy: 0.9000 - loss: 0.2435

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8960 - loss: 0.2538 
Epoch 72/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - accuracy: 0.8800 - loss: 0.3073

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8860 - loss: 0.2831 
Epoch 73/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8600 - loss: 0.3113

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8820 - loss: 0.2741 
Epoch 74/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8800 - loss: 0.3313

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9007 - loss: 0.2719 
Epoch 75/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - accuracy: 0.9000 - loss: 0.2511

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9087 - loss: 0.2359 
Epoch 76/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9000 - loss: 0.2783

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8927 - loss: 0.2680 
Epoch 77/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9600 - loss: 0.1627

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9247 - loss: 0.2249 
Epoch 78/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9200 - loss: 0.2205

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9047 - loss: 0.2507 
Epoch 79/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9600 - loss: 0.1566

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9273 - loss: 0.2135 
Epoch 80/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - accuracy: 0.8800 - loss: 0.3042

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9040 - loss: 0.2616 
Epoch 81/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8400 - loss: 0.3803

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8827 - loss: 0.2840 
Epoch 82/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9200 - loss: 0.2046

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9040 - loss: 0.2427 
Epoch 83/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9200 - loss: 0.2668

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9053 - loss: 0.2653 
Epoch 84/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8600 - loss: 0.3464

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 8ms/step - accuracy: 0.8927 - loss: 0.2841 
Epoch 85/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9400 - loss: 0.1589

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9160 - loss: 0.2185 
Epoch 86/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - accuracy: 0.9000 - loss: 0.2996

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8967 - loss: 0.2758 
Epoch 87/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9000 - loss: 0.2554

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9013 - loss: 0.2469 
Epoch 88/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - accuracy: 0.8800 - loss: 0.2475

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8940 - loss: 0.2534 
Epoch 89/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8400 - loss: 0.3613

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8847 - loss: 0.2852 
Epoch 90/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8600 - loss: 0.3279

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8927 - loss: 0.2784 
Epoch 91/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9200 - loss: 0.2437

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9100 - loss: 0.2456 
Epoch 92/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9000 - loss: 0.2486

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9073 - loss: 0.2452 
Epoch 93/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9200 - loss: 0.2034

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9100 - loss: 0.2369 
Epoch 94/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9600 - loss: 0.1699

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9233 - loss: 0.2237 
Epoch 95/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9200 - loss: 0.1942

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9107 - loss: 0.2192 
Epoch 96/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9000 - loss: 0.2670

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9040 - loss: 0.2651 
Epoch 97/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8800 - loss: 0.2470

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9020 - loss: 0.2321 
Epoch 98/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9200 - loss: 0.2356

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9193 - loss: 0.2315 
Epoch 99/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8800 - loss: 0.2910

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9053 - loss: 0.2491 
Epoch 100/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9200 - loss: 0.2176

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9067 - loss: 0.2420 
score = model.evaluate(x, v, verbose=0)
print(f"score = {score[0]}")
print(f"accuracy = {score[1]}")
score = 0.23782259225845337
accuracy = 0.9150000214576721

Let’s look at a prediction. We need to feed in a single point as an array of shape (N, 2), where N is the number of points

res = model.predict(np.array([[-2, 2]]))
res
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step

1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 44ms/step
array([[6.096349e-06]], dtype=float32)

We see that we get a floating point number. We will need to convert this to 0 or 1 by rounding.

Let’s plot the partitioning

M = 128
N = 128

xmin = -1.75
xmax = 2.5
ymin = -1.25
ymax = 1.75

xpt = np.linspace(xmin, xmax, M)
ypt = np.linspace(ymin, ymax, N)

To make the prediction go faster, we want to feed in a vector of these points, of the form:

[[xpt[0], ypt[0]],
 [xpt[1], ypt[1]],
 ...
]

We can see that this packs them into the vector

pairs = np.array(np.meshgrid(xpt, ypt)).T.reshape(-1, 2)
pairs[0]
array([-1.75, -1.25])

Now we do the prediction. We will get a vector out, which we reshape to match the original domain.

res = model.predict(pairs, verbose=0)
res.shape = (M, N)

Finally, round to 0 or 1

domain = np.where(res > 0.5, 1, 0)

and we can plot the data

fig, ax = plt.subplots()
ax.imshow(domain.T, origin="lower",
          extent=[xmin, xmax, ymin, ymax], alpha=0.25)
xpt = [q[0] for q in x]
ypt = [q[1] for q in x]

ax.scatter(xpt, ypt, s=40, c=v, cmap="viridis")
<matplotlib.collections.PathCollection at 0x7fb7105e3390>
../_images/3a00dce5a19fdc5be5c1c5a6ba2c8e83d9a6bfe111867b1544e4029769681fc4.png