{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","execution":{"iopub.status.busy":"2023-11-03T05:50:15.195419Z","iopub.execute_input":"2023-11-03T05:50:15.195759Z","iopub.status.idle":"2023-11-03T05:50:15.532698Z","shell.execute_reply.started":"2023-11-03T05:50:15.195729Z","shell.execute_reply":"2023-11-03T05:50:15.531383Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Загрузка данных","metadata":{}},{"cell_type":"code","source":"train = pd.read_csv(\"../input/freesound-audio-tagging/train.csv\")\ntest = pd.read_csv(\"../input/freesound-audio-tagging/sample_submission.csv\")\n\ntrain_path = '../input/freesound-audio-tagging/audio_train/'\ntest_path = '../input/freesound-audio-tagging/audio_test/'\n\ntest.head()","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:50:15.534674Z","iopub.execute_input":"2023-11-03T05:50:15.535232Z","iopub.status.idle":"2023-11-03T05:50:15.660713Z","shell.execute_reply.started":"2023-11-03T05:50:15.535197Z","shell.execute_reply":"2023-11-03T05:50:15.659745Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Генерация набора данных для обучения модели\n1. Обработка файла\\\nПолучение частотной характеристики","metadata":{}},{"cell_type":"code","source":"class Config(object):\n    def __init__(self,\n                 sampling_rate = 44100, audio_duration = 2,\n                 n_folds = 5, learning_rate = 0.0001,\n                 max_epochs = 50, n_mfcc = 20):\n        self.sampling_rate = sampling_rate\n        self.audio_duration = audio_duration\n        self.n_classes = None\n        self.n_mfcc = n_mfcc\n        self.n_folds = n_folds\n        self.learning_rate = learning_rate\n        self.max_epochs = max_epochs\n\n        self.audio_length = self.sampling_rate * self.audio_duration\n        self.sample_feature_dim = (self.n_mfcc, 1 + int(np.floor(self.audio_length/512)), 1)\n    \n    def set_n_classes(self, n_classes):\n        self.n_classes = n_classes\n\nconfig = Config()","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:50:15.661896Z","iopub.execute_input":"2023-11-03T05:50:15.662192Z","iopub.status.idle":"2023-11-03T05:50:15.670634Z","shell.execute_reply.started":"2023-11-03T05:50:15.662170Z","shell.execute_reply":"2023-11-03T05:50:15.668786Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import librosa\n\ndef process_audio(file_name, path):\n    audio, _ = librosa.core.load(path+file_name, sr=config.sampling_rate)\n    # Обрезка тишины:\n    clip, _ = librosa.effects.trim(audio)\n    if len(clip) > config.audio_length:\n        clip = clip[0:config.audio_length]\n    else:\n        padding = config.audio_length - len(clip)    # add padding at both ends\n        offset = padding // 2\n        clip = np.pad(clip, (offset, config.audio_length - len(clip) - offset), 'constant')\n    return librosa.feature.mfcc(y=clip, sr=config.sampling_rate, n_mfcc=config.n_mfcc)","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:50:15.674391Z","iopub.execute_input":"2023-11-03T05:50:15.674725Z","iopub.status.idle":"2023-11-03T05:50:15.693382Z","shell.execute_reply.started":"2023-11-03T05:50:15.674699Z","shell.execute_reply":"2023-11-03T05:50:15.691950Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"2. Обработка списка файлов","metadata":{}},{"cell_type":"code","source":"def audio_norm(data):\n    max_data = np.max(data)\n    min_data = np.min(data)\n    data = (data-min_data)/(max_data-min_data+1e-6)\n    return data-0.5\n\ndef process_audio_list(fname_list: np.ndarray, base_path: str) -> np.ndarray:\n    X = np.empty((len(fname_list), *config.sample_feature_dim))\n    for i in range(fname_list.shape[0]):\n        X[i] = np.expand_dims(\n            process_audio(fname_list[i], base_path), axis=-1\n        )\n    return X","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:50:15.694505Z","iopub.execute_input":"2023-11-03T05:50:15.694801Z","iopub.status.idle":"2023-11-03T05:50:15.702102Z","shell.execute_reply.started":"2023-11-03T05:50:15.694776Z","shell.execute_reply":"2023-11-03T05:50:15.700784Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train = process_audio_list(train['fname'].to_numpy(), train_path)\nX_test = process_audio_list(test['fname'].to_numpy(), test_path)","metadata":{"execution":{"iopub.status.busy":"2023-11-03T05:50:15.703855Z","iopub.execute_input":"2023-11-03T05:50:15.704752Z","iopub.status.idle":"2023-11-03T06:06:49.046239Z","shell.execute_reply.started":"2023-11-03T05:50:15.704718Z","shell.execute_reply":"2023-11-03T06:06:49.042689Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Normalize:\nmean = np.mean(X_train, axis=0)\nstd = np.std(X_train, axis=0)\n\nX_train = (X_train - mean)/std\nX_test = (X_test - mean)/std","metadata":{"execution":{"iopub.status.busy":"2023-11-03T06:06:49.054477Z","iopub.execute_input":"2023-11-03T06:06:49.056138Z","iopub.status.idle":"2023-11-03T06:06:49.423543Z","shell.execute_reply.started":"2023-11-03T06:06:49.056095Z","shell.execute_reply":"2023-11-03T06:06:49.422530Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.preprocessing import LabelEncoder\n\nencoder = LabelEncoder()\nY_train_encoded = encoder.fit_transform(train['label'].to_numpy())\nconfig.set_n_classes(len(encoder.classes_))\n\n# Make data categorical\nfrom keras.utils import to_categorical\n\nY_train = to_categorical(Y_train_encoded, num_classes=config.n_classes)","metadata":{"execution":{"iopub.status.busy":"2023-11-03T06:06:49.424815Z","iopub.execute_input":"2023-11-03T06:06:49.425093Z","iopub.status.idle":"2023-11-03T06:07:00.588636Z","shell.execute_reply.started":"2023-11-03T06:06:49.425070Z","shell.execute_reply":"2023-11-03T06:07:00.586958Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Создание модели","metadata":{}},{"cell_type":"code","source":"from keras import models, optimizers, losses\nfrom keras.layers import (Convolution2D, BatchNormalization, Flatten, MaxPool2D, Activation, Input, Dense)\nfrom keras.activations import softmax\n\ndef get_model():\n    inp = Input(shape=(config.sample_feature_dim[0], config.sample_feature_dim[1],1))\n    x = Convolution2D(64, (4,10), padding=\"same\")(inp)\n    x = BatchNormalization()(x)\n    x = Activation(\"relu\")(x)\n    x = MaxPool2D()(x)\n    \n    x = Convolution2D(64, (4,10), padding=\"same\")(x)\n    x = BatchNormalization()(x)\n    x = Activation(\"relu\")(x)\n    x = MaxPool2D()(x)\n    \n    x = Convolution2D(32, (3,9), padding=\"same\")(x)\n    x = BatchNormalization()(x)\n    x = Activation(\"relu\")(x)\n    x = MaxPool2D()(x)\n    \n    x = Convolution2D(32, (3,9), padding=\"same\")(x)\n    x = BatchNormalization()(x)\n    x = Activation(\"relu\")(x)\n    x = MaxPool2D()(x)\n    \n    x = Flatten()(x)\n    x = Dense(64)(x)\n    x = BatchNormalization()(x)\n    x = Activation(\"relu\")(x)\n    \n    out = Dense(config.n_classes, activation=softmax)(x)\n    \n    model = models.Model(inputs=inp, outputs=out)\n    opt = optimizers.Adam(0.001)\n    model.compile(optimizer=opt, loss=losses.categorical_crossentropy, metrics=['acc'])\n    return model","metadata":{"execution":{"iopub.status.busy":"2023-11-03T06:07:00.590671Z","iopub.execute_input":"2023-11-03T06:07:00.591600Z","iopub.status.idle":"2023-11-03T06:07:00.921607Z","shell.execute_reply.started":"2023-11-03T06:07:00.591569Z","shell.execute_reply":"2023-11-03T06:07:00.920207Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Обучение модели","metadata":{}},{"cell_type":"code","source":"from keras.callbacks import EarlyStopping, ModelCheckpoint\nfrom sklearn.model_selection import StratifiedKFold\nfrom keras import backend as K\nimport os\n\nk_folds = StratifiedKFold(config.n_folds)\n\nPREDICTION_FOLDER = \"predictions\"\nif not os.path.exists(PREDICTION_FOLDER):\n    os.mkdir(PREDICTION_FOLDER)\n\nfor i, (train_idx, val_idx) in enumerate(k_folds.split(X_train, Y_train_encoded)):\n    K.clear_session()\n    x_train = X_train[train_idx]\n    y_train = Y_train[train_idx]\n    x_val = X_train[val_idx]\n    y_val = Y_train[val_idx]\n\n    checkpoint = ModelCheckpoint('best_%d.h5'%i, monitor='val_loss', verbose=1, save_best_only=True)\n    early = EarlyStopping(monitor=\"val_loss\", mode=\"min\", patience=5)\n    \n    print(\"#\"*50)\n    print(\"Fold: \", i)\n    \n    model = get_model()\n    history = model.fit(x_train, y_train,\n                        validation_data=(x_val, y_val),\n                        batch_size=50,\n                        epochs=config.max_epochs,\n                        callbacks=[early, checkpoint]\n                        )\n\n    predictions = model.predict(X_test, batch_size=64, verbose=1)\n    np.save(PREDICTION_FOLDER + \"/test_predictions_%d.npy\"%i, predictions)\n\n    # Make a submission file\n    top_3 = np.array(encoder.classes_)[np.argsort(-predictions, axis=1)[:, :3]]\n    predicted_labels = [' '.join(list(x)) for x in top_3]\n    test['label'] = predicted_labels\n    test[['label']].to_csv(PREDICTION_FOLDER + \"/predictions_%d.csv\"%i)","metadata":{"execution":{"iopub.status.busy":"2023-11-03T06:07:00.924952Z","iopub.execute_input":"2023-11-03T06:07:00.925485Z","iopub.status.idle":"2023-11-03T08:40:13.498516Z","shell.execute_reply.started":"2023-11-03T06:07:00.925430Z","shell.execute_reply":"2023-11-03T08:40:13.495234Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Выведение результатов","metadata":{}},{"cell_type":"code","source":"pred_list = []\nfor i in range(config.n_folds):\n    pred_list.append(np.load(\"./predictions/test_predictions_%d.npy\"%i))\nprediction = np.ones_like(pred_list[0])\nfor pred in pred_list:\n    prediction = prediction*pred\nprediction = prediction**(1./len(pred_list))\n# Make a submission file\ntop_3 = np.array(encoder.classes_)[np.argsort(-prediction, axis=1)[:, :3]]\npredicted_labels = [' '.join(list(x)) for x in top_3]\ntest = pd.read_csv('../input/freesound-audio-tagging/sample_submission.csv')\ntest['label'] = predicted_labels\ntest[['fname', 'label']].to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2023-11-03T08:40:13.503396Z","iopub.execute_input":"2023-11-03T08:40:13.504701Z","iopub.status.idle":"2023-11-03T08:40:13.593999Z","shell.execute_reply.started":"2023-11-03T08:40:13.504662Z","shell.execute_reply":"2023-11-03T08:40:13.592105Z"},"trusted":true},"execution_count":null,"outputs":[]}]}