{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## ISLR: Create TFRecord\n\nIn this notebook, I will create time-series TFRecord for [Google - Isolated Sign Language Recognition Competition](https://www.kaggle.com/competitions/asl-signs). I will choose 12 as sequence_length. The dataset has dynamic sequence length, I will convert to static sequence length by simply using `tf.image.resize` API. [Here](https://www.kaggle.com/code/lonnieqin/isolated-sign-language-recognition-with-convlstm1d/notebook?scriptVersionId=120834686) is a baseline to train with this dataset. ","metadata":{}},{"cell_type":"markdown","source":"## Configuration","metadata":{}},{"cell_type":"code","source":"class CFG:\n    data_path = \"../input/asl-signs/\"\n    sequence_length = 1\n#     sequence_length = 12\n#     rows_per_frame = 543 \n    rows_per_frame = 1 \n    ","metadata":{"execution":{"iopub.status.busy":"2023-03-04T10:52:09.365867Z","iopub.execute_input":"2023-03-04T10:52:09.367326Z","iopub.status.idle":"2023-03-04T10:52:09.372984Z","shell.execute_reply.started":"2023-03-04T10:52:09.367262Z","shell.execute_reply":"2023-03-04T10:52:09.371658Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ! ls","metadata":{"execution":{"iopub.status.busy":"2023-03-04T10:03:17.985717Z","iopub.execute_input":"2023-03-04T10:03:17.986184Z","iopub.status.idle":"2023-03-04T10:03:17.992174Z","shell.execute_reply.started":"2023-03-04T10:03:17.986135Z","shell.execute_reply":"2023-03-04T10:03:17.990815Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\n","metadata":{"execution":{"iopub.status.busy":"2023-03-04T10:27:35.287869Z","iopub.execute_input":"2023-03-04T10:27:35.289178Z","iopub.status.idle":"2023-03-04T10:27:35.294877Z","shell.execute_reply.started":"2023-03-04T10:27:35.289124Z","shell.execute_reply":"2023-03-04T10:27:35.293010Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! ls -ahl ../input/asl-signs/train_landmark_files/16069/100015657.parquet\n","metadata":{"execution":{"iopub.status.busy":"2023-03-04T10:03:22.533052Z","iopub.execute_input":"2023-03-04T10:03:22.533956Z","iopub.status.idle":"2023-03-04T10:03:23.626202Z","shell.execute_reply.started":"2023-03-04T10:03:22.533880Z","shell.execute_reply":"2023-03-04T10:03:23.625008Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# pq_path = \"../input/asl-signs/train_landmark_files/16069/100015657.parquet\"\n# pq_path = \"../input/asl-signs/train_landmark_files/26734/1000035562.parquet\"\npq_path = \"../input/asl-signs/train_landmark_files/28656/1000106739.parquet\"","metadata":{"execution":{"iopub.status.busy":"2023-03-04T10:27:34.328041Z","iopub.execute_input":"2023-03-04T10:27:34.328463Z","iopub.status.idle":"2023-03-04T10:27:34.334797Z","shell.execute_reply.started":"2023-03-04T10:27:34.328426Z","shell.execute_reply":"2023-03-04T10:27:34.333073Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data = pd.read_parquet(pq_path)\ndata = data[data.type == \"face\"].head()","metadata":{"execution":{"iopub.status.busy":"2023-03-04T10:27:45.250942Z","iopub.execute_input":"2023-03-04T10:27:45.252678Z","iopub.status.idle":"2023-03-04T10:27:45.272015Z","shell.execute_reply.started":"2023-03-04T10:27:45.252533Z","shell.execute_reply":"2023-03-04T10:27:45.269998Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data","metadata":{"execution":{"iopub.status.busy":"2023-03-04T10:27:45.924751Z","iopub.execute_input":"2023-03-04T10:27:45.926252Z","iopub.status.idle":"2023-03-04T10:27:45.939867Z","shell.execute_reply.started":"2023-03-04T10:27:45.926201Z","shell.execute_reply":"2023-03-04T10:27:45.938867Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# data.describe()","metadata":{"execution":{"iopub.status.busy":"2023-03-04T10:25:21.429953Z","iopub.execute_input":"2023-03-04T10:25:21.430416Z","iopub.status.idle":"2023-03-04T10:25:21.436319Z","shell.execute_reply.started":"2023-03-04T10:25:21.430375Z","shell.execute_reply":"2023-03-04T10:25:21.434816Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data.type.describe()","metadata":{"execution":{"iopub.status.busy":"2023-03-04T10:28:25.096820Z","iopub.execute_input":"2023-03-04T10:28:25.098170Z","iopub.status.idle":"2023-03-04T10:28:25.110435Z","shell.execute_reply.started":"2023-03-04T10:28:25.098114Z","shell.execute_reply":"2023-03-04T10:28:25.108987Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data.type.value_counts()","metadata":{"execution":{"iopub.status.busy":"2023-03-04T10:28:25.381084Z","iopub.execute_input":"2023-03-04T10:28:25.381782Z","iopub.status.idle":"2023-03-04T10:28:25.392354Z","shell.execute_reply.started":"2023-03-04T10:28:25.381727Z","shell.execute_reply":"2023-03-04T10:28:25.390641Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# data.frame.describe()","metadata":{"execution":{"iopub.status.busy":"2023-03-04T10:26:32.677761Z","iopub.execute_input":"2023-03-04T10:26:32.679214Z","iopub.status.idle":"2023-03-04T10:26:32.684632Z","shell.execute_reply.started":"2023-03-04T10:26:32.679154Z","shell.execute_reply":"2023-03-04T10:26:32.683436Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# data.frame.value_counts()","metadata":{"execution":{"iopub.status.busy":"2023-03-04T10:26:37.693619Z","iopub.execute_input":"2023-03-04T10:26:37.694054Z","iopub.status.idle":"2023-03-04T10:26:37.699613Z","shell.execute_reply.started":"2023-03-04T10:26:37.694013Z","shell.execute_reply":"2023-03-04T10:26:37.698025Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# data[540:600]","metadata":{"execution":{"iopub.status.busy":"2023-03-04T10:26:44.104179Z","iopub.execute_input":"2023-03-04T10:26:44.105138Z","iopub.status.idle":"2023-03-04T10:26:44.110936Z","shell.execute_reply.started":"2023-03-04T10:26:44.105084Z","shell.execute_reply":"2023-03-04T10:26:44.109459Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# data.tail(20)","metadata":{"execution":{"iopub.status.busy":"2023-03-04T10:26:50.839197Z","iopub.execute_input":"2023-03-04T10:26:50.839609Z","iopub.status.idle":"2023-03-04T10:26:50.845648Z","shell.execute_reply.started":"2023-03-04T10:26:50.839573Z","shell.execute_reply":"2023-03-04T10:26:50.844187Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Import Libraries","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport tensorflow as tf\nfrom tqdm import tqdm\nimport json\nimport os","metadata":{"execution":{"iopub.status.busy":"2023-03-04T10:14:47.989795Z","iopub.execute_input":"2023-03-04T10:14:47.990243Z","iopub.status.idle":"2023-03-04T10:14:59.053308Z","shell.execute_reply.started":"2023-03-04T10:14:47.990206Z","shell.execute_reply":"2023-03-04T10:14:59.051882Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Utilities","metadata":{}},{"cell_type":"code","source":"# ROWS_PER_FRAME = 543  # number of landmarks per frame\n# ROWS_PER_FRAME = 5  # number of landmarks per frame\nROWS_PER_FRAME = 1  # number of landmarks per frame\n\n\ndef load_relevant_data_subset_with_imputation(pq_path):\n    print(\"========\\n\")\n    print(\"pq_path=\", pq_path)\n#     data = pd.read_parquet(pq_path, columns=data_columns)\n    data = pd.read_parquet(pq_path)\n    print(\"data.shape=\", data.shape)\n    \n    data.replace(np.nan, 0, inplace=True)\n    \n    data_face = data[data.type == \"face\"]\n    print(\"\\n data_face.shape=\", data_face.shape)\n#     print(\"data_face.head()=\\n\", data_face.head())\n    \n    data_columns = ['x', 'y', 'z']\n    data_subset = data_face[data_columns].head(ROWS_PER_FRAME)\n    print(\"\\n data_subset.shape=\", data_subset.shape)\n    print(\"data_subset.head()=\\n\", data_subset.head())\n    \n    \n#     n_frames = int(len(data_subset) / ROWS_PER_FRAME)\n    n_frames = 1\n#     print(\"n_frames=\", n_frames)\n#     print(\"ROWS_PER_FRAME=\", ROWS_PER_FRAME)\n    \n    data_subset_reshaped = data_subset.values.reshape(n_frames, ROWS_PER_FRAME, len(data_columns))\n#     print(\"data_subset_reshaped=\", data_subset_reshaped)\n    return data_subset_reshaped.astype(np.float32)\n\ndef load_relevant_data_subset(pq_path):\n    data_columns = ['x', 'y', 'z']\n    data = pd.read_parquet(pq_path, columns=data_columns)\n    n_frames = int(len(data) / ROWS_PER_FRAME)\n    data = data.values.reshape(n_frames, ROWS_PER_FRAME, len(data_columns))\n    return data.astype(np.float32)\n\ndef read_dict(file_path):\n    path = os.path.expanduser(file_path)\n    with open(path, \"r\") as f:\n        dic = json.load(f)\n    return dic","metadata":{"execution":{"iopub.status.busy":"2023-03-04T11:13:21.844757Z","iopub.execute_input":"2023-03-04T11:13:21.846084Z","iopub.status.idle":"2023-03-04T11:13:21.857899Z","shell.execute_reply.started":"2023-03-04T11:13:21.846025Z","shell.execute_reply":"2023-03-04T11:13:21.856189Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Load data","metadata":{}},{"cell_type":"code","source":"train = pd.read_csv(f\"{CFG.data_path}train.csv\")\nlabel_index = read_dict(f\"{CFG.data_path}sign_to_prediction_index_map.json\")\nindex_label = dict([(label_index[key], key) for key in label_index])\nprint(\"label_index=\", label_index)\ntrain[\"label\"] = train[\"sign\"].map(lambda sign: label_index[sign])\ntrain.head()","metadata":{"execution":{"iopub.status.busy":"2023-03-04T11:13:23.122603Z","iopub.execute_input":"2023-03-04T11:13:23.123066Z","iopub.status.idle":"2023-03-04T11:13:23.313332Z","shell.execute_reply.started":"2023-03-04T11:13:23.123023Z","shell.execute_reply":"2023-03-04T11:13:23.311998Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Create TF-Record","metadata":{}},{"cell_type":"code","source":"def create_record(feature, label):\n    dic = {}\n    dic[\"feature\"] = tf.train.Feature(float_list=tf.train.FloatList(value=feature))\n    dic[\"label\"] = tf.train.Feature(int64_list=tf.train.Int64List(value=[label]))\n    \n#     print(\"dic=\", dic)\n    \n    record_bytes = tf.train.Example(features=tf.train.Features(feature=dic)).SerializeToString()\n#     print(\"record_bytes=\", record_bytes)\n\n    return record_bytes\n    \ndef decode_function(record_bytes):\n  return tf.io.parse_single_example(\n      # Data\n      record_bytes,\n      # Schema\n      {\n          \"feature\": tf.io.FixedLenFeature([CFG.sequence_length * CFG.rows_per_frame * 3], dtype=tf.float32),\n          \"label\": tf.io.FixedLenFeature([], dtype=tf.int64)\n      }\n  )","metadata":{"execution":{"iopub.status.busy":"2023-03-04T11:13:24.639873Z","iopub.execute_input":"2023-03-04T11:13:24.640360Z","iopub.status.idle":"2023-03-04T11:13:24.649849Z","shell.execute_reply.started":"2023-03-04T11:13:24.640321Z","shell.execute_reply":"2023-03-04T11:13:24.648032Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CFG:\n    data_path = \"../input/asl-signs/\"\n    sequence_length = 1\n#     sequence_length = 12\n#     rows_per_frame = 543 \n    rows_per_frame = 1 \n    ","metadata":{"execution":{"iopub.status.busy":"2023-03-04T11:13:25.337787Z","iopub.execute_input":"2023-03-04T11:13:25.338207Z","iopub.status.idle":"2023-03-04T11:13:25.344210Z","shell.execute_reply.started":"2023-03-04T11:13:25.338171Z","shell.execute_reply":"2023-03-04T11:13:25.342856Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# CFG()","metadata":{"execution":{"iopub.status.busy":"2023-03-04T11:13:26.604541Z","iopub.execute_input":"2023-03-04T11:13:26.605022Z","iopub.status.idle":"2023-03-04T11:13:26.610399Z","shell.execute_reply.started":"2023-03-04T11:13:26.604985Z","shell.execute_reply":"2023-03-04T11:13:26.609119Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for participant_id in train.participant_id.unique():\n    print(\"========\\n\")\n    print(\"participant_id=\", participant_id)\n    \n    df = train[train.participant_id == participant_id]\n#     print(\"Input df=\", df)\n    save_path = f\"{participant_id}.tfrecords\"\n    with tf.io.TFRecordWriter(save_path) as file_writer:\n        for i in tqdm(range(len(df))):\n            path = f\"{CFG.data_path}{df.iloc[i].path}\"\n            feature = load_relevant_data_subset_with_imputation(path)\n#             print(\"feature=\", feature)\n            \n            feature_resized = tf.image.resize(tf.constant(feature), (CFG.sequence_length, CFG.rows_per_frame)).numpy().reshape(-1)\n            print(\"feature_resized=\", feature_resized)\n\n            label = int(df.iloc[i].label)\n            print(\"label=\", label)\n            \n            file_writer.write(create_record(feature_resized, label))","metadata":{"execution":{"iopub.status.busy":"2023-03-04T11:13:27.348223Z","iopub.execute_input":"2023-03-04T11:13:27.349667Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! ls  -ahl","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}