Training settings
Please provide a valid training processor option
Audio training options
Neural network architecture
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, InputLayer, Dropout, Conv1D, Conv2D, Flatten, Reshape, MaxPooling1D, MaxPooling2D, AveragePooling2D, BatchNormalization, Permute, ReLU, Softmax, Activation, SeparableConv2D, GlobalAveragePooling2D, SpatialDropout2D
from tensorflow.keras.optimizers.legacy import Adam
# Data augmentation for spectrograms. In expert mode this SpecAugment(...) line is
# authoritative (the visual toggles no longer drive it) — e.g. set
# mT_num_time_masks=1 to also enable time masking.
sa = SpecAugment(spectrogram_shape=[int(input_length / 13), 13], mF_num_freq_masks=1, F_freq_mask_max_consecutive=4, mT_num_time_masks=0, T_time_mask_max_consecutive=0, enable_time_warp=True, W_time_warp_max_distance=6, mask_with_mean=False)
train_dataset = train_dataset.map(sa.mapper(), num_parallel_calls=tf.data.AUTOTUNE)
EPOCHS = args.epochs or 600
LEARNING_RATE = args.learning_rate or 0.001
# If True, non-deterministic functions (e.g. shuffling batches) are not used.
# This is False by default.
ENSURE_DETERMINISM = args.ensure_determinism
# this controls the batch size, or you can manipulate the tf.data.Dataset objects yourself
BATCH_SIZE = args.batch_size or 32
if not ENSURE_DETERMINISM:
train_dataset = train_dataset.shuffle(buffer_size=BATCH_SIZE*4)
train_dataset=train_dataset.batch(BATCH_SIZE, drop_remainder=False)
validation_dataset = validation_dataset.batch(BATCH_SIZE, drop_remainder=False)
# model architecture — mini DS-CNN tuned for robustness on a small dataset
model = Sequential()
# Data augmentation (kept from visual mode): Gaussian noise on the input features
model.add(tf.keras.layers.GaussianNoise(stddev=0.45, input_shape=(input_length,)))
channels = 1
columns = 13
rows = int(input_length / (columns * channels))
model.add(Reshape((rows, columns, channels), input_shape=(input_length, )))
wd = tf.keras.regularizers.l2(1e-4) # mild weight decay -> generalization, no extra capacity
# --- Stem: a normal conv (depthwise-separable is degenerate on a 1-channel input) ---
model.add(Conv2D(16, kernel_size=3, padding='same', use_bias=False, kernel_regularizer=wd))
model.add(BatchNormalization())
model.add(ReLU())
model.add(MaxPooling2D(pool_size=2, strides=2, padding='same'))
# --- Depthwise-separable blocks: more depth for ~8-9x fewer params than dense conv ---
model.add(SeparableConv2D(32, kernel_size=3, padding='same', use_bias=False,
depthwise_regularizer=wd, pointwise_regularizer=wd))
model.add(BatchNormalization())
model.add(ReLU())
model.add(MaxPooling2D(pool_size=2, strides=2, padding='same'))
model.add(SpatialDropout2D(0.2)) # drops whole feature maps (better for convs than plain dropout)
model.add(SeparableConv2D(64, kernel_size=3, padding='same', use_bias=False,
depthwise_regularizer=wd, pointwise_regularizer=wd))
model.add(BatchNormalization())
model.add(ReLU())
model.add(SpatialDropout2D(0.2))
# --- Global average pooling instead of Flatten: time-shift invariance + tiny head ---
model.add(GlobalAveragePooling2D())
model.add(Dropout(0.3))
model.add(Dense(classes, name='y_pred', activation='softmax', kernel_regularizer=wd))
# this controls the learning rate
opt = Adam(learning_rate=LEARNING_RATE, beta_1=0.9, beta_2=0.999)
callbacks.append(BatchLoggerCallback(BATCH_SIZE, train_sample_count, epochs=EPOCHS, ensure_determinism=ENSURE_DETERMINISM))
# Early stopping: end on the best val_loss epoch and roll the weights back to it.
callbacks.append(tf.keras.callbacks.EarlyStopping(
monitor='val_loss', patience=45, min_delta=1e-3,
mode='min', restore_best_weights=True, verbose=1))
# Optional: with BN the loss converges faster — uncomment to decay LR on plateau.
# Keep its patience (20) below EarlyStopping's (45) so the LR drop gets a chance to help first.
# callbacks.append(tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=20, min_lr=1e-5))
# train the neural network
model.compile(
loss=tf.keras.losses.CategoricalCrossentropy(label_smoothing=0.1), # calibration / robustness
optimizer=opt, metrics=["accuracy"])
model.fit(train_dataset, epochs=EPOCHS, validation_data=validation_dataset, verbose=2, callbacks=callbacks)
# Use this flag to disable per-channel quantization for a model.
# This can reduce RAM usage for convolutional models, but may have
# an impact on accuracy.
disable_per_channel_quantization = False
Input layer (1,274 features)
Select a scoring function
Reshape layer (13 columns)
2D conv / pool layer (8 filters, 3 kernel size, 1 layer)
Dropout (rate 0.5)
2D conv / pool layer (16 filters, 3 kernel size, 1 layer)
Dropout (rate 0.5)
Flatten layer
Output layer (3 classes)
Model
Model version: