DenseNet Classifier: Detecting Regions of Interest in Synthetic Signals#

This example demonstrates how to use DeepPeak’s DenseNet classifier to identify regions of interest (ROIs) in synthetic 1D signals containing Gaussian peaks.

We will: - Generate a dataset of noisy signals with random Gaussian peaks - Build and train a DenseNet classifier to detect ROIs - Visualize the training process and model predictions

Note

This example is fully reproducible and suitable for Sphinx-Gallery documentation.

Imports and reproducibility#

import numpy as np

from DeepPeak.machine_learning.classifier import Autoencoder, BinaryIoU
from DeepPeak.signals import SignalDatasetGenerator
from DeepPeak import kernel

np.random.seed(42)

Generate synthetic dataset#

NUM_PEAKS = 3
SEQUENCE_LENGTH = 200

kernel = kernel.Lorentzian(
    amplitude=(1, 20),
    position=(0.1, 0.9),
    width=(0.03, 0.05),
)

generator = SignalDatasetGenerator(n_samples=100, sequence_length=SEQUENCE_LENGTH)

dataset = generator.generate(
    kernel=kernel,
    n_peaks=(1, NUM_PEAKS),
    noise_std=0.1,
    categorical_peak_count=False,
    compute_region_of_interest=True,
)

Visualize a few example signals and their regions of interest#

dataset.plot(number_of_samples=3)
Predicted ROI (Sample 0), Predicted ROI (Sample 1), Predicted ROI (Sample 2)
<Figure size 800x900 with 3 Axes>

Build and summarize the WaveNet classifier#

dense_net = Autoencoder(
    sequence_length=SEQUENCE_LENGTH,
    dropout_rate=0.30,
    filters=(32, 64, 128),
    kernel_size=3,
    pool_size=2,
    upsample_size=2,
    optimizer="adam",
    loss="binary_crossentropy",
    metrics=[BinaryIoU(threshold=0.5)],
)
dense_net.build()
dense_net.summary()
Model: "AutoencoderROILocator"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type)                    ┃ Output Shape           ┃       Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ input (InputLayer)              │ (None, 200, 1)         │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ enc_conv0 (Conv1D)              │ (None, 200, 32)        │           128 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ enc_drop0 (Dropout)             │ (None, 200, 32)        │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ enc_pool0 (MaxPooling1D)        │ (None, 100, 32)        │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ enc_conv1 (Conv1D)              │ (None, 100, 64)        │         6,208 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ enc_drop1 (Dropout)             │ (None, 100, 64)        │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ enc_pool1 (MaxPooling1D)        │ (None, 50, 64)         │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ bottleneck_conv (Conv1D)        │ (None, 50, 128)        │        24,704 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ bottleneck_drop (Dropout)       │ (None, 50, 128)        │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dec_up0 (UpSampling1D)          │ (None, 100, 128)       │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dec_conv0 (Conv1D)              │ (None, 100, 64)        │        24,640 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dec_up1 (UpSampling1D)          │ (None, 200, 64)        │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dec_conv1 (Conv1D)              │ (None, 200, 32)        │         6,176 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ ROI (Conv1D)                    │ (None, 200, 1)         │            33 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
 Total params: 61,889 (241.75 KB)
 Trainable params: 61,889 (241.75 KB)
 Non-trainable params: 0 (0.00 B)

Train the classifier#

history = dense_net.fit(
    dataset.signals,
    dataset.region_of_interest,
    validation_split=0.2,
    epochs=20,
    batch_size=64,
)
Epoch 1/20

1/2 ━━━━━━━━━━━━━━━━━━━━ 1s 2s/step - BinaryIoU: 0.0502 - loss: 0.8155
Epoch 1: val_loss improved from None to 0.65610, saving model to /tmp/wavenet_ckpt_utgc_t72/best.weights.h5

2/2 ━━━━━━━━━━━━━━━━━━━━ 2s 329ms/step - BinaryIoU: 0.0511 - loss: 0.7889 - val_BinaryIoU: 0.0000e+00 - val_loss: 0.6561
Epoch 2/20

1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step - BinaryIoU: 0.0000e+00 - loss: 0.6315
Epoch 2: val_loss improved from 0.65610 to 0.62111, saving model to /tmp/wavenet_ckpt_utgc_t72/best.weights.h5

2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 89ms/step - BinaryIoU: 0.0000e+00 - loss: 0.6290 - val_BinaryIoU: 0.0000e+00 - val_loss: 0.6211
Epoch 3/20

1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 38ms/step - BinaryIoU: 0.0000e+00 - loss: 0.6114
Epoch 3: val_loss improved from 0.62111 to 0.59884, saving model to /tmp/wavenet_ckpt_utgc_t72/best.weights.h5

2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 84ms/step - BinaryIoU: 0.0000e+00 - loss: 0.6138 - val_BinaryIoU: 0.0000e+00 - val_loss: 0.5988
Epoch 4/20

1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 39ms/step - BinaryIoU: 0.0000e+00 - loss: 0.5976
Epoch 4: val_loss improved from 0.59884 to 0.58680, saving model to /tmp/wavenet_ckpt_utgc_t72/best.weights.h5

2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 86ms/step - BinaryIoU: 0.0000e+00 - loss: 0.5989 - val_BinaryIoU: 0.0000e+00 - val_loss: 0.5868
Epoch 5/20

1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step - BinaryIoU: 0.0000e+00 - loss: 0.5773
Epoch 5: val_loss improved from 0.58680 to 0.57594, saving model to /tmp/wavenet_ckpt_utgc_t72/best.weights.h5

2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 88ms/step - BinaryIoU: 0.0000e+00 - loss: 0.5713 - val_BinaryIoU: 0.0000e+00 - val_loss: 0.5759
Epoch 6/20

1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step - BinaryIoU: 0.0000e+00 - loss: 0.5462
Epoch 6: val_loss improved from 0.57594 to 0.55021, saving model to /tmp/wavenet_ckpt_utgc_t72/best.weights.h5

2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 84ms/step - BinaryIoU: 0.0000e+00 - loss: 0.5436 - val_BinaryIoU: 0.0000e+00 - val_loss: 0.5502
Epoch 7/20

1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step - BinaryIoU: 0.0000e+00 - loss: 0.5104
Epoch 7: val_loss improved from 0.55021 to 0.50280, saving model to /tmp/wavenet_ckpt_utgc_t72/best.weights.h5

2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 85ms/step - BinaryIoU: 0.0000e+00 - loss: 0.5085 - val_BinaryIoU: 0.0000e+00 - val_loss: 0.5028
Epoch 8/20

1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step - BinaryIoU: 0.0000e+00 - loss: 0.4679
Epoch 8: val_loss improved from 0.50280 to 0.43867, saving model to /tmp/wavenet_ckpt_utgc_t72/best.weights.h5

2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 84ms/step - BinaryIoU: 0.0000e+00 - loss: 0.4601 - val_BinaryIoU: 0.0000e+00 - val_loss: 0.4387
Epoch 9/20

1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step - BinaryIoU: 0.0000e+00 - loss: 0.4134
Epoch 9: val_loss improved from 0.43867 to 0.37532, saving model to /tmp/wavenet_ckpt_utgc_t72/best.weights.h5

2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 84ms/step - BinaryIoU: 0.0000e+00 - loss: 0.4093 - val_BinaryIoU: 0.2484 - val_loss: 0.3753
Epoch 10/20

1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step - BinaryIoU: 0.0240 - loss: 0.3373
Epoch 10: val_loss improved from 0.37532 to 0.31758, saving model to /tmp/wavenet_ckpt_utgc_t72/best.weights.h5

2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 87ms/step - BinaryIoU: 0.0247 - loss: 0.3368 - val_BinaryIoU: 0.5891 - val_loss: 0.3176
Epoch 11/20

1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step - BinaryIoU: 0.1940 - loss: 0.2776
Epoch 11: val_loss improved from 0.31758 to 0.23118, saving model to /tmp/wavenet_ckpt_utgc_t72/best.weights.h5

2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 84ms/step - BinaryIoU: 0.2129 - loss: 0.2657 - val_BinaryIoU: 0.5463 - val_loss: 0.2312
Epoch 12/20

1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 38ms/step - BinaryIoU: 0.2715 - loss: 0.1964
Epoch 12: val_loss improved from 0.23118 to 0.16018, saving model to /tmp/wavenet_ckpt_utgc_t72/best.weights.h5

2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 85ms/step - BinaryIoU: 0.2644 - loss: 0.1931 - val_BinaryIoU: 0.4883 - val_loss: 0.1602
Epoch 13/20

1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step - BinaryIoU: 0.3195 - loss: 0.1582
Epoch 13: val_loss improved from 0.16018 to 0.13183, saving model to /tmp/wavenet_ckpt_utgc_t72/best.weights.h5

2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 84ms/step - BinaryIoU: 0.3606 - loss: 0.1501 - val_BinaryIoU: 0.4209 - val_loss: 0.1318
Epoch 14/20

1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step - BinaryIoU: 0.4393 - loss: 0.1203
Epoch 14: val_loss improved from 0.13183 to 0.10548, saving model to /tmp/wavenet_ckpt_utgc_t72/best.weights.h5

2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 84ms/step - BinaryIoU: 0.4497 - loss: 0.1185 - val_BinaryIoU: 0.4340 - val_loss: 0.1055
Epoch 15/20

1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step - BinaryIoU: 0.4542 - loss: 0.1072
Epoch 15: val_loss improved from 0.10548 to 0.10052, saving model to /tmp/wavenet_ckpt_utgc_t72/best.weights.h5

2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 86ms/step - BinaryIoU: 0.4562 - loss: 0.1113 - val_BinaryIoU: 0.4167 - val_loss: 0.1005
Epoch 16/20

1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step - BinaryIoU: 0.4892 - loss: 0.0970
Epoch 16: val_loss improved from 0.10052 to 0.09423, saving model to /tmp/wavenet_ckpt_utgc_t72/best.weights.h5

2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 85ms/step - BinaryIoU: 0.4797 - loss: 0.0964 - val_BinaryIoU: 0.4237 - val_loss: 0.0942
Epoch 17/20

1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 38ms/step - BinaryIoU: 0.4506 - loss: 0.1021
Epoch 17: val_loss improved from 0.09423 to 0.08521, saving model to /tmp/wavenet_ckpt_utgc_t72/best.weights.h5

2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 85ms/step - BinaryIoU: 0.4508 - loss: 0.0972 - val_BinaryIoU: 0.4960 - val_loss: 0.0852
Epoch 18/20

1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step - BinaryIoU: 0.4471 - loss: 0.0849
Epoch 18: val_loss improved from 0.08521 to 0.08100, saving model to /tmp/wavenet_ckpt_utgc_t72/best.weights.h5

2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 84ms/step - BinaryIoU: 0.4534 - loss: 0.0836 - val_BinaryIoU: 0.5419 - val_loss: 0.0810
Epoch 19/20

1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step - BinaryIoU: 0.4746 - loss: 0.0791
Epoch 19: val_loss improved from 0.08100 to 0.08060, saving model to /tmp/wavenet_ckpt_utgc_t72/best.weights.h5

2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 84ms/step - BinaryIoU: 0.4626 - loss: 0.0816 - val_BinaryIoU: 0.5681 - val_loss: 0.0806
Epoch 20/20

1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step - BinaryIoU: 0.4702 - loss: 0.0712
Epoch 20: val_loss did not improve from 0.08060

2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 58ms/step - BinaryIoU: 0.4640 - loss: 0.0763 - val_BinaryIoU: 0.5882 - val_loss: 0.0807
Restored best model weights from /tmp/wavenet_ckpt_utgc_t72/best.weights.h5

Plot training history#

dense_net.plot_model_history(filter_pattern="BinaryIoU")
BinaryIoU
<Figure size 800x300 with 1 Axes>

Predict and visualize on a test signal#

_ = dense_net.plot_prediction(dataset=dataset, number_of_samples=12, number_of_columns=3, threshold=0.1, randomize_signal=True)
Predicted ROI (Sample 6), Predicted ROI (Sample 80), Predicted ROI (Sample 91), Predicted ROI (Sample 81), Predicted ROI (Sample 82), Predicted ROI (Sample 98), Predicted ROI (Sample 78), Predicted ROI (Sample 73), Predicted ROI (Sample 59), Predicted ROI (Sample 48), Predicted ROI (Sample 75), Predicted ROI (Sample 38)

Total running time of the script: (0 minutes 10.532 seconds)

Gallery generated by Sphinx-Gallery