{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":43873,"databundleVersionId":5585780,"sourceType":"competition"},{"sourceId":5265383,"sourceType":"datasetVersion","datasetId":3055704},{"sourceId":8130176,"sourceType":"datasetVersion","datasetId":4805378},{"sourceId":32784,"sourceType":"modelInstanceVersion","modelInstanceId":27443},{"sourceType":"modelInstanceVersion","sourceId":32972,"isSourceIdPinned":true}],"dockerImageVersionId":30408,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"Opportunities for improvements\n\n- better generation arguments (temperature, top_p, top_k, etc.)\n- better text post-processing\n\n\n# Update 3: I change the generation to only do topk=1 which boosted the score from 0.42 to 0.44 (Version 21)\n\n\n# Update 2: The hosts changed the way the notebooks are scored, so now Version 15 produces the highest score (0.42)\n\nThis is predicting on each type of chart.\n\n\n# Update 1: As of version 17, this notebook can now submit successfully\n\nThe first issue was because there were grayscale images with dimensions of height, width instead of height, width, channel.\nThe second issue was because Donut was generating non-numerical data for numerical data series. This is still an issue because it is hard to know if a data series should be numerical or categorical. To get around this, I only allowed the model to make predictions for the two types of charts that it does best on: vertical bar and line. It failed for vertical_bar but it succeeded for line.\n\nMy CV for line was about 0.4 and if line figures account for about 40% of the extracted data, then 0.16 matches almost exactly (.4*.4=0.16)\n\n\n# ~~Note: This notebook currently does not work properly.~~\n\n~~It will fail when submitted. Please leave a comment if you can figure out why it fails!~~","metadata":{}},{"cell_type":"code","source":"import re\nfrom pathlib import Path\nfrom typing import List\nfrom functools import partial\n\nfrom transformers import (\n    DonutProcessor,\n    VisionEncoderDecoderConfig,\n    VisionEncoderDecoderModel,\n)\nimport torch\nfrom torch.utils.data import DataLoader\nimport numpy as np\nimport pandas as pd","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:12.372109Z","iopub.execute_input":"2024-04-17T17:00:12.372978Z","iopub.status.idle":"2024-04-17T17:00:12.379204Z","shell.execute_reply.started":"2024-04-17T17:00:12.372937Z","shell.execute_reply":"2024-04-17T17:00:12.378145Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from datasets import Dataset\nfrom datasets import Image as ds_img\nfrom tqdm.auto import tqdm","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:12.672207Z","iopub.execute_input":"2024-04-17T17:00:12.673200Z","iopub.status.idle":"2024-04-17T17:00:12.677985Z","shell.execute_reply.started":"2024-04-17T17:00:12.673155Z","shell.execute_reply":"2024-04-17T17:00:12.676823Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\n\n# List the contents of the working directory\nprint(os.listdir(\"/kaggle/input/nb_general_v0416/pytorch/nb_general_epoch1/1\"))\nprint(os.listdir(\"/kaggle/input/nb_general_processor/pytorch/nb_general_processor/2\"))","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:12.916350Z","iopub.execute_input":"2024-04-17T17:00:12.917447Z","iopub.status.idle":"2024-04-17T17:00:12.924187Z","shell.execute_reply.started":"2024-04-17T17:00:12.917402Z","shell.execute_reply":"2024-04-17T17:00:12.922845Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CFG:\n    \n    test_grayscale = True\n    debug_clean = False\n    \n    batch_size = 4\n    #image_path = \"/kaggle/input/benetech-making-graphs-accessible/test/images\"\n    image_path = \"/kaggle/input/seasonaltimeseries\"\n    \n    max_length = 512\n    model_dir = \"/kaggle/input/benetech-donut\"\n    model_dir_general_ft = \"/kaggle/input/nb_general_v0416/pytorch/nb_general_epoch1/1/NB_general_finetuned_epoch1_v0416_weights.pt\"\n    model_dir_general_ft_prc = \"/kaggle/input/nb_general_processor/pytorch/nb_general_processor/2\"\n\nBOS_TOKEN = \"<|BOS|>\"\nX_START = \"<x_start>\"\nX_END = \"<x_end>\"\nY_START = \"<y_start>\"\nY_END = \"<y_end>\"\n\nPLACEHOLDER_DATA_SERIES = \"0;0\"\nPLACEHOLDER_CHART_TYPE = \"line\"","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:13.037580Z","iopub.execute_input":"2024-04-17T17:00:13.038259Z","iopub.status.idle":"2024-04-17T17:00:13.045251Z","shell.execute_reply.started":"2024-04-17T17:00:13.038225Z","shell.execute_reply":"2024-04-17T17:00:13.044084Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This cleaning function is very ugly and can be improved a lot.","metadata":{}},{"cell_type":"code","source":"def clean_preds(x: List[str], y: List[str]):\n    \"\"\"\n    This function cleans the x and y values predicted by Donut.\n\n    Because it is a generative model, it can insert any character in the \n    model's vocabulary into the prediction string. This function primarily removes\n    characters that prevent a number from being cast to a float.\n\n    Example:\n\n    x = [\"11\", \"12\", \"1E\", \"14\", \"15\"]\n    y = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\"]\n\n    # float(\"1E\") will throw an error\n\n    new_x, new_y = clean_preds(x, y)\n\n    new_x = [\"11\", \"12\", \"13\", \"14\", \"15\"]\n    new_y = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\"]\n\n    Args:\n        x (List[str]): The x values predicted by Donut.\n        y (List[str]): The y values predicted by Donut.\n\n    Returns:\n        x (List[str]): The cleaned x values.\n        y (List[str]): The cleaned y values.\n    \"\"\"\n    \n    def clean(str_list):\n        \n        new_list = []\n        for temp in str_list:\n            if \".\" not in temp:\n                dtype = int\n            else:\n                dtype = float\n            try:\n                # First try removing whitespace e.g. float(\"10 0\") will fail\n                temp = dtype(re.sub(\"\\s\", \"\", temp))\n            except ValueError:\n\n                # remove everything that isn't a digit, period, negative sign, or the letter e\n                # It could be \"1e-5\" or \"-0.134\"\n\n                temp = re.sub(r\"[^0-9\\.\\-eE]\", \"\", temp)\n\n                if len(temp) == 0:\n                    temp = 0\n                else:\n                    multiple_periods = len(re.findall(r\"\\.\", temp)) > 1\n                    multiple_negative_signs = len(re.findall(r\"\\-\", temp)) > 1\n                    multiple_e = len(re.findall(r\"[eE]\", temp)) > 1\n\n                    # Put negative sign in from of it all\n                    if multiple_negative_signs:\n                        temp = \"-\" + re.sub(r\"\\-\", \"\", temp)\n\n                    # Keep first period if there are multiple\n                    if multiple_periods:\n                        chunks = temp.split(\".\")\n                        try:\n                            temp = chunks[0] + \".\" + \"\".join(chunks[1:])\n                        except IndexError:\n                            temp = \"\".join(chunks)\n                    \n                    # Keep last e in case it is \"e1e-5\"\n                    if multiple_e:\n                        while temp.lower().startswith(\"e\"):\n                            temp = temp[1:]\n                        \n                        while temp.lower().endswith(\"e\"):\n                            temp = temp[:-1]\n                            \n                        chunks = temp.split(\"e\")\n                        try:\n                            temp = chunks[0:-1] + \"e\" + \"\".join(chunks[-1])\n                        except IndexError:\n                            temp = \"\".join(chunks)\n                try:\n                    temp = dtype(temp)\n                except ValueError:\n                    temp = 0\n                    \n            new_list.append(temp)\n\n        return new_list\n\n    all_x_chars = \"\".join(x)\n    all_y_chars = \"\".join(y)\n\n    frac_num_x = len(re.sub(r\"[^\\d]\", \"\", all_x_chars)) / len(all_x_chars)\n    frac_num_y = len(re.sub(r\"[^\\d]\", \"\", all_y_chars)) / len(all_y_chars)\n    \n    print('fractional number of coordinate: ', frac_num_x, frac_num_y)\n\n    if CFG.debug_clean:\n        print(f\"x before clean (len={len(x)})\", x)\n        print(f\"y before clean (len={len(y)})\", y)\n\n    if frac_num_x >= 0.5:\n        x = clean(x)\n    else:\n        x = [s.strip() for s in x]\n    \n    \n    if frac_num_y >= 0.5:\n        y = clean(y)\n    else:\n        y = [s.strip() for s in y]\n        \n    if CFG.debug_clean:\n        print(f\"x after clean (len={len(x)})\", x)\n        print(f\"y after clean (len={len(x)})\", x)\n\n    return x, y\n    \n\ndef string2preds(pred_string: str):\n    \"\"\"\n    Conver the prediction string from Donut to a chart type and x and y values.\n\n    Checks to make sure the special tokens are present and that the x and y values are not empty.\n    Will truncate the list of values to the smaller length of the two lists. This is because the \n    lengths of the x and y values must be the same to earn any points.\n\n    Args:\n        pred_string (str): The prediction string from Donut.\n\n    Returns:\n        chart_type (str): The chart type predicted by Donut.\n        x (List[str]): The x values predicted by Donut.\n        y (List[str]): The y values predicted by Donut.\n    \"\"\"\n    \n    if \"<dot>\" in pred_string:\n        chart_type = \"dot\"\n    elif \"<horizontal_bar>\" in pred_string:\n        chart_type = \"horizontal_bar\"\n    elif \"<vertical_bar>\" in pred_string:\n        chart_type = \"vertical_bar\"\n    elif \"<scatter>\" in pred_string:\n        chart_type = \"scatter\"\n    elif \"<line>\" in pred_string:\n        chart_type = \"line\"\n    else:\n        return \"vertical_bar\", [], []\n    \n    \n    if not all([x in pred_string for x in [X_START, X_END, Y_START, Y_END]]):\n        return chart_type, [], []\n    \n    pred_string = re.sub(r\"<one>\", \"1\", pred_string)\n\n    xraw = pred_string.split(X_START)[1].split(X_END)[0].split(\";\")\n    yraw = pred_string.split(Y_START)[1].split(Y_END)[0].split(\";\")\n    print('raw coordinates: ',xraw , yraw ,'\\n')\n    if len(xraw) == 0 or len(yraw) == 0:\n        return chart_type, [], []\n\n    min_length = min(len(xraw), len(yraw))\n\n    x = xraw[:min_length]\n    y = yraw[:min_length]\n\n    x, y = clean_preds(x, y)\n\n    return chart_type, x, y, xraw, yraw","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:13.382267Z","iopub.execute_input":"2024-04-17T17:00:13.382675Z","iopub.status.idle":"2024-04-17T17:00:13.411861Z","shell.execute_reply.started":"2024-04-17T17:00:13.382636Z","shell.execute_reply":"2024-04-17T17:00:13.410688Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Generate ","metadata":{}},{"cell_type":"code","source":"CFG.image_path","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:14.009869Z","iopub.execute_input":"2024-04-17T17:00:14.010969Z","iopub.status.idle":"2024-04-17T17:00:14.017559Z","shell.execute_reply.started":"2024-04-17T17:00:14.010927Z","shell.execute_reply":"2024-04-17T17:00:14.016411Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_dir = Path(CFG.image_path)\nimages = list(image_dir.glob(\"*.JPG\"))","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:14.388537Z","iopub.execute_input":"2024-04-17T17:00:14.389240Z","iopub.status.idle":"2024-04-17T17:00:14.395235Z","shell.execute_reply.started":"2024-04-17T17:00:14.389199Z","shell.execute_reply":"2024-04-17T17:00:14.393960Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds = Dataset.from_dict(\n    {\"image_path\": [str(x) for x in images], \"id\": [x.stem for x in images]}\n).cast_column(\"image_path\", ds_img())","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:15.117771Z","iopub.execute_input":"2024-04-17T17:00:15.118590Z","iopub.status.idle":"2024-04-17T17:00:15.128791Z","shell.execute_reply.started":"2024-04-17T17:00:15.118548Z","shell.execute_reply":"2024-04-17T17:00:15.127879Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:15.365618Z","iopub.execute_input":"2024-04-17T17:00:15.366350Z","iopub.status.idle":"2024-04-17T17:00:15.373069Z","shell.execute_reply.started":"2024-04-17T17:00:15.366314Z","shell.execute_reply":"2024-04-17T17:00:15.371803Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"CFG.model_dir","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:15.986992Z","iopub.execute_input":"2024-04-17T17:00:15.987951Z","iopub.status.idle":"2024-04-17T17:00:15.994533Z","shell.execute_reply.started":"2024-04-17T17:00:15.987910Z","shell.execute_reply":"2024-04-17T17:00:15.993395Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def preprocess(examples, processor):\n    pixel_values = []\n\n    for sample in examples[\"image_path\"]:\n        \n        arr = np.array(sample)\n        \n        # There are some grayscale images that were making this fail\n        # This prevents that.\n        if len(arr.shape) == 2:\n            print(\"Changing grayscale to 3 channel format\")\n            print(arr.shape)\n            arr = np.stack([arr]*3, axis=-1)\n        \n        pixel_values.append(processor(arr, random_padding=True).pixel_values)\n        \n        \n    return {\n        \"pixel_values\": torch.tensor(np.vstack(pixel_values)),\n    }","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:17.318817Z","iopub.execute_input":"2024-04-17T17:00:17.319639Z","iopub.status.idle":"2024-04-17T17:00:17.329022Z","shell.execute_reply.started":"2024-04-17T17:00:17.319581Z","shell.execute_reply":"2024-04-17T17:00:17.327934Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = VisionEncoderDecoderModel.from_pretrained(CFG.model_dir)\nmodel.eval()","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:17.611206Z","iopub.execute_input":"2024-04-17T17:00:17.612223Z","iopub.status.idle":"2024-04-17T17:00:23.841031Z","shell.execute_reply.started":"2024-04-17T17:00:17.612177Z","shell.execute_reply":"2024-04-17T17:00:23.839739Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model = VisionEncoderDecoderModel.from_pretrained(CFG.model_dir)\n# # Load the model weights from the .pt file\n# model.load_state_dict(torch.load(CFG.model_dir_general_ft))\n# model.eval()","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:23.843300Z","iopub.execute_input":"2024-04-17T17:00:23.844197Z","iopub.status.idle":"2024-04-17T17:00:23.848776Z","shell.execute_reply.started":"2024-04-17T17:00:23.844143Z","shell.execute_reply":"2024-04-17T17:00:23.847725Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device(\"cuda:0\")\nmodel.to(device)\ndecoder_start_token_id = model.config.decoder_start_token_id","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:23.850288Z","iopub.execute_input":"2024-04-17T17:00:23.850923Z","iopub.status.idle":"2024-04-17T17:00:24.085999Z","shell.execute_reply.started":"2024-04-17T17:00:23.850889Z","shell.execute_reply":"2024-04-17T17:00:24.085131Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"CFG.model_dir_general_ft_prc","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:24.087808Z","iopub.execute_input":"2024-04-17T17:00:24.088121Z","iopub.status.idle":"2024-04-17T17:00:24.094671Z","shell.execute_reply.started":"2024-04-17T17:00:24.088091Z","shell.execute_reply":"2024-04-17T17:00:24.093339Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"processor = DonutProcessor.from_pretrained(CFG.model_dir)\nprocessor","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:29.338643Z","iopub.execute_input":"2024-04-17T17:00:29.339045Z","iopub.status.idle":"2024-04-17T17:00:29.459550Z","shell.execute_reply.started":"2024-04-17T17:00:29.339000Z","shell.execute_reply":"2024-04-17T17:00:29.458422Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# processor = DonutProcessor.from_pretrained(CFG.model_dir_general_ft_prc)\n# processor","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:34.402577Z","iopub.execute_input":"2024-04-17T17:00:34.403242Z","iopub.status.idle":"2024-04-17T17:00:34.407993Z","shell.execute_reply.started":"2024-04-17T17:00:34.403204Z","shell.execute_reply":"2024-04-17T17:00:34.406979Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:35.869809Z","iopub.execute_input":"2024-04-17T17:00:35.870874Z","iopub.status.idle":"2024-04-17T17:00:35.877327Z","shell.execute_reply.started":"2024-04-17T17:00:35.870827Z","shell.execute_reply":"2024-04-17T17:00:35.876346Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ids = ds[\"id\"]","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:36.696942Z","iopub.execute_input":"2024-04-17T17:00:36.698081Z","iopub.status.idle":"2024-04-17T17:00:36.703023Z","shell.execute_reply.started":"2024-04-17T17:00:36.698035Z","shell.execute_reply":"2024-04-17T17:00:36.701768Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ids","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:37.221218Z","iopub.execute_input":"2024-04-17T17:00:37.221685Z","iopub.status.idle":"2024-04-17T17:00:37.229429Z","shell.execute_reply.started":"2024-04-17T17:00:37.221647Z","shell.execute_reply":"2024-04-17T17:00:37.228273Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds.set_transform(partial(preprocess, processor=processor))\n\ndata_loader = DataLoader(\n    ds, batch_size=CFG.batch_size, shuffle=False\n)","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:37.932414Z","iopub.execute_input":"2024-04-17T17:00:37.933190Z","iopub.status.idle":"2024-04-17T17:00:37.939527Z","shell.execute_reply.started":"2024-04-17T17:00:37.933149Z","shell.execute_reply":"2024-04-17T17:00:37.938375Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"all_generations = []\nfor batch in tqdm(data_loader):\n    pixel_values = batch[\"pixel_values\"].to(device)\n    print(pixel_values.shape, pixel_values.max().max(), pixel_values.min().min())\n    batch_size = pixel_values.shape[0]\n\n    decoder_input_ids = torch.full(\n        (batch_size, 1),\n        decoder_start_token_id,\n        device=pixel_values.device,\n    )\n\n    try:\n        outputs = model.generate(\n            pixel_values,\n            decoder_input_ids=decoder_input_ids,\n            max_length=CFG.max_length,\n            early_stopping=True,\n            pad_token_id=processor.tokenizer.pad_token_id,\n            eos_token_id=processor.tokenizer.eos_token_id,\n            use_cache=True,\n            num_beams=1,\n            temperature=1,\n            top_k=1,\n            return_dict_in_generate=True,\n        )\n\n        all_generations.extend(processor.batch_decode(outputs.sequences))\n        \n    except:\n        all_generations.extend([\"\"]*batch_size)\n        \n\n","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:38.458830Z","iopub.execute_input":"2024-04-17T17:00:38.459564Z","iopub.status.idle":"2024-04-17T17:00:49.588251Z","shell.execute_reply.started":"2024-04-17T17:00:38.459525Z","shell.execute_reply":"2024-04-17T17:00:49.587213Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(all_generations)","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:49.589998Z","iopub.execute_input":"2024-04-17T17:00:49.590353Z","iopub.status.idle":"2024-04-17T17:00:49.597196Z","shell.execute_reply.started":"2024-04-17T17:00:49.590322Z","shell.execute_reply":"2024-04-17T17:00:49.595997Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"all_generations[9]","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:49.598480Z","iopub.execute_input":"2024-04-17T17:00:49.598825Z","iopub.status.idle":"2024-04-17T17:00:49.607379Z","shell.execute_reply.started":"2024-04-17T17:00:49.598793Z","shell.execute_reply":"2024-04-17T17:00:49.606201Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"chart_types, x_preds, y_preds, x_preds_raw, y_preds_raw = [], [], [], [], []\nfor gen in all_generations:\n\n    try:\n        chart_type, x, y, xraw, yraw = string2preds(gen)\n        new_chart_type = chart_type\n        x_str = \";\".join(list(map(str, x)))\n        y_str = \";\".join(list(map(str, y)))\n        xraw_str = \";\".join(list(map(str, xraw)))\n        yraw_str = \";\".join(list(map(str, yraw)))\n        \n        print('chart type : ', new_chart_type, '\\n', x_str, '\\n', y_str, '\\n\\n')\n    except Exception as e:\n        print(\"Failed to convert to string:\", gen)\n        print(e)\n        new_chart_type = PLACEHOLDER_CHART_TYPE\n        x_str = PLACEHOLDER_DATA_SERIES\n        y_str = PLACEHOLDER_DATA_SERIES\n        xraw_str = PLACEHOLDER_DATA_SERIES\n        yraw_str = PLACEHOLDER_DATA_SERIES\n\n    if len(x_str) == 0:\n        x_str = PLACEHOLDER_DATA_SERIES\n    if len(y_str) == 0:\n        y_str = PLACEHOLDER_DATA_SERIES\n    if len(xraw_str) == 0:\n        xraw_str = PLACEHOLDER_DATA_SERIES\n    if len(yraw_str) == 0:\n        yraw_str = PLACEHOLDER_DATA_SERIES\n    \n    chart_types.append(new_chart_type)\n    x_preds.append(x_str)\n    y_preds.append(y_str)\n    x_preds_raw.append(xraw_str)\n    y_preds_raw.append(yraw_str)\n        ","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:00:55.581167Z","iopub.execute_input":"2024-04-17T17:00:55.582099Z","iopub.status.idle":"2024-04-17T17:00:55.597391Z","shell.execute_reply.started":"2024-04-17T17:00:55.582060Z","shell.execute_reply":"2024-04-17T17:00:55.596288Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_df = pd.DataFrame(\n    data={\n        \"id\": [f\"{id_}_x\" for id_ in ids] + [f\"{id_}_y\" for id_ in ids],\n        \"data_series\": x_preds + y_preds,\n        \"chart_type\": chart_types * 2,\n    }\n)\n\nsub_df_raw = pd.DataFrame(\n    data={\n        \"id\": [f\"{id_}_x\" for id_ in ids] + [f\"{id_}_y\" for id_ in ids],\n        \"data_series\": x_preds_raw + y_preds_raw,\n        \"chart_type\": chart_types * 2,\n    }\n)\n\n\nsub_df.to_csv(\"submission.csv\", index=False)\n\npd.set_option('display.width', None)\nsub_df","metadata":{"execution":{"iopub.status.busy":"2024-04-17T17:01:15.856407Z","iopub.execute_input":"2024-04-17T17:01:15.857207Z","iopub.status.idle":"2024-04-17T17:01:15.877341Z","shell.execute_reply.started":"2024-04-17T17:01:15.857159Z","shell.execute_reply":"2024-04-17T17:01:15.876157Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_df_x = sub_df.loc[sub_df.id.str.contains('x')]\nsub_df_x['id'] = sub_df_x.apply(lambda x: x['id'][:-2], axis=1)\n\nsub_df_y = sub_df.loc[sub_df.id.str.contains('y')]\nsub_df_y['id'] = sub_df_y.apply(lambda x: x['id'][:-2], axis=1)\n\nsub_df_pair = sub_df_x.set_index('id').merge(sub_df_y.set_index('id')['data_series'], how='left', left_index=True, right_index=True)\nsub_df_pair.to_csv(\"submission_pair_blk_general_bad.csv\", index=True)","metadata":{"execution":{"iopub.status.busy":"2024-04-17T16:58:28.730028Z","iopub.execute_input":"2024-04-17T16:58:28.730296Z","iopub.status.idle":"2024-04-17T16:58:28.746543Z","shell.execute_reply.started":"2024-04-17T16:58:28.730269Z","shell.execute_reply":"2024-04-17T16:58:28.745468Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_df_pair","metadata":{"execution":{"iopub.status.busy":"2024-04-17T16:58:28.747801Z","iopub.execute_input":"2024-04-17T16:58:28.748134Z","iopub.status.idle":"2024-04-17T16:58:28.765089Z","shell.execute_reply.started":"2024-04-17T16:58:28.748104Z","shell.execute_reply":"2024-04-17T16:58:28.763914Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_df_x = sub_df_raw.loc[sub_df_raw.id.str.contains('x')]\nsub_df_x['id'] = sub_df_x.apply(lambda x: x['id'][:-2], axis=1)\n\nsub_df_y = sub_df_raw.loc[sub_df_raw.id.str.contains('y')]\nsub_df_y['id'] = sub_df_y.apply(lambda x: x['id'][:-2], axis=1)\n\nsub_df_raw_pair = sub_df_x.set_index('id').merge(sub_df_y.set_index('id')['data_series'], how='left', left_index=True, right_index=True)\nsub_df_raw_pair.to_csv(\"submission_raw_pair_blk_general_bad.csv\", index=True)","metadata":{"execution":{"iopub.status.busy":"2024-04-17T16:58:28.766601Z","iopub.execute_input":"2024-04-17T16:58:28.767184Z","iopub.status.idle":"2024-04-17T16:58:28.782805Z","shell.execute_reply.started":"2024-04-17T16:58:28.767150Z","shell.execute_reply":"2024-04-17T16:58:28.781665Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_df_raw_pair","metadata":{"execution":{"iopub.status.busy":"2024-04-17T16:58:28.784167Z","iopub.execute_input":"2024-04-17T16:58:28.785499Z","iopub.status.idle":"2024-04-17T16:58:28.797789Z","shell.execute_reply.started":"2024-04-17T16:58:28.785464Z","shell.execute_reply":"2024-04-17T16:58:28.796680Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Making sure it can handle grayscale\n\nif CFG.test_grayscale:\n        \n    ds = Dataset.from_dict({\"image_path\": [\n        \"/kaggle/input/benetech-donut/greyscale.jpg\", \n        \"/kaggle/input/benetech-making-graphs-accessible/test/images/007a18eb4e09.jpg\",\n        \"/kaggle/input/benetech-making-graphs-accessible/test/images/00f5404753cf.jpg\",\n    ]})\n    ds = ds.cast_column(\"image_path\", ds_img())\n    \n    ds.set_transform(partial(preprocess, processor=processor))\n        \n    from PIL import Image\n    \n    for pv in ds[:][\"pixel_values\"]:\n        img = Image.fromarray(((pv.permute(1, 2, 0)+1)*255/2).numpy().astype(\"uint8\"), \"RGB\")\n    \n        display(img)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}