From c49645d7bc0bea1bb77f3f4576c6e4d91aa2d449 Mon Sep 17 00:00:00 2001 From: Victor Mylle Date: Fri, 7 Apr 2023 09:44:12 +0000 Subject: [PATCH] Initial Commit --- Dockerfile | 21 +-- datasets/czech_slr_dataset.py | 1 + export_label_id.py | 20 +++ models/utils.py | 4 +- normalization/blazepose_mapping.py | 19 +-- normalization/main.py | 27 +-- notebooks/embeddings_evaluation.ipynb | 156 ++++++++++++++---- notebooks/visualize_embeddings.ipynb | 95 ++++++----- .../create_google_asl_landmarks_dataset.py | 146 ++++++++++++++++ .../create_wlasl_landmarks_dataset.py | 4 +- preprocessing/split_dataset.py | 32 ++++ requirements.txt | 6 +- train.sh | 20 +-- 13 files changed, 423 insertions(+), 128 deletions(-) create mode 100644 export_label_id.py create mode 100644 preprocessing/create_google_asl_landmarks_dataset.py create mode 100644 preprocessing/split_dataset.py diff --git a/Dockerfile b/Dockerfile index 93e7add..eea9f73 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,8 @@ -FROM pytorch/pytorch - -WORKDIR /app -COPY ./requirements.txt /app/ - -RUN pip install -r requirements.txt -RUN apt-get -y update -RUN apt-get -y install git -RUN apt-get install ffmpeg libsm6 libxext6 -y - -COPY . /app/ -RUN git config --global --add safe.directory /app -CMD ./train.sh +FROM ubuntu:20.04 +ADD requirements.txt /requirements.txt +ARG DEBIAN_FRONTEND=noninteractive +RUN apt-get update +RUN apt-get install ffmpeg libsm6 libxext6 git -y +RUN apt-get install -y libglib2.0-0 +RUN apt-get -y install python3-pip +RUN pip install -r /requirements.txt \ No newline at end of file diff --git a/datasets/czech_slr_dataset.py b/datasets/czech_slr_dataset.py index 39bd97b..3d883d3 100644 --- a/datasets/czech_slr_dataset.py +++ b/datasets/czech_slr_dataset.py @@ -30,6 +30,7 @@ class CzechSLRDataset(torch_data.Dataset): self.data = data self.labels = labels self.targets = list(labels) + self.num_labels = num_labels self.transform = transform diff --git a/export_label_id.py b/export_label_id.py new file mode 100644 index 0000000..fd851b4 --- /dev/null +++ b/export_label_id.py @@ -0,0 +1,20 @@ +import os +import json +# read data/wlasl/wlasl_class_list.txt + +labels = {} +with open("data/sign_to_prediction_index_map.json", "r") as f: + sign_to_prediction_index_map = json.load(f) + + # switch key and value + for key, value in sign_to_prediction_index_map.items(): + labels[value] = key + + +if os.path.exists("data/processed/id_to_label.json"): + os.remove("data/processed/id_to_label.json") + +with open("data/processed/id_to_label.json", "w") as f: + json.dump(labels, f) + + \ No newline at end of file diff --git a/models/utils.py b/models/utils.py index 4979c79..498affa 100644 --- a/models/utils.py +++ b/models/utils.py @@ -12,12 +12,14 @@ def train_epoch(model, dataloader, criterion, optimizer, device, scheduler=None) running_loss = 0.0 model.train(True) for i, data in enumerate(dataloader): + inputs, labels = data inputs = inputs.squeeze(0).to(device) labels = labels.to(device, dtype=torch.long) optimizer.zero_grad() outputs = model(inputs).expand(1, -1, -1) + loss = criterion(outputs[0], labels[0]) loss.backward() optimizer.step() @@ -159,7 +161,7 @@ def evaluate(model, dataloader, device, print_stats=False): logger = get_logger(__name__) pred_correct, pred_all = 0, 0 - stats = {i: [0, 0] for i in range(101)} + stats = {i: [0, 0] for i in range(251)} for i, data in enumerate(dataloader): inputs, labels = data diff --git a/normalization/blazepose_mapping.py b/normalization/blazepose_mapping.py index 90a0672..666aba7 100644 --- a/normalization/blazepose_mapping.py +++ b/normalization/blazepose_mapping.py @@ -62,23 +62,19 @@ def map_blazepose_keypoint(column): def map_blazepose_df(df): - to_drop = [] - renamings = {} - for column in df.columns: - mapped_column = map_blazepose_keypoint(column) - if mapped_column: - renamings[column] = mapped_column - else: - to_drop.append(column) - df = df.rename(columns=renamings) - for index, row in df.iterrows(): - sequence_size = len(row["leftEar_Y"]) lsx = row["leftShoulder_X"] rsx = row["rightShoulder_X"] lsy = row["leftShoulder_Y"] rsy = row["rightShoulder_Y"] + # convert all to list + lsx = lsx[1:-1].split(",") + rsx = rsx[1:-1].split(",") + lsy = lsy[1:-1].split(",") + rsy = rsy[1:-1].split(",") + sequence_size = len(lsx) + neck_x = [] neck_y = [] # Treat each element of the sequence (analyzed frame) individually @@ -88,5 +84,4 @@ def map_blazepose_df(df): df.loc[index, "neck_X"] = str(neck_x) df.loc[index, "neck_Y"] = str(neck_y) - df.drop(columns=to_drop, inplace=True) return df diff --git a/normalization/main.py b/normalization/main.py index 4c619a2..9f4231f 100644 --- a/normalization/main.py +++ b/normalization/main.py @@ -5,23 +5,30 @@ import pandas as pd from normalization.hand_normalization import normalize_hands_full from normalization.body_normalization import normalize_body_full -DATASET_PATH = './data' +DATASET_PATH = './data/wlasl' # Load the dataset -df = pd.read_csv(os.path.join(DATASET_PATH, "WLASL_test_15fps.csv"), encoding="utf-8") +df = pd.read_csv(os.path.join(DATASET_PATH, "WLASL100_train.csv"), encoding="utf-8") + +print(df.head()) +print(df.columns) # Retrieve metadata -video_size_heights = df["video_size_height"].to_list() -video_size_widths = df["video_size_width"].to_list() +video_size_heights = df["video_height"].to_list() +video_size_widths = df["video_width"].to_list() # Delete redundant (non-related) properties -del df["video_size_height"] -del df["video_size_width"] +del df["video_height"] +del df["video_width"] # Temporarily remove other relevant metadata labels = df["labels"].to_list() -video_fps = df["video_fps"].to_list() +video_fps = df["fps"].to_list() del df["labels"] -del df["video_fps"] +del df["fps"] +del df["split"] +del df["video_id"] +del df["label_name"] +del df["length"] # Convert the strings into lists @@ -42,6 +49,6 @@ df, invalid_row_indexes = normalize_body_full(df) # Return the metadata back to the dataset df["labels"] = labels -df["video_fps"] = video_fps +df["fps"] = video_fps -df.to_csv(os.path.join(DATASET_PATH, "WLASL_test_15fps_normalized.csv"), encoding="utf-8", index=False) +df.to_csv(os.path.join(DATASET_PATH, "wlasl_train_norm.csv"), encoding="utf-8", index=False) diff --git a/notebooks/embeddings_evaluation.ipynb b/notebooks/embeddings_evaluation.ipynb index 1db8999..f04a1c0 100644 --- a/notebooks/embeddings_evaluation.ipynb +++ b/notebooks/embeddings_evaluation.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "c20f7fd5", "metadata": {}, "outputs": [], @@ -13,7 +13,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "ada032d0", "metadata": {}, "outputs": [], @@ -28,7 +28,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "05682e73", "metadata": {}, "outputs": [], @@ -38,7 +38,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "fede7684", "metadata": {}, "outputs": [], @@ -48,7 +48,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "ce531994", "metadata": {}, "outputs": [], @@ -64,7 +64,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "f4a2d672", "metadata": {}, "outputs": [], @@ -87,10 +87,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "id": "1d9db764", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "import random\n", "seed = 43\n", @@ -108,7 +119,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "id": "71224139", "metadata": {}, "outputs": [], @@ -122,10 +133,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "id": "013d3774", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# LOAD MODEL FROM CLEARML\n", "# from clearml import InputModel\n", @@ -133,7 +155,7 @@ "# checkpoint = torch.load(model.get_weights())\n", "\n", "## Set your path to checkoint here\n", - "CHECKPOINT_PATH = \"../checkpoints/checkpoint_embed_992.pth\"\n", + "CHECKPOINT_PATH = \"../out-checkpoints/augment_rotate_75_x8/checkpoint_embed_6.pth\"\n", "checkpoint = torch.load(CHECKPOINT_PATH, map_location=device)\n", "\n", "model = SPOTER_EMBEDDINGS(\n", @@ -147,16 +169,16 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "id": "ba6b58f0", "metadata": {}, "outputs": [], "source": [ "SL_DATASET = 'wlasl' # or 'lsa'\n", "if SL_DATASET == 'wlasl':\n", - " dataset_name = \"wlasl_mapped_mediapipe_only_landmarks_25fps\"\n", + " dataset_name = \"wlasl\"\n", " num_classes = 100\n", - " split_dataset_path = \"WLASL100_{}_25fps.csv\"\n", + " split_dataset_path = \"WLASL100_train.csv\"\n", "else:\n", " dataset_name = \"lsa64_mapped_mediapipe_only_landmarks_25fps\"\n", " num_classes = 64\n", @@ -167,7 +189,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "id": "5643a72c", "metadata": {}, "outputs": [], @@ -187,7 +209,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "id": "04a62088", "metadata": {}, "outputs": [], @@ -200,7 +222,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "id": "79c837c1", "metadata": {}, "outputs": [], @@ -231,7 +253,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "id": "8b5bda73", "metadata": {}, "outputs": [], @@ -256,17 +278,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "id": "0efa0871", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(810, 810)" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "len(embeddings_split['train']), len(dfs['train'])" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 20, "id": "ab83c6e2", "metadata": { "lines_to_next_cell": 2 @@ -289,10 +322,31 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 21, "id": "7399b8ae", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Using centroids only\n", + "Top-1 accuracy: 5.19 %\n", + "Top-5 embeddings class match: 17.65 % (Picks any class in the 5 closest embeddings)\n", + "\n", + "################################\n", + "\n", + "Using all embeddings\n", + "Top-1 accuracy: 5.31 %\n", + "5-nn accuracy: 5.56 % (Picks the class that appears most often in the 5 closest embeddings)\n", + "Top-5 embeddings class match: 15.43 % (Picks any class in the 5 closest embeddings)\n", + "Top-5 unique class match: 15.56 % (Picks the 5 closest distinct classes)\n", + "\n", + "################################\n", + "\n" + ] + } + ], "source": [ "for use_centroids, str_use_centroids in zip([True, False],\n", " ['Using centroids only', 'Using all embeddings']):\n", @@ -362,7 +416,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 22, "id": "b9d1d309", "metadata": {}, "outputs": [], @@ -372,10 +426,56 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 23, "id": "fd2a0cd8", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "for row in df_train[df_train.label_name == 'thursday'][:3].itertuples():\n", " display(Video(op.join(BASE_DATA_FOLDER, f'wlasl/videos/{row.video_id}.mp4'), embed=True))" @@ -403,7 +503,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.13" + "version": "3.8.10" } }, "nbformat": 4, diff --git a/notebooks/visualize_embeddings.ipynb b/notebooks/visualize_embeddings.ipynb index c49a9fa..4268c5a 100644 --- a/notebooks/visualize_embeddings.ipynb +++ b/notebooks/visualize_embeddings.ipynb @@ -91,7 +91,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 7, @@ -151,7 +151,7 @@ "# checkpoint = torch.load(model.get_weights())\n", "\n", "\n", - "CHECKPOINT_PATH = \"../checkpoints/checkpoint_embed_992.pth\"\n", + "CHECKPOINT_PATH = \"../out-checkpoints/augment_rotate_75_x8/checkpoint_embed_18.pth\"\n", "checkpoint = torch.load(CHECKPOINT_PATH, map_location=device)\n", "\n", "\n", @@ -166,16 +166,16 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 18, "id": "20f8036d", "metadata": {}, "outputs": [], "source": [ "SL_DATASET = 'wlasl' # or 'lsa'\n", "if SL_DATASET == 'wlasl':\n", - " dataset_name = \"wlasl_mapped_mediapipe_only_landmarks_25fps\"\n", - " num_classes = 100\n", - " split_dataset_path = \"WLASL100_{}_25fps.csv\"\n", + " dataset_name = \"processed\"\n", + " num_classes = 15\n", + " split_dataset_path = \"spoter_test.csv\"\n", "else:\n", " dataset_name = \"lsa64_mapped_mediapipe_only_landmarks_25fps\"\n", " num_classes = 64\n", @@ -185,7 +185,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 19, "id": "758716b6", "metadata": {}, "outputs": [], @@ -205,7 +205,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 20, "id": "f1527959", "metadata": {}, "outputs": [ @@ -213,10 +213,10 @@ "name": "stderr", "output_type": "stream", "text": [ - "/opt/conda/lib/python3.7/site-packages/sklearn/manifold/_t_sne.py:783: FutureWarning: The default initialization in TSNE will change from 'random' to 'pca' in 1.2.\n", - " FutureWarning,\n", - "/opt/conda/lib/python3.7/site-packages/sklearn/manifold/_t_sne.py:793: FutureWarning: The default learning rate in TSNE will change from 200.0 to 'auto' in 1.2.\n", - " FutureWarning,\n" + "/usr/local/lib/python3.8/dist-packages/sklearn/manifold/_t_sne.py:780: FutureWarning: The default initialization in TSNE will change from 'random' to 'pca' in 1.2.\n", + " warnings.warn(\n", + "/usr/local/lib/python3.8/dist-packages/sklearn/manifold/_t_sne.py:790: FutureWarning: The default learning rate in TSNE will change from 200.0 to 'auto' in 1.2.\n", + " warnings.warn(\n" ] } ], @@ -255,7 +255,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 24, "id": "3c3af5bf", "metadata": { "lines_to_next_cell": 0 @@ -264,10 +264,10 @@ { "data": { "text/plain": [ - "1533" + "1220" ] }, - "execution_count": 18, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } @@ -280,19 +280,19 @@ " df['tsne_x'] = tsne_results[split][:, 0]\n", " df['tsne_y'] = tsne_results[split][:, 1]\n", " df['split'] = split\n", - " if SL_DATASET == 'wlasl':\n", - " df['video_fn'] = df['video_id'].apply(lambda video_id: os.path.join(BASE_DATA_FOLDER, f'wlasl/videos/{video_id:05d}.mp4'))\n", - " else:\n", - " df['video_fn'] = df['video_id'].apply(lambda video_id: os.path.join(BASE_DATA_FOLDER, f'lsa/videos/{video_id}.mp4'))\n", + " # if SL_DATASET == 'wlasl':\n", + " # df['video_fn'] = df['video_id'].apply(lambda video_id: os.path.join(BASE_DATA_FOLDER, f'wlasl/videos/{video_id:05d}.mp4'))\n", + " # else:\n", + " # df['video_fn'] = df['video_id'].apply(lambda video_id: os.path.join(BASE_DATA_FOLDER, f'lsa/videos/{video_id}.mp4'))\n", " dfs[split] = df\n", "\n", - "df = pd.concat([dfs['train'].sample(100), dfs['val']]).reset_index(drop=True)\n", + "df = pd.concat([dfs['train'].sample(20), dfs['val']]).reset_index(drop=True)\n", "len(df)" ] }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 25, "id": "dccbe1b9", "metadata": {}, "outputs": [], @@ -315,7 +315,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 26, "id": "904298f0", "metadata": {}, "outputs": [], @@ -329,7 +329,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 27, "id": "42832f7c", "metadata": { "scrolled": false @@ -340,7 +340,7 @@ "text/html": [ "
\n", " \n", - " Loading BokehJS ...\n", + " Loading BokehJS ...\n", "
\n" ] }, @@ -349,7 +349,7 @@ }, { "data": { - "application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\nconst JS_MIME_TYPE = 'application/javascript';\n const HTML_MIME_TYPE = 'text/html';\n const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n const CLASS_NAME = 'output_bokeh rendered_html';\n\n /**\n * Render data to the DOM node\n */\n function render(props, node) {\n const script = document.createElement(\"script\");\n node.appendChild(script);\n }\n\n /**\n * Handle when an output is cleared or removed\n */\n function handleClearOutput(event, handle) {\n const cell = handle.cell;\n\n const id = cell.output_area._bokeh_element_id;\n const server_id = cell.output_area._bokeh_server_id;\n // Clean up Bokeh references\n if (id != null && id in Bokeh.index) {\n Bokeh.index[id].model.document.clear();\n delete Bokeh.index[id];\n }\n\n if (server_id !== undefined) {\n // Clean up Bokeh references\n const cmd_clean = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n cell.notebook.kernel.execute(cmd_clean, {\n iopub: {\n output: function(msg) {\n const id = msg.content.text.trim();\n if (id in Bokeh.index) {\n Bokeh.index[id].model.document.clear();\n delete Bokeh.index[id];\n }\n }\n }\n });\n // Destroy server and session\n const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n cell.notebook.kernel.execute(cmd_destroy);\n }\n }\n\n /**\n * Handle when a new output is added\n */\n function handleAddOutput(event, handle) {\n const output_area = handle.output_area;\n const output = handle.output;\n\n // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n return\n }\n\n const toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n\n if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n // store reference to embed id on output_area\n output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n }\n if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n const bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n const script_attrs = bk_div.children[0].attributes;\n for (let i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n }\n\n function register_renderer(events, OutputArea) {\n\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n const toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n const props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[toinsert.length - 1]);\n element.append(toinsert);\n return toinsert\n }\n\n /* Handle when an output is cleared or removed */\n events.on('clear_output.CodeCell', handleClearOutput);\n events.on('delete.Cell', handleClearOutput);\n\n /* Handle when a new output is added */\n events.on('output_added.OutputArea', handleAddOutput);\n\n /**\n * Register the mime type and append_mime function with output_area\n */\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n /* Is output safe? */\n safe: true,\n /* Index of renderer in `output_area.display_order` */\n index: 0\n });\n }\n\n // register the mime type if in Jupyter Notebook environment and previously unregistered\n if (root.Jupyter !== undefined) {\n const events = require('base/js/events');\n const OutputArea = require('notebook/js/outputarea').OutputArea;\n\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n }\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n const el = document.getElementById(\"1107\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\"];\n const css_urls = [];\n\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {\n }\n ];\n\n function run_inline_js() {\n if (root.Bokeh !== undefined || force === true) {\n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\nif (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(\"1107\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));", + "application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\nconst JS_MIME_TYPE = 'application/javascript';\n const HTML_MIME_TYPE = 'text/html';\n const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n const CLASS_NAME = 'output_bokeh rendered_html';\n\n /**\n * Render data to the DOM node\n */\n function render(props, node) {\n const script = document.createElement(\"script\");\n node.appendChild(script);\n }\n\n /**\n * Handle when an output is cleared or removed\n */\n function handleClearOutput(event, handle) {\n const cell = handle.cell;\n\n const id = cell.output_area._bokeh_element_id;\n const server_id = cell.output_area._bokeh_server_id;\n // Clean up Bokeh references\n if (id != null && id in Bokeh.index) {\n Bokeh.index[id].model.document.clear();\n delete Bokeh.index[id];\n }\n\n if (server_id !== undefined) {\n // Clean up Bokeh references\n const cmd_clean = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n cell.notebook.kernel.execute(cmd_clean, {\n iopub: {\n output: function(msg) {\n const id = msg.content.text.trim();\n if (id in Bokeh.index) {\n Bokeh.index[id].model.document.clear();\n delete Bokeh.index[id];\n }\n }\n }\n });\n // Destroy server and session\n const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n cell.notebook.kernel.execute(cmd_destroy);\n }\n }\n\n /**\n * Handle when a new output is added\n */\n function handleAddOutput(event, handle) {\n const output_area = handle.output_area;\n const output = handle.output;\n\n // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n return\n }\n\n const toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n\n if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n // store reference to embed id on output_area\n output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n }\n if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n const bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n const script_attrs = bk_div.children[0].attributes;\n for (let i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n }\n\n function register_renderer(events, OutputArea) {\n\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n const toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n const props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[toinsert.length - 1]);\n element.append(toinsert);\n return toinsert\n }\n\n /* Handle when an output is cleared or removed */\n events.on('clear_output.CodeCell', handleClearOutput);\n events.on('delete.Cell', handleClearOutput);\n\n /* Handle when a new output is added */\n events.on('output_added.OutputArea', handleAddOutput);\n\n /**\n * Register the mime type and append_mime function with output_area\n */\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n /* Is output safe? */\n safe: true,\n /* Index of renderer in `output_area.display_order` */\n index: 0\n });\n }\n\n // register the mime type if in Jupyter Notebook environment and previously unregistered\n if (root.Jupyter !== undefined) {\n const events = require('base/js/events');\n const OutputArea = require('notebook/js/outputarea').OutputArea;\n\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n }\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n const el = document.getElementById(\"1144\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\"];\n const css_urls = [];\n\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {\n }\n ];\n\n function run_inline_js() {\n if (root.Bokeh !== undefined || force === true) {\n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\nif (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(\"1144\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));", "application/vnd.bokehjs_load.v0+json": "" }, "metadata": {}, @@ -387,33 +387,32 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 29, "id": "ead4daf7", "metadata": { "scrolled": false }, "outputs": [ { - "data": { - "text/html": [ - "\n", - "
\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": "(function(root) {\n function embed_document(root) {\n const docs_json = {\"458dc79d-472d-4f36-92df-cc9c2d7d3fb7\":{\"defs\":[],\"roots\":{\"references\":[{\"attributes\":{\"below\":[{\"id\":\"1119\"}],\"center\":[{\"id\":\"1122\"},{\"id\":\"1126\"}],\"height\":800,\"left\":[{\"id\":\"1123\"}],\"renderers\":[{\"id\":\"1148\"}],\"title\":{\"id\":\"1109\"},\"toolbar\":{\"id\":\"1135\"},\"width\":1000,\"x_range\":{\"id\":\"1111\"},\"x_scale\":{\"id\":\"1115\"},\"y_range\":{\"id\":\"1113\"},\"y_scale\":{\"id\":\"1117\"}},\"id\":\"1108\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{},\"id\":\"1128\",\"type\":\"WheelZoomTool\"},{\"attributes\":{},\"id\":\"1165\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{},\"id\":\"1163\",\"type\":\"AllLabels\"},{\"attributes\":{},\"id\":\"1124\",\"type\":\"BasicTicker\"},{\"attributes\":{\"data\":{\"label\":[53,51,57,89,19,27,51,42,18,18,60,61,94,35,72,51,80,1,40,50,10,38,87,62,19,36,49,32,75,72,98,7,38,59,14,59,3,94,68,67,2,30,63,3,8,28,82,80,35,46,19,57,82,9,51,69,69,38,5,3,42,26,89,1,92,85,33,92,53,34,42,52,51,18,49,50,22,89,7,24,94,73,31,61,63,23,88,73,76,80,0,98,11,13,82,47,65,73,66,57,71,52,87,62,3,19,89,82,68,34,95,2,34,93,22,93,5,58,92,86,31,52,10,42,36,13,42,1,35,23,89,16,7,9,59,13,45,67,48,74,53,26,11,36,92,63,87,48,49,16,73,7,87,94,93,97,61,44,97,6,80,60,13,59,47,53,5,18,10,13,70,19,35,55,30,81,99,7,86,40,94,12,15,46,0,88,31,62,13,20,65,19,34,7,81,84,48,67,38,78,91,41,2,75,49,43,26,44,18,94,34,26,42,87,93,41,7,76,56,1,19,67,40,16,60,10,81,85,32,39,64,25,62,14,28,39,99,88,73,53,71,14,69,67,3,73,53,83,2,45,85,58,16,32,35,37,16,62,3,4,76,15,17,48,37,99,64,47,69,95,69,5,72,44,24,49,66,61,8,38,49,33,40,53,24,92,21,40,47,50,97,34,57,26,80,72,19,31,5,10,98,81,88,25,11,11,40,82,79,81,25,70,37,73,12,72,15,12,99,48,71,81,3,4,50,32,3,91,50,97,74,9,45,46,41,67,63,37,57,50,8,66,83,13,97,34,54,83,2,48,18,51,5,60,42,5,97,27,20,27,70,37,37,36,51,88,11,90,10,39,85,44,18,41,98,3,29,72,49,96,10,21,39,91,3,15,22,21,79,32,52,92,45,48,29,50,38,70,26,3,67,17,23,51,32,45,66,61,98,17,49,69,68,43,44,5,82,20,84,8,27,80,46,22,70,44,33,50,77,31,32,34,64,39,4,55,16,36,76,59,45,25,70,95,21,66,76,1,35,9,85,57,99,69,50,5,90,90,20,78,96,12,43,70,4,78,93,35,17,35,55,52,99,23,3,10,36,75,52,91,76,35,86,74,78,37,5,28,17,69,10,2,47,95,77,70,36,80,93,43,91,14,22,13,90,71,0,27,55,65,54,40,9,26,0,77,75,23,30,11,22,55,13,33,59,13,56,66,14,68,16,9,78,75,61,85,82,52,66,12,51,38,15,51,8,0,22,83,57,41,48,99,28,11,91,55,12,15,84,9,22,24,41,21,73,64,27,88,1,60,22,64,52,67,33,35,92,17,63,4,2,82,65,56,17,40,52,67,40,77,54,88,29,56,25,42,23,38,7,82,64,44,42,18,20,19,14,29,71,33,69,46,41,59,94,33,49,76,11,42,64,96,66,32,1,12,79,75,15,6,35,2,4,24,27,44,93,23,22,62,50,72,45,78,55,87,58,84,63,6,96,1,9,41,32,65,24,30,73,71,65,87,30,78,8,54,83,77,20,29,68,32,71,27,98,0,80,24,23,34,7,10,9,6,58,14,7,54,8,72,17,0,69,54,85,75,6,85,47,87,72,71,47,68,44,6,56,16,31,33,96,77,86,43,12,49,39,92,26,24,21,5,59,58,4,93,90,86,30,8,40,59,55,79,18,21,70,15,60,86,63,45,29,43,84,89,64,15,45,55,2,47,41,23,48,53,66,4,85,65,15,39,65,84,12,12,42,66,19,40,30,35,53,65,23,1,48,86,90,30,57,43,66,68,5,68,9,5,11,21,92,95,31,95,41,90,79,34,98,43,46,36,5,52,2,90,74,36,29,17,63,99,58,22,56,57,20,23,16,81,37,1,88,94,85,71,14,60,88,18,38,14,21,78,17,94,46,32,69,76,71,47,36,90,37,25,54,98,35,74,17,27,1,18,8,74,3,42,77,23,96,47,58,20,74,5,44,54,34,82,54,31,33,43,2,63,68,83,61,9,0,57,33,54,14,27,79,56,26,45,28,81,55,68,75,85,27,6,12,25,10,88,20,22,62,71,76,96,77,46,88,57,8,27,90,17,23,79,8,48,66,93,24,2,36,77,48,13,75,90,25,2,9,84,31,20,43,2,36,83,12,25,60,96,14,52,43,51,24,49,20,49,27,76,46,25,6,75,9,65,91,12,89,96,10,86,71,56,33,39,74,46,84,74,1,7,41,56,93,95,3,64,41,64,74,20,40,62,79,16,68,86,8,96,28,91,18,74,24,46,72,53,47,46,64,45,94,11,17,70,4,99,26,23,24,34,99,95,29,97,85,97,92,87,99,82,96,31,47,80,57,34,22,10,25,29,0,46,30,26,91,78,20,29,21,57,62,19,24,38,98,2,67,63,19,32,44,60,24,75,39,1,59,77,83,39,2,28,83,13,84,79,67,97,14,50,93,49,31,84,79,29,84,48,59,68,56,74,10,50,25,30,19,83,31,58,89,64,3,39,37,58,83,29,95,53,26,16,1,25,97,81,68,92,21,42,72,7,13,8,9,91,1,2,79,4,89,23,58,5,11,15,38,28,81,62,5,32,63,53,50,3,7,61,67,14,98,54,1,1,14,18,85,99,69,46,43,20,63,97,37,85,59,58,94,47,22,97,23,9,5,13,87,72,11,22,52,0,13,11,22,0,70,1,39,9,38,29,96,7,14,51,71,74,22,17,48,41,90,61,97,5,36,42,83,45,91,32,68,76,84,78,66,49,67,63,29,5,9,19,50,10,79,51,86,80,2,76,88,7,89,15,4,46,47,41,57,39,16,81,63,17,82,71,27,3,49,64,50,95,61,87,1,21,73,74,24,48,25,44,19,8,20,68,19,6,28,59,98,46,32,53,9,30,76,90,75,73,79,77,38,36,58,83,1,16,46,14,21,35,10,7,96,73,18,70,42,93,24,61,72,64,13,15,58,76,31,65,59,82,90,38,32,42,99,57,33,37,10,69,95,10,41,26,45,33,80,21,51,41,68,22,47,26,88,71,17,24,99,74,24,14,91,47,13,52,36,34,18,36,60,55,27,98,12,57,18,65,60,64,16,79,99,98,40,12,44,1,81,93,48,77,23,62,72,8,35,54,5,94,59,75,28,67,30,67,23,97,12,15,92,84,17,3,60,86,37,27,2,49,49,2,12,13,20,56,74,2,25,14,52,55,84,75,23,91,95,29,16,33,44,92,93,54,29,24,6,4,3,26,45,0,43,44,40,82,9,20,21,11,69,82,5,87,86,70,4,56,34,19,92,48,53,56,34,30,57,75,28,77,88,3,55,66,8,89,53,7,27,25,40,93,40,50,68,25,27,78,35,43,67,66,2,2,54,85,71,37,42,66,63,32,38,34,65,62,45,26,51,39,23,17,81,72,10,83,62,31,53,85,52,25,8,31,80,1,90,89,96,64,11,5,50,31,54,94,78,55,68,34,30,3,35],\"label_desc\":[\"bird\",\"accident\",\"cow\",\"medicine\",\"black\",\"orange\",\"accident\",\"kiss\",\"all\",\"all\",\"doctor\",\"eat\",\"purple\",\"can\",\"short\",\"accident\",\"but\",\"drink\",\"hat\",\"wrong\",\"deaf\",\"fish\",\"jacket\",\"enjoy\",\"black\",\"dog\",\"white\",\"bed\",\"work\",\"short\",\"tell\",\"who\",\"fish\",\"dark\",\"thin\",\"dark\",\"before\",\"purple\",\"pizza\",\"pink\",\"computer\",\"what\",\"forget\",\"before\",\"candy\",\"table\",\"city\",\"but\",\"can\",\"shirt\",\"black\",\"cow\",\"city\",\"cousin\",\"accident\",\"play\",\"play\",\"fish\",\"go\",\"before\",\"kiss\",\"now\",\"medicine\",\"drink\",\"paper\",\"full\",\"blue\",\"paper\",\"bird\",\"bowling\",\"kiss\",\"apple\",\"accident\",\"all\",\"white\",\"wrong\",\"hot\",\"medicine\",\"who\",\"many\",\"purple\",\"time\",\"woman\",\"eat\",\"forget\",\"like\",\"letter\",\"time\",\"africa\",\"but\",\"book\",\"tell\",\"fine\",\"no\",\"city\",\"study\",\"last\",\"time\",\"meet\",\"cow\",\"secretary\",\"apple\",\"jacket\",\"enjoy\",\"before\",\"black\",\"medicine\",\"city\",\"pizza\",\"bowling\",\"right\",\"computer\",\"bowling\",\"pull\",\"hot\",\"pull\",\"go\",\"dance\",\"paper\",\"how\",\"woman\",\"apple\",\"deaf\",\"kiss\",\"dog\",\"no\",\"kiss\",\"drink\",\"can\",\"like\",\"medicine\",\"year\",\"who\",\"cousin\",\"dark\",\"no\",\"man\",\"pink\",\"tall\",\"want\",\"bird\",\"now\",\"fine\",\"dog\",\"paper\",\"forget\",\"jacket\",\"tall\",\"white\",\"year\",\"time\",\"who\",\"jacket\",\"purple\",\"pull\",\"son\",\"eat\",\"later\",\"son\",\"clothes\",\"but\",\"doctor\",\"no\",\"dark\",\"study\",\"bird\",\"go\",\"all\",\"deaf\",\"no\",\"school\",\"black\",\"can\",\"color\",\"what\",\"cheat\",\"thursday\",\"who\",\"how\",\"hat\",\"purple\",\"help\",\"walk\",\"shirt\",\"book\",\"letter\",\"woman\",\"enjoy\",\"no\",\"cool\",\"last\",\"black\",\"bowling\",\"who\",\"cheat\",\"decide\",\"tall\",\"pink\",\"fish\",\"birthday\",\"paint\",\"hearing\",\"computer\",\"work\",\"white\",\"language\",\"now\",\"later\",\"all\",\"purple\",\"bowling\",\"now\",\"kiss\",\"jacket\",\"pull\",\"hearing\",\"who\",\"africa\",\"corn\",\"drink\",\"black\",\"pink\",\"hat\",\"year\",\"doctor\",\"deaf\",\"cheat\",\"full\",\"bed\",\"graduate\",\"give\",\"mother\",\"enjoy\",\"thin\",\"table\",\"graduate\",\"thursday\",\"letter\",\"time\",\"bird\",\"secretary\",\"thin\",\"play\",\"pink\",\"before\",\"time\",\"bird\",\"cook\",\"computer\",\"man\",\"full\",\"dance\",\"year\",\"bed\",\"can\",\"family\",\"year\",\"enjoy\",\"before\",\"chair\",\"africa\",\"walk\",\"yes\",\"tall\",\"family\",\"thursday\",\"give\",\"study\",\"play\",\"right\",\"play\",\"go\",\"short\",\"later\",\"many\",\"white\",\"meet\",\"eat\",\"candy\",\"fish\",\"white\",\"blue\",\"hat\",\"bird\",\"many\",\"paper\",\"finish\",\"hat\",\"study\",\"wrong\",\"son\",\"bowling\",\"cow\",\"now\",\"but\",\"short\",\"black\",\"woman\",\"go\",\"deaf\",\"tell\",\"cheat\",\"letter\",\"mother\",\"fine\",\"fine\",\"hat\",\"city\",\"brown\",\"cheat\",\"mother\",\"school\",\"family\",\"time\",\"help\",\"short\",\"walk\",\"help\",\"thursday\",\"tall\",\"secretary\",\"cheat\",\"before\",\"chair\",\"wrong\",\"bed\",\"before\",\"paint\",\"wrong\",\"son\",\"want\",\"cousin\",\"man\",\"shirt\",\"hearing\",\"pink\",\"forget\",\"family\",\"cow\",\"wrong\",\"candy\",\"meet\",\"cook\",\"no\",\"son\",\"bowling\",\"change\",\"cook\",\"computer\",\"tall\",\"all\",\"accident\",\"go\",\"doctor\",\"kiss\",\"go\",\"son\",\"orange\",\"cool\",\"orange\",\"school\",\"family\",\"family\",\"dog\",\"accident\",\"letter\",\"fine\",\"need\",\"deaf\",\"graduate\",\"full\",\"later\",\"all\",\"hearing\",\"tell\",\"before\",\"thanksgiving\",\"short\",\"white\",\"same\",\"deaf\",\"finish\",\"graduate\",\"paint\",\"before\",\"walk\",\"hot\",\"finish\",\"brown\",\"bed\",\"apple\",\"paper\",\"man\",\"tall\",\"thanksgiving\",\"wrong\",\"fish\",\"school\",\"now\",\"before\",\"pink\",\"yes\",\"like\",\"accident\",\"bed\",\"man\",\"meet\",\"eat\",\"tell\",\"yes\",\"white\",\"play\",\"pizza\",\"language\",\"later\",\"go\",\"city\",\"cool\",\"decide\",\"candy\",\"orange\",\"but\",\"shirt\",\"hot\",\"school\",\"later\",\"blue\",\"wrong\",\"basketball\",\"woman\",\"bed\",\"bowling\",\"give\",\"graduate\",\"chair\",\"color\",\"year\",\"dog\",\"africa\",\"dark\",\"man\",\"mother\",\"school\",\"right\",\"finish\",\"meet\",\"africa\",\"drink\",\"can\",\"cousin\",\"full\",\"cow\",\"thursday\",\"play\",\"wrong\",\"go\",\"need\",\"need\",\"cool\",\"birthday\",\"same\",\"help\",\"language\",\"school\",\"chair\",\"birthday\",\"pull\",\"can\",\"yes\",\"can\",\"color\",\"apple\",\"thursday\",\"like\",\"before\",\"deaf\",\"dog\",\"work\",\"apple\",\"paint\",\"africa\",\"can\",\"how\",\"want\",\"birthday\",\"family\",\"go\",\"table\",\"yes\",\"play\",\"deaf\",\"computer\",\"study\",\"right\",\"basketball\",\"school\",\"dog\",\"but\",\"pull\",\"language\",\"paint\",\"thin\",\"hot\",\"no\",\"need\",\"secretary\",\"book\",\"orange\",\"color\",\"last\",\"change\",\"hat\",\"cousin\",\"now\",\"book\",\"basketball\",\"work\",\"like\",\"what\",\"fine\",\"hot\",\"color\",\"no\",\"blue\",\"dark\",\"no\",\"corn\",\"meet\",\"thin\",\"pizza\",\"year\",\"cousin\",\"birthday\",\"work\",\"eat\",\"full\",\"city\",\"apple\",\"meet\",\"help\",\"accident\",\"fish\",\"walk\",\"accident\",\"candy\",\"book\",\"hot\",\"cook\",\"cow\",\"hearing\",\"tall\",\"thursday\",\"table\",\"fine\",\"paint\",\"color\",\"help\",\"walk\",\"decide\",\"cousin\",\"hot\",\"many\",\"hearing\",\"finish\",\"time\",\"give\",\"orange\",\"letter\",\"drink\",\"doctor\",\"hot\",\"give\",\"apple\",\"pink\",\"blue\",\"can\",\"paper\",\"yes\",\"forget\",\"chair\",\"computer\",\"city\",\"last\",\"corn\",\"yes\",\"hat\",\"apple\",\"pink\",\"hat\",\"basketball\",\"change\",\"letter\",\"thanksgiving\",\"corn\",\"mother\",\"kiss\",\"like\",\"fish\",\"who\",\"city\",\"give\",\"later\",\"kiss\",\"all\",\"cool\",\"black\",\"thin\",\"thanksgiving\",\"secretary\",\"blue\",\"play\",\"shirt\",\"hearing\",\"dark\",\"purple\",\"blue\",\"white\",\"africa\",\"fine\",\"kiss\",\"give\",\"same\",\"meet\",\"bed\",\"drink\",\"help\",\"brown\",\"work\",\"walk\",\"clothes\",\"can\",\"computer\",\"chair\",\"many\",\"orange\",\"later\",\"pull\",\"like\",\"hot\",\"enjoy\",\"wrong\",\"short\",\"man\",\"birthday\",\"color\",\"jacket\",\"dance\",\"decide\",\"forget\",\"clothes\",\"same\",\"drink\",\"cousin\",\"hearing\",\"bed\",\"last\",\"many\",\"what\",\"time\",\"secretary\",\"last\",\"jacket\",\"what\",\"birthday\",\"candy\",\"change\",\"cook\",\"basketball\",\"cool\",\"thanksgiving\",\"pizza\",\"bed\",\"secretary\",\"orange\",\"tell\",\"book\",\"but\",\"many\",\"like\",\"bowling\",\"who\",\"deaf\",\"cousin\",\"clothes\",\"dance\",\"thin\",\"who\",\"change\",\"candy\",\"short\",\"yes\",\"book\",\"play\",\"change\",\"full\",\"work\",\"clothes\",\"full\",\"study\",\"jacket\",\"short\",\"secretary\",\"study\",\"pizza\",\"later\",\"clothes\",\"corn\",\"year\",\"woman\",\"blue\",\"same\",\"basketball\",\"how\",\"language\",\"help\",\"white\",\"graduate\",\"paper\",\"now\",\"many\",\"finish\",\"go\",\"dark\",\"dance\",\"chair\",\"pull\",\"need\",\"how\",\"what\",\"candy\",\"hat\",\"dark\",\"color\",\"brown\",\"all\",\"finish\",\"school\",\"walk\",\"doctor\",\"how\",\"forget\",\"man\",\"thanksgiving\",\"language\",\"decide\",\"medicine\",\"give\",\"walk\",\"man\",\"color\",\"computer\",\"study\",\"hearing\",\"like\",\"tall\",\"bird\",\"meet\",\"chair\",\"full\",\"last\",\"walk\",\"graduate\",\"last\",\"decide\",\"help\",\"help\",\"kiss\",\"meet\",\"black\",\"hat\",\"what\",\"can\",\"bird\",\"last\",\"like\",\"drink\",\"tall\",\"how\",\"need\",\"what\",\"cow\",\"language\",\"meet\",\"pizza\",\"go\",\"pizza\",\"cousin\",\"go\",\"fine\",\"finish\",\"paper\",\"right\",\"woman\",\"right\",\"hearing\",\"need\",\"brown\",\"bowling\",\"tell\",\"language\",\"shirt\",\"dog\",\"go\",\"apple\",\"computer\",\"need\",\"want\",\"dog\",\"thanksgiving\",\"yes\",\"forget\",\"thursday\",\"dance\",\"hot\",\"corn\",\"cow\",\"cool\",\"like\",\"year\",\"cheat\",\"family\",\"drink\",\"letter\",\"purple\",\"full\",\"secretary\",\"thin\",\"doctor\",\"letter\",\"all\",\"fish\",\"thin\",\"finish\",\"birthday\",\"yes\",\"purple\",\"shirt\",\"bed\",\"play\",\"africa\",\"secretary\",\"study\",\"dog\",\"need\",\"family\",\"mother\",\"change\",\"tell\",\"can\",\"want\",\"yes\",\"orange\",\"drink\",\"all\",\"candy\",\"want\",\"before\",\"kiss\",\"basketball\",\"like\",\"same\",\"study\",\"dance\",\"cool\",\"want\",\"go\",\"later\",\"change\",\"bowling\",\"city\",\"change\",\"woman\",\"blue\",\"language\",\"computer\",\"forget\",\"pizza\",\"cook\",\"eat\",\"cousin\",\"book\",\"cow\",\"blue\",\"change\",\"thin\",\"orange\",\"brown\",\"corn\",\"now\",\"man\",\"table\",\"cheat\",\"color\",\"pizza\",\"work\",\"full\",\"orange\",\"clothes\",\"help\",\"mother\",\"deaf\",\"letter\",\"cool\",\"hot\",\"enjoy\",\"secretary\",\"africa\",\"same\",\"basketball\",\"shirt\",\"letter\",\"cow\",\"candy\",\"orange\",\"need\",\"yes\",\"like\",\"brown\",\"candy\",\"tall\",\"meet\",\"pull\",\"many\",\"computer\",\"dog\",\"basketball\",\"tall\",\"no\",\"work\",\"need\",\"mother\",\"computer\",\"cousin\",\"decide\",\"woman\",\"cool\",\"language\",\"computer\",\"dog\",\"cook\",\"help\",\"mother\",\"doctor\",\"same\",\"thin\",\"apple\",\"language\",\"accident\",\"many\",\"white\",\"cool\",\"white\",\"orange\",\"africa\",\"shirt\",\"mother\",\"clothes\",\"work\",\"cousin\",\"last\",\"paint\",\"help\",\"medicine\",\"same\",\"deaf\",\"how\",\"secretary\",\"corn\",\"blue\",\"graduate\",\"want\",\"shirt\",\"decide\",\"want\",\"drink\",\"who\",\"hearing\",\"corn\",\"pull\",\"right\",\"before\",\"give\",\"hearing\",\"give\",\"want\",\"cool\",\"hat\",\"enjoy\",\"brown\",\"year\",\"pizza\",\"how\",\"candy\",\"same\",\"table\",\"paint\",\"all\",\"want\",\"many\",\"shirt\",\"short\",\"bird\",\"study\",\"shirt\",\"give\",\"man\",\"purple\",\"fine\",\"yes\",\"school\",\"chair\",\"thursday\",\"now\",\"like\",\"many\",\"bowling\",\"thursday\",\"right\",\"thanksgiving\",\"son\",\"full\",\"son\",\"paper\",\"jacket\",\"thursday\",\"city\",\"same\",\"woman\",\"study\",\"but\",\"cow\",\"bowling\",\"hot\",\"deaf\",\"mother\",\"thanksgiving\",\"book\",\"shirt\",\"what\",\"now\",\"paint\",\"birthday\",\"cool\",\"thanksgiving\",\"finish\",\"cow\",\"enjoy\",\"black\",\"many\",\"fish\",\"tell\",\"computer\",\"pink\",\"forget\",\"black\",\"bed\",\"later\",\"doctor\",\"many\",\"work\",\"graduate\",\"drink\",\"dark\",\"basketball\",\"cook\",\"graduate\",\"computer\",\"table\",\"cook\",\"no\",\"decide\",\"brown\",\"pink\",\"son\",\"thin\",\"wrong\",\"pull\",\"white\",\"woman\",\"decide\",\"brown\",\"thanksgiving\",\"decide\",\"tall\",\"dark\",\"pizza\",\"corn\",\"want\",\"deaf\",\"wrong\",\"mother\",\"what\",\"black\",\"cook\",\"woman\",\"dance\",\"medicine\",\"give\",\"before\",\"graduate\",\"family\",\"dance\",\"cook\",\"thanksgiving\",\"right\",\"bird\",\"now\",\"year\",\"drink\",\"mother\",\"son\",\"cheat\",\"pizza\",\"paper\",\"finish\",\"kiss\",\"short\",\"who\",\"no\",\"candy\",\"cousin\",\"paint\",\"drink\",\"computer\",\"brown\",\"chair\",\"medicine\",\"like\",\"dance\",\"go\",\"fine\",\"walk\",\"fish\",\"table\",\"cheat\",\"enjoy\",\"go\",\"bed\",\"forget\",\"bird\",\"wrong\",\"before\",\"who\",\"eat\",\"pink\",\"thin\",\"tell\",\"change\",\"drink\",\"drink\",\"thin\",\"all\",\"full\",\"thursday\",\"play\",\"shirt\",\"language\",\"cool\",\"forget\",\"son\",\"family\",\"full\",\"dark\",\"dance\",\"purple\",\"study\",\"hot\",\"son\",\"like\",\"cousin\",\"go\",\"no\",\"jacket\",\"short\",\"fine\",\"hot\",\"apple\",\"book\",\"no\",\"fine\",\"hot\",\"book\",\"school\",\"drink\",\"graduate\",\"cousin\",\"fish\",\"thanksgiving\",\"same\",\"who\",\"thin\",\"accident\",\"secretary\",\"want\",\"hot\",\"yes\",\"tall\",\"hearing\",\"need\",\"eat\",\"son\",\"go\",\"dog\",\"kiss\",\"cook\",\"man\",\"paint\",\"bed\",\"pizza\",\"africa\",\"decide\",\"birthday\",\"meet\",\"white\",\"pink\",\"forget\",\"thanksgiving\",\"go\",\"cousin\",\"black\",\"wrong\",\"deaf\",\"brown\",\"accident\",\"how\",\"but\",\"computer\",\"africa\",\"letter\",\"who\",\"medicine\",\"walk\",\"chair\",\"shirt\",\"study\",\"hearing\",\"cow\",\"graduate\",\"year\",\"cheat\",\"forget\",\"yes\",\"city\",\"secretary\",\"orange\",\"before\",\"white\",\"give\",\"wrong\",\"right\",\"eat\",\"jacket\",\"drink\",\"finish\",\"time\",\"want\",\"many\",\"tall\",\"mother\",\"later\",\"black\",\"candy\",\"cool\",\"pizza\",\"black\",\"clothes\",\"table\",\"dark\",\"tell\",\"shirt\",\"bed\",\"bird\",\"cousin\",\"what\",\"africa\",\"need\",\"work\",\"time\",\"brown\",\"basketball\",\"fish\",\"dog\",\"dance\",\"cook\",\"drink\",\"year\",\"shirt\",\"thin\",\"finish\",\"can\",\"deaf\",\"who\",\"same\",\"time\",\"all\",\"school\",\"kiss\",\"pull\",\"many\",\"eat\",\"short\",\"give\",\"no\",\"walk\",\"dance\",\"africa\",\"woman\",\"last\",\"dark\",\"city\",\"need\",\"fish\",\"bed\",\"kiss\",\"thursday\",\"cow\",\"blue\",\"family\",\"deaf\",\"play\",\"right\",\"deaf\",\"hearing\",\"now\",\"man\",\"blue\",\"but\",\"finish\",\"accident\",\"hearing\",\"pizza\",\"hot\",\"study\",\"now\",\"letter\",\"secretary\",\"yes\",\"many\",\"thursday\",\"want\",\"many\",\"thin\",\"paint\",\"study\",\"no\",\"apple\",\"dog\",\"bowling\",\"all\",\"dog\",\"doctor\",\"color\",\"orange\",\"tell\",\"help\",\"cow\",\"all\",\"last\",\"doctor\",\"give\",\"year\",\"brown\",\"thursday\",\"tell\",\"hat\",\"help\",\"later\",\"drink\",\"cheat\",\"pull\",\"tall\",\"basketball\",\"like\",\"enjoy\",\"short\",\"candy\",\"can\",\"change\",\"go\",\"purple\",\"dark\",\"work\",\"table\",\"pink\",\"what\",\"pink\",\"like\",\"son\",\"help\",\"walk\",\"paper\",\"decide\",\"yes\",\"before\",\"doctor\",\"how\",\"family\",\"orange\",\"computer\",\"white\",\"white\",\"computer\",\"help\",\"no\",\"cool\",\"corn\",\"want\",\"computer\",\"mother\",\"thin\",\"apple\",\"color\",\"decide\",\"work\",\"like\",\"paint\",\"right\",\"thanksgiving\",\"year\",\"blue\",\"later\",\"paper\",\"pull\",\"change\",\"thanksgiving\",\"many\",\"clothes\",\"chair\",\"before\",\"now\",\"man\",\"book\",\"language\",\"later\",\"hat\",\"city\",\"cousin\",\"cool\",\"finish\",\"fine\",\"play\",\"city\",\"go\",\"jacket\",\"how\",\"school\",\"chair\",\"corn\",\"bowling\",\"black\",\"paper\",\"tall\",\"bird\",\"corn\",\"bowling\",\"what\",\"cow\",\"work\",\"table\",\"basketball\",\"letter\",\"before\",\"color\",\"meet\",\"candy\",\"medicine\",\"bird\",\"who\",\"orange\",\"mother\",\"hat\",\"pull\",\"hat\",\"wrong\",\"pizza\",\"mother\",\"orange\",\"birthday\",\"can\",\"language\",\"pink\",\"meet\",\"computer\",\"computer\",\"change\",\"full\",\"secretary\",\"family\",\"kiss\",\"meet\",\"forget\",\"bed\",\"fish\",\"bowling\",\"last\",\"enjoy\",\"man\",\"now\",\"accident\",\"graduate\",\"like\",\"yes\",\"cheat\",\"short\",\"deaf\",\"cook\",\"enjoy\",\"woman\",\"bird\",\"full\",\"apple\",\"mother\",\"candy\",\"woman\",\"but\",\"drink\",\"need\",\"medicine\",\"same\",\"give\",\"fine\",\"go\",\"wrong\",\"woman\",\"change\",\"purple\",\"birthday\",\"color\",\"pizza\",\"bowling\",\"what\",\"before\",\"can\"],\"split\":[\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\",\"val\"],\"video_id\":[6343,639,13697,35460,6476,40115,631,31757,1999,1992,17023,18323,70247,8949,70355,65009,8435,17722,69359,64089,14888,22121,30843,19259,6478,68035,63209,5632,63792,51236,57278,63227,22114,14685,57943,14669,5740,45438,42960,42835,12332,62968,65761,70348,68018,56552,10904,8429,8936,51069,6455,13698,10894,13633,629,69433,68133,22115,24970,5729,31753,70345,35453,17712,41037,23771,6839,68127,6334,65241,31758,2999,633,1998,63203,64091,28123,35462,63231,34829,45432,58499,63673,18332,68054,33266,68089,58502,1386,8431,70266,57273,21887,38536,10902,55369,32257,58498,35517,13695,50042,3000,30835,70051,5724,6474,35457,10899,42959,7400,48107,12320,7394,45271,28125,66351,24946,65434,41026,28205,63668,65085,14885,31755,17095,38544,31749,17727,65294,33269,35467,64222,63225,13636,14671,38524,34737,42841,66591,62251,70107,38982,21886,65507,41034,22954,30849,56844,63202,64221,58508,69534,30831,45436,69439,66531,18325,32319,53268,11310,8437,17026,69411,14674,55370,6331,24948,1991,68033,38482,49595,6481,8945,11773,62987,10149,66637,63242,28204,26712,45443,27209,62164,51071,7075,32954,66798,19267,38530,13196,32263,6472,7395,63239,65341,65449,56846,42829,22124,6355,40837,26974,12335,63789,63208,68085,39000,32322,1988,45434,7402,39003,31750,30834,45265,26972,63232,1384,65408,17713,6477,42830,26719,64212,17016,14900,10158,23766,5638,25318,24643,36932,68046,57942,56564,25324,58370,32946,58497,6332,50036,57950,43180,66296,5730,58503,6341,13160,12316,34732,23774,70152,64210,65162,8955,20983,64209,19264,5731,9849,1385,62169,64281,56849,20987,58367,24651,68162,43173,48108,43170,24954,51225,66014,34826,69533,68099,18331,8927,22109,63214,6843,26721,6335,34839,41008,68050,26717,66575,64094,53279,7389,13699,38994,8424,51233,6484,63672,24955,14898,57282,65342,32949,36946,68048,21883,26715,10901,7961,10160,36930,49577,20982,69511,27216,51223,62163,27215,58368,56850,50040,10157,5744,65328,64085,5637,5728,40847,64086,53273,62257,13641,66099,51056,26983,70246,70376,20981,13681,70132,8926,66112,13154,38534,53269,7391,9953,13158,12336,56843,1987,625,24857,17014,31756,24973,53274,69422,13200,40117,69455,20986,20989,17097,632,32953,21869,37891,14883,25333,23782,32338,2000,26975,57284,5746,57641,51224,63212,49186,14896,21943,25323,40841,68007,62168,28110,21954,7963,65161,65084,41025,69395,56845,57632,64097,22130,49599,39006,5734,68132,69546,33279,635,5642,34734,35523,18333,57277,64295,63211,43166,42974,32163,32337,24941,10893,13198,70119,8916,40114,8433,51067,69368,49597,32320,6833,64088,5233,63679,5639,7401,24648,25326,9869,11772,66816,17085,1392,14676,34743,36934,49596,48120,70361,35520,65029,17734,8938,13640,23775,13710,58361,43174,64090,24960,37883,37886,13197,6363,49178,69364,32167,49602,9855,6360,45261,8952,64294,69257,11777,3002,58362,33274,5739,14895,17091,63806,3001,40835,1388,8950,28201,62249,6368,20978,24971,70323,64280,43169,14884,12329,55365,48126,69225,49598,65506,68016,45252,32158,40844,57919,28115,38532,37889,50048,7076,40126,11768,32260,9957,26688,13646,39001,70212,5234,63803,33273,62984,21872,28107,11752,38541,6822,14675,38527,13333,35515,57934,42966,64224,13632,6366,63793,69307,65792,10900,68003,35521,27213,634,22126,62152,618,8917,7099,28108,13167,13696,68070,56839,66639,56563,21885,40836,11767,27217,62160,15037,13635,28112,34825,26980,21942,68171,69343,40122,32959,68042,17020,28109,24638,3003,69430,69238,8942,41029,64293,22952,9851,12330,10888,32255,69282,64287,26726,3008,42840,26739,5241,9945,32945,57647,65409,69402,31765,33283,22120,63229,10892,24645,32325,31767,1995,13216,65200,57939,57638,50039,6842,43175,51064,26981,69290,69440,6834,63205,1387,21890,31759,24642,49184,35506,5641,17723,65891,7973,63799,62170,11316,8948,12328,9854,34830,70310,32333,45270,33285,28116,19265,64082,51227,66098,70359,11770,30832,14623,15035,22965,11309,49176,17721,13648,70016,5628,32246,34824,62975,58488,50037,32248,30842,62988,6365,8921,9968,13156,5227,69281,57631,42972,5630,50043,40123,57283,69241,8434,34823,33268,7397,63236,14855,13643,68024,14633,57940,68183,70379,8929,51231,64275,7074,43179,9967,23772,63790,11311,23776,55366,30840,51232,50050,55364,66297,32335,11305,13323,68190,63669,6835,49181,5231,28214,32154,27219,63210,25339,70211,39002,34822,21951,24965,65440,68032,9856,45262,37882,28202,62964,8920,26724,65439,11774,7967,65043,21949,70207,68177,17017,28203,22962,34742,57628,32164,15034,35458,24636,62172,34738,11780,68028,55361,26976,33271,56842,6337,35512,70230,23767,32249,62171,25329,32254,15039,27207,27214,31746,35514,6471,26713,69531,8951,65187,68086,33282,17710,56841,69370,37892,62970,13704,66008,35513,42962,24950,42969,13630,69345,21870,21944,41035,48106,63666,48124,26986,37888,7957,65242,57291,32156,51072,69298,24943,69213,12313,37881,62254,17083,57629,64284,22953,58359,14628,28122,13325,13707,65403,69389,64211,10161,20976,17729,32956,45435,23768,50052,66606,17015,70325,1986,22116,57936,21933,6367,64292,45440,51054,5634,43176,1382,50041,55375,17076,70237,20992,36929,9950,57288,8947,68178,64283,40119,17709,69206,8915,62253,5733,31754,65145,68093,49180,55368,14625,13214,62259,24952,32324,9966,7393,69269,9960,63665,6845,66007,12317,68053,42953,70030,18316,13634,68011,13706,6840,9955,57941,40124,65263,13334,38990,34746,56560,10146,11775,42967,63802,23777,40121,11315,65889,36939,14899,32951,13201,28121,19258,50044,1398,49179,5230,51066,32950,13701,8909,40118,37887,68192,70299,7962,65300,66592,35516,45267,34834,12319,17087,5232,56837,38540,63788,37884,36942,12315,13638,15031,63667,13209,68084,12318,17092,13165,27218,36944,70049,49173,57953,3005,32160,626,34831,63201,13202,63207,40116,1391,51063,36933,11314,63795,13639,32253,40843,27206,35455,49185,14886,28210,50046,13337,6841,70176,62241,51060,15043,62247,17730,63237,26985,13329,45268,48117,5732,24655,26973,24660,62245,13213,26714,19261,7971,64219,42958,28211,70326,49183,56567,40840,1912,69524,34828,51070,51220,6339,55373,51068,24639,34744,68137,21878,64296,68145,9850,58366,38991,33286,34837,7399,58363,48115,57642,70335,70029,53270,41032,30841,58365,10898,49182,63662,55372,8426,13705,7392,70270,14893,36938,57639,7069,51061,62966,69413,40816,6371,13199,57643,21952,69283,19269,6480,34833,22117,57276,12312,42831,22960,6486,5631,66015,17018,34836,63804,25330,17733,14683,5243,13161,25321,12311,56566,68029,38539,15033,69252,42836,53271,57935,64092,45264,70245,63664,65450,7968,57634,15040,56852,14672,42977,13328,62250,14887,64087,36940,62982,69236,13164,63677,14621,35463,24657,5727,25325,20980,14624,13162,57635,68142,6330,39004,66818,17728,36941,53277,10159,42963,41033,21950,31764,51221,63226,38533,8918,13637,40845,17711,12326,70242,68019,35454,33277,14627,24951,21891,62159,22125,56557,10166,19266,24962,65163,22963,69233,64095,5741,63240,18324,42833,57948,57287,9956,69302,17731,57949,1996,23778,66638,43167,51059,32155,70271,22964,53275,20988,23779,14673,14630,45433,55363,28120,53258,33278,65415,24940,38531,68079,51226,21884,28119,70309,7070,38529,70234,28074,68012,49600,65540,25322,13647,22113,57633,49188,63238,57937,623,66441,62248,28111,64297,56838,26971,37890,18335,66532,24947,17093,31762,13157,66097,40842,5636,69431,1393,15038,6369,35511,63191,42843,22961,57645,24961,13642,6482,64093,65445,7966,627,70295,8425,12338,1395,32947,63228,35452,62158,9848,51081,55362,65884,13708,65843,64213,10151,22955,64288,10896,50038,66246,5749,68182,24649,64084,48105,68044,30830,17720,21955,66644,62256,69396,56848,36936,32326,6483,65298,13203,42971,70244,11313,56556,14680,57285,51057,5629,6326,13631,62944,1383,37885,63791,70356,7960,5238,69325,17090,14622,13168,70173,64218,51058,57933,21941,8937,14894,63219,49174,58504,68001,49606,31763,45263,34832,18329,51235,24652,68110,62173,14631,1394,63675,66010,14682,10895,37879,65731,5644,31752,70026,13703,65216,69316,14903,43168,48109,14882,26984,38999,34733,6832,8421,21953,628,26982,42964,28118,55371,68114,32955,50045,64291,34827,66640,62246,70308,66607,40834,55356,38525,2997,17084,7383,1997,17086,17019,68027,68122,57286,65890,13702,2003,32250,17013,24641,64201,7969,58360,57289,26723,27208,32321,17724,10148,70378,56840,5229,33267,19255,51206,8925,8935,9970,24956,66355,14681,66804,56579,42827,62967,42832,33281,53276,27221,62175,41030,15041,64300,5747,17007,28212,20979,70249,12333,63204,63200,12327,27194,38538,13217,13326,62244,12314,36927,57947,3006,11778,15032,63769,33270,68125,48114,57630,70306,68010,32334,41028,45269,9963,57640,34835,11330,70263,5750,38995,34736,7068,32146,32323,26722,65362,70332,13208,21945,21874,43171,65363,24969,30833,28187,49603,9847,13309,7390,6473,41027,56835,6340,13327,7388,62965,13700,63801,56558,5239,32948,5743,11769,35509,8924,35456,6338,63230,40130,36931,26741,45273,68068,70296,42956,66147,40129,6359,8944,32157,42838,35518,12331,12306,9949,23773,50049,65677,31751,35519,22967,5633,22127,7396,32261,19260,34685,38997,624,25332,33280,64298,10147,66469,70015,13155,19257,68187,6333,23769,65086,36937,8919,63676,8432,17725,37894,35461,49175,24640,21871,65824,68189,66799,9954,45439,70357,69274,42961,7398,62979,5742,8946],\"x\":{\"__ndarray__\":\"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\",\"dtype\":\"float32\",\"order\":\"little\",\"shape\":[1533]},\"y\":{\"__ndarray__\":\"bt7Rwe+lR8F82rTBB0SFQSoWBcK6menBWoiLQZBW8EAQnpJAZqyLQKWxQUEEJsRAZBc6wZCKw0Gcc9ZB1JhFwVhRYEHP8cLBdhoUwCn0hMFhAEhBCO8awfUlWkEB4eLAfezAwbNQEcDmaR3BKcpYQecsrUFLkthBMSnswaDM/cGdcirBEOurvy+q8MHnWVW+VXwQQA1aVcH354fBQl7ZwXVy2UHdswjBFdeMwaLWUcHs3sHBSYeDwCRuxr5dtlRBb7W4QbePocHX6AHCeJSkQWRJvz9DvkBBPdNKwfLMgkHxg35BugkhwcRv4EFw1pFBiua/QL1wjMHRqY5BnZ5sQfn7n0ERH0/B6NoOQHC8qEHAusfBxLI2wdCu+UDxeQnC8J6PwW5mE0EEbqvBGyqKwRumMMFO/YVBOVHlwTAFesGOWP3AY1zVQcnqocCce8FAltqRwT1vuMDLc5ZBq0fOQYrAz8HY5OtBNKXKvyS/78HbhOo/nYMFQglplL5+XzNB7naQwWGt1UGKGc1BMd29we6ypkGUNQvCU91ZQfw59MBEq5fB9aSzwWN7gUHbjH6/oUp6wSebZcHE+7VBnXDRQW+OXcEj+8E/hP0fweNJtT8H+/FBV329Pm0prEF22UFBzpgwwLRt8j4vsCBBfY0QP0cNMMDy1gxC4Df0QGjFeEG65rZBtb60wM4Mi0F4zDxBv5HxwQbEREF74CDASQIMQssCr0EA18zBBoTbQb/AE8HMSNvBMDx8wYDu+T+UUflBYHmlQf/BjMGJe1BBsIHeQYf4PsEe3jpBHZTdQZ1W98GiAVRBB5hBwYZICz8rDapBtFnKQOyTMkGjlqFBjUyoQL1++EEMezlBMvMMQsMkYr+n3zRBVrPQwf/K7EF6GlpB/t1bQZwwBkLZ+ZpBZFrHwXwptkEEwrvBIfQMwTmNtz/hP0FA6/32wVrCSEHAXpzBrktAwStOUkGVBlLB5ZCawZw6AsCG44pBgyOhwOMC7sCb/ARCaHkQwm4TN8F0EMDBrDBNwd0p9MFHemQ/oMqtQPs8ikBts8zBs9AfwaDtxcHKub3AdQkGwpCp1kFu+6BByMnGwZBLr0Fx/3zB12DdQbRQjkDzxj/BFIZbwfMYhcG37eZA2hFhQc89wj9MsgzCqH/uwRb9CsENdRPC3sJmQU0tCcI37MXB+dSXwXdPMUFPHkBBQehfQeAzyT9x/kvB4HZMQfzenEGBaUjB/4AZQT2h5cCtZPXB0rNfwGBZx8H4AiZAOSGKQQss20Hvyc3BImnWQU268MGHcYRBeEnRwVSkIcEUZ9BBIVjXwc/qAkHAlcxBN+GvQdoY5cHDACC/FD8uQR85dEG9CL9BYzSTQJlAOkGPKfHAdiOdwbxF9D9FR8rB3Y1cwauC1MGhc9hBokieQNDtnkB20m3BXOMsQcIgiUH4FLZB8R1+Qbbn5UGWZttBIpPUQYU3b8H2sR3BaGXVQZhrez8FGNPBDcpCwQVCK8HqZPRA995bQNyQ1cHlUG7BVg6mQYxaFsDUM8nBrDIPQT39i8EG6Z9BGMBbwRPnsMFmiXnBetz4Qde0y0EifLzBLITVwQb75UG2KU5B/yrdwV1Slj9PnYlBs8oHQRMazj9fI4xBawCiwbXYh74mNYlBo2mMP52TLUFg4qFBVbSYQDbH1kGnI15BUrfOQfTmUcFby1tBYuT7vzRW2EE1s8hB9pc4wUmKLcFtNA9A5cZ8wa1kgEFxGJnBYEHQwFs9lMH7MatB228awZ9NeUDX3rFBxd2VwRUnEMI8S8rBugCBweinjkA3iLLBKz55wVoDxcHXDM5BJinsQBwxB0Ky56RBIdBAQeJp+UBuz/dAAD7fQcyE1kF4qKNA/66YwTL83EFrMzxBTbrDQBK15kE1xp1BJYPrwci29cE3K/rB1ZyWQVrsnkAFmqpArfbIvxMsRcGv6pRBzTY1P1BPc0H29k9Bxh6PQTptTcFfDuJB7JTcQBG/DsLy4d3BvLyTwf7CzsGVRdNB3i69wd/kz0E1mFtBHKE8wdsKn0G2pbXA/L9WwdgNWsHciBfBu+26we4YakENK2ZBYC8Jwlo/n0GWSYnAWiDgQaLw/MGTsIfBkvApwdbLn0GEkoLBFf9kwSbpy8FJUqbBNkTIwFZiT8HO/3tBe8qrQbh6yEHdl8lAHhDxwSOZscGfKxbBLD6DQRrJgsHAaLhBP/fgQfgO3kGf6hi+fgKZP7zGj0AJcrrB0j7rwXDEXUEH9d3BKZwawVVfnEGyldxBE0bgQJAcjcFQHxZAw568wOeuaUFtIFTBlMUzwZJDn0GPyvA//smqwc+FLUGnIiDAd1gSwQ1I+b7Vda1B2OC/QZQnoUFUpA1CDERAwAlWy0H+T45Bc2VoQeNWw0GYj4FAW7PfwW52vsG0Uuw/DA6IQZpekMFEWInBb892QWmBb0GnUPTBmfuqwHGjJsHtN1lBt3GhQVBLnUFvuNY/PKi1wWTrej/TJL9BLnKvwUK1tkFGba7Be1AGwpT6tUE9C9XBcRd7QM93WkFb7G3BPkCqQWy/DcJ5sSU/zsuVQfKYwkG6R0BBGEdBwXwz/sCpL4xAFpvfQfaWC8GErbfBJPFsQarHVUH+K9NBVfE2QQkuEUJjgfY/pjSfQfV+9L/WIO5BwR0uQb2RlkGJ8dLAHdZWQVLtr8EcLAtCxqdvQc5YvkH+NfK/Ntrxwd5VqsHn7jrBMiXmQCH8mcE4y1pBJ+2HwZJAGME/q+w/H2qnQST7O8FkgxXBOn7OwBORJcF48L7BsbgMQp51FUDyzP6/ebkNQiO6B8Jhuc5BbOv0wRgtjMHgADtBa65UQSsxq8Gi96hBc8zJQJgrPsGLYUW+HQQMwuaBxkHV/F1B6ASKQV0EHcEuh0HB9JiNQTJavsGMJee/u+ccwZDQy0D9abjBjIwTwlFx10G4m0NAoz2awL95tkGHSPI/TKCrwdu4WUG5vkrBQg1hQFDrOEGdZwvB6P+Cwcs35MEHNwrAMNfXQfNKgcF2RfDB7iX1QQ1NWEFlBDlBQ4MuwQjOBcBiVwvCQsjIwQj2BEG5pcNB/2ykQTWNpMEFwH3BmRKNP26y2kHxBVG9CLadwdWPAMJSM/vA6MCdwS3jC8K5C8jBetWjwZqZOkDHQSpBo6yMQc2W/MF71Zc/zUUWQcXB70A3zdbA+P4bwUU08sFTlKM7EUeLwY5Y2EE0ig1B8giBQIt5JEBJhLrBxchHQa55sMGq8L5BGqn+QM8peUEtHtHBcgcTwpHbeL9fljbBXksKQSuAHMHvGddB2h+5QW303kA1glLBEIstwYf9z0FfM29B5qvlwaYKSEHxcHlBylegQbxBacEwO8lAoru+QSRczkGBMSdAGMWDwX0m68EIBN1BUI/IPrX458DVMNjBvtX5wFnAiMFG28ZB4ImsQR1aoMH8wqzBzMZWQV0h3r4aPZNAIkKSwUkOsUBFjjDBlznCwYeAPUEBsRPBCQFKQd7nM8F6Q3DBfxZuwW+fy0EcarxBXhJpwapfWEFggcFB2ejCweD028E+9A9BVw7OQCfMF0Cu4/FAUPOrwTG+isF7dXBBuF+pQUqo8MEer+XBdh7tvwXS9kEwC4rB2wq0wAZ4VsEQpf7BV0HXwVpTTUFETL1AgNgGPqL088EYePrBLn3ZQNfLusERq0PBeabxQSFWTkFqg4lBvGzVQMUP+MEGMalBg9mmQGaasEG7zBVBcdhkQe440EFOvcdBkgZNQWu6gcHN7dtBYbPSQPx9zsHr3yVBAN6xwK+LBUDVVDzBuqIbQBGjN0HJQKxBhZJWQfxbMsFmUqRB+xWbQYsHiMFwR4XBxjSnvrXW6UFlsKK/nK4cP0p0jD+A2Ek+LRNmQZdtS0HqoBbBOx3FwaQHocFw+7G/dxenP+zvdUEtFUtAt2M+PmbvlEHd6EjB2KYyQXN+PEGKZ4rBRPioQZLcs8HvprBBxW99QCOSe0H3/IfBqqRKwSfIqUGzAbDBNzXRQc3WL0FyKhHC5HbTwSuT20HxnszBeMLLQQZVzj/IAUfBY4M6wSTYSME7tIlBF54wwTRgoECDv19BrtJfQUu/okAoT8hBBJC1wfQBosHyFQnBCLOzQXek0MGeBTHB6xPLwEeKZEEzB4pA1cdYQSZibkHBsBDBi0G8wQJfr0E7CsZBE7GEwbfKXL9/IvLBgkVOQRBs20FJ5QRA7sZPQZuSoUHAiaZBIVaJwHCPuUHfWBDCWSNlQZDbokEhEFjBuCvgwSItpUEC/I3BYvwAwNuj9kHBUg7CHujNQcB/fEEByifB0m48wAUABMIuqrTBI9aPwXFstD8XA50/LAoTwbjKnT/oqbTBEqgZQJ/228C18CtBY7xnP622YUDcEgPCqbFtQeNGN8FSO0bBLte6QUre6cH0WzdBNT+KQYlSiUATQkDBlV30we16xr+RHLrB3/GkwcM4S8HA89XBtgR5QVpWhUE5xQvBMxizQeSHK0FXN5q/4sGEQaUPrECCSoVBk2LWQOGX68FgBr5B2aobwSYRxMFBlvXBFmZhQcpXnEC1lb3BjBoqwZZpNcG+2J5AqiEzQDeXvcALvi7BLvg2QRKNHT/XcTpAFvYVwXgAlEBmHSFB/tQSQWjMRcGpHtC+ZCcMQYYDbcDVxd9AGm2sQV6KzkFBT4HBYuAwQavK3ECqn8TBOWo5Qf18HUBZfbvBmiZ2QCzG4kBkBuHBwKzwwWvaZUGSHQzCFDCDwUfIpkHcCK3AubzIPuPZrj9YJQxC0zKtQUJKRsGBq/nBzfnRQOkOQ0G7iP9AwwdWQVxBj0H59cXB0rogwRGLAsFo7ntBfQQAwVYhMcHr1bE/cuPMwf9MIUFAmbvBeQy1wZPP8sGyFmVBEga5wZGi3cApQXlB+Oe+wR9m40EeOshBvzFrP6Z7Y8Eo9sZBIbZywD72DUCDJeJBPGkNQsb3r0GcHXlBlSDzQHu/10EsjRBA82VeQFWkM8F8rds/QuuYQUDG2kHejC7AAYDaQMlOUUFOdhtBIupQQWK/HcFjie3BL2oFwmV1rEFKYopBcDarwftFLMG+wfPBgU3OwWGU9cHyI53BJe0WwUNIs0BvyJ9A3NKiQbu1FUCgTKHBiGLQwPgST0FZYYdBx+EowTFYUUHhr21BRousQZf4zMHcdQdBKe6kQQokOMEinw7BCte1QBglLMG/bG5BaLj4wWDHD8IzYRPC7hh4Pzi1t0HljFvBQnF0wc+zBMKckoLB1O0LwS/duMHWfnpBUN4FwcXHQ0G88SBBvfuDwZ8yYkFPkLjBhTMkwelqccDV5LfA+jCXQAbcEsEGRnrBJ76YwfL42kFFm9PBZxE8QUWY0sEX40vBea2nQT+JUcE5LsnBd0q7wXqgl0FhqRtAJz0QQKSEh8Hf0s/AwAxhwSuORMErZso/i+kNQYXkscE056VBhq5RwdFBn0FkBqVBwOlPQSJiycFOSEc+Z1Umwd5S2cF8ZThBlrT3QQ7cucHAjz9BNd4dwanoS0FpuxJB7iniwWKkb78LrqDBGFOXwWRUfsEmO7nAbb22wfpvUEA13/zB7NgBwAtUt8GINAjB767CwZBHcMH4bS7BxFYBwsNj2EHC8dvBkxOXwauZtMEDV0ZBWy/SQeJcJ0HICGTBfmmnQfRTkUHdsWJBkS7qvuAP4z/uRdhAeqiiQTkNyUEFbW/AL9PRQLzeA0K5LJpA8rxrQUZ3xcEdsZ1BW+XswXs5f8GOEuG/DPQOwZHUwsBzV4xAGnRBQWJW48Ft2J9A5AjfQX9og79jc3/BaGkNwo4bHcHOnVBBIQSCwV/t3EBCHBPBGvm4weeiykBO5LHAViacP6GHjUEokXDBfhQwwU4lkUGoOKBAH5Q8vqqCzUDhYcvB6467QSblyMH5S4bBxmEwQXrAacG1FCRB8MehQRGRGj5DNs3BTESlQSq6x7/3AQFBo7XPQacN78HeMoVBynjBwdu7FUCPDsrAwBtUQSUl1UHxUXFBBfxTPwYXi0H8bb3A4GnCP+LM5kElsRlA8yZSwbzEIMFbOz7ApWuOPyoN0MDMpAs/AUdfQXDXiMFmfMzBtUCGwdRHosENiPTBuvfYQCtC2cFd3fnBwNvfwRaLNEFvccDBr5xqQYT2+cEc3n5A++I5wSltUECy3nxBWfVjQZXNjEHCFOFBUf+MwTuGmkG8d7tAlPM3wZemwz7OsbQ/QdwTwlt3rMBIxKg/3lWjQcYI7sD1j1tBm73lQXIwEEIcsU9Bf/0dwfemmz+59LE/Ie/wP5o4dkFHcgNCyxCrweBf3MFprQK/nNakQeFcwMG07A1BsQgqQaLLlUEvYb/BNl1kQFnh7MHjUfDBxJNHwbaBskFKEkbBYdkHwdRQrcGAmeJBIQUQwl5bb0FtorvBZmiiQZgk+EGOLgbAA8vhQM13xEBhMLdBNZGrwPQvtcBc7UnB+LYpQX+69MCBWr/AQ+PTQW1/zMFaRdbBLiKIwXOS0MHwF4rBqCJ8QJBancECFI/BmdtQQbm0s0Cq4ZfB5kbMQTkf+0HexNlBjwwmQcEq5kH9A+3BcqyLQbrEKUGJcwE+RFidwWDqJkFEUw/CYe6/waiPl0H4iUZBc+UwPzOqksF7mafBgpKCvlVGz0By1uvBekJiwRFoysG+6mXBKEmFwbMGE0Lu279A8KlqQYy2mMCocrvB9+zdQTK2DcHcrPjABn7VQa8pkUBxUNxBn7udwdB29sHvFipA5HeSwVBmzEExq89Ac+VfwPo9JkAox5S/71DbwT76QEF07rnBP31WQf7cwT+OPpFBMfxYQQHgqEGqvwjBQv8xQfpUmkGKS4hBabJMwZCVGL82iOpA2jQ9wJyaP0FteZ7BuOHrwfJR1L/4HsJB82xHQSxxAcKEKvpBZ7nZQdh6H0Fu8o9B3HvvQPR55MEFvnrBaXytwQC0BUL8enrB5o4KQhZlS8GnUwc/8ekkQRjoGEDOEDXBcl2iv3NXMcEsTFJB8JspwXBQcUHYOgVBfv3PwTcIrsFB59RAupO7QMrvN0HqtzXB51UrQasBT0FBWA7CnChJQYCD2cHKpJ5APlLsQczL0b9kM5nBfTMUwtOVdcEWcyzBZ908QYRQgMEGcoVBLLpNQdl7ksF+onrB1s2nQTpcA8IjhCHBzBLtwWCZnj9CtT5BZt4IQi6EA8KZwFTAdhQ6wTR4IUFF8NDBqjE5QUogtsGhivfBMsuhv2fsQUGZdLzB7ItJQFxtKUETNkRB9MtmwW/TPUFlo4BBW72vP+4Qf8EvkqTBQgVKQeLSSEEqmsPBy0rlv5hjtsFg7cVB6pMfQEzP4sC6tTfBw5cdwaF23sFehrdBBMIPQRdT9kHaYzvBtrLIOx0wskHDblfAghnJwVJk58BaAs3Bc+nSwKZhpEGXEjtBXL1mwR0To0Hi56rBoimzwRuC5cBLwnNBa1kVQJPstECqFN/BAVDIQcwizcA9FBzBl6vEQfoFY0HW0Uc/J9evP8UXDsJcihrBdf/gQcKmwUGt3jdBeL4OwujnsMEIjfXAaPWeQbMrGcFmdKXAa/QMQiIC/MHZUrlBJvq3wRbA1EGebTe/MRlEP67+PUGEOgTCQL9jwaZpp0CtYDLB5xkCwTK+g8HIGAJCXhrbPf4A6kFvpUVBsXLHwfjEkz5m5t8/tYmOwYlk4r+lScVBI9R3QZiQCz8Ttt9BefRhQUjLBkEN2p1B+IcpP9ZH58G6/T1ByL+wwbe4X0BoxI1A6KDOwSt3B8KL8E3BsVMSwZxEssF/1bNBGtxdwByeskFsQzjB+NCRwbeVrsGen8VBB3G0wTldA0DiT9TBFqvywQEkB8JV789APOqjwcKSAr+PxYZB45hZQRVcG8Fe8FZBYNYFwkSzvsHDNcxBSHqoQRhv7MEeQtJBOCTeQUuH4EE5exFBRT42wWC7skFZ3b5ANJ0QQb7j10HFJ4HBhMZ2QQj2MMEms2LB1ZlpwRKassDJpOPBNpFVwW9wO8Hjdo9BZ1bBwI4JU0Fzq5lBZVbYQd9Uvr+YuN9A3QTpwBog18F3EsfB+mFLwaPQ7kAB18NAxkPBwT684MCwtl5Bf45WwHrwd0FATolBJocuwb0LjMH2CWxBXQzmQbq0isEVPrjAxIUUQRcvQMGpsEZBTkrSP2qNQ8EIMlbBBYZUQX+ansGMEbNB\",\"dtype\":\"float32\",\"order\":\"little\",\"shape\":[1533]}},\"selected\":{\"id\":\"1168\"},\"selection_policy\":{\"id\":\"1167\"}},\"id\":\"1143\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1111\",\"type\":\"DataRange1d\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1143\"},\"glyph\":{\"id\":\"1145\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1147\"},\"nonselection_glyph\":{\"id\":\"1146\"},\"view\":{\"id\":\"1149\"}},\"id\":\"1148\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"tools\":[{\"id\":\"1127\"},{\"id\":\"1128\"},{\"id\":\"1129\"},{\"id\":\"1130\"},{\"id\":\"1131\"},{\"id\":\"1132\"},{\"id\":\"1134\"}]},\"id\":\"1135\",\"type\":\"Toolbar\"},{\"attributes\":{\"fill_color\":{\"field\":\"label\",\"transform\":{\"id\":\"1106\"}},\"line_color\":{\"field\":\"label\",\"transform\":{\"id\":\"1106\"}},\"size\":{\"value\":10},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1145\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1131\",\"type\":\"ResetTool\"},{\"attributes\":{},\"id\":\"1120\",\"type\":\"BasicTicker\"},{\"attributes\":{\"high\":100,\"low\":0,\"palette\":[\"#30123b\",\"#311542\",\"#32184a\",\"#341b51\",\"#351e58\",\"#36215f\",\"#372365\",\"#38266c\",\"#392972\",\"#3a2c79\",\"#3b2f7f\",\"#3c3285\",\"#3c358b\",\"#3d3791\",\"#3e3a96\",\"#3f3d9c\",\"#4040a1\",\"#4043a6\",\"#4145ab\",\"#4148b0\",\"#424bb5\",\"#434eba\",\"#4350be\",\"#4353c2\",\"#4456c7\",\"#4458cb\",\"#455bce\",\"#455ed2\",\"#4560d6\",\"#4563d9\",\"#4666dd\",\"#4668e0\",\"#466be3\",\"#466de6\",\"#4670e8\",\"#4673eb\",\"#4675ed\",\"#4678f0\",\"#467af2\",\"#467df4\",\"#467ff6\",\"#4682f8\",\"#4584f9\",\"#4587fb\",\"#4589fc\",\"#448cfd\",\"#438efd\",\"#4291fe\",\"#4193fe\",\"#4096fe\",\"#3f98fe\",\"#3e9bfe\",\"#3c9dfd\",\"#3ba0fc\",\"#39a2fc\",\"#38a5fb\",\"#36a8f9\",\"#34aaf8\",\"#33acf6\",\"#31aff5\",\"#2fb1f3\",\"#2db4f1\",\"#2bb6ef\",\"#2ab9ed\",\"#28bbeb\",\"#26bde9\",\"#25c0e6\",\"#23c2e4\",\"#21c4e1\",\"#20c6df\",\"#1ec9dc\",\"#1dcbda\",\"#1ccdd7\",\"#1bcfd4\",\"#1ad1d2\",\"#19d3cf\",\"#18d5cc\",\"#18d7ca\",\"#17d9c7\",\"#17dac4\",\"#17dcc2\",\"#17debf\",\"#18e0bd\",\"#18e1ba\",\"#19e3b8\",\"#1ae4b6\",\"#1be5b4\",\"#1de7b1\",\"#1ee8af\",\"#20e9ac\",\"#22eba9\",\"#24eca6\",\"#27eda3\",\"#29eea0\",\"#2cef9d\",\"#2ff09a\",\"#32f197\",\"#35f394\",\"#38f491\",\"#3bf48d\",\"#3ff58a\",\"#42f687\",\"#46f783\",\"#4af880\",\"#4df97c\",\"#51f979\",\"#55fa76\",\"#59fb72\",\"#5dfb6f\",\"#61fc6c\",\"#65fc68\",\"#69fd65\",\"#6dfd62\",\"#71fd5f\",\"#74fe5c\",\"#78fe59\",\"#7cfe56\",\"#80fe53\",\"#84fe50\",\"#87fe4d\",\"#8bfe4b\",\"#8efe48\",\"#92fe46\",\"#95fe44\",\"#98fe42\",\"#9bfd40\",\"#9efd3e\",\"#a1fc3d\",\"#a4fc3b\",\"#a6fb3a\",\"#a9fb39\",\"#acfa37\",\"#aef937\",\"#b1f836\",\"#b3f835\",\"#b6f735\",\"#b9f534\",\"#bbf434\",\"#bef334\",\"#c0f233\",\"#c3f133\",\"#c5ef33\",\"#c8ee33\",\"#caed33\",\"#cdeb34\",\"#cfea34\",\"#d1e834\",\"#d4e735\",\"#d6e535\",\"#d8e335\",\"#dae236\",\"#dde036\",\"#dfde36\",\"#e1dc37\",\"#e3da37\",\"#e5d838\",\"#e7d738\",\"#e8d538\",\"#ead339\",\"#ecd139\",\"#edcf39\",\"#efcd39\",\"#f0cb3a\",\"#f2c83a\",\"#f3c63a\",\"#f4c43a\",\"#f6c23a\",\"#f7c039\",\"#f8be39\",\"#f9bc39\",\"#f9ba38\",\"#fab737\",\"#fbb537\",\"#fbb336\",\"#fcb035\",\"#fcae34\",\"#fdab33\",\"#fda932\",\"#fda631\",\"#fda330\",\"#fea12f\",\"#fe9e2e\",\"#fe9b2d\",\"#fe982c\",\"#fd952b\",\"#fd9229\",\"#fd8f28\",\"#fd8c27\",\"#fc8926\",\"#fc8624\",\"#fb8323\",\"#fb8022\",\"#fa7d20\",\"#fa7a1f\",\"#f9771e\",\"#f8741c\",\"#f7711b\",\"#f76e1a\",\"#f66b18\",\"#f56817\",\"#f46516\",\"#f36315\",\"#f26014\",\"#f15d13\",\"#ef5a11\",\"#ee5810\",\"#ed550f\",\"#ec520e\",\"#ea500d\",\"#e94d0d\",\"#e84b0c\",\"#e6490b\",\"#e5460a\",\"#e3440a\",\"#e24209\",\"#e04008\",\"#de3e08\",\"#dd3c07\",\"#db3a07\",\"#d93806\",\"#d73606\",\"#d63405\",\"#d43205\",\"#d23005\",\"#d02f04\",\"#ce2d04\",\"#cb2b03\",\"#c92903\",\"#c72803\",\"#c52602\",\"#c32402\",\"#c02302\",\"#be2102\",\"#bb1f01\",\"#b91e01\",\"#b61c01\",\"#b41b01\",\"#b11901\",\"#ae1801\",\"#ac1601\",\"#a91501\",\"#a61401\",\"#a31201\",\"#a01101\",\"#9d1001\",\"#9a0e01\",\"#970d01\",\"#940c01\",\"#910b01\",\"#8e0a01\",\"#8b0901\",\"#870801\",\"#840701\",\"#810602\",\"#7d0502\",\"#7a0402\"]},\"id\":\"1106\",\"type\":\"LinearColorMapper\"},{\"attributes\":{\"axis\":{\"id\":\"1119\"},\"coordinates\":null,\"group\":null,\"ticker\":null},\"id\":\"1122\",\"type\":\"Grid\"},{\"attributes\":{\"axis\":{\"id\":\"1123\"},\"coordinates\":null,\"dimension\":1,\"group\":null,\"ticker\":null},\"id\":\"1126\",\"type\":\"Grid\"},{\"attributes\":{},\"id\":\"1168\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1132\",\"type\":\"HelpTool\"},{\"attributes\":{\"callback\":null,\"tooltips\":\"\\n
\\n \\n
\\n @label_desc - @split\\n [#@video_id]\\n
\\n
\\n \\n\"},\"id\":\"1134\",\"type\":\"HoverTool\"},{\"attributes\":{},\"id\":\"1113\",\"type\":\"DataRange1d\"},{\"attributes\":{\"bottom_units\":\"screen\",\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"right_units\":\"screen\",\"syncable\":false,\"top_units\":\"screen\"},\"id\":\"1133\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1162\"},\"group\":null,\"major_label_policy\":{\"id\":\"1163\"},\"ticker\":{\"id\":\"1124\"}},\"id\":\"1123\",\"type\":\"LinearAxis\"},{\"attributes\":{\"overlay\":{\"id\":\"1133\"}},\"id\":\"1129\",\"type\":\"BoxZoomTool\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"field\":\"label\",\"transform\":{\"id\":\"1106\"}},\"hatch_alpha\":{\"value\":0.1},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"field\":\"label\",\"transform\":{\"id\":\"1106\"}},\"size\":{\"value\":10},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1146\",\"type\":\"Scatter\"},{\"attributes\":{\"coordinates\":null,\"group\":null,\"text\":\"Check label by hovering mouse over the dots\"},\"id\":\"1109\",\"type\":\"Title\"},{\"attributes\":{},\"id\":\"1167\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1165\"},\"group\":null,\"major_label_policy\":{\"id\":\"1166\"},\"ticker\":{\"id\":\"1120\"}},\"id\":\"1119\",\"type\":\"LinearAxis\"},{\"attributes\":{},\"id\":\"1130\",\"type\":\"SaveTool\"},{\"attributes\":{},\"id\":\"1117\",\"type\":\"LinearScale\"},{\"attributes\":{},\"id\":\"1162\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{},\"id\":\"1115\",\"type\":\"LinearScale\"},{\"attributes\":{\"source\":{\"id\":\"1143\"}},\"id\":\"1149\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1127\",\"type\":\"PanTool\"},{\"attributes\":{},\"id\":\"1166\",\"type\":\"AllLabels\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.2},\"fill_color\":{\"field\":\"label\",\"transform\":{\"id\":\"1106\"}},\"hatch_alpha\":{\"value\":0.2},\"line_alpha\":{\"value\":0.2},\"line_color\":{\"field\":\"label\",\"transform\":{\"id\":\"1106\"}},\"size\":{\"value\":10},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1147\",\"type\":\"Scatter\"}],\"root_ids\":[\"1108\"]},\"title\":\"Bokeh Application\",\"version\":\"2.4.3\"}};\n const render_items = [{\"docid\":\"458dc79d-472d-4f36-92df-cc9c2d7d3fb7\",\"root_ids\":[\"1108\"],\"roots\":{\"1108\":\"74ea627a-4164-4f24-bbf8-b9b7c4c5836c\"}}];\n root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n }\n if (root.Bokeh !== undefined) {\n embed_document(root);\n } else {\n let attempts = 0;\n const timer = setInterval(function(root) {\n if (root.Bokeh !== undefined) {\n clearInterval(timer);\n embed_document(root);\n } else {\n attempts++;\n if (attempts > 100) {\n clearInterval(timer);\n console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n }\n }\n }, 10, root)\n }\n})(window);", - "application/vnd.bokehjs_exec.v0+json": "" - }, - "metadata": { - "application/vnd.bokehjs_exec.v0+json": { - "id": "1108" - } - }, - "output_type": "display_data" + "ename": "KeyError", + "evalue": "'label_name'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "File \u001b[0;32m/usr/local/lib/python3.8/dist-packages/pandas/core/indexes/base.py:3802\u001b[0m, in \u001b[0;36mIndex.get_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m 3801\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m-> 3802\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_engine\u001b[39m.\u001b[39;49mget_loc(casted_key)\n\u001b[1;32m 3803\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m err:\n", + "File \u001b[0;32m/usr/local/lib/python3.8/dist-packages/pandas/_libs/index.pyx:138\u001b[0m, in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n", + "File \u001b[0;32m/usr/local/lib/python3.8/dist-packages/pandas/_libs/index.pyx:165\u001b[0m, in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n", + "File \u001b[0;32mpandas/_libs/hashtable_class_helper.pxi:5745\u001b[0m, in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n", + "File \u001b[0;32mpandas/_libs/hashtable_class_helper.pxi:5753\u001b[0m, in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n", + "\u001b[0;31mKeyError\u001b[0m: 'label_name'", + "\nThe above exception was the direct cause of the following exception:\n", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[29], line 5\u001b[0m\n\u001b[1;32m 1\u001b[0m column_data \u001b[39m=\u001b[39m \u001b[39mdict\u001b[39m(\n\u001b[1;32m 2\u001b[0m x\u001b[39m=\u001b[39mdf[\u001b[39m'\u001b[39m\u001b[39mtsne_x\u001b[39m\u001b[39m'\u001b[39m],\n\u001b[1;32m 3\u001b[0m y\u001b[39m=\u001b[39mdf[\u001b[39m'\u001b[39m\u001b[39mtsne_y\u001b[39m\u001b[39m'\u001b[39m],\n\u001b[1;32m 4\u001b[0m label\u001b[39m=\u001b[39mdf[\u001b[39m'\u001b[39m\u001b[39msign\u001b[39m\u001b[39m'\u001b[39m],\n\u001b[0;32m----> 5\u001b[0m label_desc\u001b[39m=\u001b[39mdf[\u001b[39m'\u001b[39;49m\u001b[39mlabel_name\u001b[39;49m\u001b[39m'\u001b[39;49m],\n\u001b[1;32m 6\u001b[0m split\u001b[39m=\u001b[39mdf[\u001b[39m'\u001b[39m\u001b[39msplit\u001b[39m\u001b[39m'\u001b[39m],\n\u001b[1;32m 7\u001b[0m video_id\u001b[39m=\u001b[39mdf[\u001b[39m'\u001b[39m\u001b[39mvideo_id\u001b[39m\u001b[39m'\u001b[39m]\n\u001b[1;32m 8\u001b[0m )\n\u001b[1;32m 10\u001b[0m \u001b[39mif\u001b[39;00m use_img_div:\n\u001b[1;32m 11\u001b[0m emb_videos \u001b[39m=\u001b[39m load_videos(df[\u001b[39m'\u001b[39m\u001b[39mvideo_fn\u001b[39m\u001b[39m'\u001b[39m])\n", + "File \u001b[0;32m/usr/local/lib/python3.8/dist-packages/pandas/core/frame.py:3807\u001b[0m, in \u001b[0;36mDataFrame.__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 3805\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mcolumns\u001b[39m.\u001b[39mnlevels \u001b[39m>\u001b[39m \u001b[39m1\u001b[39m:\n\u001b[1;32m 3806\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_getitem_multilevel(key)\n\u001b[0;32m-> 3807\u001b[0m indexer \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mcolumns\u001b[39m.\u001b[39;49mget_loc(key)\n\u001b[1;32m 3808\u001b[0m \u001b[39mif\u001b[39;00m is_integer(indexer):\n\u001b[1;32m 3809\u001b[0m indexer \u001b[39m=\u001b[39m [indexer]\n", + "File \u001b[0;32m/usr/local/lib/python3.8/dist-packages/pandas/core/indexes/base.py:3804\u001b[0m, in \u001b[0;36mIndex.get_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m 3802\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_engine\u001b[39m.\u001b[39mget_loc(casted_key)\n\u001b[1;32m 3803\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m err:\n\u001b[0;32m-> 3804\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mKeyError\u001b[39;00m(key) \u001b[39mfrom\u001b[39;00m \u001b[39merr\u001b[39;00m\n\u001b[1;32m 3805\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mTypeError\u001b[39;00m:\n\u001b[1;32m 3806\u001b[0m \u001b[39m# If we have a listlike key, _check_indexing_error will raise\u001b[39;00m\n\u001b[1;32m 3807\u001b[0m \u001b[39m# InvalidIndexError. Otherwise we fall through and re-raise\u001b[39;00m\n\u001b[1;32m 3808\u001b[0m \u001b[39m# the TypeError.\u001b[39;00m\n\u001b[1;32m 3809\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_check_indexing_error(key)\n", + "\u001b[0;31mKeyError\u001b[0m: 'label_name'" + ] } ], "source": [ @@ -421,7 +420,7 @@ " x=df['tsne_x'],\n", " y=df['tsne_y'],\n", " label=df['labels'],\n", - " label_desc=df['label_name'],\n", + " label_desc=df['sign'],\n", " split=df['split'],\n", " video_id=df['video_id']\n", ")\n", @@ -483,7 +482,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.13" + "version": "3.8.10" } }, "nbformat": 4, diff --git a/preprocessing/create_google_asl_landmarks_dataset.py b/preprocessing/create_google_asl_landmarks_dataset.py new file mode 100644 index 0000000..4a4beda --- /dev/null +++ b/preprocessing/create_google_asl_landmarks_dataset.py @@ -0,0 +1,146 @@ +import os +import os.path as op +import pandas as pd +from tqdm.auto import tqdm +import json + +def create(train_landmark_files, train_csv, dataset_folder, test_size): + os.makedirs(dataset_folder, exist_ok=True) + + # load json sign_to_prediciton_index_map.json + with open('data/sign_to_prediction_index_map.json', 'r') as f: + sign_to_prediction_index_map = json.load(f) + + train_df = pd.read_csv(train_csv) + video_data = [] + + mapping = { + 'pose_0': 'nose', + 'pose_1': 'leftEye', + 'pose_2': 'rightEye', + 'pose_3': 'leftEar', + 'pose_4': 'rightEar', + 'pose_5': 'leftShoulder', + 'pose_6': 'rightShoulder', + 'pose_7': 'leftElbow', + 'pose_8': 'rightElbow', + 'pose_9': 'leftWrist', + 'pose_10': 'rightWrist', + + 'left_hand_0': 'wrist_left', + 'left_hand_1': 'thumbCMC_left', + 'left_hand_2': 'thumbMP_left', + 'left_hand_3': 'thumbIP_left', + 'left_hand_4': 'thumbTip_left', + 'left_hand_5': 'indexMCP_left', + 'left_hand_6': 'indexPIP_left', + 'left_hand_7': 'indexDIP_left', + 'left_hand_8': 'indexTip_left', + 'left_hand_9': 'middleMCP_left', + 'left_hand_10': 'middlePIP_left', + 'left_hand_11': 'middleDIP_left', + 'left_hand_12': 'middleTip_left', + 'left_hand_13': 'ringMCP_left', + 'left_hand_14': 'ringPIP_left', + 'left_hand_15': 'ringDIP_left', + 'left_hand_16': 'ringTip_left', + 'left_hand_17': 'littleMCP_left', + 'left_hand_18': 'littlePIP_left', + 'left_hand_19': 'littleDIP_left', + 'left_hand_20': 'littleTip_left', + + 'right_hand_0': 'wrist_right', + 'right_hand_1': 'thumbCMC_right', + 'right_hand_2': 'thumbMP_right', + 'right_hand_3': 'thumbIP_right', + 'right_hand_4': 'thumbTip_right', + 'right_hand_5': 'indexMCP_right', + 'right_hand_6': 'indexPIP_right', + 'right_hand_7': 'indexDIP_right', + 'right_hand_8': 'indexTip_right', + 'right_hand_9': 'middleMCP_right', + 'right_hand_10': 'middlePIP_right', + 'right_hand_11': 'middleDIP_right', + 'right_hand_12': 'middleTip_right', + 'right_hand_13': 'ringMCP_right', + 'right_hand_14': 'ringPIP_right', + 'right_hand_15': 'ringDIP_right', + 'right_hand_16': 'ringTip_right', + 'right_hand_17': 'littleMCP_right', + 'right_hand_18': 'littlePIP_right', + 'right_hand_19': 'littleDIP_right', + 'right_hand_20': 'littleTip_right', + } + + columns = [] + for k,v in mapping.items(): + columns.append(f'{v}_X') + columns.append(f'{v}_Y') + + for _, row in tqdm(train_df.head(6000).iterrows(), total=6000): + path, participant_id, sequence_id, sign = row['path'], row['participant_id'], row['sequence_id'], row['sign'] + parquet_file = os.path.join(train_landmark_files, str(participant_id), f"{sequence_id}.parquet") + + if not os.path.exists(parquet_file): + print(f"{parquet_file} not found. Skipping.") + continue + + landmark_data = pd.read_parquet(parquet_file) + + # all nan to 0 + landmark_data = landmark_data.fillna(0) + + # create a new dataframe with the correct column names (each mapping with x and y coordinates) + new_landmark_data = pd.DataFrame(columns=columns) + + # add each row of the parquet file to the correct column (use mapping based on {type}_{index}) + # for each frame, construct the new row + + frame_column = landmark_data['frame'] + # get unique frames + frames = frame_column.unique() + # sort + frames.sort() + new_row = {} + + for frame_id in frames: + # get all rows for this frame + frame_data = landmark_data.loc[landmark_data['frame'] == frame_id] + # construct new row + for _, row in frame_data.iterrows(): + t = f"{row['type']}_{row['landmark_index']}" + if t in mapping: + c = mapping[t] + new_row.setdefault(f"{c}_X", []).append(row['x']) + new_row.setdefault(f"{c}_Y", []).append(row['y']) + + + d = pd.DataFrame({k: [v] for k, v in new_row.items()}) + + # add to new dataframe + new_landmark_data = pd.concat([new_landmark_data, d], axis=0, ignore_index=True) + + # set nan values to 0 + new_landmark_data = new_landmark_data.fillna(0) + + video_dict = {'path': path, + 'participant_id': participant_id, + 'sequence_id': sequence_id, + 'sign': sign, + 'labels': sign_to_prediction_index_map[sign] + } + + # add these columns to the landmark data using concat + new_landmark_data = pd.concat([pd.DataFrame(video_dict, index=[0]), new_landmark_data], axis=1) + + video_data.append(new_landmark_data) + + video_data = pd.concat(video_data, axis=0, ignore_index=True) + video_data.to_csv(os.path.join(dataset_folder, 'spoter.csv'), index=False) + +train_landmark_files = 'data/train_landmark_files' +train_csv = 'data/train.csv' +dataset_folder = 'data/processed' +test_size = 0.25 + +create(train_landmark_files, train_csv, dataset_folder, test_size) diff --git a/preprocessing/create_wlasl_landmarks_dataset.py b/preprocessing/create_wlasl_landmarks_dataset.py index a457c89..c1e4d5c 100644 --- a/preprocessing/create_wlasl_landmarks_dataset.py +++ b/preprocessing/create_wlasl_landmarks_dataset.py @@ -76,8 +76,8 @@ def create(args): os.makedirs(dataset_folder, exist_ok=True) - shutil.copy(os.path.join(BASE_DATA_FOLDER, 'wlasl/id_to_label.json'), dataset_folder) - shutil.copy(os.path.join(BASE_DATA_FOLDER, 'wlasl/WLASL_v0.3.json'), dataset_folder) + # shutil.copy(os.path.join(BASE_DATA_FOLDER, 'wlasl/id_to_label.json'), dataset_folder) + # shutil.copy(os.path.join(BASE_DATA_FOLDER, 'wlasl/WLASL_v0.3.json'), dataset_folder) wlasl_json_fn = op.join(dataset_folder, 'WLASL_v0.3.json') diff --git a/preprocessing/split_dataset.py b/preprocessing/split_dataset.py new file mode 100644 index 0000000..17e1f55 --- /dev/null +++ b/preprocessing/split_dataset.py @@ -0,0 +1,32 @@ +import pandas as pd +import json + +from normalization.blazepose_mapping import map_blazepose_df + +# split the dataset into train and test set +dataset = "data/processed/spoter.csv" + +# read the dataset +df = pd.read_csv(dataset) +df = map_blazepose_df(df) + +with open("data/sign_to_prediction_index_map.json", "r") as f: + sign_to_prediction_index_max = json.load(f) + + +# filter df to make sure each sign has at least 4 samples +df = df[df["sign"].map(df["sign"].value_counts()) > 4] + +# use the path column to split the dataset +paths = df["path"].unique() + +# split the dataset into train and test set +train_paths = paths[:int(len(paths) * 0.8)] + +# create the train and test set +train_df = df[df["path"].isin(train_paths)] +test_df = df[~df["path"].isin(train_paths)] + +# save the train and test set +train_df.to_csv("data/processed/spoter_train.csv", index=False) +test_df.to_csv("data/processed/spoter_test.csv", index=False) diff --git a/requirements.txt b/requirements.txt index 2e081ab..2308b4c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ +pandas bokeh==2.4.3 boto3>=1.9 clearml==1.6.4 @@ -6,9 +7,8 @@ matplotlib==3.5.3 mediapipe==0.8.11 notebook==6.5.2 opencv-python==4.6.0.66 -pandas==1.1.5 -pandas==1.1.5 plotly==5.11.0 scikit-learn==1.0.2 -torchvision==0.13.0 +torch +torchvision tqdm==4.54.1 diff --git a/train.sh b/train.sh index 73f0c3a..fe68689 100755 --- a/train.sh +++ b/train.sh @@ -1,14 +1,14 @@ #!/bin/sh python -m train \ - --save_checkpoints_every -1 \ + --save_checkpoints_every 10 \ --experiment_name "augment_rotate_75_x8" \ - --epochs 10 \ - --optimizer "SGD" \ + --epochs 300 \ + --optimizer "ADAM" \ --lr 0.001 \ - --batch_size 32 \ - --dataset_name "wlasl" \ - --training_set_path "WLASL100_train.csv" \ - --validation_set_path "WLASL100_test.csv" \ + --batch_size 16 \ + --dataset_name "processed" \ + --training_set_path "spoter_train.csv" \ + --validation_set_path "spoter_test.csv" \ --vector_length 32 \ --epoch_iters -1 \ --scheduler_factor 0 \ @@ -16,9 +16,7 @@ python -m train \ --filter_easy_triplets \ --triplet_loss_margin 1 \ --dropout 0.2 \ - --start_mining_hard=200 \ - --hard_mining_pre_batch_multipler=16 \ - --hard_mining_pre_batch_mining_count=5 \ --augmentations_prob=0.75 \ --hard_mining_scheduler_triplets_threshold=0 \ - # --normalize_embeddings \ + --normalize_embeddings \ + --num_classes 100 \ \ No newline at end of file