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.84620768 0.42818795], 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/b992c59eceaa80eefb48e66198dbe84050dad82509e42d0bdd07308d332b1542.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-01-21 15:49:11.347350: 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-01-21 15:49:11.350575: 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-01-21 15:49:11.357131: 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:1737474551.370252    3332 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:1737474551.374422    3332 cuda_blas.cc:1418] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered
2025-01-21 15:49:11.390797: 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-01-21 15:49:13.045088: 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 599ms/step - accuracy: 0.7800 - loss: 0.6726

4/4 ━━━━━━━━━━━━━━━━━━━━ 1s 6ms/step - accuracy: 0.7973 - loss: 0.6609  
Epoch 2/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8400 - loss: 0.6204

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8160 - loss: 0.6181 
Epoch 3/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8200 - loss: 0.6027

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8027 - loss: 0.5957 
Epoch 4/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8200 - loss: 0.5784

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8120 - loss: 0.5716 
Epoch 5/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.7600 - loss: 0.5754

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.7947 - loss: 0.5576 
Epoch 6/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8000 - loss: 0.5444

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.7960 - loss: 0.5366 
Epoch 7/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.7400 - loss: 0.5405

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.7800 - loss: 0.5238 
Epoch 8/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8200 - loss: 0.5007

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8100 - loss: 0.4995 
Epoch 9/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.7600 - loss: 0.5089

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.7920 - loss: 0.4928 
Epoch 10/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8400 - loss: 0.5074

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8140 - loss: 0.4823 
Epoch 11/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.7400 - loss: 0.5182

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.7880 - loss: 0.4764 
Epoch 12/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.7000 - loss: 0.5135

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.7820 - loss: 0.4705 
Epoch 13/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8800 - loss: 0.3976

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8367 - loss: 0.4238 
Epoch 14/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8800 - loss: 0.3725

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8360 - loss: 0.4076 
Epoch 15/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8200 - loss: 0.4188

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8267 - loss: 0.4204 
Epoch 16/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8000 - loss: 0.4021

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8200 - loss: 0.4006 
Epoch 17/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9000 - loss: 0.3335

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8427 - loss: 0.3875 
Epoch 18/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8000 - loss: 0.3994

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8260 - loss: 0.3905 
Epoch 19/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8400 - loss: 0.3792

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8407 - loss: 0.3776 
Epoch 20/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8800 - loss: 0.3248

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8420 - loss: 0.3660 
Epoch 21/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 15ms/step - accuracy: 0.8600 - loss: 0.3640

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8473 - loss: 0.3642 
Epoch 22/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8200 - loss: 0.3499

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8227 - loss: 0.3712 
Epoch 23/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8200 - loss: 0.4245

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8193 - loss: 0.3944 
Epoch 24/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8200 - loss: 0.3334

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8327 - loss: 0.3517 
Epoch 25/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8400 - loss: 0.3363

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8380 - loss: 0.3503 
Epoch 26/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.7400 - loss: 0.4536

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8033 - loss: 0.3779 
Epoch 27/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8200 - loss: 0.3762

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8420 - loss: 0.3480 
Epoch 28/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8200 - loss: 0.3658

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8307 - loss: 0.3493 
Epoch 29/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8200 - loss: 0.3404

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8413 - loss: 0.3339 
Epoch 30/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.7800 - loss: 0.3893

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8327 - loss: 0.3462 
Epoch 31/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.7600 - loss: 0.4224

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8227 - loss: 0.3530 
Epoch 32/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.7800 - loss: 0.4212

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8173 - loss: 0.3703 
Epoch 33/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8800 - loss: 0.2956

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8593 - loss: 0.3211 
Epoch 34/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8600 - loss: 0.3187

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8367 - loss: 0.3330 
Epoch 35/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8800 - loss: 0.2706

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8500 - loss: 0.3181 
Epoch 36/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 15ms/step - accuracy: 0.7800 - loss: 0.3968

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8320 - loss: 0.3415 
Epoch 37/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8000 - loss: 0.3884

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8393 - loss: 0.3373 
Epoch 38/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.7800 - loss: 0.4043

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8300 - loss: 0.3410 
Epoch 39/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8400 - loss: 0.3507

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8533 - loss: 0.3217 
Epoch 40/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9200 - loss: 0.2370

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8727 - loss: 0.2951 
Epoch 41/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8600 - loss: 0.2964

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8647 - loss: 0.2873 
Epoch 42/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9000 - loss: 0.1972

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8747 - loss: 0.2701 
Epoch 43/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8200 - loss: 0.3514

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8420 - loss: 0.3208 
Epoch 44/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8600 - loss: 0.2881

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8693 - loss: 0.2819 
Epoch 45/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8800 - loss: 0.2354

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8680 - loss: 0.2672 
Epoch 46/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8200 - loss: 0.3594

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8507 - loss: 0.3126 
Epoch 47/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9000 - loss: 0.2373

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8907 - loss: 0.2644 
Epoch 48/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9000 - loss: 0.2553

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8840 - loss: 0.2727 
Epoch 49/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8600 - loss: 0.2664

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8693 - loss: 0.2809 
Epoch 50/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8600 - loss: 0.2487

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8660 - loss: 0.2683 
Epoch 51/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9000 - loss: 0.2677

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8840 - loss: 0.2762 
Epoch 52/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8800 - loss: 0.2305

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8793 - loss: 0.2612 
Epoch 53/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9200 - loss: 0.1808

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8893 - loss: 0.2511 
Epoch 54/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8600 - loss: 0.3092

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8800 - loss: 0.2749 
Epoch 55/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8600 - loss: 0.3032

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8773 - loss: 0.2794 
Epoch 56/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step - accuracy: 0.9400 - loss: 0.1909

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8927 - loss: 0.2571 
Epoch 57/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8600 - loss: 0.3301

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8847 - loss: 0.2704 
Epoch 58/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - accuracy: 0.8400 - loss: 0.2881

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8740 - loss: 0.2696 
Epoch 59/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8600 - loss: 0.3143

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8820 - loss: 0.2738 
Epoch 60/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8600 - loss: 0.2840

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8807 - loss: 0.2651 
Epoch 61/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8400 - loss: 0.2582

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8800 - loss: 0.2473 
Epoch 62/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8200 - loss: 0.3246

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8533 - loss: 0.2950 
Epoch 63/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8800 - loss: 0.2538

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8827 - loss: 0.2524 
Epoch 64/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8800 - loss: 0.2657

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8940 - loss: 0.2399 
Epoch 65/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8000 - loss: 0.3610

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8587 - loss: 0.2858 
Epoch 66/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.8400 - loss: 0.2765

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8733 - loss: 0.2538 
Epoch 67/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8800 - loss: 0.2910

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8920 - loss: 0.2451 
Epoch 68/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8400 - loss: 0.3312

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8740 - loss: 0.2689 
Epoch 69/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9000 - loss: 0.2299

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8940 - loss: 0.2355 
Epoch 70/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9600 - loss: 0.1923

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9180 - loss: 0.2168 
Epoch 71/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9200 - loss: 0.2013

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8987 - loss: 0.2234 
Epoch 72/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8800 - loss: 0.2411

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8893 - loss: 0.2404 
Epoch 73/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9000 - loss: 0.2432

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8993 - loss: 0.2341 
Epoch 74/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9000 - loss: 0.2276

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8973 - loss: 0.2304 
Epoch 75/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9400 - loss: 0.1721

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9153 - loss: 0.1939 
Epoch 76/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9200 - loss: 0.2196

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9100 - loss: 0.2219 
Epoch 77/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9000 - loss: 0.2161

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9053 - loss: 0.2083 
Epoch 78/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9200 - loss: 0.2166

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9200 - loss: 0.2059 
Epoch 79/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9000 - loss: 0.2306

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9120 - loss: 0.2175 
Epoch 80/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9000 - loss: 0.2422

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9140 - loss: 0.2115 
Epoch 81/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.8800 - loss: 0.2516

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9053 - loss: 0.2202 
Epoch 82/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9600 - loss: 0.1896

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9420 - loss: 0.1877 
Epoch 83/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9400 - loss: 0.1985

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9360 - loss: 0.1901 
Epoch 84/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9600 - loss: 0.1492

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9433 - loss: 0.1712 
Epoch 85/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9200 - loss: 0.2348

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9247 - loss: 0.2052 
Epoch 86/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9800 - loss: 0.1476

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9353 - loss: 0.1946 
Epoch 87/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9000 - loss: 0.1980

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9127 - loss: 0.2029 
Epoch 88/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9600 - loss: 0.1275

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9367 - loss: 0.1699 
Epoch 89/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9400 - loss: 0.1898

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9280 - loss: 0.1896 
Epoch 90/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step - accuracy: 0.9600 - loss: 0.1462

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 6ms/step - accuracy: 0.9433 - loss: 0.1674 
Epoch 91/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step - accuracy: 0.9400 - loss: 0.1790

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9293 - loss: 0.1926 
Epoch 92/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9000 - loss: 0.2391

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9267 - loss: 0.1899 
Epoch 93/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9000 - loss: 0.2247

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9140 - loss: 0.2045 
Epoch 94/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9400 - loss: 0.1748

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9340 - loss: 0.1711 
Epoch 95/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - accuracy: 0.9200 - loss: 0.1674

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9280 - loss: 0.1785 
Epoch 96/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9200 - loss: 0.1449

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9293 - loss: 0.1703 
Epoch 97/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9000 - loss: 0.2397

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9320 - loss: 0.1931 
Epoch 98/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9200 - loss: 0.1801

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9253 - loss: 0.1679 
Epoch 99/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9400 - loss: 0.1344

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9413 - loss: 0.1516 
Epoch 100/100
1/4 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.9400 - loss: 0.1812

4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.9420 - loss: 0.1693 
score = model.evaluate(x, v, verbose=0)
print(f"score = {score[0]}")
print(f"accuracy = {score[1]}")
score = 0.15979984402656555
accuracy = 0.9399999976158142

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 31ms/step

1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 41ms/step
array([[6.9725087e-07]], 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 0x7f5c27f133d0>
../_images/4b3dfe897011c0668e2c6d3f835120616416f96515a571dc0c32c289f54ade65.png