{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":21669,"databundleVersionId":1692278,"sourceType":"competition"}],"dockerImageVersionId":31154,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## Import","metadata":{}},{"cell_type":"code","source":"#Data handling\nimport os\nimport pandas as pd\nimport itertools\nfrom PIL import Image\n\n# Randomization\nimport random\n\n# Audio handling\n!pip install PySoundFile\nimport librosa\nfrom IPython.display import Audio\n\n# Visualization\nimport matplotlib.pyplot as plt\nfrom sklearn.manifold import TSNE\n\n# Feedback with progress bar\nfrom tqdm.notebook import tqdm\n\n# Math & Algorithms\nimport numpy as np\n\n# Model\nimport keras\nfrom keras import layers\nfrom tensorflow.keras import models, layers\nfrom tensorflow.keras.layers import Resizing\n\n# Clustering\nfrom sklearn.preprocessing import StandardScaler\nfrom sklearn.cluster import KMeans","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:15:19.766499Z","iopub.execute_input":"2025-11-11T13:15:19.767209Z","iopub.status.idle":"2025-11-11T13:15:38.786777Z","shell.execute_reply.started":"2025-11-11T13:15:19.767184Z","shell.execute_reply":"2025-11-11T13:15:38.785919Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Variable setting","metadata":{}},{"cell_type":"code","source":"# Initialize random number generation\nrandom_seed = 42\nrandom.seed(random_seed)\nrng = np.random.default_rng()\n\n# NN training parameters\n# target_shape=(256, 512)\nsegment_length=3\noverlap=0.5\nlatent_dim=256\nbatch_size = 32\nlr = 1e-3\npatience = 10\nepochs = 50\nnum_files=1000 # number of files used for training\nnum_clusters=24\n\n# Folder for storing generated spectrograms\nsave_path='/kaggle/working/spectrograms'\nos.makedirs(save_path, exist_ok=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:15:38.788078Z","iopub.execute_input":"2025-11-11T13:15:38.788571Z","iopub.status.idle":"2025-11-11T13:15:38.793282Z","shell.execute_reply.started":"2025-11-11T13:15:38.788552Z","shell.execute_reply":"2025-11-11T13:15:38.792499Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## File path","metadata":{}},{"cell_type":"code","source":"# Root data path for RainForest Species\ninput_path='/kaggle/input/rfcx-species-audio-detection'\n\n# Train and Test audio recordings data\ntrain_path=os.path.join(input_path, 'train')\ntest_path=os.path.join(input_path, 'test')\n\n# Labels\ntp_label_csv_path=os.path.join(input_path, 'train_tp.csv')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:15:38.793998Z","iopub.execute_input":"2025-11-11T13:15:38.794363Z","iopub.status.idle":"2025-11-11T13:15:38.844876Z","shell.execute_reply.started":"2025-11-11T13:15:38.794341Z","shell.execute_reply":"2025-11-11T13:15:38.844102Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Number of files\nnum_train_files=len([f for f in os.listdir(train_path) if os.path.isfile(os.path.join(train_path, f))])\nnum_test_files=len([f for f in os.listdir(test_path) if os.path.isfile(os.path.join(test_path, f))])\nnum_tp_rows=len(pd.read_csv(tp_label_csv_path))\nprint(f\"Number of training files: {num_train_files}\")\nprint(f\"Number of test files: {num_test_files}\")\nprint(f\"Number of labeled parts (true positive): {num_tp_rows}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:15:38.846279Z","iopub.execute_input":"2025-11-11T13:15:38.846480Z","iopub.status.idle":"2025-11-11T13:16:00.613820Z","shell.execute_reply.started":"2025-11-11T13:15:38.846465Z","shell.execute_reply":"2025-11-11T13:16:00.613049Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Chooses files randomly from the given folder\ndef random_files(source_path, num_files=1):\n\n    all_files=os.listdir(source_path)\n    chosen_files=random.sample(all_files, num_files)\n    return [os.path.join(source_path, f) for f in chosen_files]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:16:00.614627Z","iopub.execute_input":"2025-11-11T13:16:00.614987Z","iopub.status.idle":"2025-11-11T13:16:00.619187Z","shell.execute_reply.started":"2025-11-11T13:16:00.614959Z","shell.execute_reply":"2025-11-11T13:16:00.618396Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"random_file, sr=librosa.core.load(random_files(train_path)[0])\nprint(sr)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:16:00.619845Z","iopub.execute_input":"2025-11-11T13:16:00.620020Z","iopub.status.idle":"2025-11-11T13:16:12.375760Z","shell.execute_reply.started":"2025-11-11T13:16:00.620005Z","shell.execute_reply":"2025-11-11T13:16:12.375114Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Data generation","metadata":{}},{"cell_type":"markdown","source":"### Short segment","metadata":{}},{"cell_type":"code","source":"# Returns random audio segment\ndef random_audio_segment(file_path, segment_length=3.0, sr=22050):\n    \n    y, sr = librosa.load(file_path, sr=sr)\n    total_length=librosa.get_duration(y=y, sr=sr)\n\n    # Random start point\n    start_time=random.uniform(0, total_length-segment_length)\n    segment_samples=int(segment_length*sr)\n    start_sample=int(start_time*sr)\n    end_sample=start_sample+segment_samples\n    return y[start_sample:end_sample], sr","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:16:12.376448Z","iopub.execute_input":"2025-11-11T13:16:12.376940Z","iopub.status.idle":"2025-11-11T13:16:12.381621Z","shell.execute_reply.started":"2025-11-11T13:16:12.376921Z","shell.execute_reply":"2025-11-11T13:16:12.380882Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def spec_gen_short(file_path, sr=22050, n_mels=128, segment_length=3):\n    \n    audio, sr=random_audio_segment(file_path, segment_length, sr)\n    S=librosa.feature.melspectrogram(y=audio, sr=sr, n_mels=n_mels)\n    S_db=librosa.power_to_db(S, ref=np.max)\n    S_norm = (S_db - S_db.min()) / (S_db.max() - S_db.min())\n    return S_norm","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:16:12.382302Z","iopub.execute_input":"2025-11-11T13:16:12.382487Z","iopub.status.idle":"2025-11-11T13:16:12.394485Z","shell.execute_reply.started":"2025-11-11T13:16:12.382471Z","shell.execute_reply":"2025-11-11T13:16:12.393855Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def spec_save_short(source_path, save_path, num_files=100, sr=22050, segment_length=3, n_mels=128):\n\n    files=[f for f in os.scandir(source_path) if f.is_file()]\n    files=files[:num_files]\n    for f in tqdm(files):\n        if f.is_file():\n            output=os.path.join(save_path, os.path.splitext(f.name)[0]+\".png\")\n            spec=spec_gen_short(f.path, sr=sr, segment_length=segment_length)\n            spec=(spec*255).astype(np.uint8)\n            spec=Image.fromarray(spec, mode='L')\n            spec.save(output)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:16:12.395207Z","iopub.execute_input":"2025-11-11T13:16:12.395451Z","iopub.status.idle":"2025-11-11T13:16:12.406160Z","shell.execute_reply.started":"2025-11-11T13:16:12.395427Z","shell.execute_reply":"2025-11-11T13:16:12.405374Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Original","metadata":{}},{"cell_type":"code","source":"# Generates spectrogram from the given file\ndef spec_gen(file_path, target_shape=(128, 256), sr=22050):\n    \n    audio, sr=librosa.core.load(file_path)\n    S=librosa.feature.melspectrogram(y=audio, sr=sr, n_mels=target_shape[0]) # f_max, f_min \n    S_db=librosa.power_to_db(S, ref=np.max)\n\n    if S_db.shape[1]>target_shape[1]:\n        S_db=S_db[:, :target_shape[1]]\n    elif S_db.shape[1]<target_shape[1]:\n        pad_width=[(0, 0), (0, target_shape[1]-S_db.shape[1])]\n        S_db=np.pad(S_db, pad_width=pad_width, mode='constant')\n    \n    S_norm = (S_db - S_db.min()) / (S_db.max() - S_db.min())\n    \n    return S_norm","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:16:12.408530Z","iopub.execute_input":"2025-11-11T13:16:12.409076Z","iopub.status.idle":"2025-11-11T13:16:12.419605Z","shell.execute_reply.started":"2025-11-11T13:16:12.409038Z","shell.execute_reply":"2025-11-11T13:16:12.418699Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Generates and saves spectrograms from a given number of files\ndef spec_save(source_path, save_path, target_shape=(128, 256), num_files=100, sr=22050):\n    \n    files=[f for f in os.scandir(source_path) if f.is_file()]\n    files=files[:num_files]\n    for f in tqdm(files):\n        if f.is_file():\n            output=os.path.join(save_path, os.path.splitext(f.name)[0]+\".png\")\n            spec=spec_gen(f.path, target_shape, sr)\n            spec=(spec*255).astype(np.uint8)\n            spec=Image.fromarray(spec, mode='L')\n            spec.save(output)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:16:12.420555Z","iopub.execute_input":"2025-11-11T13:16:12.420799Z","iopub.status.idle":"2025-11-11T13:16:12.436432Z","shell.execute_reply.started":"2025-11-11T13:16:12.420772Z","shell.execute_reply":"2025-11-11T13:16:12.435630Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# spec_save(train_path, save_path, target_shape, num_files=num_files, sr=sr)\nspec_save_short(train_path, save_path, num_files, sr, segment_length, n_mels=128)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:16:12.437351Z","iopub.execute_input":"2025-11-11T13:16:12.437784Z","iopub.status.idle":"2025-11-11T13:18:07.197690Z","shell.execute_reply.started":"2025-11-11T13:16:12.437767Z","shell.execute_reply":"2025-11-11T13:18:07.196940Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Autoencoder","metadata":{}},{"cell_type":"code","source":"def conv_autoencoder(input_shape=(128, 256, 1), latent_dim=64):\n\n    # Encoder\n    encoder_input=layers.Input(shape=input_shape)\n    # x=layers.Conv2D(128, (3,3), activation='relu', padding='same')(encoder_input)\n    # x=layers.MaxPooling2D((2,2), padding='same')(x)\n    x=layers.Conv2D(64, (3,3), activation='relu', padding='same')(encoder_input)\n    x=layers.MaxPooling2D((2,2), padding='same')(x)\n    x=layers.Conv2D(32, (3,3), activation='relu', padding='same')(x)\n    x=layers.MaxPooling2D((2,2), padding='same')(x)\n    x=layers.Conv2D(16, (3,3), activation='relu', padding='same')(x)\n    x=layers.MaxPooling2D((2,2), padding='same')(x)\n    x_shape=x.shape[1:]\n    x_prod=np.prod(x_shape)\n\n    # Bottleneck\n    x=layers.Flatten()(x)\n    latent=layers.Dense(latent_dim, activation='relu')(x)\n    encoder=models.Model(encoder_input, latent)\n\n    # Decoder\n    decoder_input=layers.Input(shape=(latent_dim,))\n    x=layers.Dense(x_prod, activation='relu')(decoder_input)\n    x=layers.Reshape((x_shape))(x)\n\n    # x = layers.Conv2DTranspose(128, (3,3), strides=(2,2), activation='relu', padding='same')(x)\n    x = layers.Conv2DTranspose(16, (3,3), strides=(2,2), activation='relu', padding='same')(x)\n    x = layers.Conv2DTranspose(32, (3,3), strides=(2,2), activation='relu', padding='same')(x)\n    x = layers.Conv2DTranspose(64, (3,3), strides=(2,2), activation='relu', padding='same')(x)\n    \n    # x=layers.Conv2D(16, (3,3), activation='relu', padding='same')(x)\n    # x=layers.UpSampling2D((2, 2))(x)\n    # x=layers.Conv2D(32, (3,3), activation='relu', padding='same')(x)\n    # x=layers.UpSampling2D((2, 2))(x)\n    # x=layers.Conv2D(64, (3,3), activation='relu', padding='same')(x)\n    # x=layers.UpSampling2D((2, 2))(x)\n    # x=layers.Conv2D(128, (3,3), activation='relu', padding='same')(x)\n    # x=layers.UpSampling2D((2, 2))(x)\n    decoder_output=layers.Conv2D(1, (3, 3), activation='sigmoid', padding='same')(x)\n    decoder_output=Resizing(input_shape[0], input_shape[1])(decoder_output)\n    decoder=models.Model(decoder_input, decoder_output)\n\n    # Autoencoder\n    autoencoder_output=decoder(encoder(encoder_input))\n    autoencoder=models.Model(encoder_input, autoencoder_output)\n\n    return autoencoder, encoder, decoder","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:18:07.198614Z","iopub.execute_input":"2025-11-11T13:18:07.198998Z","iopub.status.idle":"2025-11-11T13:18:07.207127Z","shell.execute_reply.started":"2025-11-11T13:18:07.198969Z","shell.execute_reply":"2025-11-11T13:18:07.206386Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Training logic","metadata":{}},{"cell_type":"code","source":"# Optimizer\noptimizer=keras.optimizers.Adam(learning_rate=lr)\n\n# Callbacks\nreduce_lr = keras.callbacks.ReduceLROnPlateau(factor = 0.5, patience = patience / 2, verbose=1)\nearly_stop = keras.callbacks.EarlyStopping(patience = patience, verbose = 1, restore_best_weights = True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:18:07.207747Z","iopub.execute_input":"2025-11-11T13:18:07.208243Z","iopub.status.idle":"2025-11-11T13:18:08.188693Z","shell.execute_reply.started":"2025-11-11T13:18:07.208225Z","shell.execute_reply":"2025-11-11T13:18:08.187904Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Compile model","metadata":{}},{"cell_type":"code","source":"# Calculate input shape\nexample_path=os.path.join(save_path, os.listdir(save_path)[0])\nexample_image=Image.open(example_path).convert('L')\nexample_array=np.array(example_image)\ntarget_shape=example_array.shape\nprint(f\"Target shape: {target_shape}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:18:08.189522Z","iopub.execute_input":"2025-11-11T13:18:08.189874Z","iopub.status.idle":"2025-11-11T13:18:08.195804Z","shell.execute_reply.started":"2025-11-11T13:18:08.189849Z","shell.execute_reply":"2025-11-11T13:18:08.195104Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"autoencoder, encoder, decoder=conv_autoencoder(input_shape=(target_shape[0], target_shape[1], 1), latent_dim=latent_dim)\nautoencoder.compile(optimizer=optimizer, loss='mse')\nautoencoder.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:18:08.196566Z","iopub.execute_input":"2025-11-11T13:18:08.196792Z","iopub.status.idle":"2025-11-11T13:18:09.464778Z","shell.execute_reply.started":"2025-11-11T13:18:08.196769Z","shell.execute_reply":"2025-11-11T13:18:09.464235Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Data loading","metadata":{}},{"cell_type":"code","source":"def load_images(source_path, target_shape=(128, 256)):\n\n    images=[]\n    for f in os.listdir(source_path):\n        if f.endswith('.png'):\n            image_path=os.path.join(source_path, f)\n            image=Image.open(image_path).convert('L')\n            image=image.resize(target_shape)\n            image_array=np.array(image)/255.0\n            images.append(image_array)\n    return np.array(images)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:18:09.465455Z","iopub.execute_input":"2025-11-11T13:18:09.465634Z","iopub.status.idle":"2025-11-11T13:18:09.469841Z","shell.execute_reply.started":"2025-11-11T13:18:09.465616Z","shell.execute_reply":"2025-11-11T13:18:09.469169Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"images=load_images(save_path, target_shape=target_shape).reshape(-1, target_shape[0], target_shape[1], 1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:18:09.470610Z","iopub.execute_input":"2025-11-11T13:18:09.471207Z","iopub.status.idle":"2025-11-11T13:18:10.259432Z","shell.execute_reply.started":"2025-11-11T13:18:09.471183Z","shell.execute_reply":"2025-11-11T13:18:10.258817Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(images.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:18:10.260181Z","iopub.execute_input":"2025-11-11T13:18:10.260428Z","iopub.status.idle":"2025-11-11T13:18:10.264362Z","shell.execute_reply.started":"2025-11-11T13:18:10.260402Z","shell.execute_reply":"2025-11-11T13:18:10.263835Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Training","metadata":{}},{"cell_type":"code","source":"history=autoencoder.fit(\n    images,\n    images,\n    epochs=epochs,\n    batch_size=batch_size,\n    validation_split=0.2,\n    callbacks=[early_stop, reduce_lr],\n    verbose=1\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:18:10.265230Z","iopub.execute_input":"2025-11-11T13:18:10.265671Z","iopub.status.idle":"2025-11-11T13:19:20.693597Z","shell.execute_reply.started":"2025-11-11T13:18:10.265647Z","shell.execute_reply":"2025-11-11T13:19:20.693028Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Feature extraction","metadata":{}},{"cell_type":"code","source":"def feature_extraction(spectrograms, encoder, n_clusters=24):\n    \n    X_features=spectrograms.reshape(-1, target_shape[0], target_shape[1], 1)\n    latent_features=encoder.predict(X_features, verbose=0)\n    print(f\"Shape of latent_features: {latent_features.shape}\")\n    normalized_latent_features=StandardScaler().fit_transform(latent_features)\n    kmeans=KMeans(\n        n_clusters=n_clusters,\n        n_init=10,\n        random_state=random_seed,\n        verbose=1\n    )\n    cluster_labels=kmeans.fit_predict(normalized_latent_features)\n    return cluster_labels, latent_features, kmeans","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:19:20.697681Z","iopub.execute_input":"2025-11-11T13:19:20.697952Z","iopub.status.idle":"2025-11-11T13:19:20.702597Z","shell.execute_reply.started":"2025-11-11T13:19:20.697934Z","shell.execute_reply":"2025-11-11T13:19:20.701805Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"cluster_labels, latent_features, kmeans=feature_extraction(images, encoder, num_clusters)\nprint(f\"Found {len(np.unique(cluster_labels))} clusters.\")\n\ncluster_counts=np.bincount(cluster_labels)\nprint(\"Number of files in each cluster:\")\nfor i, count in enumerate(cluster_counts):\n    print(f\"Cluster {i}:\\t{count}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:19:20.703385Z","iopub.execute_input":"2025-11-11T13:19:20.703795Z","iopub.status.idle":"2025-11-11T13:19:21.967239Z","shell.execute_reply.started":"2025-11-11T13:19:20.703778Z","shell.execute_reply":"2025-11-11T13:19:21.966672Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Visualization","metadata":{}},{"cell_type":"code","source":"def visualization(images, cluster_labels, latent_features):\n\n    # t-SNE visualization\n    tsne=TSNE(n_components=2, perplexity=30, random_state=random_seed, verbose=1)\n    features_tsne=tsne.fit_transform(latent_features)\n    plt.figure(figsize=(15, 5))\n    plt.subplot(1, 1, 1)\n    colors=plt.cm.tab20.colors+plt.cm.tab10.colors[:4]\n    cmap=plt.matplotlib.colors.ListedColormap(colors)\n    scatter=plt.scatter(features_tsne[:, 0], features_tsne[:, 1], c=cluster_labels, cmap=cmap, alpha=0.6)\n    plt.colorbar(scatter, ticks=range(num_clusters))\n    plt.title('t-SNE visualization of the clusters')\n    plt.xlabel('t-SNE 1')\n    plt.ylabel('t-SNE 2')\n    plt.show()\n\n    # Example spectrogram from each cluster\n    unique_clusters=np.unique(cluster_labels)\n    for i, c in enumerate(unique_clusters):\n        plt.subplot(4, 6, i+1)\n        cluster_indices=np.where(cluster_labels==c)[0]\n        if len(cluster_indices)>0:\n            plt.imshow(images[cluster_indices[0]], aspect='auto', origin='lower')\n            plt.title(f'Cluster {c}')\n            plt.axis('off')\n    plt.tight_layout()\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:19:21.967737Z","iopub.execute_input":"2025-11-11T13:19:21.967915Z","iopub.status.idle":"2025-11-11T13:19:21.977254Z","shell.execute_reply.started":"2025-11-11T13:19:21.967899Z","shell.execute_reply":"2025-11-11T13:19:21.976748Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"visualization(images, cluster_labels, latent_features)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:19:21.977637Z","iopub.execute_input":"2025-11-11T13:19:21.978722Z","iopub.status.idle":"2025-11-11T13:19:26.806318Z","shell.execute_reply.started":"2025-11-11T13:19:21.978694Z","shell.execute_reply":"2025-11-11T13:19:26.805603Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def visualize_latent_features(decoder, latent_dim, n_cols=8):\n\n    n_rows=int(np.ceil(latent_dim/n_cols))\n    plt.figure(figsize=(n_cols*2, n_rows*2))\n    for i in range(latent_dim):\n        latent_vector=np.zeros((1, latent_dim))\n        latent_vector[0, i]=1.0\n        latent_img=decoder.predict(latent_vector)\n        latent_img=latent_img.squeeze()\n        plt.subplot(n_rows, n_cols, i+1)\n        plt.imshow(latent_img, cmap='gray')\n        plt.title(f\"Feature {i+1}\")\n        plt.axis('off')\n    plt.tight_layout()\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:19:26.807325Z","iopub.execute_input":"2025-11-11T13:19:26.807577Z","iopub.status.idle":"2025-11-11T13:19:26.814096Z","shell.execute_reply.started":"2025-11-11T13:19:26.807558Z","shell.execute_reply":"2025-11-11T13:19:26.813196Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"visualize_latent_features(decoder, latent_dim, 8)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T13:19:26.814906Z","iopub.execute_input":"2025-11-11T13:19:26.815480Z","iopub.status.idle":"2025-11-11T13:19:59.590521Z","shell.execute_reply.started":"2025-11-11T13:19:26.815453Z","shell.execute_reply":"2025-11-11T13:19:59.589489Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Reconstruction","metadata":{}},{"cell_type":"markdown","source":"### Short version","metadata":{}},{"cell_type":"code","source":"def segment_audio(file_path, segment_duration=3.0, overlap=0.5):\n    \n    # audio, sr = librosa.load(file_path)\n    # segment_length = int(segment_duration * sr)\n    # hop_length = int(segment_length * (1 - overlap))\n    \n    # segments = []\n    # starts = []\n    # for start in range(0, len(audio) - segment_length + 1, hop_length):\n    #     end = start + segment_length\n    #     segment = audio[start:end]\n    #     segments.append(segment)\n    #     starts.append(start)\n    \n    # return np.array(segments), starts, sr   \n\n\n    audio, sr = librosa.load(file_path, sr=sr)\n    segment_length = int(segment_duration * sr)\n    segments = []\n    \n    for start in range(0, len(audio), segment_length):\n        end = start + segment_length\n        segment = audio[start:end]\n        if len(segment) < segment_length:\n            segment = np.pad(segment, (0, segment_length - len(segment)))\n        segments.append(segment)\n    \n    return segments, sr","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T14:12:18.171243Z","iopub.execute_input":"2025-11-11T14:12:18.171799Z","iopub.status.idle":"2025-11-11T14:12:18.177088Z","shell.execute_reply.started":"2025-11-11T14:12:18.171775Z","shell.execute_reply":"2025-11-11T14:12:18.176195Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def segments_to_specs(segments, sr=22050):\n    \n    specs = []\n    for seg in segments:\n        S = librosa.feature.melspectrogram(y=seg, sr=sr, n_mels=128)\n        S_db = librosa.power_to_db(S, ref=np.max)\n        S_norm = (S_db - S_db.min()) / (S_db.max() - S_db.min())\n        specs.append(S_norm)\n    return np.array(specs)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T14:12:18.178430Z","iopub.execute_input":"2025-11-11T14:12:18.178712Z","iopub.status.idle":"2025-11-11T14:12:18.193344Z","shell.execute_reply.started":"2025-11-11T14:12:18.178694Z","shell.execute_reply":"2025-11-11T14:12:18.192570Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def reconstruct_segments(specs, autoencoder):\n    \n    reconstructed = []\n    for S in specs:\n        h, w = S.shape\n        input_image = S.reshape(1, h, w, 1)\n        rec = autoencoder.predict(input_image, verbose=0)[0, :, :, 0]\n        reconstructed.append(rec)\n    rec_h, rec_w=reconstructed[0].shape\n    return np.array(reconstructed), rec_h, rec_w","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T14:12:18.194080Z","iopub.execute_input":"2025-11-11T14:12:18.194313Z","iopub.status.idle":"2025-11-11T14:12:18.206570Z","shell.execute_reply.started":"2025-11-11T14:12:18.194288Z","shell.execute_reply":"2025-11-11T14:12:18.205882Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# def combine_specs_with_overlap(rec_specs, overlap=0.5)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T14:12:18.208139Z","iopub.execute_input":"2025-11-11T14:12:18.208345Z","iopub.status.idle":"2025-11-11T14:12:18.217154Z","shell.execute_reply.started":"2025-11-11T14:12:18.208328Z","shell.execute_reply":"2025-11-11T14:12:18.216546Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def combine_specs(specs):\n    return np.concatenate(specs, axis=1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T14:12:18.217734Z","iopub.execute_input":"2025-11-11T14:12:18.217917Z","iopub.status.idle":"2025-11-11T14:12:18.229219Z","shell.execute_reply.started":"2025-11-11T14:12:18.217902Z","shell.execute_reply":"2025-11-11T14:12:18.228551Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def reconstruct_full_spectrogram(file_path, autoencoder, segment_length=3.0, overlap=0.5):\n    \n    segments, starts, sr= segment_audio(file_path, segment_length, overlap)\n    specs = segments_to_specs(segments, sr)\n    rec_specs, rec_h, rec_w = reconstruct_segments(specs, autoencoder)\n    # full_rec_spec=combine_specs_with_overlap(rec_specs, overlap)\n    full_rec_spec=combine_specs(rec_specs)\n\n    # original=spec_gen(file_path, (rec_h, rec_w), sr)\n    y, sr = librosa.load(file_path, sr=sr)\n    S = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=128)\n    S_db = librosa.power_to_db(S, ref=np.max)\n    original = (S_db - S_db.min()) / (S_db.max() - S_db.min())\n    \n    plt.figure(figsize=(12, 5))\n    plt.subplot(1, 2, 1)\n    plt.imshow(original, aspect='auto', origin='lower', cmap='viridis')\n    plt.title(\"Original\")\n    plt.subplot(1, 2, 2)\n    plt.imshow(full_rec_spec, aspect='auto', origin='lower', cmap='viridis')\n    plt.title(\"Reconstructed\")\n    plt.tight_layout()\n    plt.show()\n\n    print(original.shape)\n    print(full_rec_spec.shape)\n    \n    return full_rec_spec\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T14:14:51.152466Z","iopub.execute_input":"2025-11-11T14:14:51.152729Z","iopub.status.idle":"2025-11-11T14:14:51.158997Z","shell.execute_reply.started":"2025-11-11T14:14:51.152710Z","shell.execute_reply":"2025-11-11T14:14:51.158227Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Original version","metadata":{}},{"cell_type":"code","source":"def spec_reconstruct(file_path, autoencoder, target_shape=(128, 256)):\n\n    S_norm=spec_gen(file_path, target_shape)\n    input_image=S_norm.reshape(1, target_shape[0], target_shape[1], 1)\n    reconstructed_image=autoencoder.predict(input_image, verbose=1)[0, :, :, 0]\n\n    plt.figure(figsize=(12, 5))\n    plt.subplot(1, 2, 1)\n    plt.imshow(S_norm, aspect='auto', origin='lower', cmap='viridis')\n    plt.title('Original')\n    plt.subplot(1, 2, 2)\n    plt.imshow(reconstructed_image, aspect='auto', origin='lower', cmap='viridis')\n    plt.title('Reconstructed')\n    plt.tight_layout()\n    plt.show()\n    print(target_shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T14:12:18.239257Z","iopub.execute_input":"2025-11-11T14:12:18.239444Z","iopub.status.idle":"2025-11-11T14:12:18.249832Z","shell.execute_reply.started":"2025-11-11T14:12:18.239429Z","shell.execute_reply":"2025-11-11T14:12:18.249186Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"example_file=random_files(train_path)[0]\n# spec_reconstruct(example_file, autoencoder, target_shape)\nrec_spec = reconstruct_full_spectrogram(example_file, autoencoder, segment_length, overlap)\nAudio(example_file, rate=sr)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-11T14:14:25.475512Z","iopub.execute_input":"2025-11-11T14:14:25.475783Z","iopub.status.idle":"2025-11-11T14:14:25.503764Z","shell.execute_reply.started":"2025-11-11T14:14:25.475766Z","shell.execute_reply":"2025-11-11T14:14:25.502903Z"}},"outputs":[],"execution_count":null}]}