{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.10.14"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":21669,"databundleVersionId":1692278,"sourceType":"competition"},{"sourceId":10157270,"sourceType":"datasetVersion","datasetId":6271467}],"dockerImageVersionId":30804,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false},"papermill":{"default_parameters":{},"duration":3365.405595,"end_time":"2024-12-10T12:43:49.686360","environment_variables":{},"exception":null,"input_path":"__notebook__.ipynb","output_path":"__notebook__.ipynb","parameters":{},"start_time":"2024-12-10T11:47:44.280765","version":"2.6.0"}},"nbformat_minor":4,"nbformat":4,"cells":[{"id":"045509d2","cell_type":"code","source":"import os\nfrom tqdm import tqdm\n\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import StratifiedKFold\nimport librosa\n\nfrom keras.utils import to_categorical\nimport keras\nfrom keras import Sequential\nfrom keras.layers import Input, Convolution2D, MaxPooling2D, Dense, Dropout, Flatten\nfrom keras.optimizers import Adam","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","papermill":{"duration":13.605632,"end_time":"2024-12-10T11:48:00.383369","exception":false,"start_time":"2024-12-10T11:47:46.777737","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"3638eb25","cell_type":"code","source":"data = pd.read_csv(\"../input/rfcx-species-audio-detection/train_tp.csv\")\ndata","metadata":{"papermill":{"duration":0.039801,"end_time":"2024-12-10T11:48:00.427523","exception":false,"start_time":"2024-12-10T11:48:00.387722","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"fcaa1629","cell_type":"code","source":"NUM_CLASSES = len(data.species_id.unique())\nNUM_CLASSES","metadata":{"papermill":{"duration":0.01363,"end_time":"2024-12-10T11:48:00.446694","exception":false,"start_time":"2024-12-10T11:48:00.433064","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"7fd01d1e","cell_type":"code","source":"df = data.t_max - data.t_min\ndf, df.max(), df.mean()","metadata":{"papermill":{"duration":0.014491,"end_time":"2024-12-10T11:48:00.465200","exception":false,"start_time":"2024-12-10T11:48:00.450709","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"8e1a1dc7","cell_type":"code","source":"f_min = 0\nf_max = data.f_max.max() * 1.1\nf_min, f_max","metadata":{"papermill":{"duration":0.011682,"end_time":"2024-12-10T11:48:00.480852","exception":false,"start_time":"2024-12-10T11:48:00.469170","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"5a1499d1","cell_type":"code","source":"sr = 22050\nn_mels = 90\nn_fft = 8192\nhop_length = 512\nexpected_time_steps = 700\n\nmin_max = [[0, 0], [1, 1], [0, 2], [2, 2], [0, 100], [1, 100], [2, 100]]\nmin_max2 = [[100, 0], [100, 1], [100, 2]]\n\n\ndef audio_to_mel_spectrogram(\n    file_path,\n    start_time=0,\n    end_time=None,\n    sr=sr,\n    n_mels=n_mels,\n    n_fft=n_fft,\n    hop_length=hop_length,\n):\n    data_audio, _ = librosa.load(\n        file_path,\n        sr=sr,\n        offset=int(start_time),\n        duration=int(end_time - start_time + 1) if end_time else None,\n    )\n    mel_spectrogram = librosa.feature.melspectrogram(\n        y=data_audio,\n        sr=sr,\n        n_mels=n_mels,\n        n_fft=n_fft,\n        hop_length=hop_length,\n        fmin=f_min,\n        fmax=f_max,\n    )\n    log_mel_spec = librosa.power_to_db(mel_spectrogram)\n    return log_mel_spec\n\n\ndef make_same_size(log_mel_spec, is_right=True):\n    current_steps = log_mel_spec.shape[1]\n    if current_steps < expected_time_steps:\n        pad_width = expected_time_steps - current_steps\n        log_mel_spec = np.pad(log_mel_spec, pad_width=((0, 0), (0, pad_width)), mode='constant')\n    elif current_steps > expected_time_steps:\n        log_mel_spec = log_mel_spec[:, :expected_time_steps] if is_right else log_mel_spec[:, -expected_time_steps:]\n    return log_mel_spec\n\n\ndef prepare_data(df, data_dir):\n    X = []\n    y = []\n    for i, row in tqdm(df.iterrows()):\n        file_path = os.path.join(data_dir, row[\"recording_id\"]) + \".flac\"\n        for mi, ma in min_max:\n            mel_spectrogram = audio_to_mel_spectrogram(\n                file_path, max(row[\"t_min\"] - mi, 0), row[\"t_max\"] + ma\n            )\n            mel_spectrogram = make_same_size(mel_spectrogram)\n            X.append(mel_spectrogram)\n            y.append(row[\"species_id\"])\n        for mi, ma in min_max2:\n            mel_spectrogram = audio_to_mel_spectrogram(\n                file_path, max(row[\"t_min\"] - mi, 0), row[\"t_max\"] + ma\n            )\n            mel_spectrogram = make_same_size(mel_spectrogram, is_right=False)\n            X.append(mel_spectrogram)\n            y.append(row[\"species_id\"])\n\n    return np.array(X), np.array(y)","metadata":{"papermill":{"duration":0.016929,"end_time":"2024-12-10T11:48:00.501934","exception":false,"start_time":"2024-12-10T11:48:00.485005","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"dff67b10","cell_type":"code","source":"# x_data, y_data = prepare_data(data, \"/kaggle/input/rfcx-species-audio-detection/train\")","metadata":{"papermill":{"duration":0.009432,"end_time":"2024-12-10T11:48:00.515524","exception":false,"start_time":"2024-12-10T11:48:00.506092","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"aff5d383","cell_type":"code","source":"# np.save(\"x_data.npy\", x_data)\n# np.save(\"y_data.npy\", y_data)","metadata":{"papermill":{"duration":0.009261,"end_time":"2024-12-10T11:48:00.528751","exception":false,"start_time":"2024-12-10T11:48:00.519490","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"b4541096","cell_type":"code","source":"x_data = np.load(\"/kaggle/input/rainforest-prepared-data-22050-90-8192-700/x_data.npy\")\ny_data = np.load(\"/kaggle/input/rainforest-prepared-data-22050-90-8192-700/y_data.npy\")\nx_data.shape, y_data.shape","metadata":{"papermill":{"duration":16.018898,"end_time":"2024-12-10T11:48:16.551675","exception":false,"start_time":"2024-12-10T11:48:00.532777","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"88db8988","cell_type":"code","source":"x_data[0]","metadata":{"papermill":{"duration":0.013026,"end_time":"2024-12-10T11:48:16.569142","exception":false,"start_time":"2024-12-10T11:48:16.556116","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"6c6ece89","cell_type":"code","source":"def normalize(spec):\n    return (spec - np.mean(spec)) / np.std(spec)\n\nnew_x_data = []\nfor x in x_data:\n    new_x_data.append(normalize(x))\nnew_x_data = np.array(new_x_data)","metadata":{"papermill":{"duration":5.361278,"end_time":"2024-12-10T11:48:21.935094","exception":false,"start_time":"2024-12-10T11:48:16.573816","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"60915782","cell_type":"code","source":"x_data.shape, new_x_data.shape","metadata":{"papermill":{"duration":0.012368,"end_time":"2024-12-10T11:48:21.952673","exception":false,"start_time":"2024-12-10T11:48:21.940305","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"24811f1d","cell_type":"code","source":"x_data = new_x_data\nx_data[0]","metadata":{"papermill":{"duration":0.012695,"end_time":"2024-12-10T11:48:21.969623","exception":false,"start_time":"2024-12-10T11:48:21.956928","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"3468e64a","cell_type":"code","source":"for i, mm in zip(x_data[10:20], min_max + min_max2):\n    print(mm)\n    plt.figure(figsize=(16, 5))\n    librosa.display.specshow(i, x_axis=\"time\", y_axis=\"mel\", sr=sr)\n    plt.colorbar(format=\"%+2.0f dB\")\n    plt.xlabel(\"Время\")\n    plt.ylabel(\"Частота (Гц)\")\n    plt.show()","metadata":{"papermill":{"duration":3.913375,"end_time":"2024-12-10T11:48:25.887412","exception":false,"start_time":"2024-12-10T11:48:21.974037","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"d2365179","cell_type":"code","source":"kernel_size = 3\npool_size = 2\nconv_depth_1 = 32\nconv_depth_2 = 64\nconv_depth_3 = 128\ndrop_prob_1 = 0.25\ndrop_prob_2 = 0.5\nhidden_size = 512\n\n\ndef create_model():\n    model = Sequential(\n        [\n            Input(shape=(n_mels, expected_time_steps, 1)),\n            Convolution2D(conv_depth_1, kernel_size, padding=\"same\", activation=\"relu\"),\n            MaxPooling2D(pool_size=pool_size),\n            Dropout(drop_prob_1),\n            Convolution2D(conv_depth_2, kernel_size, padding=\"same\", activation=\"relu\"),\n            MaxPooling2D(pool_size=pool_size),\n            Dropout(drop_prob_1),\n            Convolution2D(conv_depth_3, kernel_size, padding=\"same\", activation=\"relu\"),\n            MaxPooling2D(pool_size=pool_size),\n            Dropout(drop_prob_1),\n            Flatten(),\n            Dense(hidden_size, activation=\"relu\"),\n            Dropout(drop_prob_2),\n            Dense(NUM_CLASSES, activation=\"softmax\"),\n        ]\n    )\n\n    model.compile(\n        loss=\"categorical_crossentropy\",\n        optimizer=Adam(),\n        metrics=[\"accuracy\"],\n    )\n    return model","metadata":{"papermill":{"duration":0.031955,"end_time":"2024-12-10T11:48:25.945187","exception":false,"start_time":"2024-12-10T11:48:25.913232","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"5b9018e7","cell_type":"code","source":"num_folds = 5\npart_len = len(x_data) // num_folds\nbatch_size = 32\nnum_epochs = 50\n\nkfold = StratifiedKFold(n_splits=num_folds, shuffle=True)\n\nx_data_ax = x_data[..., np.newaxis]\ny_data_cat = to_categorical(y_data, NUM_CLASSES)\n\nfor num, (train, test) in enumerate(kfold.split(x_data_ax, y_data)):\n    print(f\"Train #{num}\")\n    X_val, y_val = x_data_ax[test], y_data_cat[test]\n    X_train, y_train = x_data_ax[train], y_data_cat[train]\n    print(X_train.shape, y_train.shape)\n    print(X_val.shape, y_val.shape)\n\n    model = create_model()\n\n    checkpoint_filepath = f\"{num}_checkpoint.weights.h5\"\n    model_checkpoint_callback = keras.callbacks.ModelCheckpoint(\n        filepath=checkpoint_filepath,\n        save_weights_only=True,\n        monitor=\"val_accuracy\",\n        mode=\"max\",\n        save_best_only=True,\n        verbose=1,\n    )\n    early_stoping = keras.callbacks.EarlyStopping(\n        monitor=\"val_loss\", patience=5, verbose=1\n    )\n    history = model.fit(\n        X_train,\n        y_train,\n        batch_size=batch_size,\n        epochs=num_epochs,\n        validation_data=(X_val, y_val),\n        callbacks=[model_checkpoint_callback, early_stoping],\n    )\n    print()","metadata":{"papermill":{"duration":1516.980007,"end_time":"2024-12-10T12:13:42.942677","exception":false,"start_time":"2024-12-10T11:48:25.962670","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"e58b8c27","cell_type":"code","source":"models = []\nfor i in range(num_folds):\n    model = create_model()\n    checkpoint_filepath = f\"{i}_checkpoint.weights.h5\"\n    model.load_weights(checkpoint_filepath, skip_mismatch=False)\n    models.append(model)","metadata":{"papermill":{"duration":9.032275,"end_time":"2024-12-10T12:13:52.775797","exception":false,"start_time":"2024-12-10T12:13:43.743522","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"3d921aa2","cell_type":"code","source":"# Test data\nTEST_DIR = \"/kaggle/input/rfcx-species-audio-detection/test/\"\ntest_files = os.listdir(TEST_DIR)\n\nrows = []\none_model_rows = [[] for _ in models]\nfor f in tqdm(test_files):\n    id = f.replace(\".flac\", \"\")\n    mel = audio_to_mel_spectrogram(TEST_DIR + f)\n    preds = []\n    mels = []\n    for i in range(0, mel.shape[1], expected_time_steps):\n        mel_part = mel[:, i : i + expected_time_steps]\n        if mel_part.shape[1] < expected_time_steps:\n            mel_part = make_same_size(mel_part)\n        mel_part = normalize(mel_part)\n        mels.append(mel_part)\n    mels = np.array(mels)\n    models_predictions = []\n    for model in models:\n        preds = model.predict(mels, verbose=0)\n        pred = np.max(preds, axis=0)\n        models_predictions.append(pred)\n    pred = np.mean(np.array(models_predictions), axis=0)\n    row = [id]\n    row.extend(pred)\n    rows.append(row)\n\n    for n, pred in enumerate(models_predictions):\n        row = [id]\n        row.extend(pred)\n        one_model_rows[n].append(row)","metadata":{"papermill":{"duration":1781.11948,"end_time":"2024-12-10T12:43:34.704713","exception":false,"start_time":"2024-12-10T12:13:53.585233","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"a510fa85","cell_type":"code","source":"columns = [\"recording_id\"]\nsample = pd.read_csv(\"/kaggle/input/rfcx-species-audio-detection/sample_submission.csv\")\n\ndf = pd.DataFrame(rows, columns=sample.columns)\ndf","metadata":{"papermill":{"duration":0.955819,"end_time":"2024-12-10T12:43:36.563685","exception":false,"start_time":"2024-12-10T12:43:35.607866","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"15655bb1","cell_type":"code","source":"df.to_csv(\"submission.csv\", index=False)","metadata":{"papermill":{"duration":0.889012,"end_time":"2024-12-10T12:43:38.353757","exception":false,"start_time":"2024-12-10T12:43:37.464745","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"f07fe8c9","cell_type":"code","source":"ids = df.recording_id\nfor n, omrows in enumerate(one_model_rows):\n    df = pd.DataFrame(omrows, columns=sample.columns)\n    df.to_csv(f\"submission_{n}.csv\", index=False)\n    for j, omrows2 in enumerate(one_model_rows[n + 1 :]):\n        arr = np.array([[i[1:] for i in omrows], [i[1:] for i in omrows2]])\n        rows_mean = np.mean(arr, axis=0)\n        df = pd.DataFrame(rows_mean, columns=sample.columns[1:])\n        df.insert(0, sample.columns[0], ids)\n        df.to_csv(f\"submission_{n}_{n+j+1}.csv\", index=False)\n        for k, omrows3 in enumerate(one_model_rows[n + j + 2 :]):\n            arr = np.array(\n                [\n                    [i[1:] for i in omrows],\n                    [i[1:] for i in omrows2],\n                    [i[1:] for i in omrows3],\n                ]\n            )\n            rows_mean = np.mean(arr, axis=0)\n            df = pd.DataFrame(rows_mean, columns=sample.columns[1:])\n            df.insert(0, sample.columns[0], ids)\n            df.to_csv(f\"submission_{n}_{n+j+1}_{n+j+k+2}.csv\", index=False)","metadata":{"papermill":{"duration":3.738028,"end_time":"2024-12-10T12:43:42.975795","exception":false,"start_time":"2024-12-10T12:43:39.237767","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"679c60b5","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.882849,"end_time":"2024-12-10T12:43:44.706771","exception":false,"start_time":"2024-12-10T12:43:43.823922","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null}]}