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 WaveNet, BinaryIoU
from DeepPeak.signals import Kernel, SignalDatasetGenerator
np.random.seed(42)
Generate synthetic dataset#
NUM_PEAKS = 3
SEQUENCE_LENGTH = 200
generator = SignalDatasetGenerator(n_samples=100, sequence_length=SEQUENCE_LENGTH)
dataset = generator.generate(
signal_type=Kernel.GAUSSIAN,
n_peaks=(1, NUM_PEAKS),
amplitude=(1, 20),
position=(0.1, 0.9),
width=(0.03, 0.05),
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)

Build and summarize the WaveNet classifier#
dense_net = WaveNet(
sequence_length=SEQUENCE_LENGTH,
num_filters=64,
num_dilation_layers=6,
kernel_size=3,
optimizer="adam",
loss="binary_crossentropy",
metrics=["accuracy", BinaryIoU(threshold=0.5)],
)
dense_net.build()
dense_net.summary()
Model: "WaveNetDetector"
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃ Connected to ┃
┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩
│ input (InputLayer) │ (None, 200, 1) │ 0 │ - │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ input_projection │ (None, 200, 64) │ 128 │ input[0][0] │
│ (Conv1D) │ │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dilated_conv_0 │ (None, 200, 64) │ 12,352 │ input_projection… │
│ (Conv1D) │ │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ res_0 (Conv1D) │ (None, 200, 64) │ 4,160 │ dilated_conv_0[0… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ residual_add_0 │ (None, 200, 64) │ 0 │ input_projection… │
│ (Add) │ │ │ res_0[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dilated_conv_1 │ (None, 200, 64) │ 12,352 │ residual_add_0[0… │
│ (Conv1D) │ │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ res_1 (Conv1D) │ (None, 200, 64) │ 4,160 │ dilated_conv_1[0… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ residual_add_1 │ (None, 200, 64) │ 0 │ residual_add_0[0… │
│ (Add) │ │ │ res_1[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dilated_conv_2 │ (None, 200, 64) │ 12,352 │ residual_add_1[0… │
│ (Conv1D) │ │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ res_2 (Conv1D) │ (None, 200, 64) │ 4,160 │ dilated_conv_2[0… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ residual_add_2 │ (None, 200, 64) │ 0 │ residual_add_1[0… │
│ (Add) │ │ │ res_2[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dilated_conv_3 │ (None, 200, 64) │ 12,352 │ residual_add_2[0… │
│ (Conv1D) │ │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ res_3 (Conv1D) │ (None, 200, 64) │ 4,160 │ dilated_conv_3[0… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ residual_add_3 │ (None, 200, 64) │ 0 │ residual_add_2[0… │
│ (Add) │ │ │ res_3[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dilated_conv_4 │ (None, 200, 64) │ 12,352 │ residual_add_3[0… │
│ (Conv1D) │ │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ res_4 (Conv1D) │ (None, 200, 64) │ 4,160 │ dilated_conv_4[0… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ residual_add_4 │ (None, 200, 64) │ 0 │ residual_add_3[0… │
│ (Add) │ │ │ res_4[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dilated_conv_5 │ (None, 200, 64) │ 12,352 │ residual_add_4[0… │
│ (Conv1D) │ │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ res_5 (Conv1D) │ (None, 200, 64) │ 4,160 │ dilated_conv_5[0… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ residual_add_5 │ (None, 200, 64) │ 0 │ residual_add_4[0… │
│ (Add) │ │ │ res_5[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ skip_0 (Conv1D) │ (None, 200, 64) │ 4,160 │ residual_add_0[0… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ skip_1 (Conv1D) │ (None, 200, 64) │ 4,160 │ residual_add_1[0… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ skip_2 (Conv1D) │ (None, 200, 64) │ 4,160 │ residual_add_2[0… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ skip_3 (Conv1D) │ (None, 200, 64) │ 4,160 │ residual_add_3[0… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ skip_4 (Conv1D) │ (None, 200, 64) │ 4,160 │ residual_add_4[0… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ skip_5 (Conv1D) │ (None, 200, 64) │ 4,160 │ residual_add_5[0… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ skip_add (Add) │ (None, 200, 64) │ 0 │ skip_0[0][0], │
│ │ │ │ skip_1[0][0], │
│ │ │ │ skip_2[0][0], │
│ │ │ │ skip_3[0][0], │
│ │ │ │ skip_4[0][0], │
│ │ │ │ skip_5[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ post_relu (ReLU) │ (None, 200, 64) │ 0 │ skip_add[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ output (Conv1D) │ (None, 200, 1) │ 65 │ post_relu[0][0] │
└─────────────────────┴───────────────────┴────────────┴───────────────────┘
Total params: 124,225 (485.25 KB)
Trainable params: 124,225 (485.25 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 ━━━━━━━━━━━━━━━━━━━━ 4s 4s/step - BinaryIoU: 0.0637 - accuracy: 0.2576 - loss: 2.6198
2/2 ━━━━━━━━━━━━━━━━━━━━ 5s 509ms/step - BinaryIoU: 0.0707 - accuracy: 0.3804 - loss: 2.2031 - val_BinaryIoU: 0.0000e+00 - val_accuracy: 0.9613 - val_loss: 0.5487
Epoch 2/20
1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 102ms/step - BinaryIoU: 0.0000e+00 - accuracy: 0.9472 - loss: 0.7395
2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 87ms/step - BinaryIoU: 0.0000e+00 - accuracy: 0.9496 - loss: 0.7084 - val_BinaryIoU: 0.0000e+00 - val_accuracy: 0.9613 - val_loss: 0.5057
Epoch 3/20
1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 102ms/step - BinaryIoU: 0.0000e+00 - accuracy: 0.9490 - loss: 0.7025
2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 86ms/step - BinaryIoU: 0.0000e+00 - accuracy: 0.9496 - loss: 0.6781 - val_BinaryIoU: 0.0000e+00 - val_accuracy: 0.9613 - val_loss: 0.3129
Epoch 4/20
1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 102ms/step - BinaryIoU: 0.0000e+00 - accuracy: 0.9507 - loss: 0.4260
2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 87ms/step - BinaryIoU: 0.0787 - accuracy: 0.9510 - loss: 0.3949 - val_BinaryIoU: 0.2988 - val_accuracy: 0.9290 - val_loss: 0.2618
Epoch 5/20
1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 101ms/step - BinaryIoU: 0.2955 - accuracy: 0.9074 - loss: 0.3475
2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 86ms/step - BinaryIoU: 0.2967 - accuracy: 0.9076 - loss: 0.3439 - val_BinaryIoU: 0.3852 - val_accuracy: 0.9625 - val_loss: 0.1375
Epoch 6/20
1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 100ms/step - BinaryIoU: 0.3680 - accuracy: 0.9454 - loss: 0.1807
2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 85ms/step - BinaryIoU: 0.3202 - accuracy: 0.9460 - loss: 0.1857 - val_BinaryIoU: 0.0000e+00 - val_accuracy: 0.9613 - val_loss: 0.1559
Epoch 7/20
1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 101ms/step - BinaryIoU: 0.0000e+00 - accuracy: 0.9491 - loss: 0.2195
2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 85ms/step - BinaryIoU: 0.0000e+00 - accuracy: 0.9496 - loss: 0.2145 - val_BinaryIoU: 0.3114 - val_accuracy: 0.9712 - val_loss: 0.0827
Epoch 8/20
1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 99ms/step - BinaryIoU: 0.2759 - accuracy: 0.9573 - loss: 0.1092
2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 87ms/step - BinaryIoU: 0.3110 - accuracy: 0.9544 - loss: 0.1143 - val_BinaryIoU: 0.4036 - val_accuracy: 0.9583 - val_loss: 0.1018
Epoch 9/20
1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 101ms/step - BinaryIoU: 0.3727 - accuracy: 0.9411 - loss: 0.1307
2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 87ms/step - BinaryIoU: 0.3692 - accuracy: 0.9424 - loss: 0.1272 - val_BinaryIoU: 0.0194 - val_accuracy: 0.9620 - val_loss: 0.0861
Epoch 10/20
1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 100ms/step - BinaryIoU: 0.0154 - accuracy: 0.9500 - loss: 0.1122
2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 85ms/step - BinaryIoU: 0.0123 - accuracy: 0.9497 - loss: 0.1166 - val_BinaryIoU: 0.0323 - val_accuracy: 0.9625 - val_loss: 0.0886
Epoch 11/20
1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 101ms/step - BinaryIoU: 0.0125 - accuracy: 0.9506 - loss: 0.1135
2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 86ms/step - BinaryIoU: 0.0927 - accuracy: 0.9517 - loss: 0.1112 - val_BinaryIoU: 0.4093 - val_accuracy: 0.9683 - val_loss: 0.0854
Epoch 12/20
1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 102ms/step - BinaryIoU: 0.4290 - accuracy: 0.9573 - loss: 0.1014
2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 86ms/step - BinaryIoU: 0.4180 - accuracy: 0.9556 - loss: 0.1048 - val_BinaryIoU: 0.4018 - val_accuracy: 0.9673 - val_loss: 0.0862
Epoch 13/20
1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 100ms/step - BinaryIoU: 0.4335 - accuracy: 0.9567 - loss: 0.1028
2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 85ms/step - BinaryIoU: 0.4117 - accuracy: 0.9567 - loss: 0.1030 - val_BinaryIoU: 0.1928 - val_accuracy: 0.9665 - val_loss: 0.0822
Epoch 14/20
1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 102ms/step - BinaryIoU: 0.1924 - accuracy: 0.9554 - loss: 0.0966
2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 86ms/step - BinaryIoU: 0.2011 - accuracy: 0.9561 - loss: 0.0980 - val_BinaryIoU: 0.2229 - val_accuracy: 0.9677 - val_loss: 0.0767
Epoch 15/20
1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 102ms/step - BinaryIoU: 0.2332 - accuracy: 0.9563 - loss: 0.0922
2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 87ms/step - BinaryIoU: 0.2689 - accuracy: 0.9584 - loss: 0.0899 - val_BinaryIoU: 0.4279 - val_accuracy: 0.9712 - val_loss: 0.0738
Epoch 16/20
1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 100ms/step - BinaryIoU: 0.4325 - accuracy: 0.9596 - loss: 0.0901
2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 86ms/step - BinaryIoU: 0.4331 - accuracy: 0.9600 - loss: 0.0902 - val_BinaryIoU: 0.4301 - val_accuracy: 0.9735 - val_loss: 0.0674
Epoch 17/20
1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 102ms/step - BinaryIoU: 0.4203 - accuracy: 0.9616 - loss: 0.0858
2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 87ms/step - BinaryIoU: 0.4069 - accuracy: 0.9622 - loss: 0.0846 - val_BinaryIoU: 0.2609 - val_accuracy: 0.9703 - val_loss: 0.0635
Epoch 18/20
1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 99ms/step - BinaryIoU: 0.2849 - accuracy: 0.9600 - loss: 0.0849
2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 87ms/step - BinaryIoU: 0.2808 - accuracy: 0.9609 - loss: 0.0840 - val_BinaryIoU: 0.4152 - val_accuracy: 0.9750 - val_loss: 0.0592
Epoch 19/20
1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 101ms/step - BinaryIoU: 0.3758 - accuracy: 0.9637 - loss: 0.0812
2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 86ms/step - BinaryIoU: 0.3868 - accuracy: 0.9641 - loss: 0.0804 - val_BinaryIoU: 0.5269 - val_accuracy: 0.9780 - val_loss: 0.0593
Epoch 20/20
1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 101ms/step - BinaryIoU: 0.4596 - accuracy: 0.9639 - loss: 0.0826
2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 86ms/step - BinaryIoU: 0.4753 - accuracy: 0.9655 - loss: 0.0806 - val_BinaryIoU: 0.4972 - val_accuracy: 0.9775 - val_loss: 0.0575
Plot training history#
dense_net.plot_model_history()

Predict and visualize on a test signal#
dense_net.plot_prediction(signal=dataset.signals[0:1, :], threshold=0.4)

<Figure size 1200x500 with 1 Axes>
Total running time of the script: (0 minutes 10.587 seconds)