{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":7634,"databundleVersionId":46676,"sourceType":"competition"}],"dockerImageVersionId":30664,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-03-14T02:13:45.194981Z","iopub.execute_input":"2024-03-14T02:13:45.195364Z","iopub.status.idle":"2024-03-14T02:13:45.675149Z","shell.execute_reply.started":"2024-03-14T02:13:45.195334Z","shell.execute_reply":"2024-03-14T02:13:45.674240Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"librosa is a python package for music and audio analysis. It provides the building blocks necessary to create music information retrieval systems.","metadata":{}},{"cell_type":"code","source":"import csv\nimport librosa\nimport librosa.display\nimport matplotlib.pyplot as plt\n%matplotlib inline","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:13:45.676611Z","iopub.execute_input":"2024-03-14T02:13:45.677707Z","iopub.status.idle":"2024-03-14T02:13:45.705700Z","shell.execute_reply.started":"2024-03-14T02:13:45.677663Z","shell.execute_reply":"2024-03-14T02:13:45.704827Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We will be using pyunpack and patool to handle archieve files. So, let's install them.","metadata":{}},{"cell_type":"code","source":"!pip install pyunpack \n!pip install patool","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:13:45.707184Z","iopub.execute_input":"2024-03-14T02:13:45.707829Z","iopub.status.idle":"2024-03-14T02:14:18.441910Z","shell.execute_reply.started":"2024-03-14T02:13:45.707791Z","shell.execute_reply":"2024-03-14T02:14:18.440587Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from pyunpack import Archive\n\nos.makedirs(\"./data\", exist_ok = True)\nArchive(\"../input/tensorflow-speech-recognition-challenge/train.7z\").extractall(\"./data\")\nprint(\"Extracted!\")","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:14:18.446801Z","iopub.execute_input":"2024-03-14T02:14:18.447218Z","iopub.status.idle":"2024-03-14T02:16:05.669152Z","shell.execute_reply.started":"2024-03-14T02:14:18.447178Z","shell.execute_reply":"2024-03-14T02:16:05.667993Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dir = \"./data/train/audio/\"\n\nclasses = os.listdir(train_dir)\nclasses.remove(\"_background_noise_\")","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:16:05.670474Z","iopub.execute_input":"2024-03-14T02:16:05.670840Z","iopub.status.idle":"2024-03-14T02:16:05.678843Z","shell.execute_reply.started":"2024-03-14T02:16:05.670811Z","shell.execute_reply":"2024-03-14T02:16:05.677429Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(classes)","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:16:05.680451Z","iopub.execute_input":"2024-03-14T02:16:05.680871Z","iopub.status.idle":"2024-03-14T02:16:05.689591Z","shell.execute_reply.started":"2024-03-14T02:16:05.680842Z","shell.execute_reply":"2024-03-14T02:16:05.688353Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with open(\"./data/train/validation_list.txt\") as val_list:\n    validation_list = [row[0] for row in csv.reader(val_list)]\nassert len(validation_list) == 6798, \"Validation files not loaded\"\n\nwith open(\"./data/train/testing_list.txt\") as test_list:\n    testing_list = [row[0] for row in csv.reader(test_list)]\nassert len(testing_list) == 6835, \"testing files not loaded\"","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:16:05.691636Z","iopub.execute_input":"2024-03-14T02:16:05.692121Z","iopub.status.idle":"2024-03-14T02:16:05.710929Z","shell.execute_reply.started":"2024-03-14T02:16:05.692070Z","shell.execute_reply":"2024-03-14T02:16:05.709883Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"training_list  = []\nall_files_list = []\nclass_counts = {}\n\nfor folder in classes:\n    files = os.listdir(train_dir+folder)\n    for i, f in enumerate(files):\n        all_files_list.append(folder+\"/\"+f)\n        path = folder+'/'+f\n        if path not in validation_list and path not in testing_list:\n            training_list .append(folder+'/'+f)\n        class_counts[folder] = i\n\n#remove filenames from validation_list that don't exist anymore (due to eda)\nvalidation_list = list(set(validation_list).intersection(all_files_list))\ntesting_list = list(set(testing_list).intersection(all_files_list))\n\nassert len(validation_list) + len(testing_list) + len(training_list) == len(all_files_list), \"Not All files splitted\"","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:16:05.712505Z","iopub.execute_input":"2024-03-14T02:16:05.712943Z","iopub.status.idle":"2024-03-14T02:16:18.689573Z","shell.execute_reply.started":"2024-03-14T02:16:05.712904Z","shell.execute_reply":"2024-03-14T02:16:18.688335Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(class_counts)","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:16:18.691193Z","iopub.execute_input":"2024-03-14T02:16:18.691543Z","iopub.status.idle":"2024-03-14T02:16:18.697272Z","shell.execute_reply.started":"2024-03-14T02:16:18.691514Z","shell.execute_reply":"2024-03-14T02:16:18.696029Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from IPython.display import Audio\n\nsample_audio_file = os.listdir(train_dir+\"yes\")[0]\nprint(sample_audio_file)\n\nx, r = librosa.load(train_dir+\"yes/{}\".format(sample_audio_file))\nplt.plot(x)\n\nAudio(x, rate=r)","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:16:18.701210Z","iopub.execute_input":"2024-03-14T02:16:18.701520Z","iopub.status.idle":"2024-03-14T02:16:32.359735Z","shell.execute_reply.started":"2024-03-14T02:16:18.701494Z","shell.execute_reply":"2024-03-14T02:16:32.358816Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def make_spec(file, file_dir=train_dir, flip=False, ps=False, st = 4):\n    \"\"\"\n    create a melspectrogram from the amplitude of the sound\n    \n    Args:\n        file (str): filename\n        file_dir (str): directory path\n        flip (bool): reverse time axis\n        ps (bool): pitch shift\n        st (int): half-note steps for pitch shift\n    Returns:\n        np.array with shape (122,85) (time, freq)\n    \"\"\"\n    \n    sig, sr = librosa.load(file_dir+file, sr=16000)\n    \n    if len(sig) < 16000: #pad shorter than 1 sec audio with ramp to zero\n        sig = np.pad(sig, (0,16000-len(sig)), \"linear_ramp\")\n        \n    if ps:\n        sig = librosa.effects.pitch_shift(sig, rate, st)\n        \n    D = librosa.amplitude_to_db(librosa.stft(sig[:16000], \n                                             n_fft=512, \n                                             hop_length=128,\n                                             center=False),\n                               ref=np.max)\n    S = librosa.feature.melspectrogram(S=D, n_mels=85).T\n    \n    if flip:\n        S = np.flipud(S)\n    \n    return S.astype(np.float32)","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:16:32.361126Z","iopub.execute_input":"2024-03-14T02:16:32.361589Z","iopub.status.idle":"2024-03-14T02:16:32.375507Z","shell.execute_reply.started":"2024-03-14T02:16:32.361561Z","shell.execute_reply":"2024-03-14T02:16:32.374149Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"librosa.display.specshow(make_spec(\"yes/{}\".format(sample_audio_file)),\n                         x_axis=\"mel\",\n                         fmax=8000,\n                         y_axis=\"time\",\n                         sr=16000,\n                         hop_length=128)\nmake_spec(\"yes/{}\".format(sample_audio_file)).shape","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:16:32.376914Z","iopub.execute_input":"2024-03-14T02:16:32.377323Z","iopub.status.idle":"2024-03-14T02:16:34.417955Z","shell.execute_reply.started":"2024-03-14T02:16:32.377293Z","shell.execute_reply":"2024-03-14T02:16:34.416740Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_sets(file_list=training_list):\n    X_array = np.zeros([len(file_list), 122, 85])\n    y_array = np.zeros([len(file_list)])\n    for ind, file in enumerate(file_list):\n        if ind%2000 == 0:\n            print(\"{} done!\".format(ind))\n        try:\n            X_array[ind] = make_spec(file)\n        except ValueError:\n            print(ind, file, ValueError)\n        y_array[ind] = classes.index(file.rsplit('/')[0])\n    print(\"All Done!\")\n    return X_array, y_array","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:16:34.419523Z","iopub.execute_input":"2024-03-14T02:16:34.420580Z","iopub.status.idle":"2024-03-14T02:16:34.431463Z","shell.execute_reply.started":"2024-03-14T02:16:34.420547Z","shell.execute_reply":"2024-03-14T02:16:34.430201Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train, y_train = create_sets()","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:16:34.432735Z","iopub.execute_input":"2024-03-14T02:16:34.433744Z","iopub.status.idle":"2024-03-14T02:24:58.612448Z","shell.execute_reply.started":"2024-03-14T02:16:34.433701Z","shell.execute_reply":"2024-03-14T02:24:58.611354Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(X_train.shape, y_train.shape)","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:24:58.614278Z","iopub.execute_input":"2024-03-14T02:24:58.614951Z","iopub.status.idle":"2024-03-14T02:24:58.622568Z","shell.execute_reply.started":"2024-03-14T02:24:58.614912Z","shell.execute_reply":"2024-03-14T02:24:58.621160Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"librosa.display.specshow(X_train[6500],\n                         x_axis=\"mel\",\n                         fmax=8000,\n                         y_axis=\"time\",\n                         sr=16000,\n                         hop_length=128)","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:24:58.624483Z","iopub.execute_input":"2024-03-14T02:24:58.625093Z","iopub.status.idle":"2024-03-14T02:24:59.019467Z","shell.execute_reply.started":"2024-03-14T02:24:58.625054Z","shell.execute_reply":"2024-03-14T02:24:59.018625Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('min: ',np.min(X_train), \n      '\\nmax: ', np.max(X_train), \n      '\\nmean: ', np.mean(X_train),\n      '\\nmedian: ', np.median(X_train),\n      '\\nvariance: ', np.var(X_train))","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:24:59.020458Z","iopub.execute_input":"2024-03-14T02:24:59.020773Z","iopub.status.idle":"2024-03-14T02:25:10.414747Z","shell.execute_reply.started":"2024-03-14T02:24:59.020745Z","shell.execute_reply":"2024-03-14T02:25:10.413686Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.hist(X_train.flatten(), bins=50)","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:25:10.416631Z","iopub.execute_input":"2024-03-14T02:25:10.417113Z","iopub.status.idle":"2024-03-14T02:25:24.108605Z","shell.execute_reply.started":"2024-03-14T02:25:10.417073Z","shell.execute_reply":"2024-03-14T02:25:24.105937Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.save(\"./data/X_train.npy\", np.expand_dims(X_train, -1)+1.3) #Normalizing using mean\nnp.save(\"./data/y_train.npy\", y_train.astype(np.int64))\nprint(\"Saved!\")","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:25:24.111648Z","iopub.execute_input":"2024-03-14T02:25:24.112163Z","iopub.status.idle":"2024-03-14T02:25:35.064900Z","shell.execute_reply.started":"2024-03-14T02:25:24.112096Z","shell.execute_reply":"2024-03-14T02:25:35.063718Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_val, y_val = create_sets(file_list=validation_list)","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:25:35.067098Z","iopub.execute_input":"2024-03-14T02:25:35.067952Z","iopub.status.idle":"2024-03-14T02:26:52.869813Z","shell.execute_reply.started":"2024-03-14T02:25:35.067900Z","shell.execute_reply":"2024-03-14T02:26:52.868315Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.hist(X_val.flatten(), bins=50)","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:26:52.871983Z","iopub.execute_input":"2024-03-14T02:26:52.873407Z","iopub.status.idle":"2024-03-14T02:26:54.793729Z","shell.execute_reply.started":"2024-03-14T02:26:52.873345Z","shell.execute_reply":"2024-03-14T02:26:54.792710Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.save('data/X_val.npy', np.expand_dims(X_val, -1)+1.3) #Normalization using mean value\nnp.save('data/y_val.npy', y_val.astype(np.int64))\nprint(\"Saved!\")","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:26:54.795034Z","iopub.execute_input":"2024-03-14T02:26:54.795385Z","iopub.status.idle":"2024-03-14T02:26:55.438373Z","shell.execute_reply.started":"2024-03-14T02:26:54.795346Z","shell.execute_reply":"2024-03-14T02:26:55.437354Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%reset -f","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:26:55.439540Z","iopub.execute_input":"2024-03-14T02:26:55.439890Z","iopub.status.idle":"2024-03-14T02:26:56.135169Z","shell.execute_reply.started":"2024-03-14T02:26:55.439862Z","shell.execute_reply":"2024-03-14T02:26:56.133826Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport os","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:26:56.136604Z","iopub.execute_input":"2024-03-14T02:26:56.137811Z","iopub.status.idle":"2024-03-14T02:26:56.142146Z","shell.execute_reply.started":"2024-03-14T02:26:56.137777Z","shell.execute_reply":"2024-03-14T02:26:56.141036Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dir = \"./data/train/audio/\"\n\nX_train = np.load(\"./data/X_train.npy\")\ny_train = np.load(\"./data/y_train.npy\")\n\nX_val = np.load(\"./data/X_val.npy\")\ny_val = np.load(\"./data/y_val.npy\")","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:26:56.143169Z","iopub.execute_input":"2024-03-14T02:26:56.143602Z","iopub.status.idle":"2024-03-14T02:26:57.991238Z","shell.execute_reply.started":"2024-03-14T02:26:56.143573Z","shell.execute_reply":"2024-03-14T02:26:57.989976Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train.shape","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:26:57.992831Z","iopub.execute_input":"2024-03-14T02:26:57.994056Z","iopub.status.idle":"2024-03-14T02:26:58.002104Z","shell.execute_reply.started":"2024-03-14T02:26:57.994020Z","shell.execute_reply":"2024-03-14T02:26:58.000719Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train = X_train.reshape((-1, X_train.shape[1], X_train.shape[2]))\nX_val = X_val.reshape((-1, X_val.shape[1], X_val.shape[2]))","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:26:58.003812Z","iopub.execute_input":"2024-03-14T02:26:58.004114Z","iopub.status.idle":"2024-03-14T02:26:58.012524Z","shell.execute_reply.started":"2024-03-14T02:26:58.004088Z","shell.execute_reply":"2024-03-14T02:26:58.011271Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"classes = os.listdir(train_dir)\nprint(classes)","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:26:58.020474Z","iopub.execute_input":"2024-03-14T02:26:58.020914Z","iopub.status.idle":"2024-03-14T02:26:58.027865Z","shell.execute_reply.started":"2024-03-14T02:26:58.020882Z","shell.execute_reply":"2024-03-14T02:26:58.026466Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from collections import Counter\n\ndef get_class_weights(y):\n    counter = Counter(y)\n    majority = max(counter.values())\n    return {cls: float(majority/count) for cls, count in counter.items()}\n\nclass_weights = get_class_weights(y_train)\nclass_weights","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:26:58.029566Z","iopub.execute_input":"2024-03-14T02:26:58.030054Z","iopub.status.idle":"2024-03-14T02:26:58.059606Z","shell.execute_reply.started":"2024-03-14T02:26:58.030014Z","shell.execute_reply":"2024-03-14T02:26:58.058112Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def convert_list_dict(lst):\n    res_dct = {i: val for i, val in enumerate(lst)}\n    return res_dct\n         \nclasses_index = convert_list_dict(classes)\nclasses_index","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:26:58.061161Z","iopub.execute_input":"2024-03-14T02:26:58.061565Z","iopub.status.idle":"2024-03-14T02:26:58.072164Z","shell.execute_reply.started":"2024-03-14T02:26:58.061530Z","shell.execute_reply":"2024-03-14T02:26:58.070942Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"NB_CLASSES = len(classes)","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:26:58.073383Z","iopub.execute_input":"2024-03-14T02:26:58.073733Z","iopub.status.idle":"2024-03-14T02:26:58.080254Z","shell.execute_reply.started":"2024-03-14T02:26:58.073701Z","shell.execute_reply":"2024-03-14T02:26:58.079156Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.utils import to_categorical\n\ny_train = to_categorical(y_train, num_classes=NB_CLASSES)\ny_val = to_categorical(y_val, num_classes=NB_CLASSES)","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:26:58.081779Z","iopub.execute_input":"2024-03-14T02:26:58.082192Z","iopub.status.idle":"2024-03-14T02:27:12.599756Z","shell.execute_reply.started":"2024-03-14T02:26:58.082161Z","shell.execute_reply":"2024-03-14T02:27:12.598354Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install livelossplot #to plot training loss in real time.","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:27:12.601228Z","iopub.execute_input":"2024-03-14T02:27:12.601933Z","iopub.status.idle":"2024-03-14T02:27:28.335229Z","shell.execute_reply.started":"2024-03-14T02:27:12.601899Z","shell.execute_reply":"2024-03-14T02:27:28.333848Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.models import Model\nfrom tensorflow.keras.optimizers import Adam #general and commonly applicable optimizer\nfrom keras.layers import Conv1D, BatchNormalization, Activation, Input, Dense, Bidirectional, LSTM, Dropout, TimeDistributed, Lambda\nfrom keras.callbacks import ModelCheckpoint, ReduceLROnPlateau, EarlyStopping\nfrom livelossplot import PlotLossesKeras\nfrom tensorflow.keras.metrics import Recall, Precision\nimport keras\nimport keras.backend as K\nimport time","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:27:28.338356Z","iopub.execute_input":"2024-03-14T02:27:28.338898Z","iopub.status.idle":"2024-03-14T02:27:28.366292Z","shell.execute_reply.started":"2024-03-14T02:27:28.338850Z","shell.execute_reply":"2024-03-14T02:27:28.365000Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"char_map_str = \"\"\"\n<SPACE> 0\na 1\nb 2\nc 3\nd 4\ne 5\nf 6\ng 7\nh 8\ni 9\nj 10\nk 11\nl 12\nm 13\nn 14\no 15\np 16\nq 17\nr 18\ns 19\nt 20\nu 21\nv 22\nw 23\nx 24\ny 25\nz 26\n' 27\n\"\"\"\n\nchar_map = {}\nindex_map = {}\n\nfor line in char_map_str.strip().split('\\n'):\n    ch, index = line.split()\n    char_map[ch] = int(index)\n    index_map[int(index)] = ch\n\nindex_map[0] = ' '","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:27:28.368001Z","iopub.execute_input":"2024-03-14T02:27:28.368427Z","iopub.status.idle":"2024-03-14T02:27:28.375606Z","shell.execute_reply.started":"2024-03-14T02:27:28.368393Z","shell.execute_reply":"2024-03-14T02:27:28.374420Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def  get_intseq(text, max_len = 8):\n    \"\"\"\n    takes the character map and returns a series of \n    integers for the inserted text\n    \n    pads integer list with 27's up to max length\n    \"\"\"\n    int_seq = []\n    for c in text:\n        num = char_map[c]\n        int_seq.append(num)\n    while (len(int_seq) < max_len):\n        int_seq.append(27)\n    return int_seq","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:27:28.377217Z","iopub.execute_input":"2024-03-14T02:27:28.377591Z","iopub.status.idle":"2024-03-14T02:27:28.386883Z","shell.execute_reply.started":"2024-03-14T02:27:28.377561Z","shell.execute_reply":"2024-03-14T02:27:28.385904Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CTC():\n    \"\"\"\n    Usage:\n        sr_ctc = CTC(enter input_size and output_size)\n        sr_ctc.build()\n        sr_ctc.m.compile()\n        sr_ctc.tm.compile()\n    \"\"\" \n    def __init__(self, input_shape, nb_classes, weights_directory='./', nb_epochs=100, batch_size=64):\n        self.input_shape = input_shape\n        self.nb_classes = nb_classes\n        self.weights_directory = weights_directory\n        self.nb_epochs = nb_epochs\n        self.batch_size = batch_size\n        self.m = None\n        self.tm = None    \n        \n        self.build()\n        \n    def ctc_layer_func(self, args):\n        y_pred, labels, input_length, label_length = args\n        return K.ctc_batch_cost(labels, y_pred, input_length, label_length)\n    \n    # dummy loss\n    def ctc_loss(self, y_true, y_pred):\n        return y_pred\n        \n    def build(self, conv_filters=196, conv_size=13, conv_strides=4, activation=\"relu\", rnn_layers=2, lstm_units=128, drop_out=0.8):\n        \"\"\"\n        build CTC training model (self.m) and \n        prediction model without the ctc loss function (self.tm)\n        \n        Usage: \n            enter conv parameters for Cov1D layer\n            specify number of rnn layers, LSTM units and dropout\n        Args:\n            \n        Returns:\n            self.m: keras.engine.training.Model\n            self.tm: keras.engine.training.Model\n        \"\"\"        \n        \n        inputs = Input(shape=self.input_shape, name='input')\n        x = Conv1D(conv_filters, \n                   conv_size, \n                   strides = conv_strides, \n                   name = 'conv1d')(inputs)\n        x = BatchNormalization()(x)\n        x = Activation(activation)(x)\n        for _ in range(rnn_layers):          \n            x = Bidirectional(LSTM(lstm_units, \n                                   return_sequences = True))(x)\n            x = Dropout(drop_out)(x)\n            x = BatchNormalization()(x)\n        outputs = TimeDistributed(Dense(self.nb_classes, activation=\"softmax\"))(x)\n        \n        # ctc inputs\n        labels = Input(name=\"the_labels\", shape=[None,], dtype=\"int32\")\n        input_length = Input(name=\"input_length\", shape=[1], dtype=\"int32\")\n        label_length = Input(name=\"label_length\", shape=[1], dtype=\"int32\")\n        \n        ctc_layer = Lambda(self.ctc_layer_func, output_shape=(1,), name=\"ctc\")([outputs, labels, input_length, label_length])\n        self.tm = Model(inputs=inputs, outputs=outputs)\n        self.m = Model(inputs=[inputs,labels,input_length,label_length],\n                       outputs=ctc_layer)            \n        \n        self.m.compile(loss=self.ctc_loss, \n                       optimizer=Adam(),\n                       metrics=['accuracy'])\n        \n        self.tm.compile(loss=self.ctc_loss, \n                        optimizer=Adam())\n              \n        reduce_lr = ReduceLROnPlateau(monitor='val_accuracy', \n                                      factor=0.5, \n                                      patience=int(self.nb_epochs/20),\n                                      min_lr=0.0001)\n        \n        file_path = os.path.join(self.weights_directory,\"ctc_best_weights.keras\")\n        model_checkpoint = ModelCheckpoint(filepath=file_path, \n                                           monitor='val_accuracy',\n                                           mode=\"max\",\n                                           save_best_only=True)\n        \n        early_stopping = EarlyStopping(monitor=\"val_accuracy\", \n                                       mode=\"max\", \n                                       verbose=1, \n                                       patience=int(self.nb_epochs/10))\n        plotlosses = PlotLossesKeras()\n        self.callbacks = [reduce_lr, model_checkpoint, early_stopping, plotlosses]\n     \n        print(self.m.summary())\n        print(self.tm.summary())\n        \n        return self.m, self.tm\n    \n    \n    def fit(self, X_train, train_labels, train_input_length, train_label_length, y_train,\n                  X_val, val_labels, val_input_length, val_label_length, y_val):       \n        if self.batch_size is None:\n            mini_batch_size = int(min(x_train.shape[0] / 10, 16))\n        else:\n            mini_batch_size = self.batch_size\n\n        start_time = time.time()\n        hist = sr_ctc.m.fit([np.squeeze(X_train), \n                            train_labels, \n                            train_input_length, \n                            train_label_length], \n                       np.zeros([len(y_train)]), \n                       batch_size = self.batch_size, \n                       epochs = self.nb_epochs, \n                       validation_data = ([np.squeeze(X_val), \n                                           val_labels, \n                                           val_input_length, \n                                           val_label_length],\n                                          np.zeros([len(y_val)])), \n                       callbacks = self.callbacks, \n                       verbose = 1, \n                       shuffle = True)\n        \n        duration = time.time() - start_time\n        keras.backend.clear_session()\n        print(\"Model take {} S to train \".format(duration))\n        return hist\n    \n    def str_out(self, dataset):\n        k_ctc_out = K.ctc_decode(self.tm.predict(np.squeeze(dataset), \n                                                verbose = 1), \n                             np.array([28 for _ in dataset]))\n        decoded_out = K.eval(k_ctc_out[0][0])\n        str_decoded_out = []\n        for i, _ in enumerate(decoded_out):     \n            str_decoded_out.append(\"\".join([index_map[c] for c in decoded_out[i] if not c == -1]))\n\n        return str_decoded_out","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:27:28.403186Z","iopub.execute_input":"2024-03-14T02:27:28.403545Z","iopub.status.idle":"2024-03-14T02:27:28.435733Z","shell.execute_reply.started":"2024-03-14T02:27:28.403504Z","shell.execute_reply":"2024-03-14T02:27:28.434421Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"INPUT_SHAPE = X_train.shape[1:]\nBATCH_SIZE = 64\nWEIGHTS_DIR = \"./\"\nsr_ctc = CTC(INPUT_SHAPE, NB_CLASSES, WEIGHTS_DIR, nb_epochs=100, batch_size=BATCH_SIZE)","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:27:28.438077Z","iopub.execute_input":"2024-03-14T02:27:28.438596Z","iopub.status.idle":"2024-03-14T02:27:28.821785Z","shell.execute_reply.started":"2024-03-14T02:27:28.438551Z","shell.execute_reply":"2024-03-14T02:27:28.820724Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_ctc_params(y, classes_list, len_char_map = 28):\n    \"\"\"\n    Usage:\n        creates parameters required for K.ctc_batch_cost function \n    Args:\n        Y (ndarray): target set with all classes\n        classes_list (list): list with class names\n        len_char_map (int): length of the character map\n    Returns:\n        3 ndarrays\n    \"\"\"\n    labels = np.array([get_intseq(classes_list[np.argmax(y[l])]) for l in range(len(y))])\n    input_length = np.array([len_char_map for _ in range(len(y))])\n    label_length = np.array([8 for _ in range(len(y))])\n    return labels, input_length, label_length\n","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:28:22.175402Z","iopub.execute_input":"2024-03-14T02:28:22.175856Z","iopub.status.idle":"2024-03-14T02:28:22.184161Z","shell.execute_reply.started":"2024-03-14T02:28:22.175824Z","shell.execute_reply":"2024-03-14T02:28:22.182916Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"execution":{"iopub.status.busy":"2024-03-14T02:28:38.850575Z","iopub.execute_input":"2024-03-14T02:28:38.851033Z","iopub.status.idle":"2024-03-14T02:28:39.049939Z","shell.execute_reply.started":"2024-03-14T02:28:38.850997Z","shell.execute_reply":"2024-03-14T02:28:39.048250Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"execution":{"iopub.status.busy":"2024-03-15T07:17:00.386593Z","iopub.execute_input":"2024-03-15T07:17:00.388049Z","iopub.status.idle":"2024-03-15T07:17:00.835810Z","shell.execute_reply.started":"2024-03-15T07:17:00.387992Z","shell.execute_reply":"2024-03-15T07:17:00.834106Z"},"trusted":true},"execution_count":null,"outputs":[]}]}