{"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":"markdown","source":"## Install Dependencies","metadata":{}},{"cell_type":"code","source":"import os\nimport math\nimport random\nimport re\nimport warnings\nfrom pathlib import Path\nfrom typing import Optional, Tuple\n\n#import efficientnet.tfkeras as efn\nimport numpy as np\nimport pandas as pd\nimport tensorflow as tf\n#import tensorflow_addons as tfa\nfrom kaggle_datasets import KaggleDatasets\nfrom scipy.signal import get_window","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-08-17T15:12:46.217998Z","iopub.execute_input":"2021-08-17T15:12:46.218708Z","iopub.status.idle":"2021-08-17T15:12:52.713707Z","shell.execute_reply.started":"2021-08-17T15:12:46.218602Z","shell.execute_reply":"2021-08-17T15:12:52.712737Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tqdm.notebook import tqdm\nfrom time import perf_counter","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-08-17T15:12:52.715494Z","iopub.execute_input":"2021-08-17T15:12:52.715905Z","iopub.status.idle":"2021-08-17T15:12:52.787683Z","shell.execute_reply.started":"2021-08-17T15:12:52.715862Z","shell.execute_reply":"2021-08-17T15:12:52.786825Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tf.__version__","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-08-17T15:12:52.789758Z","iopub.execute_input":"2021-08-17T15:12:52.790156Z","iopub.status.idle":"2021-08-17T15:12:52.799610Z","shell.execute_reply.started":"2021-08-17T15:12:52.790117Z","shell.execute_reply":"2021-08-17T15:12:52.798971Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Config","metadata":{}},{"cell_type":"code","source":"IMAGE_SIZE = 256\nBATCH_SIZE = 32\nEFFICIENTNET_SIZE = 7\nWEIGHTS = \"imagenet\"","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-08-17T15:12:52.801173Z","iopub.execute_input":"2021-08-17T15:12:52.801603Z","iopub.status.idle":"2021-08-17T15:12:52.808003Z","shell.execute_reply.started":"2021-08-17T15:12:52.801556Z","shell.execute_reply":"2021-08-17T15:12:52.806933Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Utilities","metadata":{}},{"cell_type":"code","source":"def set_seed(seed=42):\n    random.seed(seed)\n    os.environ[\"PYTHONHASHSEED\"] = str(seed)\n    np.random.seed(seed)\n    tf.random.set_seed(seed)\n\n\nset_seed(1213)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-08-17T15:12:52.809268Z","iopub.execute_input":"2021-08-17T15:12:52.809717Z","iopub.status.idle":"2021-08-17T15:12:52.819227Z","shell.execute_reply.started":"2021-08-17T15:12:52.809657Z","shell.execute_reply":"2021-08-17T15:12:52.818416Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# From https://www.kaggle.com/xhlulu/ranzcr-efficientnet-tpu-training\ndef auto_select_accelerator():\n    TPU_DETECTED = False\n    try:\n        tpu = tf.distribute.cluster_resolver.TPUClusterResolver()\n        tf.config.experimental_connect_to_cluster(tpu)\n        tf.tpu.experimental.initialize_tpu_system(tpu)\n        strategy = tf.distribute.experimental.TPUStrategy(tpu)\n        print(\"Running on TPU:\", tpu.master())\n        TPU_DETECTED =True\n    except ValueError:\n        strategy = tf.distribute.get_strategy()\n    print(f\"Running on {strategy.num_replicas_in_sync} replicas\")\n    \n    return strategy, TPU_DETECTED","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-08-17T15:12:52.820382Z","iopub.execute_input":"2021-08-17T15:12:52.820897Z","iopub.status.idle":"2021-08-17T15:12:52.831925Z","shell.execute_reply.started":"2021-08-17T15:12:52.820858Z","shell.execute_reply":"2021-08-17T15:12:52.830750Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"strategy, tpu_detected = auto_select_accelerator()\nAUTO = tf.data.experimental.AUTOTUNE\nREPLICAS = strategy.num_replicas_in_sync","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-08-17T15:12:52.833054Z","iopub.execute_input":"2021-08-17T15:12:52.833479Z","iopub.status.idle":"2021-08-17T15:12:58.572626Z","shell.execute_reply.started":"2021-08-17T15:12:52.833436Z","shell.execute_reply":"2021-08-17T15:12:58.571737Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data Loading","metadata":{}},{"cell_type":"code","source":"gcs_paths = []\nfor i, j in [(0, 4), (5, 9)]:\n    GCS_path = KaggleDatasets().get_gcs_path(f\"g2net-waveform-tfrecords-test-{i}-{j}\")\n    gcs_paths.append(GCS_path)\n    print(GCS_path)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-08-17T15:12:58.573818Z","iopub.execute_input":"2021-08-17T15:12:58.574107Z","iopub.status.idle":"2021-08-17T15:12:59.525808Z","shell.execute_reply.started":"2021-08-17T15:12:58.574080Z","shell.execute_reply":"2021-08-17T15:12:59.524982Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"all_files = []\nfor path in gcs_paths:\n    all_files.extend(np.sort(np.array(tf.io.gfile.glob(path + \"/test*.tfrecords\"))))\n\nprint(\"test_files: \", len(all_files))","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-08-17T15:12:59.527822Z","iopub.execute_input":"2021-08-17T15:12:59.528230Z","iopub.status.idle":"2021-08-17T15:12:59.690382Z","shell.execute_reply.started":"2021-08-17T15:12:59.528201Z","shell.execute_reply":"2021-08-17T15:12:59.689445Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Dataset Preparation","metadata":{}},{"cell_type":"code","source":"def create_cqt_kernels(\n    q: float,\n    fs: float,\n    fmin: float,\n    n_bins: int = 84,\n    bins_per_octave: int = 12,\n    norm: float = 1,\n    window: str = \"hann\",\n    fmax: Optional[float] = None,\n    topbin_check: bool = True\n) -> Tuple[np.ndarray, int, np.ndarray, float]:\n    fft_len = 2 ** _nextpow2(np.ceil(q * fs / fmin))\n    \n    if (fmax is not None) and (n_bins is None):\n        n_bins = np.ceil(bins_per_octave * np.log2(fmax / fmin))\n        freqs = fmin * 2.0 ** (np.r_[0:n_bins] / np.float(bins_per_octave))\n    elif (fmax is None) and (n_bins is not None):\n        freqs = fmin * 2.0 ** (np.r_[0:n_bins] / np.float(bins_per_octave))\n    else:\n        warnings.warn(\"If nmax is given, n_bins will be ignored\", SyntaxWarning)\n        n_bins = np.ceil(bins_per_octave * np.log2(fmax / fmin))\n        freqs = fmin * 2.0 ** (np.r_[0:n_bins] / np.float(bins_per_octave))\n        \n    if np.max(freqs) > fs / 2 and topbin_check:\n        raise ValueError(f\"The top bin {np.max(freqs)} Hz has exceeded the Nyquist frequency, \\\n                           please reduce the `n_bins`\")\n    \n    kernel = np.zeros((int(n_bins), int(fft_len)), dtype=np.complex64)\n    \n    length = np.ceil(q * fs / freqs)\n    for k in range(0, int(n_bins)):\n        freq = freqs[k]\n        l = np.ceil(q * fs / freq)\n        \n        if l % 2 == 1:\n            start = int(np.ceil(fft_len / 2.0 - l / 2.0)) - 1\n        else:\n            start = int(np.ceil(fft_len / 2.0 - l / 2.0))\n\n        sig = get_window(window, int(l), fftbins=True) * np.exp(\n            np.r_[-l // 2:l // 2] * 1j * 2 * np.pi * freq / fs) / l\n        \n        if norm:\n            kernel[k, start:start + int(l)] = sig / np.linalg.norm(sig, norm)\n        else:\n            kernel[k, start:start + int(l)] = sig\n    return kernel, fft_len, length, freqs\n\n\ndef _nextpow2(a: float) -> int:\n    return int(np.ceil(np.log2(a)))\n\n\ndef prepare_cqt_kernel(\n    sr=22050,\n    hop_length=512,\n    fmin=32.70,\n    fmax=None,\n    n_bins=84,\n    bins_per_octave=12,\n    norm=1,\n    filter_scale=1,\n    window=\"hann\"\n):\n    q = float(filter_scale) / (2 ** (1 / bins_per_octave) - 1)\n    print(q)\n    return create_cqt_kernels(q, sr, fmin, n_bins, bins_per_octave, norm, window, fmax)","metadata":{"_kg_hide-output":true,"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-08-17T15:12:59.692705Z","iopub.execute_input":"2021-08-17T15:12:59.693006Z","iopub.status.idle":"2021-08-17T15:12:59.711529Z","shell.execute_reply.started":"2021-08-17T15:12:59.692979Z","shell.execute_reply":"2021-08-17T15:12:59.710426Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"HOP_LENGTH = 16\ncqt_kernels, KERNEL_WIDTH, lengths, _ = prepare_cqt_kernel(\n    sr=2048,\n    hop_length=HOP_LENGTH,\n    fmin=20,\n    fmax=1024,\n    bins_per_octave=24)\nLENGTHS = tf.constant(lengths, dtype=tf.float32)\nCQT_KERNELS_REAL = tf.constant(np.swapaxes(cqt_kernels.real[:, np.newaxis, :], 0, 2))\nCQT_KERNELS_IMAG = tf.constant(np.swapaxes(cqt_kernels.imag[:, np.newaxis, :], 0, 2))\nPADDING = tf.constant([[0, 0],\n                        [KERNEL_WIDTH // 2, KERNEL_WIDTH // 2],\n                        [0, 0]])","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-08-17T15:12:59.713035Z","iopub.execute_input":"2021-08-17T15:12:59.713333Z","iopub.status.idle":"2021-08-17T15:12:59.778378Z","shell.execute_reply.started":"2021-08-17T15:12:59.713306Z","shell.execute_reply":"2021-08-17T15:12:59.777241Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_cqt_image(wave, hop_length=16):\n    CQTs = []\n    for i in range(3):\n        x = wave[i]\n        x = tf.expand_dims(tf.expand_dims(x, 0), 2)\n        x = tf.pad(x, PADDING, \"REFLECT\")\n\n        CQT_real = tf.nn.conv1d(x, CQT_KERNELS_REAL, stride=hop_length, padding=\"VALID\")\n        CQT_imag = -tf.nn.conv1d(x, CQT_KERNELS_IMAG, stride=hop_length, padding=\"VALID\")\n        CQT_real *= tf.math.sqrt(LENGTHS)\n        CQT_imag *= tf.math.sqrt(LENGTHS)\n\n        CQT = tf.math.sqrt(tf.pow(CQT_real, 2) + tf.pow(CQT_imag, 2))\n        CQTs.append(CQT[0])\n    return tf.stack(CQTs, axis=2)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-08-17T15:12:59.780107Z","iopub.execute_input":"2021-08-17T15:12:59.780506Z","iopub.status.idle":"2021-08-17T15:12:59.789043Z","shell.execute_reply.started":"2021-08-17T15:12:59.780464Z","shell.execute_reply":"2021-08-17T15:12:59.787980Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def read_labeled_tfrecord(example):\n    tfrec_format = {\n        \"wave\": tf.io.FixedLenFeature([], tf.string),\n        \"wave_id\": tf.io.FixedLenFeature([], tf.string),\n        \"target\": tf.io.FixedLenFeature([], tf.int64)\n    }\n    example = tf.io.parse_single_example(example, tfrec_format)\n    return prepare_image(example[\"wave\"], IMAGE_SIZE), tf.reshape(tf.cast(example[\"target\"], tf.float32), [1])\n\n\ndef read_unlabeled_tfrecord(example, return_image_id):\n    tfrec_format = {\n        \"wave\": tf.io.FixedLenFeature([], tf.string),\n        \"wave_id\": tf.io.FixedLenFeature([], tf.string)\n    }\n    example = tf.io.parse_single_example(example, tfrec_format)\n    return prepare_image(example[\"wave\"], IMAGE_SIZE), example[\"wave_id\"] if return_image_id else 0\n\n\ndef count_data_items(fileids):\n    return len(fileids) * 28000\n\n\ndef count_data_items_test(fileids):\n    return len(fileids) * 22600\n\n\ndef prepare_image(wave, dim=256):\n    wave = tf.reshape(tf.io.decode_raw(wave, tf.float64), (3, 4096))\n    normalized_waves = []\n    for i in range(3):\n        normalized_wave = wave[i] / tf.math.reduce_max(wave[i])\n        normalized_waves.append(normalized_wave)\n    wave = tf.stack(normalized_waves)\n    wave = tf.cast(wave, tf.float32)\n    image = create_cqt_image(wave, HOP_LENGTH)\n    image = tf.image.resize(image, size=(dim, dim))\n    return tf.reshape(image, (dim, dim, 3))\n\n\ndef get_dataset(files, batch_size=16, repeat=False, shuffle=False, aug=True, labeled=True, return_image_ids=True):\n    ds = tf.data.TFRecordDataset(files, num_parallel_reads=AUTO, compression_type=\"GZIP\")\n    ds = ds.cache()\n\n    if repeat:\n        ds = ds.repeat()\n\n    if shuffle:\n        ds = ds.shuffle(1024 * 2)\n        opt = tf.data.Options()\n        opt.experimental_deterministic = False\n        ds = ds.with_options(opt)\n\n    if labeled:\n        ds = ds.map(read_labeled_tfrecord, num_parallel_calls=AUTO)\n    else:\n        ds = ds.map(lambda example: read_unlabeled_tfrecord(example, return_image_ids), num_parallel_calls=AUTO)\n\n    ds = ds.batch(batch_size * REPLICAS)\n    if aug:\n        ds = ds.map(lambda x, y: aug_f(x, y, batch_size * REPLICAS), num_parallel_calls=AUTO)\n    ds = ds.prefetch(AUTO)\n    return ds","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-08-17T15:12:59.790480Z","iopub.execute_input":"2021-08-17T15:12:59.791067Z","iopub.status.idle":"2021-08-17T15:12:59.809278Z","shell.execute_reply.started":"2021-08-17T15:12:59.791025Z","shell.execute_reply":"2021-08-17T15:12:59.808372Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Inference","metadata":{}},{"cell_type":"code","source":"files_test_all = np.array(all_files)","metadata":{"execution":{"iopub.status.busy":"2021-08-17T15:12:59.812220Z","iopub.execute_input":"2021-08-17T15:12:59.812551Z","iopub.status.idle":"2021-08-17T15:12:59.826405Z","shell.execute_reply.started":"2021-08-17T15:12:59.812520Z","shell.execute_reply":"2021-08-17T15:12:59.825373Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"NUM_TEST_IMAGES = len(pd.read_csv(\"../input/g2net-gravitational-wave-detection/sample_submission.csv\"))","metadata":{"execution":{"iopub.status.busy":"2021-08-17T15:12:59.827864Z","iopub.execute_input":"2021-08-17T15:12:59.828233Z","iopub.status.idle":"2021-08-17T15:13:00.069679Z","shell.execute_reply.started":"2021-08-17T15:12:59.828203Z","shell.execute_reply":"2021-08-17T15:13:00.068768Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds = get_dataset(files_test_all, batch_size=BATCH_SIZE * 2, repeat=False, shuffle=False, aug=False, labeled=False, return_image_ids=True)\nid_ds = ds.map(lambda image, label: label).unbatch()\nstart_time = perf_counter()\nids = next(iter(id_ds.batch(NUM_TEST_IMAGES))).numpy().astype('U')\nprint('one batch', f'finished; duration = {perf_counter() - start_time} s')","metadata":{"execution":{"iopub.status.busy":"2021-08-17T15:13:00.070915Z","iopub.execute_input":"2021-08-17T15:13:00.071195Z","iopub.status.idle":"2021-08-17T15:15:26.022419Z","shell.execute_reply.started":"2021-08-17T15:13:00.071168Z","shell.execute_reply":"2021-08-17T15:15:26.021306Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds_test = get_dataset(files_test_all, batch_size=BATCH_SIZE * 2, repeat=False, shuffle=False, aug=False, labeled=False, return_image_ids=True)\nstart_time = perf_counter()\nfile_ids = np.array([target.numpy().decode(\"utf-8\") for img, target in tqdm(ds_test.unbatch())])\nprint('iter by for loop', f'finished; duration = {perf_counter() - start_time} s')","metadata":{"execution":{"iopub.status.busy":"2021-08-17T15:16:02.581373Z","iopub.execute_input":"2021-08-17T15:16:02.581735Z","iopub.status.idle":"2021-08-17T15:23:25.621547Z","shell.execute_reply.started":"2021-08-17T15:16:02.581704Z","shell.execute_reply":"2021-08-17T15:23:25.620137Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"(ids==file_ids).all()","metadata":{"execution":{"iopub.status.busy":"2021-08-17T15:24:33.980007Z","iopub.execute_input":"2021-08-17T15:24:33.980340Z","iopub.status.idle":"2021-08-17T15:24:33.990554Z","shell.execute_reply.started":"2021-08-17T15:24:33.980311Z","shell.execute_reply":"2021-08-17T15:24:33.989491Z"},"trusted":true},"execution_count":null,"outputs":[]}]}