Note
Go to the end to download the full example code.
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)

<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")

<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)

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