{"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":"### [ pytorch transformer solution ]\n\nlocal validation CV:\n\nfold-2 by : https://www.kaggle.com/code/clemchris/asl-sign-detection-pytorch-lightning  \nstratification by participant id (i.e. train and validation participant id does not overlap)\n\n- time_taken =  ~30 msec per video (or 25 min for all 40_000 hidden test video)\n- crop entropy loss = 1.9538569450378418\n- topk[0] = 0.5876061120543293\n- topk[1] = 0.7024900962082626\n- topk[2] = 0.755461233729485\n- topk[3] = 0.7844934917940012\n- topk[4] = 0.8033955857385399\n\nLB = 0.62\n\nsetting :\nembed_dim = 512  \nlength    = 60  \nnum_head  = 4  \nnum_block = 1  \n\nit seems that transformer solution easily gets of out memory.   \nneed to investigate more on optimal setting.  ","metadata":{}},{"cell_type":"markdown","source":"updates:\n\n- for experiment results, refer to:\nhttps://www.kaggle.com/competitions/asl-signs/discussion/391265  \n\n- it is better to use keras input_net (shape normalisation) for reasons explained here\nhttps://www.kaggle.com/competitions/asl-signs/discussion/390935#2176801  \nhttps://www.kaggle.com/competitions/asl-signs/discussion/393655#2177124  \n\n- add features like distance between points in same frame, velocity, etc\n\n\n![https://i.ibb.co/XVxP67c/Selection-999-1440.png](https://i.ibb.co/XVxP67c/Selection-999-1440.png)\n\n","metadata":{}},{"cell_type":"code","source":"#pytorch model\n\nimport torch\nimport torch.nn.functional as F\nimport torch.nn as nn\n\n#num_landmark = 543\nmax_length = 80\nnum_class  = 250\nnum_point  = 82  # LIP, LHAND, RHAND\n\ndef pack_seq(\n    seq,\n):\n    length = [len(s) for s in seq]\n    batch_size = len(seq)\n    num_landmark=seq[0].shape[1]\n\n    x = torch.zeros((batch_size, max(length), num_landmark, 3)).to(seq[0].device)\n    x_mask = torch.zeros((batch_size, max(length))).to(seq[0].device)\n    for b in range(batch_size):\n        L = length[b]\n        x[b, :L] = seq[b][:L]\n        x_mask[b, L:] = 1\n    x_mask = (x_mask>0.5)\n    x = x.reshape(batch_size,-1,num_landmark*3)\n    return x, x_mask\n\n\nclass FeedForward(nn.Module):\n    def __init__(self, embed_dim, hidden_dim):\n        super().__init__()\n        self.mlp = nn.Sequential(\n            nn.Linear(embed_dim, hidden_dim),\n            nn.ReLU(inplace=True),\n            nn.Linear(hidden_dim, embed_dim),\n        )\n    def forward(self, x):\n        return self.mlp(x)\n\n\n#https://pytorch.org/docs/stable/generated/torch.nn.MultiheadAttention.html\nclass MultiHeadAttention(nn.Module):\n    def __init__(self,\n            embed_dim,\n            num_head,\n            batch_first,\n        ):\n        super().__init__()\n        self.mha = nn.MultiheadAttention(\n            embed_dim,\n            num_heads=num_head,\n            bias=True,\n            add_bias_kv=False,\n            kdim=None,\n            vdim=None,\n            dropout=0.0,\n            batch_first=batch_first,\n        )\n\n    def forward(self, x, x_mask):\n        out, _ = self.mha(x,x,x, key_padding_mask=x_mask)\n        return out\n\n\ndef positional_encoding(length, embed_dim):\n    dim = embed_dim//2\n\n    position = np.arange(length)[:, np.newaxis]     # (seq, 1)\n    dim = np.arange(dim)[np.newaxis, :]/dim   # (1, dim)\n\n    angle = 1 / (10000**dim)         # (1, dim)\n    angle = position * angle    # (pos, dim)\n\n    pos_embed = np.concatenate(\n        [np.sin(angle), np.cos(angle)],\n        axis=-1\n    )\n    pos_embed = torch.from_numpy(pos_embed).float()\n    return pos_embed\n\nclass TransformerBlock(nn.Module):\n    def __init__(self,\n        embed_dim,\n        num_head,\n        out_dim,\n        batch_first=True,\n    ):\n        super().__init__()\n        self.attn  = MultiHeadAttention(embed_dim, num_head,batch_first)\n        self.ffn   = FeedForward(embed_dim, out_dim)\n        self.norm1 = nn.LayerNorm(embed_dim)\n        self.norm2 = nn.LayerNorm(out_dim)\n\n    def forward(self, x, x_mask=None):\n        x = x + self.attn((self.norm1(x)), x_mask)\n        x = x + self.ffn((self.norm2(x)))\n        return x\n\nclass Net(nn.Module):\n\n    def __init__(self, num_class=num_class):\n        super().__init__()\n        self.output_type = ['inference', 'loss']\n\n        num_block = 1\n        embed_dim = 1024\n        num_head  = 8\n\n        pos_embed = positional_encoding(max_length, embed_dim)\n        # self.register_buffer('pos_embed', pos_embed)\n        self.pos_embed = nn.Parameter(pos_embed)\n\n        self.cls_embed = nn.Parameter(torch.zeros((1, embed_dim)))\n        self.x_embed = nn.Sequential(\n            nn.Linear(num_point * 3, embed_dim, bias=False),\n        )\n\n        self.encoder = nn.ModuleList([\n            TransformerBlock(\n                embed_dim,\n                num_head,\n                embed_dim,\n            ) for i in range(num_block)\n        ])\n        self.logit = nn.Linear(embed_dim, num_class)\n\n    def forward(self, batch):\n        length = [len(x) for x in batch['xyz']]\n        xyz = batch['xyz']\n\n        x, x_mask = pack_seq(xyz)\n        B,L,_ = x.shape\n        x = self.x_embed(x)\n        x = x + self.pos_embed[:L].unsqueeze(0)\n\n        x = torch.cat([\n            self.cls_embed.unsqueeze(0).repeat(B,1,1),\n            x\n        ],1)\n        x_mask = torch.cat([\n            torch.zeros(B,1).to(x_mask),\n            x_mask\n        ],1)\n\n\n        #x = F.dropout(x,p=0.25,training=self.training)\n        for block in self.encoder:\n            x = block(x,x_mask)\n\n        cls = x[:,0]\n        cls = F.dropout(cls,p=0.4,training=self.training)\n        logit = self.logit(cls)\n\n        output = {}\n        if 'loss' in self.output_type:\n            output['label_loss'] = F.cross_entropy(logit, batch['label'])\n\n        if 'inference' in self.output_type:\n            output['sign'] = torch.softmax(logit,-1)\n\n        return output\n\n\ndef pre_process(xyz):\n    xyz = xyz - xyz[~torch.isnan(xyz)].mean(0,keepdims=True) #noramlisation to common mean\n    xyz = xyz / xyz[~torch.isnan(xyz)].std(0, keepdims=True)\n    \n    lip = xyz[:, LIP]\n    lhand = xyz[:, LHAND]\n    rhand = xyz[:, RHAND]\n    xyz = torch.cat([ #(none, 82, 3)\n        lip,\n        lhand,\n        rhand,\n    ],1)\n    xyz[torch.isnan(xyz)] = 0\n    xyz = xyz[:max_length]\n    return xyz\n\n\n\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-03-10T12:33:27.460682Z","iopub.execute_input":"2023-03-10T12:33:27.461572Z","iopub.status.idle":"2023-03-10T12:33:30.347138Z","shell.execute_reply.started":"2023-03-10T12:33:27.461510Z","shell.execute_reply":"2023-03-10T12:33:30.345640Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#pytorch model for tflite conversion\n\n#simplfiy for one video input \nmax_length = 96  #reduce this if gets out of memory error\n\nclass InputNet(nn.Module):\n    def __init__(self, ):\n        super().__init__()\n        self.max_length = max_length \n  \n    def forward(self, xyz):\n        xyz = xyz - xyz[~torch.isnan(xyz)].mean(0,keepdim=True) #noramlisation to common maen\n        xyz = xyz / xyz[~torch.isnan(xyz)].std(0, keepdim=True)\n\n        LIP = [\n            61, 185, 40, 39, 37, 0, 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        ]\n        #LHAND = np.arange(468, 489).tolist()\n        #RHAND = np.arange(522, 543).tolist()\n\n        lip = xyz[:, LIP]\n        lhand = xyz[:, 468:489]\n        rhand = xyz[:, 522:543]\n        xyz = torch.cat([  # (none, 82, 3)\n            lip,\n            lhand,\n            rhand,\n        ], 1)\n        xyz[torch.isnan(xyz)] = 0\n        x = xyz[:self.max_length]\n        return x\n\n\n#overwrite the model used in training ....\n\n# use fix dimension\nclass MultiHeadAttention(nn.Module):\n    def __init__(self,\n            embed_dim,\n            num_head,\n            batch_first,\n        ):\n        super().__init__()\n        self.mha = nn.MultiheadAttention(\n            embed_dim,\n            num_heads=num_head,\n            bias=True,\n            add_bias_kv=False,\n            kdim=None,\n            vdim=None,\n            dropout=0.0,\n            batch_first=batch_first,\n        )\n    #https://github.com/pytorch/text/blob/60907bf3394a97eb45056a237ca0d647a6e03216/torchtext/modules/multiheadattention.py#L5\n    def forward(self, x):\n        # out,_ = self.mha(x,x,x,need_weights=False)\n        # out,_ = F.multi_head_attention_forward(\n        #     x, x, x,\n        #     self.mha.embed_dim,\n        #     self.mha.num_heads,\n        #     self.mha.in_proj_weight,\n        #     self.mha.in_proj_bias,\n        #     self.mha.bias_k,\n        #     self.mha.bias_v,\n        #     self.mha.add_zero_attn,\n        #     0,#self.mha.dropout,\n        #     self.mha.out_proj.weight,\n        #     self.mha.out_proj.bias,\n        #     training=False,\n        #     key_padding_mask=None,\n        #     need_weights=False,\n        #     attn_mask=None,\n        #     average_attn_weights=False\n        # )\n \n        #qkv = F.linear(x, self.mha.in_proj_weight, self.mha.in_proj_bias)\n        #qkv = qkv.reshape(-1,3,1024)\n        #q,k,v = qkv[[0],0], qkv[:,1],  qkv[:,2]\n\n        q = F.linear(x[:1], self.mha.in_proj_weight[:1024], self.mha.in_proj_bias[:1024]) #since we need only cls\n        k = F.linear(x, self.mha.in_proj_weight[1024:2048], self.mha.in_proj_bias[1024:2048])\n        v = F.linear(x, self.mha.in_proj_weight[2048:], self.mha.in_proj_bias[2048:]) \n        q = q.reshape(-1, 8, 128).permute(1, 0, 2)\n        k = k.reshape(-1, 8, 128).permute(1, 2, 0)\n        v = v.reshape(-1, 8, 128).permute(1, 0, 2)\n        dot  = torch.matmul(q, k) * (1/128**0.5) # H L L\n        attn = F.softmax(dot, -1)  #   L L\n        out  = torch.matmul(attn, v)  #   L H dim\n        out  = out.permute(1, 0, 2).reshape(-1, 1024)\n        out  = F.linear(out, self.mha.out_proj.weight, self.mha.out_proj.bias)  \n        return out\n\n# remove mask\nclass TransformerBlock(nn.Module):\n    def __init__(self,\n        embed_dim,\n        num_head,\n        out_dim,\n        batch_first=True,\n    ):\n        super().__init__()\n        self.attn  = MultiHeadAttention(embed_dim, num_head,batch_first)\n        self.ffn   = FeedForward(embed_dim, out_dim)\n        self.norm1 = nn.LayerNorm(embed_dim)\n        self.norm2 = nn.LayerNorm(out_dim)\n\n    def forward(self, x): \n        x = x[:1] + self.attn((self.norm1(x)))\n        x = x + self.ffn((self.norm2(x)))\n        return x\n\nclass SingleNet(nn.Module):\n\n    def __init__(self, num_class=num_class):\n        super().__init__()\n        self.num_block = 1\n        self.embed_dim = 1024\n        self.num_head  = 8\n        self.max_length = max_length\n        self.num_point = num_point\n\n        pos_embed = positional_encoding(max_length, self.embed_dim)\n        self.pos_embed = nn.Parameter(pos_embed)\n\n        self.cls_embed = nn.Parameter(torch.zeros((1, self.embed_dim)))\n        self.x_embed = nn.Sequential(\n            nn.Linear(num_point * 3, self.embed_dim, bias=False),\n        )\n\n        self.encoder = nn.ModuleList([\n            TransformerBlock(\n                self.embed_dim,\n                self.num_head,\n                self.embed_dim,\n                batch_first=False\n            ) for i in range(self.num_block)\n        ])\n        self.logit = nn.Linear(self.embed_dim, num_class)\n\n    def forward(self, xyz):\n        L = xyz.shape[0]\n        x_embed = self.x_embed(xyz.flatten(1)) \n        x = x_embed[:L] + self.pos_embed[:L]\n        x = torch.cat([\n            self.cls_embed,\n            x\n        ],0)\n        #x = x.unsqueeze(1)\n\n        #for block in self.encoder: x = block(x) #remove tflite loop\n        x = self.encoder[0](x)\n        cls = x[[0]]\n        logit = self.logit(cls)\n        return logit\n    ","metadata":{"execution":{"iopub.status.busy":"2023-03-10T12:33:30.349970Z","iopub.execute_input":"2023-03-10T12:33:30.350695Z","iopub.status.idle":"2023-03-10T12:33:30.383263Z","shell.execute_reply.started":"2023-03-10T12:33:30.350643Z","shell.execute_reply":"2023-03-10T12:33:30.382264Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#pytorch to onnx to tflite\nif 0:\n    \n    name='transformer-pool-2b' \n    input_onnx_file   = f'{fold_dir}/{name}.input.onnx'\n    single_onnx_file  = f'{fold_dir}/{name}.single.onnx' \n    input_tf_file    = f'{fold_dir}/input_tf'\n    single_tf_file   = f'{fold_dir}/single_tf'\n    tf_file     = f'{fold_dir}/tf'\n    tflite_file = f'{fold_dir}/{name}-{max_length}.tflite'\n\n    def run_convert_onnx(): \n        if 1:\n            torch.onnx.export(\n                input_net,\n                #torch.jit.script(input_net),\n                #torch.jit.trace(input_net, torch.zeros(100,num_landmark,3)),          # model being run \n                torch.zeros((100,num_landmark,3)), # model input (or a tuple for multiple inputs)\n                input_onnx_file,             # where to save the model (can be a file or file-like object)\n                export_params = True,        # store the trained parameter weights inside the model file\n                opset_version = 12,          # the ONNX version to export the model to\n                do_constant_folding=True,    # whether to execute constant folding for optimization \n                input_names =  ['inputs'],    # the model's input names\n                output_names = ['outputs'],   # the model's output names\n                dynamic_axes={\n                    'inputs': {0: 'length'},\n                    #'output': {0: 'length'},\n                },\n                #verbose = True,\n            )\n            torch.onnx.export(\n                single_net,         \n                #torch.jit.script(single_net),\n                #torch.jit.trace(single_net, torch.zeros(max_length,82,3)),           \n\n                torch.zeros((max_length,82,3)), \n                single_onnx_file,             \n                export_params = True,         \n                opset_version = 12, \n                do_constant_folding=True,      \n                input_names =  ['inputs'],     \n                output_names = ['outputs'],  \n                dynamic_axes={\n                    'inputs': {0: 'length'},\n                },\n                #verbose = True,\n            )\n            print('torch.onnx.export() passed !!')\n\n        if 1:\n            for f in [input_onnx_file, single_onnx_file]:\n                if f is None: continue\n                model = onnx.load(f)\n                onnx.checker.check_model(model)\n                model_simple, check = onnxsim.simplify(model)\n                onnx.save(model_simple, f)\n            print('onnx simplify() passed !!')\n\n\n    def run_convert_tflite():\n        if 1:\n            tf_rep = prepare(onnx.load(input_onnx_file))\n            tf_rep.export_graph(input_tf_file) \n            tf_rep = prepare(onnx.load(single_onnx_file))\n            tf_rep.export_graph(single_tf_file) \n            print('tf_rep.export_graph() passed !!')\n\n        if 1:\n            class TFModel(tf.Module):\n                def __init__(self):\n                    super(TFModel, self).__init__()\n                    self.input  = tf.saved_model.load(input_tf_file)\n                    self.single = tf.saved_model.load(single_tf_file)\n                    self.input.trainable = False\n                    self.single.trainable = False\n\n                @tf.function(input_signature=[\n                    tf.TensorSpec(shape=[None, 543, 3], dtype=tf.float32, name='inputs')\n                ])\n                def call(self, input):\n                    y = {}\n                    x = self.input(**{'inputs': input})['outputs']\n                    y['outputs'] = self.single(**{'inputs': x})['outputs'][0]\n                    return y\n\n            tfmodel = TFModel()\n            tf.saved_model.save(tfmodel, tf_file, signatures={'serving_default': tfmodel.call})\n            print('tf.saved_model() passed !!')\n\n        if 1:\n            converter = tf.lite.TFLiteConverter.from_saved_model(tf_file)\n            # converter.target_spec.supported_ops = [\n            #     tf.lite.OpsSet.TFLITE_BUILTINS,  # enable TensorFlow Lite ops.\n            #     tf.lite.OpsSet.SELECT_TF_OPS  # enable TensorFlow ops.\n            # ]\n            # converter.optimizations = [tf.lite.Optimize.DEFAULT]\n            #converter.allow_custom_ops = True\n            #converter.experimental_new_converter = True \n            tf_lite_model = converter.convert()\n            with open(tflite_file, 'wb') as f:\n                f.write(tf_lite_model)\n            print('tflite convert() passed !!')\n \n    run_convert_onnx()\n    run_convert_tflite()\n    ","metadata":{"execution":{"iopub.status.busy":"2023-03-10T12:33:30.385132Z","iopub.execute_input":"2023-03-10T12:33:30.385793Z","iopub.status.idle":"2023-03-10T12:33:30.405418Z","shell.execute_reply.started":"2023-03-10T12:33:30.385755Z","shell.execute_reply":"2023-03-10T12:33:30.404293Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#submission\n#tflite_file = '/kaggle/input/asl-demo/transformer-pool-2b.tflite'   #max_length =180\n#tflite_file = '/kaggle/input/asl-demo/transformer-pool-2b-96.tflite' #max_length =96 \n#tflite_file = '/kaggle/input/asl-demo/transformer-pool-2c-512-80-fixed-int8.tflite'\n\n#tflite_file = '/kaggle/input/asl-demo/transfomer-60-256-lip-hand-my-part-3a-int8.tflite'\n#tflite_file = '/kaggle/input/asl-demo/run10-fold1-swa-transfomer-60-512-lip-hand-crop-center-00a-int8.tflite'\n#tflite_file = '/kaggle/input/asl-demo/run15.tflite'\ntflite_file = '/kaggle/input/asl-demo/run20-aug3-xyz2.tflite'\n\n\n\n\nmode = 'submit' #debug #submit\n\n\n\nimport pandas as pd\nimport numpy as np\nimport os\nimport shutil\nfrom datetime import datetime\nfrom timeit import default_timer as timer\n\n\nif mode in ['debug']:  \n    try:\n        import tflite_runtime\n    except:\n        !pip install tflite-runtime\n\n    import tflite_runtime.interpreter as tflite   \n    import tflite_runtime\n    print(tflite_runtime.__version__)\n    #'2.11.0'\n    \n    #import tensorflow as tf\n    #print(tf.__version__)\n    # 2.11.0\n\nprint('import ok')\n'''\nYour model must also require less than 40 MB in memory and \nperform inference with less than 100 milliseconds of latency per video. \nExpect to see approximately 40,000 videos in the test set. \nWe allow an additional 10 minute buffer for loading the data and miscellaneous overhead.\n\n'''\ndef time_to_str(t, mode='min'):\n    if mode=='min':\n        t  = int(t)/60\n        hr = t//60\n        min = t%60\n        return '%2d hr %02d min'%(hr,min)\n\n    elif mode=='sec':\n        t   = int(t)\n        min = t//60\n        sec = t%60\n        return '%2d min %02d sec'%(min,sec)\n\n    else:\n        raise NotImplementedError\n\n        \nROWS_PER_FRAME = 543\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\nif mode in ['debug']: \n \n    interpreter = tflite.Interpreter(tflite_file)\n    prediction_fn = interpreter.get_signature_runner('serving_default')\n\n    valid_df = pd.read_csv('/kaggle/input/asl-demo/train_prepared.csv') \n    valid_df = valid_df[valid_df.fold==2].reset_index(drop=True)\n    valid_df = valid_df[:4_000]\n    valid_num = len(valid_df)\n    valid = {\n        'sign':[],\n    }\n\n    start_timer = timer()\n    for t, d in valid_df.iterrows():\n\n        pq_file = f'/kaggle/input/asl-signs/{d.path}'\n        #print(pq_file)\n        xyz = load_relevant_data_subset(pq_file)\n\n        output = prediction_fn(inputs=xyz)\n        p = output['outputs'].reshape(-1)\n\n        valid['sign'].append(p)\n\n        #---\n        if t%100==0:\n            time_taken = timer() - start_timer\n            print('\\r %8d / %d  %s'%(t,valid_num,time_to_str(time_taken,'sec')),end='',flush=True)\n\n    print('\\n')\n\n\n    truth = valid_df.label.values\n    sign  = np.stack(valid['sign'])\n    predict = np.argsort(-sign, -1)\n    correct = predict==truth.reshape(valid_num,1)\n    topk = correct.cumsum(-1).mean(0)[:5]\n\n\n    print(f'time_taken = {time_to_str(time_taken,\"sec\")}')\n    print(f'time_taken for LB = {time_taken*1000/valid_num:05f} msec\\n')\n    for i in range(5):\n        print(f'topk[{i}] = {topk[i]}')  \n    print('----- end -----\\n')\n\n\n\n\nshutil.copyfile(tflite_file, 'model.tflite') \n!zip submission.zip  'model.tflite'\n!ls\n\nprint('tflite_file:', tflite_file)\nprint(f'submit ok')\n\n# '''\n\n# 2.11.0\n# import ok\n\n# ######################################################\n# embed_dim = 1024\n# max_length=180\n\n#      7900 / 8000   7 min 49 sec\n# time_taken =  7 min 49 sec\n# time_taken for LB = 58.693773 msec\n\n# topk[0] = 0.588625\n# topk[1] = 0.702\n# topk[2] = 0.755375\n# topk[3] = 0.785375\n# topk[4] = 0.804125\n\n \n# ----- end -----\n\n# updating: model.tflite (deflated 8%)\n# __notebook_source__.ipynb  model.tflite  submission.zip\n# submit ok\n\n\n\n# ######################################################\n# embed_dim = 1024\n# max_length=96\n\n# import ok\n#      7900 / 8000   6 min 23 sec\n\n# time_taken =  6 min 23 sec\n# time_taken for LB = 47.972998 msec\n\n# topk[0] = 0.58425\n# topk[1] = 0.696375\n# topk[2] = 0.748125\n# topk[3] = 0.77825\n# topk[4] = 0.797125\n\n\n\n# ######################################################\n# embed_dim = 512\n# max_length = 80\n\n# 2.11.0\n# import ok\n#      7900 / 8000   5 min 44 sec\n\n# time_taken =  5 min 44 sec\n# time_taken for LB = 43.067440 msec\n\n# topk[0] = 0.57525\n# topk[1] = 0.690625\n# topk[2] = 0.74\n# topk[3] = 0.77175\n# topk[4] = 0.79375\n# ----- end -----\n\n# transformer-pool-2c-512-80-cut.tflite\n\n# time_taken =  4 min 53 sec\n# time_taken for LB = 36.710013 msec\n\n# topk[0] = 0.574875\n# topk[1] = 0.69025\n# topk[2] = 0.73975\n# topk[3] = 0.7715\n# topk[4] = 0.79375\n\n# ######################################################\n# ldd --version | head -n1\n\n# 2.11.0\n# import ok\n#     17600 / 17670   9 min 39 sec\n\n# time_taken =  9 min 39 sec\n# time_taken for LB = 32.815303 msec\n\n# topk[0] = 0.5780418788907753\n# topk[1] = 0.6922467458970005\n# topk[2] = 0.7432937181663837\n# topk[3] = 0.7735144312393888\n# topk[4] = 0.7942275042444822\n# ----- end -----\n\n# updating: model.tflite (deflated 8%)\n# __notebook_source__.ipynb  model.tflite  submission.zip\n# submit ok\n\n# ---\n# int8\n\n#    17600 / 17670  11 min 34 sec\n\n# time_taken = 11 min 34 sec\n# time_taken for LB = 39.286630 msec\n\n# topk[0] = 0.5782116581777024\n# topk[1] = 0.6921335597057159\n# topk[2] = 0.7434069043576683\n# topk[3] = 0.7740237691001698\n# topk[4] = 0.7953027730616865\n# '''\n\n# import ok\n#     17600 / 17670   9 min 48 sec\n\n# time_taken =  9 min 48 sec\n# time_taken for LB = 33.307542 msec\n\n# topk[0] = 0.5782116581777024\n# topk[1] = 0.6921335597057159\n# topk[2] = 0.7434634974533108\n# topk[3] = 0.7740237691001698\n# topk[4] = 0.7951895868704019\n# ----- end -----\n\n#   adding: model.tflite (deflated 15%)\n# __notebook_source__.ipynb  model.tflite  submission.zip\n# tflite_file: /kaggle/input/asl-demo/transformer-pool-2c-512-80-fixed-int8.tflite\n# submit ok\n","metadata":{"execution":{"iopub.status.busy":"2023-03-10T12:33:30.407612Z","iopub.execute_input":"2023-03-10T12:33:30.408284Z","iopub.status.idle":"2023-03-10T12:33:32.907090Z","shell.execute_reply.started":"2023-03-10T12:33:30.408241Z","shell.execute_reply":"2023-03-10T12:33:32.905515Z"},"trusted":true},"execution_count":null,"outputs":[]}]}