TPU Detection and Initialization
This cell is responsible for detecting if the code is running on a TPU (Tensor Processing Unit) and
initializing the appropriate strategy for distributed training.
Overview
• TPU Detection: The code tries to create a TPUClusterResolver to identify available
TPU resources.
• TPU Initialization: If a TPU is detected, it connects to the TPU cluster and initializes the
TPU system.
• Strategy Selection:
– TPUStrategy: Used for model training when a TPU is available.
– Default Strategy: Used if no TPU is detected.
Output Messages
• If a TPU is successfully initialized, it prints:
– "Running on TPU"
• If no TPU is detected, it prints:
– "Running on default strategy"
This setup allows for efficient model training by leveraging TPUs when available, while also
ensuring compatibility in environments without TPU support.
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
import pandas as pd
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D,
Dropout
from tensorflow.keras.applications import ResNet50V2,EfficientNetV2M
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.regularizers import l2
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras.applications.resnet_v2 import preprocess_input
from sklearn.model_selection import train_test_split
from tensorflow.keras import layers
import random
import cv2
import os,librosa
# Detect TPU and initialize TPU strategy
try:
resolver = tf.distribute.cluster_resolver.TPUClusterResolver() #
TPU detection
tf.config.experimental_connect_to_cluster(resolver)
tf.tpu.experimental.initialize_tpu_system(resolver)
strategy = tf.distribute.TPUStrategy(resolver) # TPUStrategy
print("Running on TPU")
except ValueError:
strategy = tf.distribute.get_strategy() # default strategy if not
on TPU
print("Running on default strategy")
training_data_dir =
"/kaggle/input/audio-identification/training_split/training_split"
Spectrogram and Label Extraction from Audio
Files
This section contains two functions: extract_spectrogram and
extract_spectrograms_and_labels. These functions are used to extract audio features
and associated labels from a dataset of audio files.
1. extract_spectrogram(y, sr)
This function generates a mel spectrogram from an audio signal.
Parameters:
• y: The audio time series (1D NumPy array).
• sr: The sample rate of the audio signal.
Returns:
• A 3D NumPy array representing the mel spectrogram, resized to fit the input shape
expected by the model.
Key Steps:
• Computes the mel spectrogram using librosa.feature.melspectrogram.
• Converts the power spectrogram to decibel (dB) scale.
• Resizes the spectrogram to 512x512 pixels.
• Stacks the 2D spectrogram to create a 3D array for compatibility with models like
ResNetV2.
2. extract_spectrograms_and_labels(data_dir, max_files=None)
This function extracts spectrogram features and associated age and gender labels from audio
files organized in directories.
Parameters:
• data_dir (str): The directory containing the training data.
• max_files (int, optional): The maximum number of files to process. Default is None.
Returns:
• A tuple containing:
– features (list of np.array): Extracted audio spectrograms.
– age_labels (list of int): Age group labels (0, 1, 2).
– gender_labels (list of int): Gender labels (0 for male, 1 for female).
Key Steps:
• Iterates through each person's directory and extracts age and gender information from
the folder name.
• Converts age into a categorical label:
– Age <= 15: Label 0
– 16 <= Age <= 40: Label 1
– Age > 40: Label 2
• Loads each audio file (in WAV format) and generates spectrograms using the
extract_spectrogram function.
• Appends the features and labels to respective lists.
def extract_spectrogram(y,sr): # Extract spectrogram (example feature) S =
librosa.feature.melspectrogram(y=y, sr=sr, n_mels=512) S_DB = librosa.power_to_db(S,
ref=np.max)
# Resize and expand dimensions to fit ResNetV2 input
S_DB_resized = cv2.resize(S_DB, (512, 512),
interpolation=cv2.INTER_LINEAR)
S_DB_3d = np.stack((S_DB_resized,) * 3, axis=-1)
return S_DB_3d
def extract_spectrograms_and_labels(data_dir, max_files=None):
"""Extracts spectrogram features and labels from audio files.
Args:
data_dir (str): The directory containing the training data.
max_files (int, optional): Maximum number of files to process
for testing purposes. Default is None.
Returns:
tuple: A tuple containing:
- features (list of np.array): Extracted audio
spectrograms.
- age_labels (list of int): Age group labels.
- gender_labels (list of int): Gender labels.
"""
features_y = []
features_sr=[]
age_labels = []
gender_labels = []
# Walk through all directories and files in the specified
directory
for person_dir in os.listdir(data_dir):
person_path = os.path.join(data_dir, person_dir)
if os.path.isdir(person_path):
# Extract age and gender from the folder name (format:
personId_age_gender)
_, age, gender = person_dir.split('_')
age = int(age)
gender = gender.lower()
# Convert age to age group label
if age <= 15:
age_label = 0
elif 16 <= age <= 40:
age_label = 1
else:
age_label = 2
# Process each audio file in the person's folder
for audio_file in os.listdir(person_path):
audio_path = os.path.join(person_path, audio_file)
if audio_path.endswith('.wav'):
# Load audio file
try:
y, sr = librosa.load(audio_path, sr=None)
features_y.append(y)
features_sr.append(sr)
age_labels.append(age_label)
gender_labels.append(0 if gender == 'male'
else 1) # 0 for male, 1 for female
if max_files and len(features) >= max_files:
return features, age_labels, gender_labels
except Exception as e:
print(f"Error loading {audio_path}: {e}")
continue
return features_y,features_sr, age_labels, gender_labels
# Example usage
with strategy.scope():
features_y,features_sr, age_labels, gender_labels =
extract_spectrograms_and_labels(training_data_dir)
# Split the data into 80% training and 25% dev
features_y_train, features_y_dev, features_sr_train, features_sr_dev,
age_train, age_dev, gender_train, gender_dev = train_test_split(
features_y, features_sr, age_labels, gender_labels,
test_size=0.30, random_state=42, stratify=age_labels
)
Audio Augmentation for Model Training
This section contains functions for augmenting audio data, which helps improve the robustness
of machine learning models by providing diverse training samples.
1. vtlp(y, sr, low=0.9, high=1.1)
This function applies Vocal Tract Length Perturbation (VTLP) to simulate different vocal
characteristics.
Parameters:
• y: The audio time series (1D NumPy array).
• sr: The sample rate of the audio signal.
• low (float): Lower bound for the warp factor (default is 0.9).
• high (float): Upper bound for the warp factor (default is 1.1).
Returns:
• y_vtlp: The audio signal after applying VTLP.
Key Steps:
• A warp factor is randomly selected within the specified range.
• The warp factor is converted into a number of semitones.
• The audio signal is pitch-shifted using librosa.effects.pitch_shift.
2. augment_audio(y, sr)
This function applies a series of random augmentations to an audio signal to enhance the
diversity of the dataset.
Parameters:
• y: The audio time series (1D NumPy array).
• sr: The sample rate of the audio signal.
Returns:
• A list of augmented audio signals.
Key Augmentations:
• Random Noise: Adds Gaussian noise to the audio signal.
• Time Shifting: Shifts the audio signal in time by a random amount.
• Pitch Shifting: Changes the pitch of the audio by a random number of semitones.
• Vocal Tract Length Perturbation: Applies VTLP to modify vocal characteristics.
3. augment_and_extract(features_y, features_sr, age_labels,
gender_labels)
This function augments the audio features and extracts spectrograms along with their
corresponding labels.
Parameters:
• features_y: List of audio signals.
• features_sr: List of sample rates.
• age_labels: List of age group labels.
• gender_labels: List of gender labels.
Returns:
• A tuple containing:
– augmented_features: List of augmented spectrograms.
– augmented_age_labels: List of age labels corresponding to the augmented
features.
– augmented_gender_labels: List of gender labels corresponding to the
augmented features.
Key Steps:
• Iterates over each audio signal and applies the augment_audio function.
• Extracts spectrograms from the augmented audio signals.
• Appends the augmented features and corresponding labels to their respective lists.
def vtlp(y, sr, low=0.9, high=1.1):
"""
Vocal Tract Length Perturbation to simulate different vocal
characteristics.
"""
warp_factor = np.random.uniform(low, high)
n_steps = np.log2(warp_factor) * 12 # Convert warp factor to
semitones
y_vtlp = librosa.effects.pitch_shift(y=y, sr=sr, n_steps=n_steps)
return y_vtlp
def augment_audio(y, sr):
"""
Apply a series of random augmentations to the audio signal.
"""
augmentations = []
# Add random noise
if random.choice([True, False]):
y_noisy = y + np.random.normal(0, 0.01, len(y))
augmentations.append(y_noisy)
# Time stretching
# if random.choice([True, False]):
# try:
# y_stretch = librosa.effects.time_stretch(y,
rate=np.random.uniform(0.8, 1.2))
# augmentations.append(y_stretch)
# except:
# # Time stretching can fail if y is too short or other
issues
# pass
# Time shifting
if random.choice([True, False]):
shift = int(np.random.uniform(0.1, 0.3) * sr)
y_shifted = np.roll(y, shift)
augmentations.append(y_shifted)
# Pitch shifting
if random.choice([True, False]):
y_pitch = librosa.effects.pitch_shift(y, sr=sr,
n_steps=random.randint(-3, 3))
augmentations.append(y_pitch)
# Vocal Tract Length Perturbation (VTLP)
if random.choice([True, False]):
y_vtlp = vtlp(y, sr)
augmentations.append(y_vtlp)
return augmentations
def augment_and_extract(features_y, features_sr,age_labels,
gender_labels):
augmented_features=[]
augmented_age_labels=[]
augmented_gender_labels=[]
for i in range(len(features_y)):
y=features_y[i]
sr=features_sr[i]
augmented_audios=augment_audio(y,sr)
for y in augmented_audios:
spectrogram=extract_spectrogram(y,sr)
augmented_features.append(spectrogram)
augmented_age_labels.append(age_labels[i])
augmented_gender_labels.append(gender_labels[i])
return
augmented_features,augmented_age_labels,augmented_gender_labels
with strategy.scope():
augmented_features, augmented_age_labels, augmented_gender_labels
= augment_and_extract(
features_y_train, features_sr_train, age_train, gender_train
)
original_features=[extract_spectrogram(y,sr) for y,sr in
zip(features_y_train,features_sr_train)]
# Step 5: Combine original and augmented training data
X_train = np.concatenate((original_features, augmented_features),
axis=0)
age_train = np.concatenate((age_train, augmented_age_labels), axis=0)
gender_train = np.concatenate((gender_train, augmented_gender_labels),
axis=0)
# Step 6: Extract spectrograms for validation data without
augmentation
X_dev_features = [extract_spectrogram(y, sr) for y, sr in
zip(features_y_dev, features_sr_dev)]
X_dev = np.array(X_dev_features)
age_dev = np.array(age_dev)
gender_dev = np.array(gender_dev)
# Step 7: Convert training data to numpy arrays
X_train = np.array(X_train)
age_train = np.array(age_train)
gender_train = np.array(gender_train)
# Convert labels to categorical format
age_train = to_categorical(age_train, num_classes=3)
age_dev = to_categorical(age_dev, num_classes=3)
gender_train = to_categorical(gender_train, num_classes=2)
gender_dev = to_categorical(gender_dev, num_classes=2)
gender_train_bin = np.argmax(gender_train, axis=1) # Converts [1, 0]
to 0, [0, 1] to 1
gender_dev_bin = np.argmax(gender_dev, axis=1)
Dataset Preparation and Preprocessing
In this section, we preprocess the input images and prepare the training and development
datasets for model training.
1. Image Preprocessing
The input images are normalized using the preprocess_input function, which is tailored for
the ResNetV2 model architecture being used. Normalization is essential for ensuring that the
input data is on a suitable scale for the neural network.
```python
Normalize the training and development
images
X_train_norm = preprocess_input(np.array(X_train)) X_dev_norm =
preprocess_input(np.array(X_dev))
# Preprocess the input images
X_train_norm = preprocess_input(np.array(X_train))
X_dev_norm = preprocess_input(np.array(X_dev))
# Convert numpy arrays to tf.data.Dataset
batch_size = 16 * tpu_strategy.num_replicas_in_sync # TPU typically
requires a higher batch size
train_dataset = tf.data.Dataset.from_tensor_slices((X_train_norm,
{'age': age_train, 'gender': gender_train_bin}))
dev_dataset = tf.data.Dataset.from_tensor_slices((X_dev_norm, {'age':
age_dev, 'gender': gender_dev_bin}))
# Shuffle and batch the dataset
train_dataset =
train_dataset.shuffle(buffer_size=1024).batch(batch_size).prefetch(tf.
data.AUTOTUNE)
dev_dataset = dev_dataset.batch(batch_size).prefetch(tf.data.AUTOTUNE)
TPU Training Strategy: Age and Gender Classification with
ResNet50V2 and LSTM
This strategy utilizes a pre-trained ResNet50V2 base model, combined with LSTM layers for
temporal data handling, to classify both age and gender from image inputs. The key features of
the training setup include regularization, dropout, and learning rate decay, all aimed at
improving model performance and preventing overfitting during training on TPU.
Key Components:
1. Base Model: ResNet50V2
– Pre-trained on ImageNet and used for feature extraction. The top layers are
removed to allow for custom modifications.
– Input shape: (512, 512, 3) for image data.
2. Global Average Pooling:
– Reduces the spatial dimensions from the base model output, creating a more
compact feature representation.
3. Reshaping for Temporal Input:
– The output of the GlobalAveragePooling2D is reshaped to include a temporal
dimension, making it compatible with LSTM layers.
4. LSTM Layer:
– A single LSTM layer with 256 units processes the temporal aspect of the input
features. This addition is crucial for sequential or time-based data.
5. Fully Connected Layers with Regularization and Dropout:
– Four Dense layers (1024, 512, 256, and 128 units) with relu activation are added
to the model.
– Each layer includes L2 regularization (0.01) and dropout (0.2) to prevent
overfitting by penalizing large weights and randomly deactivating neurons during
training.
6. Dual Outputs:
– Age Classification: A Dense layer with softmax activation for 3 age groups.
– Gender Classification: A Dense layer with sigmoid activation for binary gender
classification.
7. Learning Rate Decay:
– A ReduceLROnPlateau callback adjusts the learning rate by a factor of 0.2 if no
improvement in val_loss is detected for 3 consecutive epochs. The learning
rate is bounded by 1e-7.
8. Early Stopping:
– The EarlyStopping callback monitors the validation loss, halting training after
20 epochs without improvement. It restores the best model weights to ensure
optimal performance.
9. Compilation:
– The model is compiled with the Adam optimizer and two loss functions:
• Categorical Crossentropy for age classification.
• Binary Crossentropy for gender classification.
– Accuracy is used as the evaluation metric for both outputs.
Callbacks:
• Learning Rate Decay: Prevents overfitting by reducing the learning rate when
performance stagnates.
• Early Stopping: Stops training early to avoid overfitting and long, unnecessary training
times.
This setup is well-suited for TPU training, taking advantage of the parallelism and speed while
ensuring model robustness through the use of regularization techniques and careful monitoring
of learning rate and validation performance.
# Strategy for TPU training
regularization_parameter=0.01
dropout_value=0.2
with strategy.scope():
# Load ResNet50V2 with pre-trained ImageNet weights and modify for
your task
base_model = ResNet50V2(weights='imagenet', include_top=False,
input_shape=(512, 512, 3))
# Add custom layers
x = base_model.output
x = GlobalAveragePooling2D()(x) # Use GlobalAveragePooling2D to
reduce dimensionality
# Reshape for LSTM input (we add a 'temporal' dimension)
x = layers.Reshape((1, -1))(x) # Reshape to (batch_size,
time_steps=1, features)
# Add LSTM Layer
x = layers.LSTM(256, return_sequences=False)(x) # LSTM with 64
units
# Increase regularization with more dropout and L2
x = Dense(1024, activation='relu',
kernel_regularizer=l2(regularization_parameter))(x)
x = Dropout(dropout_value)(x)
x = Dense(512, activation='relu',
kernel_regularizer=l2(regularization_parameter))(x)
x = Dropout(dropout_value)(x)
x = Dense(256, activation='relu',
kernel_regularizer=l2(regularization_parameter))(x)
x = Dropout(dropout_value)(x)
x = Dense(128, activation='relu',
kernel_regularizer=l2(regularization_parameter))(x)
x = Dropout(dropout_value)(x)
# Output layers for age and gender classification"
age_output = Dense(3, activation='softmax', name='age')(x)
gender_output = Dense(1, activation='sigmoid', name='gender')(x)
# Learning Rate Decay
reduce_lr = tf.keras.callbacks.ReduceLROnPlateau(
monitor='val_loss', # Metric to monitor
factor=0.2, # Factor by which to reduce the
learning rate
patience=3, # Number of epochs with no improvement
after which the learning rate is reduced
min_lr=1e-7 # Lower bound on the learning rate
)
# Early Stopping
early_stopping = EarlyStopping(monitor='val_loss', patience=20,
restore_best_weights=True)
# Create the final model
model = Model(inputs=base_model.input, outputs=[age_output,
gender_output])
# Compile the model with appropriate loss functions
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=1e-
3),
loss={'age': 'categorical_crossentropy', 'gender':
'binary_crossentropy'},
metrics={'age': 'accuracy', 'gender': 'accuracy'})
# Train the model with data augmentation
with strategy.scope():
history = model.fit(train_dataset,
validation_data=dev_dataset,
epochs=50,
callbacks=[early_stopping,reduce_lr],steps_per_execution=100)
Epoch 1/50
2024-09-10 13:54:21.167712: E
tensorflow/core/grappler/optimizers/meta_optimizer.cc:961]
model_pruner failed: INVALID_ARGUMENT: Graph does not contain terminal
node StatefulPartitionedCall.
I0000 00:00:1725976464.953696 827
tpu_compilation_cache_interface.cc:441] TPU host compilation cache
miss: cache_key(3f7db64c608f8497:0:0), session_name()
I0000 00:00:1725976501.440408 827 tpu_compile_op_common.cc:245]
Compilation of 3f7db64c608f8497:0:0 with session name took
36.486652471s and succeeded
I0000 00:00:1725976501.527749 827
tpu_compilation_cache_interface.cc:475] TPU host compilation cache:
compilation complete for cache_key(3f7db64c608f8497:0:0),
session_name(), subgraph_key(std::string(property.function_name) =
"cluster_one_step_on_iterator_17918388998778187092",
property.function_library_fingerprint = 3646480674883092343,
property.mlir_module_fingerprint = 0, property.num_replicas = 8,
topology.chip_bounds().x = 2, topology.chip_bounds().y = 2,
topology.chip_bounds().z = 1, topology.wrap().x = false,
topology.wrap().y = false, topology.wrap().z = false,
std::string(property.shapes_prefix) = "16,512,512,3,;16,3,;16,;",
property.guaranteed_constants_size = 0,
embedding_partitions_fingerprint = "1688352644216761960")
I0000 00:00:1725976501.527805 827
tpu_compilation_cache_interface.cc:541] After adding entry for key
3f7db64c608f8497:0:0 with session_name cache is 1 entries (159300189
bytes), marked for eviction 0 entries (0 bytes).
24/24 ━━━━━━━━━━━━━━━━━━━━ 0s 1s/step - age_accuracy: 0.7113 -
age_loss: 0.7149 - gender_accuracy: 0.6211 - gender_loss: 0.5840 -
loss: 14.4499
2024-09-10 13:55:45.114246: E
tensorflow/core/grappler/optimizers/meta_optimizer.cc:961]
model_pruner failed: INVALID_ARGUMENT: Graph does not contain terminal
node Add/ReadVariableOp.
I0000 00:00:1725976546.137372 821
tpu_compilation_cache_interface.cc:441] TPU host compilation cache
miss: cache_key(d3562e5aa89b3bd9:0:0), session_name()
I0000 00:00:1725976551.979646 821 tpu_compile_op_common.cc:245]
Compilation of d3562e5aa89b3bd9:0:0 with session name took
5.842223252s and succeeded
I0000 00:00:1725976551.991051 821
tpu_compilation_cache_interface.cc:475] TPU host compilation cache:
compilation complete for cache_key(d3562e5aa89b3bd9:0:0),
session_name(), subgraph_key(std::string(property.function_name) =
"cluster_one_step_on_iterator_10276527399086649280",
property.function_library_fingerprint = 5543601231518299573,
property.mlir_module_fingerprint = 0, property.num_replicas = 8,
topology.chip_bounds().x = 2, topology.chip_bounds().y = 2,
topology.chip_bounds().z = 1, topology.wrap().x = false,
topology.wrap().y = false, topology.wrap().z = false,
std::string(property.shapes_prefix) = "16,512,512,3,;16,3,;16,;",
property.guaranteed_constants_size = 0,
embedding_partitions_fingerprint = "1688352644216761960")
I0000 00:00:1725976551.991084 821
tpu_compilation_cache_interface.cc:541] After adding entry for key
d3562e5aa89b3bd9:0:0 with session_name cache is 2 entries (184538072
bytes), marked for eviction 0 entries (0 bytes).
I0000 00:00:1725976552.848790 770
tpu_compilation_cache_interface.cc:441] TPU host compilation cache
miss: cache_key(40076213ed7fcf95:0:0), session_name()
I0000 00:00:1725976559.841582 770 tpu_compile_op_common.cc:245]
Compilation of 40076213ed7fcf95:0:0 with session name took
6.992702084s and succeeded
I0000 00:00:1725976559.851941 770
tpu_compilation_cache_interface.cc:475] TPU host compilation cache:
compilation complete for cache_key(40076213ed7fcf95:0:0),
session_name(), subgraph_key(std::string(property.function_name) =
"cluster_one_step_on_iterator_10276527399086649280",
property.function_library_fingerprint = 5543601231518299573,
property.mlir_module_fingerprint = 0, property.num_replicas = 8,
topology.chip_bounds().x = 2, topology.chip_bounds().y = 2,
topology.chip_bounds().z = 1, topology.wrap().x = false,
topology.wrap().y = false, topology.wrap().z = false,
std::string(property.shapes_prefix) = "7,512,512,3,;7,3,;7,;",
property.guaranteed_constants_size = 0,
embedding_partitions_fingerprint = "1688352644216761960")
I0000 00:00:1725976559.851971 770
tpu_compilation_cache_interface.cc:541] After adding entry for key
40076213ed7fcf95:0:0 with session_name cache is 3 entries (209416472
bytes), marked for eviction 0 entries (0 bytes).
24/24 ━━━━━━━━━━━━━━━━━━━━ 129s 3s/step - age_accuracy: 0.7134 -
age_loss: 0.7093 - gender_accuracy: 0.6240 - gender_loss: 0.5817 -
loss: 14.3421 - val_age_accuracy: 0.8182 - val_age_loss: 0.6190 -
val_gender_accuracy: 0.7818 - val_gender_loss: 0.7084 - val_loss:
7.4391 - learning_rate: 0.0010
Epoch 2/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 60s 2s/step - age_accuracy: 0.8053 -
age_loss: 0.4362 - gender_accuracy: 0.7164 - gender_loss: 0.4485 -
loss: 5.7344 - val_age_accuracy: 0.8182 - val_age_loss: 0.8427 -
val_gender_accuracy: 0.7455 - val_gender_loss: 1.0414 - val_loss:
4.0182 - learning_rate: 0.0010
Epoch 3/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.7204 -
age_loss: 0.4931 - gender_accuracy: 0.8807 - gender_loss: 0.2887 -
loss: 2.5555 - val_age_accuracy: 0.8182 - val_age_loss: 0.7554 -
val_gender_accuracy: 0.7818 - val_gender_loss: 1.1441 - val_loss:
2.8378 - learning_rate: 0.0010
Epoch 4/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.7796 -
age_loss: 0.4363 - gender_accuracy: 0.8957 - gender_loss: 0.2765 -
loss: 1.5104 - val_age_accuracy: 0.8182 - val_age_loss: 0.6529 -
val_gender_accuracy: 0.2182 - val_gender_loss: 3.9409 - val_loss:
5.0084 - learning_rate: 0.0010
Epoch 5/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.8081 -
age_loss: 0.3478 - gender_accuracy: 0.9170 - gender_loss: 0.1875 -
loss: 0.9990 - val_age_accuracy: 0.7273 - val_age_loss: 0.5380 -
val_gender_accuracy: 0.7818 - val_gender_loss: 0.4913 - val_loss:
1.3876 - learning_rate: 0.0010
Epoch 6/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.8167 -
age_loss: 0.3632 - gender_accuracy: 0.9422 - gender_loss: 0.1911 -
loss: 0.8761 - val_age_accuracy: 0.8182 - val_age_loss: 1.0693 -
val_gender_accuracy: 0.7818 - val_gender_loss: 1.1766 - val_loss:
2.4854 - learning_rate: 0.0010
Epoch 7/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 60s 2s/step - age_accuracy: 0.8079 -
age_loss: 0.3594 - gender_accuracy: 0.9547 - gender_loss: 0.1238 -
loss: 0.7304 - val_age_accuracy: 0.7636 - val_age_loss: 0.7089 -
val_gender_accuracy: 0.6545 - val_gender_loss: 1.1546 - val_loss:
1.9975 - learning_rate: 0.0010
Epoch 8/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.8622 -
age_loss: 0.3103 - gender_accuracy: 0.9521 - gender_loss: 0.1525 -
loss: 0.6643 - val_age_accuracy: 0.8182 - val_age_loss: 0.6943 -
val_gender_accuracy: 0.7818 - val_gender_loss: 0.9615 - val_loss:
1.8312 - learning_rate: 0.0010
Epoch 9/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 60s 2s/step - age_accuracy: 0.8974 -
age_loss: 0.2361 - gender_accuracy: 0.9734 - gender_loss: 0.0809 -
loss: 0.4960 - val_age_accuracy: 0.8182 - val_age_loss: 0.6928 -
val_gender_accuracy: 0.7818 - val_gender_loss: 0.7535 - val_loss:
1.5944 - learning_rate: 2.0000e-04
Epoch 10/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 60s 2s/step - age_accuracy: 0.9109 -
age_loss: 0.1989 - gender_accuracy: 0.9911 - gender_loss: 0.0490 -
loss: 0.4282 - val_age_accuracy: 0.8182 - val_age_loss: 0.7665 -
val_gender_accuracy: 0.7455 - val_gender_loss: 0.7230 - val_loss:
1.7404 - learning_rate: 2.0000e-04
Epoch 11/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.9374 -
age_loss: 0.1695 - gender_accuracy: 0.9862 - gender_loss: 0.0643 -
loss: 0.4110 - val_age_accuracy: 0.7091 - val_age_loss: 0.5066 -
val_gender_accuracy: 0.7818 - val_gender_loss: 0.3604 - val_loss:
1.1034 - learning_rate: 2.0000e-04
Epoch 12/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.9422 -
age_loss: 0.1506 - gender_accuracy: 0.9931 - gender_loss: 0.0381 -
loss: 0.3635 - val_age_accuracy: 0.7273 - val_age_loss: 0.4864 -
val_gender_accuracy: 0.7636 - val_gender_loss: 0.4498 - val_loss:
1.1815 - learning_rate: 2.0000e-04
Epoch 13/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.9677 -
age_loss: 0.0950 - gender_accuracy: 0.9979 - gender_loss: 0.0247 -
loss: 0.2912 - val_age_accuracy: 0.7818 - val_age_loss: 0.4920 -
val_gender_accuracy: 0.4545 - val_gender_loss: 1.9185 - val_loss:
2.7492 - learning_rate: 2.0000e-04
Epoch 14/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 60s 2s/step - age_accuracy: 0.9701 -
age_loss: 0.0939 - gender_accuracy: 0.9992 - gender_loss: 0.0240 -
loss: 0.2878 - val_age_accuracy: 0.7273 - val_age_loss: 0.4526 -
val_gender_accuracy: 0.8545 - val_gender_loss: 0.2376 - val_loss:
0.9218 - learning_rate: 2.0000e-04
Epoch 15/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.9676 -
age_loss: 0.0873 - gender_accuracy: 0.9905 - gender_loss: 0.0314 -
loss: 0.2858 - val_age_accuracy: 0.6727 - val_age_loss: 0.5409 -
val_gender_accuracy: 0.6727 - val_gender_loss: 0.6783 - val_loss:
1.4772 - learning_rate: 2.0000e-04
Epoch 16/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 58s 2s/step - age_accuracy: 0.9672 -
age_loss: 0.0789 - gender_accuracy: 0.9982 - gender_loss: 0.0200 -
loss: 0.2611 - val_age_accuracy: 0.7455 - val_age_loss: 0.5028 -
val_gender_accuracy: 0.8364 - val_gender_loss: 0.2649 - val_loss:
1.0212 - learning_rate: 2.0000e-04
Epoch 17/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.9839 -
age_loss: 0.0736 - gender_accuracy: 0.9964 - gender_loss: 0.0207 -
loss: 0.2534 - val_age_accuracy: 0.8364 - val_age_loss: 0.3892 -
val_gender_accuracy: 0.8727 - val_gender_loss: 0.2226 - val_loss:
0.8367 - learning_rate: 2.0000e-04
Epoch 18/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.9783 -
age_loss: 0.0674 - gender_accuracy: 0.9882 - gender_loss: 0.0314 -
loss: 0.2564 - val_age_accuracy: 0.8545 - val_age_loss: 0.6208 -
val_gender_accuracy: 0.9091 - val_gender_loss: 0.2333 - val_loss:
1.0535 - learning_rate: 2.0000e-04
Epoch 19/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.9831 -
age_loss: 0.0528 - gender_accuracy: 0.9995 - gender_loss: 0.0133 -
loss: 0.2183 - val_age_accuracy: 0.3818 - val_age_loss: 1.5990 -
val_gender_accuracy: 0.8364 - val_gender_loss: 0.5519 - val_loss:
2.5262 - learning_rate: 2.0000e-04
Epoch 20/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 60s 2s/step - age_accuracy: 0.9822 -
age_loss: 0.0501 - gender_accuracy: 0.9966 - gender_loss: 0.0122 -
loss: 0.2115 - val_age_accuracy: 0.8727 - val_age_loss: 0.2683 -
val_gender_accuracy: 0.9273 - val_gender_loss: 0.1606 - val_loss:
0.6413 - learning_rate: 2.0000e-04
Epoch 21/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.9827 -
age_loss: 0.0525 - gender_accuracy: 0.9997 - gender_loss: 0.0166 -
loss: 0.2135 - val_age_accuracy: 0.8182 - val_age_loss: 0.3652 -
val_gender_accuracy: 0.9273 - val_gender_loss: 0.1550 - val_loss:
0.7247 - learning_rate: 2.0000e-04
Epoch 22/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.9885 -
age_loss: 0.0429 - gender_accuracy: 0.9973 - gender_loss: 0.0201 -
loss: 0.2062 - val_age_accuracy: 0.8545 - val_age_loss: 0.3393 -
val_gender_accuracy: 0.9273 - val_gender_loss: 0.1938 - val_loss:
0.7593 - learning_rate: 2.0000e-04
Epoch 23/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 60s 2s/step - age_accuracy: 0.9691 -
age_loss: 0.0678 - gender_accuracy: 0.9958 - gender_loss: 0.0146 -
loss: 0.2235 - val_age_accuracy: 0.8727 - val_age_loss: 0.3054 -
val_gender_accuracy: 0.9091 - val_gender_loss: 0.2148 - val_loss:
0.7254 - learning_rate: 2.0000e-04
Epoch 24/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.9705 -
age_loss: 0.0545 - gender_accuracy: 0.9953 - gender_loss: 0.0209 -
loss: 0.2125 - val_age_accuracy: 0.8182 - val_age_loss: 0.2640 -
val_gender_accuracy: 0.9455 - val_gender_loss: 0.1663 - val_loss:
0.6298 - learning_rate: 4.0000e-05
Epoch 25/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 60s 2s/step - age_accuracy: 0.9975 -
age_loss: 0.0094 - gender_accuracy: 1.0000 - gender_loss: 0.0075 -
loss: 0.1533 - val_age_accuracy: 0.8727 - val_age_loss: 0.3327 -
val_gender_accuracy: 0.9455 - val_gender_loss: 0.1796 - val_loss:
0.7281 - learning_rate: 4.0000e-05
Epoch 26/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.9961 -
age_loss: 0.0162 - gender_accuracy: 0.9997 - gender_loss: 0.0104 -
loss: 0.1629 - val_age_accuracy: 0.8727 - val_age_loss: 0.2303 -
val_gender_accuracy: 0.9273 - val_gender_loss: 0.2042 - val_loss:
0.6391 - learning_rate: 4.0000e-05
Epoch 27/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.9988 -
age_loss: 0.0107 - gender_accuracy: 1.0000 - gender_loss: 0.0079 -
loss: 0.1545 - val_age_accuracy: 0.8909 - val_age_loss: 0.1661 -
val_gender_accuracy: 0.8909 - val_gender_loss: 0.2486 - val_loss:
0.6166 - learning_rate: 4.0000e-05
Epoch 28/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 1.0000 -
age_loss: 0.0137 - gender_accuracy: 1.0000 - gender_loss: 0.0095 -
loss: 0.1588 - val_age_accuracy: 0.9273 - val_age_loss: 0.1861 -
val_gender_accuracy: 0.8909 - val_gender_loss: 0.2950 - val_loss:
0.6936 - learning_rate: 4.0000e-05
Epoch 29/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 60s 2s/step - age_accuracy: 0.9904 -
age_loss: 0.0249 - gender_accuracy: 0.9942 - gender_loss: 0.0264 -
loss: 0.1862 - val_age_accuracy: 0.9273 - val_age_loss: 0.1444 -
val_gender_accuracy: 0.9091 - val_gender_loss: 0.2476 - val_loss:
0.5891 - learning_rate: 4.0000e-05
Epoch 30/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 58s 2s/step - age_accuracy: 0.9925 -
age_loss: 0.0163 - gender_accuracy: 1.0000 - gender_loss: 0.0085 -
loss: 0.1589 - val_age_accuracy: 0.9455 - val_age_loss: 0.1394 -
val_gender_accuracy: 0.9091 - val_gender_loss: 0.2449 - val_loss:
0.5793 - learning_rate: 4.0000e-05
Epoch 31/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 60s 2s/step - age_accuracy: 0.9950 -
age_loss: 0.0140 - gender_accuracy: 0.9966 - gender_loss: 0.0135 -
loss: 0.1608 - val_age_accuracy: 0.9091 - val_age_loss: 0.2513 -
val_gender_accuracy: 0.8909 - val_gender_loss: 0.3146 - val_loss:
0.7888 - learning_rate: 4.0000e-05
Epoch 32/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.9962 -
age_loss: 0.0225 - gender_accuracy: 0.9997 - gender_loss: 0.0074 -
loss: 0.1617 - val_age_accuracy: 0.9091 - val_age_loss: 0.3021 -
val_gender_accuracy: 0.9091 - val_gender_loss: 0.2799 - val_loss:
0.8062 - learning_rate: 4.0000e-05
Epoch 33/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.9967 -
age_loss: 0.0103 - gender_accuracy: 0.9992 - gender_loss: 0.0107 -
loss: 0.1516 - val_age_accuracy: 0.9273 - val_age_loss: 0.2165 -
val_gender_accuracy: 0.9273 - val_gender_loss: 0.2066 - val_loss:
0.6205 - learning_rate: 4.0000e-05
Epoch 34/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.9932 -
age_loss: 0.0227 - gender_accuracy: 1.0000 - gender_loss: 0.0087 -
loss: 0.1615 - val_age_accuracy: 0.9273 - val_age_loss: 0.2083 -
val_gender_accuracy: 0.9273 - val_gender_loss: 0.2148 - val_loss:
0.6206 - learning_rate: 8.0000e-06
Epoch 35/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.9960 -
age_loss: 0.0116 - gender_accuracy: 1.0000 - gender_loss: 0.0080 -
loss: 0.1495 - val_age_accuracy: 0.9273 - val_age_loss: 0.2153 -
val_gender_accuracy: 0.9091 - val_gender_loss: 0.2238 - val_loss:
0.6391 - learning_rate: 8.0000e-06
Epoch 36/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.9944 -
age_loss: 0.0156 - gender_accuracy: 1.0000 - gender_loss: 0.0073 -
loss: 0.1526 - val_age_accuracy: 0.9091 - val_age_loss: 0.2291 -
val_gender_accuracy: 0.9091 - val_gender_loss: 0.2353 - val_loss:
0.6685 - learning_rate: 1.6000e-06
Epoch 39/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 61s 2s/step - age_accuracy: 0.9986 -
age_loss: 0.0084 - gender_accuracy: 1.0000 - gender_loss: 0.0091 -
loss: 0.1471 - val_age_accuracy: 0.9091 - val_age_loss: 0.2370 -
val_gender_accuracy: 0.9091 - val_gender_loss: 0.2383 - val_loss:
0.6810 - learning_rate: 1.6000e-06
Epoch 40/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 1.0000 -
age_loss: 0.0085 - gender_accuracy: 1.0000 - gender_loss: 0.0077 -
loss: 0.1458 - val_age_accuracy: 0.9091 - val_age_loss: 0.2435 -
val_gender_accuracy: 0.9091 - val_gender_loss: 0.2395 - val_loss:
0.6900 - learning_rate: 3.2000e-07
Epoch 41/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.9968 -
age_loss: 0.0118 - gender_accuracy: 1.0000 - gender_loss: 0.0066 -
loss: 0.1480 - val_age_accuracy: 0.9091 - val_age_loss: 0.2468 -
val_gender_accuracy: 0.9091 - val_gender_loss: 0.2388 - val_loss:
0.6929 - learning_rate: 3.2000e-07
Epoch 42/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 60s 2s/step - age_accuracy: 0.9991 -
age_loss: 0.0081 - gender_accuracy: 1.0000 - gender_loss: 0.0068 -
loss: 0.1445 - val_age_accuracy: 0.9091 - val_age_loss: 0.2484 -
val_gender_accuracy: 0.9091 - val_gender_loss: 0.2399 - val_loss:
0.6960 - learning_rate: 3.2000e-07
Epoch 43/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.9995 -
age_loss: 0.0057 - gender_accuracy: 0.9992 - gender_loss: 0.0082 -
loss: 0.1435 - val_age_accuracy: 0.9091 - val_age_loss: 0.2470 -
val_gender_accuracy: 0.9091 - val_gender_loss: 0.2400 - val_loss:
0.6943 - learning_rate: 1.0000e-07
Epoch 44/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 60s 2s/step - age_accuracy: 0.9966 -
age_loss: 0.0180 - gender_accuracy: 0.9997 - gender_loss: 0.0085 -
loss: 0.1560 - val_age_accuracy: 0.9091 - val_age_loss: 0.2463 -
val_gender_accuracy: 0.9091 - val_gender_loss: 0.2417 - val_loss:
0.6956 - learning_rate: 1.0000e-07
Epoch 45/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 60s 2s/step - age_accuracy: 0.9968 -
age_loss: 0.0129 - gender_accuracy: 1.0000 - gender_loss: 0.0070 -
loss: 0.1494 - val_age_accuracy: 0.9091 - val_age_loss: 0.2482 -
val_gender_accuracy: 0.9091 - val_gender_loss: 0.2450 - val_loss:
0.7016 - learning_rate: 1.0000e-07
Epoch 46/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 59s 2s/step - age_accuracy: 0.9929 -
age_loss: 0.0135 - gender_accuracy: 0.9989 - gender_loss: 0.0091 -
loss: 0.1521 - val_age_accuracy: 0.9091 - val_age_loss: 0.2452 -
val_gender_accuracy: 0.9091 - val_gender_loss: 0.2447 - val_loss:
0.6978 - learning_rate: 1.0000e-07
Epoch 47/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 60s 2s/step - age_accuracy: 0.9828 -
age_loss: 0.0225 - gender_accuracy: 1.0000 - gender_loss: 0.0083 -
loss: 0.1603 - val_age_accuracy: 0.9091 - val_age_loss: 0.2443 -
val_gender_accuracy: 0.9091 - val_gender_loss: 0.2460 - val_loss:
0.6982 - learning_rate: 1.0000e-07
Epoch 48/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 60s 2s/step - age_accuracy: 0.9944 -
age_loss: 0.0137 - gender_accuracy: 0.9988 - gender_loss: 0.0108 -
loss: 0.1541 - val_age_accuracy: 0.9091 - val_age_loss: 0.2439 -
val_gender_accuracy: 0.9091 - val_gender_loss: 0.2497 - val_loss:
0.7021 - learning_rate: 1.0000e-07
Epoch 49/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 60s 2s/step - age_accuracy: 0.9984 -
age_loss: 0.0110 - gender_accuracy: 0.9988 - gender_loss: 0.0086 -
loss: 0.1491 - val_age_accuracy: 0.9091 - val_age_loss: 0.2443 -
val_gender_accuracy: 0.9091 - val_gender_loss: 0.2530 - val_loss:
0.7063 - learning_rate: 1.0000e-07
Epoch 50/50
24/24 ━━━━━━━━━━━━━━━━━━━━ 60s 2s/step - age_accuracy: 1.0000 -
age_loss: 0.0112 - gender_accuracy: 1.0000 - gender_loss: 0.0101 -
loss: 0.1509 - val_age_accuracy: 0.9091 - val_age_loss: 0.2440 -
val_gender_accuracy: 0.9091 - val_gender_loss: 0.2523 - val_loss:
0.7051 - learning_rate: 1.0000e-07
print("Final training age accuracy: {:.2f}
%".format(history.history['age_accuracy'][-1] * 100))
print("Final validation age accuracy: {:.2f}
%".format(history.history['val_age_accuracy'][-1] * 100))
print("Final training gender accuracy: {:.2f}
%".format(history.history['gender_accuracy'][-1] * 100))
print("Final validation gender accuracy: {:.2f}
%".format(history.history['val_gender_accuracy'][-1] * 100))
model.evaluate(dev_dataset)
Final training age accuracy: 100.00%
Final validation age accuracy: 90.91%
Final training gender accuracy: 100.00%
Final validation gender accuracy: 90.91%
2024-09-10 14:45:06.785813: E
tensorflow/core/grappler/optimizers/meta_optimizer.cc:961]
model_pruner failed: INVALID_ARGUMENT: Graph does not contain terminal
node Add/ReadVariableOp.
I0000 00:00:1725979507.817519 809
tpu_compilation_cache_interface.cc:441] TPU host compilation cache
miss: cache_key(2d4860dbf87a3f35:0:0), session_name()
1/4 ━━━━━━━━━━━━━━━━━━━━ 32s 11s/step - age_accuracy: 0.9375 -
age_loss: 0.1309 - gender_accuracy: 0.9375 - gender_loss: 0.3286 -
loss: 0.5930
I0000 00:00:1725979513.438948 809 tpu_compile_op_common.cc:245]
Compilation of 2d4860dbf87a3f35:0:0 with session name took
5.621358473s and succeeded
I0000 00:00:1725979513.452675 809
tpu_compilation_cache_interface.cc:475] TPU host compilation cache:
compilation complete for cache_key(2d4860dbf87a3f35:0:0),
session_name(), subgraph_key(std::string(property.function_name) =
"cluster_one_step_on_iterator_15838435082906321797",
property.function_library_fingerprint = 16985971535604093498,
property.mlir_module_fingerprint = 0, property.num_replicas = 8,
topology.chip_bounds().x = 2, topology.chip_bounds().y = 2,
topology.chip_bounds().z = 1, topology.wrap().x = false,
topology.wrap().y = false, topology.wrap().z = false,
std::string(property.shapes_prefix) = "16,512,512,3,;16,3,;16,;",
property.guaranteed_constants_size = 0,
embedding_partitions_fingerprint = "1688352644216761960")
I0000 00:00:1725979513.452712 809
tpu_compilation_cache_interface.cc:541] After adding entry for key
2d4860dbf87a3f35:0:0 with session_name cache is 4 entries (234654355
bytes), marked for eviction 0 entries (0 bytes).
3/4 ━━━━━━━━━━━━━━━━━━━━ 0s 373ms/step - age_accuracy: 0.9271 -
age_loss: 0.1920 - gender_accuracy: 0.9132 - gender_loss: 0.3440 -
loss: 0.6695
I0000 00:00:1725979514.303487 818
tpu_compilation_cache_interface.cc:441] TPU host compilation cache
miss: cache_key(1f9814a6bc24e89e:0:0), session_name()
4/4 ━━━━━━━━━━━━━━━━━━━━ 18s 3s/step - age_accuracy: 0.9344 -
age_loss: 0.1709 - gender_accuracy: 0.9116 - gender_loss: 0.3044 -
loss: 0.6334
I0000 00:00:1725979521.208800 818 tpu_compile_op_common.cc:245]
Compilation of 1f9814a6bc24e89e:0:0 with session name took
6.905247989s and succeeded
I0000 00:00:1725979521.219465 818
tpu_compilation_cache_interface.cc:475] TPU host compilation cache:
compilation complete for cache_key(1f9814a6bc24e89e:0:0),
session_name(), subgraph_key(std::string(property.function_name) =
"cluster_one_step_on_iterator_15838435082906321797",
property.function_library_fingerprint = 16985971535604093498,
property.mlir_module_fingerprint = 0, property.num_replicas = 8,
topology.chip_bounds().x = 2, topology.chip_bounds().y = 2,
topology.chip_bounds().z = 1, topology.wrap().x = false,
topology.wrap().y = false, topology.wrap().z = false,
std::string(property.shapes_prefix) = "7,512,512,3,;7,3,;7,;",
property.guaranteed_constants_size = 0,
embedding_partitions_fingerprint = "1688352644216761960")
I0000 00:00:1725979521.219500 818
tpu_compilation_cache_interface.cc:541] After adding entry for key
1f9814a6bc24e89e:0:0 with session_name cache is 5 entries (259532755
bytes), marked for eviction 0 entries (0 bytes).
[0.579304039478302,
0.13935422897338867,
0.24491183459758759,
0.9454545378684998,
0.9090909361839294]
with strategy.scope():
save_locally =
tf.saved_model.SaveOptions(experimental_io_device='/job:localhost')
model.save('model2.keras') # saving in Tensorflow's "SavedModel"
format
# Plot training & validation accuracy for age classification
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(history.history['age_accuracy'], label='Train Age Accuracy')
plt.plot(history.history['val_age_accuracy'], label='Validation Age
Accuracy')
plt.title('Age Classification Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()
# Plot training & validation accuracy for gender classification
plt.subplot(1, 2, 2)
plt.plot(history.history['gender_accuracy'], label='Train Gender
Accuracy')
plt.plot(history.history['val_gender_accuracy'], label='Validation
Gender Accuracy')
plt.title('Gender Classification Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()
plt.tight_layout()
plt.show()
Test Data Extraction and Prediction for Audio Classification
In this notebook, we perform audio data extraction and apply a pre-trained model to predict
both age group and gender from audio spectrograms. The key steps include loading the test
audio data, generating spectrograms, normalizing the input, and using a trained deep learning
model to make predictions. The results are saved in a CSV file for further analysis.
Steps:
1. Testing Data Directory:
– The test data is located in the testing_data_dir directory. This directory
contains WAV audio files which we will process and classify.
testing_data_dir =
"/kaggle/input/audio-identification/testing_split/testing_split"
1. Audio Data Extraction:
– The function extract_audio_data is used to load the audio files, extract their
corresponding waveforms and sampling rates, and store their filenames.
– The function processes files in the .wav format and can handle a specified
number of files through the max_files parameter.
def extract_audio_data(data_dir, max_files=None):
# Extract audio waveforms and metadata (sampling rate and file
name)
...
features_y_test, features_sr_test, file_names =
extract_audio_data(testing_data_dir)
1. Spectrogram Extraction:
– For each audio waveform, we convert it into a spectrogram using the
extract_spectrogram function, which converts the time-domain audio data
into a frequency-domain representation suitable for input into the model.
– The extracted spectrograms are normalized using preprocess_input to
prepare them for prediction.
X_test = [extract_spectrogram(y, sr) for y, sr in zip(features_y_test,
features_sr_test)]
X_test = np.array(X_test)
X_test_norm = preprocess_input(np.array(X_test))
1. Model Input Shape:
– Before prediction, we check that the model input shape matches the shape of the
test data to ensure compatibility.
print("Model input shape:", model.input_shape)
1. Loading the Trained Model:
– We load the trained model using tf.keras.models.load_model. Ensure the
correct model path is specified.
mk = tf.keras.models.load_model('/kaggle/working/model2.keras')
1. Prediction:
– The model is applied to the normalized test data to obtain predictions for both
age group and gender.
– Age predictions are handled as multi-class predictions, while gender predictions
are binary (Male/Female).
predictions = mk.predict(X_test_norm, verbose=1)
age_predictions = predictions[0]
gender_predictions = predictions[1]
1. Post-processing Predictions:
– Age Prediction: The predicted probabilities are converted to class labels using
argmax. A fallback logic is applied where predictions below a confidence
threshold (0.85) are set to class 0.
– Gender Prediction: Gender predictions are thresholded at 0.5 to classify as
either 'Male' or 'Female'.
age_predictions_classes = np.argmax(age_predictions, axis=1)
gender_predictions_classes = (gender_predictions >
0.5).astype(int).flatten()
gender_predictions_classes = np.where(gender_predictions_classes == 0,
'Male', 'Female')
1. Saving Predictions:
– The results, including the file name, predicted age group, and gender, are saved
to a CSV file (test_predictions.csv) for future reference.
results_df = pd.DataFrame({
'File_name': file_names,
'Age_group': age_predictions_classes,
'Gender': gender_predictions_classes
})
results_df = results_df.sort_values(by='File_name')
results_df.to_csv('/kaggle/working/test_predictions.csv', index=False)
This notebook showcases the workflow of applying a trained model to predict age and gender
from audio data, including data extraction, preprocessing, and saving predictions for further
analysis.
testing_data_dir =
"/kaggle/input/audio-identification/testing_split/testing_split"
def extract_audio_data(data_dir, max_files=None):
"""Extracts spectrogram features and labels from audio files.
Args:
data_dir (str): The directory containing the training data.
max_files (int, optional): Maximum number of files to process
for testing purposes. Default is None.
Returns:
tuple: A tuple containing:
- features (list of np.array): Extracted audio
spectrograms.
- age_labels (list of int): Age group labels.
- gender_labels (list of int): Gender labels.
"""
features_y = []
features_sr=[]
filenames=[]
# Process each audio file in the testing folder
for audio_file in os.listdir(data_dir):
audio_path = os.path.join(data_dir, audio_file)
file,_=audio_file.split('.')
if audio_path.endswith('.wav'):
# Load audio file
try:
y, sr = librosa.load(audio_path, sr=None)
features_y.append(y)
features_sr.append(sr)
filenames.append(file)
if max_files and len(features) >= max_files:
return features_y,features_sr, filenames
except Exception as e:
print(f"Error loading {audio_path}: {e}")
continue
return features_y,features_sr, filenames
features_y_test, features_sr_test,
file_names=extract_audio_data(testing_data_dir)
X_test=[extract_spectrogram(y,sr) for y,sr in
zip(features_y_test,features_sr_test)]
X_test=np.array(X_test)
file_names=np.array(file_names)
file_names=file_names.astype(np.int32)
# Preprocess the test data
X_test_norm = preprocess_input(np.array(X_test))
print("Model input shape:", model.input_shape)
# Load the trained model (if needed, replace with your actual model
path)
mk=tf.keras.models.load_model('/kaggle/working/model2.keras')
# Predict on test data
predictions = mk.predict(X_test_norm,verbose=1)
# Extract age and gender predictions
age_predictions = predictions[0]
gender_predictions = predictions[1]
# Convert predictions to class labels
age_predictions_classes = np.argmax(age_predictions, axis=1)
gender_predictions_classes = (gender_predictions >
0.5).astype(int).flatten()
gender_predictions_classes = np.where(gender_predictions_classes == 0,
'Male', 'Female')
# Fallback Logic
threshold=0.85
for i,probs in enumerate(age_predictions):
if np.max(probs) < threshold:
age_predictions_classes[i]=0
# Print or save predictions
print("Age predictions:", age_predictions_classes)
print("Gender predictions:", gender_predictions_classes)
results_df = pd.DataFrame({
'File_name': file_names,
'Age_group': age_predictions_classes,
'Gender': gender_predictions_classes
})
results_df=results_df.sort_values(by='File_name')
results_df.to_csv('/kaggle/working/test_predictions.csv', index=False)
Model input shape: (None, 512, 512, 3)
20/20 ━━━━━━━━━━━━━━━━━━━━ 60s 3s/step
Age predictions: [1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 2 1 1 0 1 1 1 1 1
1 1 1 1 0 1 1 1 2 2 1
1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 2 0 1 1 1 1
1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 1 1 1 1 2 1 2 1 1 1 1 1 1 1 1 1 1
1 1
1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 2 0 1 0 1 1 0
1 1
1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 1 1 2 1 1 1 1 1 1 1 2 0 1 0
1 1
2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 2 1 1 1 1 1 1 2 1 0 1 1 2 1
1 1
1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1
1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 0 1 1 1 1 1 1 2 0 1 2 1 1 1 1
1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1
1 1 1 1 0 2 1 1 2 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1
2 1
1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 2 1 1 2 1 0 1 1 1 1 1 1 1 1 1 1 2 1
1 1
1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 2 1 1 1 1 1 1 1 0 1 2 1 1 1 1 1 1
1 1
1 1 1 1 1 1 1 1 1 1 2 1 0 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1
1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1
1 1
1 1 1 1 1 1 1 1 0 1 1 2 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1
0 1 1 1 1 1 2 1 0 2 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1
1 1 1 1 1 1 1 1]
Gender predictions: ['Male' 'Female' 'Female' 'Female' 'Female' 'Male'
'Male' 'Male' 'Male'
'Male' 'Female' 'Male' 'Male' 'Male' 'Female' 'Female' 'Female'
'Male'
'Male' 'Male' 'Male' 'Male' 'Male' 'Female' 'Male' 'Male' 'Female'
'Male'
'Male' 'Male' 'Female' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male'
'Male'
'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male'
'Female'
'Female' 'Male' 'Male' 'Female' 'Male' 'Female' 'Female' 'Male'
'Female'
'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Female' 'Male'
'Male'
'Male' 'Male' 'Male' 'Male' 'Male' 'Female' 'Male' 'Male' 'Male'
'Male'
'Male' 'Male' 'Male' 'Female' 'Male' 'Male' 'Female' 'Male' 'Male'
'Female' 'Male' 'Male' 'Female' 'Female' 'Male' 'Male' 'Male' 'Male'
'Male' 'Male' 'Male' 'Male' 'Female' 'Male' 'Male' 'Male' 'Male'
'Female'
'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Female' 'Male' 'Male'
'Female'
'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Female' 'Male'
'Female'
'Female' 'Male' 'Female' 'Male' 'Female' 'Male' 'Male' 'Female'
'Male'
'Male' 'Male' 'Male' 'Male' 'Male' 'Female' 'Male' 'Male' 'Male'
'Female'
'Female' 'Male' 'Male' 'Male' 'Female' 'Male' 'Male' 'Female' 'Male'
'Female' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male'
'Male'
'Male' 'Female' 'Female' 'Male' 'Male' 'Female' 'Male' 'Female'
'Male'
'Male' 'Male' 'Female' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male'
'Male'
'Male' 'Male' 'Male' 'Female' 'Male' 'Female' 'Male' 'Male' 'Male'
'Male'
'Male' 'Male' 'Male' 'Female' 'Male' 'Male' 'Female' 'Male' 'Male'
'Male'
'Female' 'Female' 'Male' 'Male' 'Female' 'Male' 'Male' 'Male' 'Male'
'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male'
'Male' 'Male' 'Female' 'Male' 'Female' 'Male' 'Female' 'Female'
'Female'
'Male' 'Male' 'Male' 'Male' 'Male' 'Female' 'Female' 'Male' 'Female'
'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Female' 'Male'
'Male'
'Male' 'Female' 'Male' 'Male' 'Male' 'Male' 'Male' 'Female' 'Male'
'Female' 'Male' 'Male' 'Male' 'Male' 'Female' 'Female' 'Female'
'Male'
'Male' 'Male' 'Male' 'Male' 'Male' 'Female' 'Male' 'Female' 'Male'
'Male'
'Male' 'Female' 'Male' 'Male' 'Male' 'Female' 'Male' 'Male' 'Male'
'Female' 'Male' 'Female' 'Male' 'Male' 'Male' 'Male' 'Female' 'Male'
'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Female'
'Male'
'Female' 'Male' 'Female' 'Female' 'Male' 'Female' 'Female' 'Female'
'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male'
'Male' 'Female' 'Male' 'Male' 'Female' 'Male' 'Female' 'Male' 'Male'
'Female' 'Male' 'Male' 'Male' 'Male' 'Female' 'Male' 'Female'
'Female'
'Female' 'Male' 'Male' 'Male' 'Male' 'Female' 'Male' 'Male' 'Male'
'Male'
'Male' 'Male' 'Male' 'Female' 'Male' 'Female' 'Male' 'Female'
'Female'
'Male' 'Male' 'Male' 'Male' 'Male' 'Female' 'Male' 'Male' 'Male'
'Male'
'Male' 'Male' 'Male' 'Male' 'Female' 'Male' 'Female' 'Male' 'Female'
'Male' 'Male' 'Male' 'Male' 'Female' 'Female' 'Male' 'Female'
'Female'
'Male' 'Female' 'Male' 'Male' 'Female' 'Male' 'Female' 'Male' 'Male'
'Male' 'Male' 'Male' 'Female' 'Female' 'Female' 'Female' 'Female'
'Male'
'Male' 'Female' 'Female' 'Female' 'Male' 'Male' 'Female' 'Male'
'Male'
'Female' 'Female' 'Male' 'Female' 'Male' 'Male' 'Male' 'Male' 'Male'
'Female' 'Female' 'Male' 'Male' 'Male' 'Female' 'Male' 'Female'
'Female'
'Female' 'Female' 'Female' 'Male' 'Male' 'Male' 'Female' 'Male'
'Male'
'Female' 'Female' 'Female' 'Male' 'Male' 'Male' 'Female' 'Female'
'Female' 'Male' 'Male' 'Female' 'Male' 'Male' 'Female' 'Female'
'Female'
'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male'
'Male' 'Male' 'Male' 'Female' 'Male' 'Male' 'Male' 'Female' 'Male'
'Male'
'Male' 'Female' 'Female' 'Male' 'Female' 'Female' 'Male' 'Female'
'Male'
'Female' 'Male' 'Female' 'Female' 'Male' 'Male' 'Male' 'Female'
'Female'
'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male'
'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male'
'Female'
'Male' 'Male' 'Male' 'Male' 'Male' 'Female' 'Female' 'Female'
'Female'
'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male'
'Male' 'Male' 'Male' 'Male' 'Female' 'Male' 'Female' 'Male' 'Female'
'Male' 'Female' 'Female' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male'
'Male'
'Male' 'Female' 'Male' 'Male' 'Female' 'Female' 'Male' 'Male'
'Female'
'Male' 'Female' 'Female' 'Female' 'Male' 'Male' 'Female' 'Male'
'Male'
'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Female' 'Male'
'Female'
'Male' 'Male' 'Female' 'Male' 'Male' 'Male' 'Female' 'Male' 'Male'
'Female' 'Female' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male'
'Male'
'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Female' 'Female' 'Male'
'Male'
'Male' 'Male' 'Male' 'Male' 'Female' 'Male' 'Female' 'Male' 'Female'
'Male' 'Female' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male' 'Male'
'Female'
'Male' 'Male' 'Male' 'Male' 'Female' 'Male']