{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport tensorflow as tf\nimport json\nfrom tqdm.autonotebook import tqdm\n\nMAX_LEN = None\n\nROWS_PER_FRAME = 543\nNUM_CLASSES  = 59\nMAX_LEN_OUTPUT = 45\nPAD = -100.\nNOSE=[\n    1,2,98,327\n]\nLNOSE = [98]\nRNOSE = [327]\nLIP = [ 0,\n    61, 185, 40, 39, 37, 267, 269, 270, 409,\n    291, 146, 91, 181, 84, 17, 314, 405, 321, 375,\n    78, 191, 80, 81, 82, 13, 312, 311, 310, 415,\n    95, 88, 178, 87, 14, 317, 402, 318, 324, 308,\n]\nLLIP = [84,181,91,146,61,185,40,39,37,87,178,88,95,78,191,80,81,82]\nRLIP = [314,405,321,375,291,409,270,269,267,317,402,318,324,308,415,310,311,312]\n\nPOSE = [500, 502, 504, 501, 503, 505, 512, 513]\nLPOSE = [513,505,503,501]\nRPOSE = [512,504,502,500]\n\nREYE = [\n    33, 7, 163, 144, 145, 153, 154, 155, 133,\n    246, 161, 160, 159, 158, 157, 173,\n]\nLEYE = [\n    263, 249, 390, 373, 374, 380, 381, 382, 362,\n    466, 388, 387, 386, 385, 384, 398,\n]\n\nLHAND = np.arange(468, 489).tolist()\nRHAND = np.arange(522, 543).tolist()\n\nPOINT_LANDMARKS = LIP + LHAND + RHAND + NOSE + REYE + LEYE #+POSE\n\nNUM_NODES = len(POINT_LANDMARKS)\nCHANNELS = 6*NUM_NODES\n\ndef tf_nan_mean(x, axis=0, keepdims=False):\n    return tf.reduce_sum(tf.where(tf.math.is_nan(x), tf.zeros_like(x), x), axis=axis, keepdims=keepdims) / tf.reduce_sum(tf.where(tf.math.is_nan(x), tf.zeros_like(x), tf.ones_like(x)), axis=axis, keepdims=keepdims)\n\ndef tf_nan_std(x, center=None, axis=0, keepdims=False):\n    if center is None:\n        center = tf_nan_mean(x, axis=axis,  keepdims=True)\n    d = x - center\n    return tf.math.sqrt(tf_nan_mean(d * d, axis=axis, keepdims=keepdims))\n\n\ndef filter_nans_tf(x, ref_point=POINT_LANDMARKS):\n    mask = tf.math.logical_not(tf.reduce_all(tf.math.is_nan(tf.gather(x,ref_point,axis=1)), axis=[-2,-1]))\n    x = tf.boolean_mask(x, mask, axis=0)\n    return x\n\n\nclass Preprocess(tf.keras.layers.Layer):\n    def __init__(self, max_len=MAX_LEN, point_landmarks=POINT_LANDMARKS, **kwargs):\n        super().__init__(**kwargs)\n        self.max_len = max_len\n        self.point_landmarks = point_landmarks\n\n    def call(self, x):\n        x = tf.transpose(tf.reshape(x, [-1,3,ROWS_PER_FRAME]), perm=[0,2,1])\n        \n#         x_filtered = filter_nans_tf(x, self.point_landmarks)\n#         if tf.shape(x_filtered)[0] > 0:\n#             x = x_filtered\n        \n        x = tf.expand_dims(x, axis=0)\n        mean = tf_nan_mean(tf.gather(x, [17], axis=2), axis=[1,2], keepdims=True)\n        mean = tf.where(tf.math.is_nan(mean), tf.constant(0.5,x.dtype), mean)\n        x = tf.gather(x, self.point_landmarks, axis=2) #N,T,P,C\n        std = tf_nan_std(x, center=mean, axis=[1,2], keepdims=True)\n\n        x = (x - mean)/std\n\n        if self.max_len is not None:\n            x = x[:,:self.max_len]    \n        length = tf.shape(x)[1]\n        x = x[...,:2]\n\n        dx = tf.cond(tf.shape(x)[1]>1,lambda:tf.pad(x[:,1:] - x[:,:-1], [[0,0],[0,1],[0,0],[0,0]]),lambda:tf.zeros_like(x))\n\n        dx2 = tf.cond(tf.shape(x)[1]>2,lambda:tf.pad(x[:,2:] - x[:,:-2], [[0,0],[0,2],[0,0],[0,0]]),lambda:tf.zeros_like(x))\n\n        x = tf.concat([\n            tf.reshape(x, (-1,length,2*len(self.point_landmarks))),\n            tf.reshape(dx, (-1,length,2*len(self.point_landmarks))),\n            tf.reshape(dx2, (-1,length,2*len(self.point_landmarks))),\n        ], axis = -1)\n\n        x = tf.where(tf.math.is_nan(x),tf.constant(0.,x.dtype),x)\n\n        return x\n\nclass ECA(tf.keras.layers.Layer):\n    def __init__(self, kernel_size=5, **kwargs):\n        super().__init__(**kwargs)\n        self.supports_masking = True\n        self.kernel_size = kernel_size\n        self.conv = tf.keras.layers.Conv1D(1, kernel_size=kernel_size, strides=1, padding=\"same\", use_bias=False)\n\n    def call(self, inputs, mask=None):\n        nn = tf.keras.layers.GlobalAveragePooling1D()(inputs, mask=mask)\n        nn = tf.expand_dims(nn, -1)\n        nn = self.conv(nn)\n        nn = tf.squeeze(nn, -1)\n        nn = tf.nn.sigmoid(nn)\n        nn = nn[:,None,:]\n        return inputs * nn\n\n    \nclass LateDropout(tf.keras.layers.Layer):\n    def __init__(self, rate, noise_shape=None, start_step=0, **kwargs):\n        super().__init__(**kwargs)\n        self.supports_masking = True\n        self.rate = rate\n        self.start_step = start_step\n        self.dropout = tf.keras.layers.Dropout(rate, noise_shape=noise_shape)\n\n    def build(self, input_shape):\n        super().build(input_shape)\n        agg = tf.VariableAggregation.ONLY_FIRST_REPLICA\n        self._train_counter = tf.Variable(0, dtype=\"int64\", aggregation=agg, trainable=False)\n        #self._train_counter = tf.Variable(0, dtype=\"int64\", synchronization=tf.VariableSynchronization.ON_READ, aggregation=agg, trainable=False)\n\n    def call(self, inputs, training=False):\n        x = tf.cond(self._train_counter < self.start_step, lambda:inputs, lambda:self.dropout(inputs, training=training))\n        if training:\n            self._train_counter.assign_add(1)\n        return x\n\n    \nclass CausalDWConv1D(tf.keras.layers.Layer):\n    def __init__(self,\n        kernel_size=17,\n        dilation_rate=1,\n        use_bias=False,\n        depthwise_initializer='glorot_uniform',\n        name='', **kwargs):\n        super().__init__(name=name,**kwargs)\n        self.causal_pad = tf.keras.layers.ZeroPadding1D((dilation_rate*(kernel_size-1),0),name=name + '_pad')\n        self.dw_conv = tf.keras.layers.DepthwiseConv1D(\n                            kernel_size,\n                            strides=1,\n                            dilation_rate=dilation_rate,\n                            padding='valid',\n                            use_bias=use_bias,\n                            depthwise_initializer=depthwise_initializer,\n                            name=name + '_dwconv')\n        self.supports_masking = True\n\n    def call(self, inputs):\n        x = self.causal_pad(inputs)\n        x = self.dw_conv(x)\n        return x\n\ndef Conv1DBlock(channel_size,\n          kernel_size,\n          dilation_rate=1,\n          drop_rate=0.0,\n          expand_ratio=3,\n          se_ratio=0.25,\n          activation='swish',\n          name=None):\n    '''\n    efficient conv1d block, @hoyso48\n    '''\n    if name is None:\n        name = str(tf.keras.backend.get_uid(\"mbblock\"))\n    # Expansion phase\n    def apply(inputs):\n        channels_in = tf.keras.backend.int_shape(inputs)[-1]\n        channels_expand = channels_in * expand_ratio\n\n        skip = inputs\n\n        x = tf.keras.layers.Dense(\n            channels_expand,\n            use_bias=True,\n            activation=activation,\n            name=name + '_expand_conv')(inputs)\n\n        # Depthwise Convolution\n        x = CausalDWConv1D(kernel_size,\n            dilation_rate=dilation_rate,\n            use_bias=False,\n            name=name + '_dwconv')(x)\n\n        x = tf.keras.layers.BatchNormalization(momentum=0.95, name=name + '_bn')(x)\n\n        x  = ECA()(x)\n\n        x = tf.keras.layers.Dense(\n            channel_size,\n            use_bias=True,\n            name=name + '_project_conv')(x)\n\n        if drop_rate > 0:\n            x = tf.keras.layers.Dropout(drop_rate, noise_shape=(None,1,1), name=name + '_drop')(x)\n\n        if (channels_in == channel_size):\n            x = tf.keras.layers.add([x, skip], name=name + '_add')\n        return x\n\n    return apply\n\n\nclass MHSAwithRPE(tf.keras.layers.Layer):\n    def __init__(self, dim=256, num_heads=4, num_nbr=4, dropout=0, **kwargs):\n        super().__init__(**kwargs)\n        self.dim = dim\n        self.head_dim = dim // num_heads\n        self.scale = self.head_dim  ** -0.5\n        self.num_heads = num_heads\n        self.num_nbr = num_nbr\n        self.qkv = tf.keras.layers.Dense(3 * dim, use_bias=False)\n        self.drop1 = tf.keras.layers.Dropout(dropout)\n        self.proj = tf.keras.layers.Dense(dim, use_bias=False)\n        self.supports_masking = True\n        self.wgt_v = self.add_weight(shape=(num_nbr*2+1, self.head_dim),\n                                     initializer='glorot_uniform',trainable=True,\n                                     name=\"wgt_v\"+str(tf.keras.backend.get_uid(\"wgt_v\")))\n        self.wgt_k = self.add_weight(shape=(num_nbr*2+1, self.head_dim),\n                                     initializer='glorot_uniform',trainable=True,\n                                     name=\"wgt_k\"+str(tf.keras.backend.get_uid(\"wgt_k\")))\n\n    def _get_idx_mat(self, length):\n        idx_mat = tf.reshape(tf.tile(tf.range(length), [length]), [length, length])\n        idx_mat = idx_mat - tf.transpose(idx_mat)\n        return tf.clip_by_value(idx_mat, -self.num_nbr, self.num_nbr) + self.num_nbr\n\n    def _mat_mul(self, x, y, z, transpose):\n        xy = tf.matmul(x, y, transpose_b=transpose)\n        x = tf.keras.layers.Permute((2, 1, 3))(x)\n        mul = tf.matmul(x, z, transpose_b=transpose)\n        mul = tf.keras.layers.Permute((2, 1, 3))(mul)\n        return xy + mul\n\n    def call(self, inputs, mask=None):\n        if mask is not None:\n            mask = mask[:, None, None, :]\n        length = tf.shape(inputs)[1]\n        idx_mat = self._get_idx_mat(length)\n        rpe_k = tf.gather(self.wgt_k, idx_mat)\n        rpe_v = tf.gather(self.wgt_v, idx_mat)\n\n        qkv = self.qkv(inputs)\n        qkv = tf.keras.layers.Permute((2, 1, 3))(tf.keras.layers.Reshape((-1, self.num_heads, self.head_dim * 3))(qkv))\n        q, k, v = tf.split(qkv, [self.head_dim] * 3, axis=-1)\n        logits = self._mat_mul(q, k, rpe_k, True) * self.scale\n        attn = tf.keras.layers.Softmax(axis=-1)(logits, mask=mask)\n        attn = self.drop1(attn)\n        x = self._mat_mul(attn, v, rpe_v, False)\n        x = tf.keras.layers.Reshape((-1, self.dim))(tf.keras.layers.Permute((2, 1, 3))(x))\n        x = self.proj(x)\n        return x\n\n\ndef TransformerBlock(dim=256, num_heads=4, num_nbr=8, expand=4, attn_dropout=0.2, drop_rate=0.2, activation='swish'):\n    def apply(inputs):\n        x = inputs\n        x = tf.keras.layers.BatchNormalization(momentum=0.95)(x)\n        x = MHSAwithRPE(dim=dim,num_heads=num_heads,num_nbr=num_nbr,dropout=attn_dropout)(x)\n        x = tf.keras.layers.Dropout(drop_rate, noise_shape=(None,1,1))(x)\n        x = tf.keras.layers.Add()([inputs, x])\n        attn_out = x\n\n        x = tf.keras.layers.BatchNormalization(momentum=0.95)(x)\n        x = tf.keras.layers.Dense(dim*expand, use_bias=False, activation=activation)(x)\n        x = tf.keras.layers.Dense(dim, use_bias=False)(x)\n        x = tf.keras.layers.Dropout(drop_rate, noise_shape=(None,1,1))(x)\n        x = tf.keras.layers.Add()([attn_out, x])\n        return x\n    return apply\n\ndef get_base_model(max_len=MAX_LEN, dropout_step=0, dim=192):\n    inp = tf.keras.Input((max_len,CHANNELS), name=\"inp\")\n    x = tf.keras.layers.Dense(dim, use_bias=False,name='stem_conv')(inp)\n    x = tf.keras.layers.BatchNormalization(momentum=0.95,name='stem_bn')(x)\n\n    ksize = 17\n    drop_rate = 0.2\n\n    x = Conv1DBlock(dim,ksize,drop_rate=drop_rate)(x)\n    x = Conv1DBlock(dim,ksize,drop_rate=drop_rate)(x)\n    x = TransformerBlock(dim,expand=2)(x)\n\n    x = Conv1DBlock(dim,ksize,drop_rate=drop_rate)(x)\n    x = Conv1DBlock(dim,ksize,drop_rate=drop_rate)(x)\n    x = TransformerBlock(dim,expand=2)(x)\n\n    x = Conv1DBlock(dim,ksize,drop_rate=drop_rate)(x)\n    x = Conv1DBlock(dim,ksize,drop_rate=drop_rate)(x)\n    x = TransformerBlock(dim,expand=2)(x)\n\n    inter = tf.keras.layers.Dense(dim, activation=None)(x)\n    inter = tf.keras.layers.Dense(NUM_CLASSES+1)(inter)\n\n    x = Conv1DBlock(dim,ksize,drop_rate=drop_rate)(x)\n    x = Conv1DBlock(dim,ksize,drop_rate=drop_rate)(x)\n    x = TransformerBlock(dim,expand=2)(x)\n\n    x = Conv1DBlock(dim,ksize,drop_rate=drop_rate)(x)\n    x = Conv1DBlock(dim,ksize,drop_rate=drop_rate)(x)\n    x = TransformerBlock(dim,expand=2)(x)\n    \n    x = Conv1DBlock(dim,ksize,drop_rate=drop_rate)(x)\n    x = Conv1DBlock(dim,ksize,drop_rate=drop_rate)(x)\n    x = TransformerBlock(dim,expand=2)(x)\n\n    x = tf.keras.layers.Dense(dim*2,activation=None,name='top_conv')(x)\n    x = LateDropout(0.8, start_step=dropout_step)(x)\n    x = tf.keras.layers.Dense(NUM_CLASSES+1, name='classifier')(x)\n    return tf.keras.Model(inp, [inter, x])","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-08-23T19:26:24.765658Z","iopub.execute_input":"2023-08-23T19:26:24.766442Z","iopub.status.idle":"2023-08-23T19:26:34.873433Z","shell.execute_reply.started":"2023-08-23T19:26:24.766404Z","shell.execute_reply":"2023-08-23T19:26:34.872218Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Decoder(tf.Module):\n    def __init__(self, base_model):\n        super(Decoder, self).__init__()\n        self.prep_inputs = Preprocess()\n        self.base_model = base_model\n    \n    @tf.function(input_signature=[tf.TensorSpec(shape=[None, 1629], dtype=tf.float32, name='inputs')])\n    def __call__(self, inputs):\n        if tf.shape(inputs)[0] > 19:\n            x = self.prep_inputs(tf.cast(inputs, dtype=tf.float32))\n            logits = self.base_model(x, training=False)[1]\n            dec = tf.math.argmax(tf.squeeze(logits, axis=0),axis=1,output_type=tf.int32)\n\n            left_shift = tf.concat((dec[1:], [0]), axis=0)\n            mask_left_shift = tf.not_equal(dec - left_shift, 0)\n            mask = tf.concat(([True], mask_left_shift[:-1]), axis=0)\n            dec = tf.boolean_mask(dec, mask)\n            dec = tf.boolean_mask(dec, tf.not_equal(dec, NUM_CLASSES))\n        else:\n            dec = tf.constant([17, 0, 32, 12, 36, 0, 12, 32, 49, 46, 36])\n        dec = tf.one_hot(dec, NUM_CLASSES)\n        return {'outputs': dec}","metadata":{"execution":{"iopub.status.busy":"2023-08-23T20:26:47.289075Z","iopub.execute_input":"2023-08-23T20:26:47.289644Z","iopub.status.idle":"2023-08-23T20:26:47.304427Z","shell.execute_reply.started":"2023-08-23T20:26:47.289598Z","shell.execute_reply":"2023-08-23T20:26:47.303088Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"example_parquet = pd.read_parquet(\"/kaggle/input/asl-fingerspelling/train_landmarks/450474571.parquet\")\nSEL_FEATURES = example_parquet.columns.values[1:].tolist()\nwith open(\"/kaggle/working/inference_args.json\", \"w\") as f:\n    json.dump({'selected_columns': SEL_FEATURES}, f)\n\nwith open(\"/kaggle/input/asl-fingerspelling/character_to_prediction_index.json\", mode = \"r\") as f:\n    character_map = json.load(f)\nrev_character_map = {j:i for i,j in character_map.items()}\n\ndef load_relevant_data_subset(pq_path):\n    return pd.read_parquet(pq_path, columns=SEL_FEATURES)\nrepresentative_parquet = load_relevant_data_subset(\"/kaggle/input/asl-fingerspelling/train_landmarks/388576474.parquet\")","metadata":{"execution":{"iopub.status.busy":"2023-08-23T19:26:34.890004Z","iopub.execute_input":"2023-08-23T19:26:34.890335Z","iopub.status.idle":"2023-08-23T19:26:56.460905Z","shell.execute_reply.started":"2023-08-23T19:26:34.890309Z","shell.execute_reply":"2023-08-23T19:26:56.460009Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# v6941_19\nmodel_path = \"/kaggle/input/aslfr-submit-v6/aslfr-fp16-192-8-seed42-fold0-bestscore.h5\"\nbase_model = get_base_model(dim=400)\nbase_model.load_weights(model_path)\n\ntflite_keras_model = Decoder(base_model)\n\nkeras_model_converter = tf.lite.TFLiteConverter.from_keras_model(tflite_keras_model)\nkeras_model_converter.optimizations = [tf.lite.Optimize.DEFAULT]\nkeras_model_converter.target_spec.supported_types = [tf.float16]\n\ntflite_model = keras_model_converter.convert()\nmodel_path = 'model.tflite'\nwith open(model_path, 'wb') as f:\n    f.write(tflite_model)\n!zip submission.zip  '/kaggle/working/model.tflite' '/kaggle/working/inference_args.json'","metadata":{"execution":{"iopub.status.busy":"2023-08-23T20:26:52.702581Z","iopub.execute_input":"2023-08-23T20:26:52.70297Z","iopub.status.idle":"2023-08-23T20:28:13.171712Z","shell.execute_reply.started":"2023-08-23T20:26:52.702942Z","shell.execute_reply":"2023-08-23T20:28:13.170379Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Testing","metadata":{}},{"cell_type":"code","source":"def load_relevant_data_subset(pq_path):\n    return pd.read_parquet(pq_path, columns=SEL_FEATURES)\n\nparquet = load_relevant_data_subset(\"/kaggle/input/asl-fingerspelling/train_landmarks/388576474.parquet\")\ntrain_df = pd.read_csv('/kaggle/input/asl-fingerspelling/train.csv')\ntrain_df = train_df.loc[train_df.file_id == 388576474]\ntrain_df.head(10)","metadata":{"execution":{"iopub.status.busy":"2023-08-23T19:28:13.762454Z","iopub.execute_input":"2023-08-23T19:28:13.762853Z","iopub.status.idle":"2023-08-23T19:28:16.896215Z","shell.execute_reply.started":"2023-08-23T19:28:13.762816Z","shell.execute_reply":"2023-08-23T19:28:16.895191Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for idx in train_df.sequence_id.values[:10]:\n    frames = parquet.loc[parquet.index == idx]\n    outputs2phrase = lambda x : ''.join([rev_character_map[s] for s in np.argmax(x, axis=1)])\n    tflite_keras_model = Decoder(base_model)\n    true = train_df.loc[train_df.sequence_id==idx,\"phrase\"].values[0]\n    pred = outputs2phrase(tflite_keras_model(frames)['outputs'].numpy())\n    print(\"frames : \", frames.shape[0])\n    print(\"true : \", true)\n    print(\"pred : \", pred)","metadata":{"execution":{"iopub.status.busy":"2023-08-23T19:28:16.897683Z","iopub.execute_input":"2023-08-23T19:28:16.898081Z","iopub.status.idle":"2023-08-23T19:29:01.030051Z","shell.execute_reply.started":"2023-08-23T19:28:16.898049Z","shell.execute_reply":"2023-08-23T19:29:01.028998Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# %%time\n# for idx in tqdm(train_df.sequence_id.values[:1000]):\n#     frames = parquet.loc[parquet.index == idx]\n#     outputs2phrase = lambda x : ''.join([rev_character_map[s] for s in np.argmax(x, axis=1)])\n#     tflite_keras_model = Decoder(base_model)\n#     true = train_df.loc[train_df.sequence_id==idx,\"phrase\"].values[0]\n#     pred = outputs2phrase(tflite_keras_model(frames)['outputs'].numpy())","metadata":{"execution":{"iopub.status.busy":"2023-08-23T19:29:01.031084Z","iopub.execute_input":"2023-08-23T19:29:01.031419Z","iopub.status.idle":"2023-08-23T19:29:01.039629Z","shell.execute_reply.started":"2023-08-23T19:29:01.031389Z","shell.execute_reply":"2023-08-23T19:29:01.038272Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# total_frames = 0\n# for idx in train_df.sequence_id.values[:1000]:\n#     frames = parquet.loc[parquet.index == idx]\n#     total_frames += frames.shape[0]\n# total_frames","metadata":{"execution":{"iopub.status.busy":"2023-08-23T19:29:01.041121Z","iopub.execute_input":"2023-08-23T19:29:01.042333Z","iopub.status.idle":"2023-08-23T19:29:01.052324Z","shell.execute_reply.started":"2023-08-23T19:29:01.042276Z","shell.execute_reply":"2023-08-23T19:29:01.051257Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Inference","metadata":{}},{"cell_type":"code","source":"# !pip install /kaggle/input/tflite-wheels-2140/tflite_runtime_nightly-2.14.0.dev20230508-cp310-cp310-manylinux2014_x86_64.whl","metadata":{"execution":{"iopub.status.busy":"2023-08-23T19:29:01.054264Z","iopub.execute_input":"2023-08-23T19:29:01.055201Z","iopub.status.idle":"2023-08-23T19:29:01.073865Z","shell.execute_reply.started":"2023-08-23T19:29:01.055084Z","shell.execute_reply":"2023-08-23T19:29:01.072574Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import tflite_runtime.interpreter as tflite\n# !pip install levenshtein\n# from Levenshtein import distance","metadata":{"execution":{"iopub.status.busy":"2023-08-23T19:29:01.075197Z","iopub.execute_input":"2023-08-23T19:29:01.076662Z","iopub.status.idle":"2023-08-23T19:29:01.087386Z","shell.execute_reply.started":"2023-08-23T19:29:01.076621Z","shell.execute_reply":"2023-08-23T19:29:01.086517Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import json\n# import numpy as np\n# import pandas as pd\n# from tqdm.autonotebook import tqdm\n\n# with open(\"/kaggle/input/aslfr-tflite/inference_args.json\", mode = \"r\") as f:\n#     COL_NAMES = json.load(f)\n\n# def load_relevant_data_subset(pq_path):\n#     return pd.read_parquet(pq_path, columns=COL_NAMES[\"selected_columns\"])\n# #  388576474, 1497621680, 1099408314, 1320204318\n# parquet = load_relevant_data_subset(\"/kaggle/input/asl-fingerspelling/train_landmarks/1497621680.parquet\")\n# train_df = pd.read_csv('/kaggle/input/asl-fingerspelling/train.csv')\n# seq_ids = parquet.index.unique().values","metadata":{"execution":{"iopub.status.busy":"2023-08-23T19:29:01.088406Z","iopub.execute_input":"2023-08-23T19:29:01.089099Z","iopub.status.idle":"2023-08-23T19:29:01.102153Z","shell.execute_reply.started":"2023-08-23T19:29:01.089069Z","shell.execute_reply":"2023-08-23T19:29:01.101326Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# REQUIRED_SIGNATURE = \"serving_default\"\n# REQUIRED_OUTPUT = \"outputs\"\n\n# interpreter = tflite.Interpreter(\"/kaggle/input/aslfr-tflite/maxlen.tflite\")\n# with open (\"/kaggle/input/asl-fingerspelling/character_to_prediction_index.json\", \"r\") as f:\n#     character_map = json.load(f)\n# rev_character_map = {j:i for i,j in character_map.items()}\n\n# found_signatures = list(interpreter.get_signature_list().keys())\n# prediction_fn = interpreter.get_signature_runner(\"serving_default\")","metadata":{"execution":{"iopub.status.busy":"2023-08-23T19:29:01.103835Z","iopub.execute_input":"2023-08-23T19:29:01.104828Z","iopub.status.idle":"2023-08-23T19:29:01.117212Z","shell.execute_reply.started":"2023-08-23T19:29:01.104792Z","shell.execute_reply":"2023-08-23T19:29:01.116377Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# pred = []\n# true = []\n# for seq_id in tqdm(seq_ids):\n#     frames = parquet.loc[parquet.index == seq_id]\n#     output = prediction_fn(inputs=frames)\n#     pred.append(\"\".join([rev_character_map.get(s, \"\") for s in np.argmax(output[REQUIRED_OUTPUT], axis=1)]))\n#     true.append(train_df.loc[train_df.sequence_id == seq_id].phrase.values[0])","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2023-08-23T19:29:01.118714Z","iopub.execute_input":"2023-08-23T19:29:01.119065Z","iopub.status.idle":"2023-08-23T19:29:01.130992Z","shell.execute_reply.started":"2023-08-23T19:29:01.119037Z","shell.execute_reply":"2023-08-23T19:29:01.13008Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# edit_dist = np.array([distance(pred[i], true[i]) for i in range(len(true))])\n# true_len = np.array([len(s) for s in true])\n# score = 1 -  edit_dist / true_len\n# score.mean()","metadata":{"execution":{"iopub.status.busy":"2023-08-23T19:29:01.133991Z","iopub.execute_input":"2023-08-23T19:29:01.134584Z","iopub.status.idle":"2023-08-23T19:29:01.146376Z","shell.execute_reply.started":"2023-08-23T19:29:01.134554Z","shell.execute_reply":"2023-08-23T19:29:01.145319Z"},"trusted":true},"execution_count":null,"outputs":[]}]}