{
  "id": 418430,
  "title": "2nd Place Solution [Updated with Code Link]",
  "url": "/competitions/benetech-making-graphs-accessible/discussion/418430",
  "author_name": "Raja Biswas",
  "post_date": "2023-06-20T14:38:52.022000",
  "votes": 64,
  "comment_count": 32,
  "views": 0,
  "content": "<p>First of all, I would like to thank the Kaggle community for sharing great ideas and engaging discussions. Special shout outs to <a href=\"https://www.kaggle.com/nbroad\" target=\"_blank\">@nbroad</a>  and <a href=\"https://www.kaggle.com/brendanartley\" target=\"_blank\">@brendanartley</a>. Congratulations to the winning teams - looking forward to your write ups.</p>\n<p>Thank you Kaggle and hosts for organizing this interesting competition.</p>\n<h2>Links</h2>\n<ul>\n<li>Inference notebook: <a href=\"https://www.kaggle.com/code/conjuring92/a05-mga-split-pipe\" target=\"_blank\">https://www.kaggle.com/code/conjuring92/a05-mga-split-pipe</a></li>\n<li>Github Repo: <a href=\"https://github.com/rbiswasfc/benetech-mga\" target=\"_blank\">https://github.com/rbiswasfc/benetech-mga</a></li>\n</ul>\n<p>The following is a detailed summary of my solution:</p>\n<h2>1 Overview</h2>\n<p>My solution is entirely based on image-to-text models finetuned from the <code>google/matcha-base</code> backbone. The training pipeline, as depicted below, is a sequence of two phases. In the first phase, I leveraged a large number of synthetic plots to adapt the backbone for the current task.  In the second phase, I used oversampled extracted / non-generated plots to specialize the pipeline for real world graphs. In this phase, I created separate models for scatter and non-scatter plots, primarily to mitigate the difficulty in predicting scatter data points.</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F2125251%2F232cced3276ad6561fe6a56d2e7509ad%2Fmga_flow.png?generation=1687269107458839&amp;alt=media\" alt=\"\"></p>\n<h2>2 Model</h2>\n<p>All models share the same architecture (image-to-text transformer) and input-output pattern. Model input is simply the plot image itself without any prompts. The output text has the following template:</p>\n<p><code>&lt;|bos|&gt; &lt;|chart_type_start|&gt; {chart_type} &lt;|chart_type_end|&gt; &lt;|num_point_start|&gt; {n_x} | {n_y} &lt;|num_point_end|&gt; &lt;|x_span_start|&gt; {x0} | {x1} | {x2} | … | {xn} &lt;|x_span_end|&gt; &lt;|y_span_start|&gt; {y0} | {y1} | {y2} | … | {ym}  &lt;|y_span_end|&gt; &lt;|eos|&gt;</code></p>\n<p>Some minor details:</p>\n<ul>\n<li>Numeric values are cast into scientific notation using <code>val = \"{:.2e}\".format(float(val))</code>.</li>\n<li>Added histogram as additional chart type, which later converted to vertical_bar during post processing</li>\n</ul>\n<h2>3 Data</h2>\n<p>Apart from the competition data, I used the following sources.</p>\n<h3>Synthetic Dataset</h3>\n<p>I spent majority of my competition time creating the synthetic dataset. For the underlying data in synthetic plots, I used</p>\n<ul>\n<li>Wikitables data i.e. tables from wikipedia (25%)<ul>\n<li><a href=\"http://websail-fe.cs.northwestern.edu/TabEL/\" target=\"_blank\">http://websail-fe.cs.northwestern.edu/TabEL/</a></li>\n<li><a href=\"https://github.com/sunlab-osu/TURL\" target=\"_blank\">https://github.com/sunlab-osu/TURL</a></li></ul></li>\n<li>Synthetic XY data (75%)<ul>\n<li>Categorical series: I created a list of categories using wikipedia glossary pages in STEM domain (<a href=\"https://www.kaggle.com/code/conjuring92/w03-stem-glossary/notebook\" target=\"_blank\">https://www.kaggle.com/code/conjuring92/w03-stem-glossary/notebook</a>)</li>\n<li>Numerical series: random function generators ensuring all combinations of narrow to wide min-max range, small (1e-6) - large values (1e6), inclusion of outliers etc</li></ul></li>\n</ul>\n<p>I generated the plots using matplotlib ensuring they capture all aspects of the graph conventions. For example, in the case of line plots, the generated graphs included shared origin plots, having tick labels that are not included in the data-series, additional point markers in between two tick labels, unequal spacing between x tick labels etc. I tried to maximize the diversity in the graphs by -</p>\n<ul>\n<li>customizing tick marks, tick labels, tick direction, formatting of numerical tick labels (e.g. scientific notation, different rounding, European style formatting, adding % as suffix, currency symbol as prefix etc), major / minor grids, titles, axis limits, spines (e.g. setting bottom spine at y=0),  legends, markers etc</li>\n<li>grayscale, background textures, aspect ratio (very wide to very narrow)</li>\n<li>number of data points (4-24 points for non-scatter, 4-64 for scatter)</li>\n<li>random special effects: text boxes with stats on y values, horizontal / vertical bands, insets, random texts, random equations, annotating min/max points, error bands, adding random shapes, varying line width, color, data point marker size, hatches, error bars, slopes etc</li>\n<li>log-log, semi-log plots, reverse y axis (although these weren’t part of test set, my hypothesis (?) was they would help in model generalization)</li>\n</ul>\n<p>The synthetic dataset consisted of</p>\n<ul>\n<li>100k horizontal bars</li>\n<li>100k vertical bars + histograms</li>\n<li>100k dot plots</li>\n<li>200k line plots</li>\n<li>200k scatter plots</li>\n</ul>\n<h3>Synthetic Dataset - Bartley</h3>\n<ul>\n<li>Random selection of 25k data points from the synthetic dataset shared by <a href=\"https://www.kaggle.com/brendanartley\" target=\"_blank\">@brendanartley</a>: <a href=\"https://www.kaggle.com/datasets/brendanartley/benetech-extra-generated-data\" target=\"_blank\">https://www.kaggle.com/datasets/brendanartley/benetech-extra-generated-data</a></li>\n</ul>\n<h3>Pseudo Labelling</h3>\n<p>I took screenshot of around 700 images from wikimedia commons (e.g. <a href=\"https://commons.wikimedia.org/w/index.php?search=line+plots&amp;title=Special:MediaSearch&amp;go=Go&amp;type=image)\" target=\"_blank\">https://commons.wikimedia.org/w/index.php?search=line+plots&amp;title=Special:MediaSearch&amp;go=Go&amp;type=image)</a>. I used pseudo labelling, followed by manual correction, to generate the annotations.</p>\n<h3>ICDAR dataset</h3>\n<p>I used around 1100 images from ICDAR, only those having 1 XY series (250 horizontal bar + 450 vertical bar + 250 lines + 150 scatter). I also did post-processing to ensure annotations match competition graph conventions (e.g. handling percentages, interpolation of line plot data to match tick labels etc).</p>\n<h2>4 Datamix</h2>\n<ul>\n<li>Datamix 1: used for domain adaptation</li>\n</ul>\n<table>\n<thead>\n<tr>\n<th>Dataset</th>\n<th>Size</th>\n<th>Multiplier</th>\n<th>Effective Size</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Competition Dataset - Synthetic</td>\n<td>60k</td>\n<td>3</td>\n<td>180k</td>\n</tr>\n<tr>\n<td>Competition Dataset - Extracted</td>\n<td>1.1k</td>\n<td>16</td>\n<td>17k</td>\n</tr>\n<tr>\n<td>Synthetic Dataset - Self</td>\n<td>700k</td>\n<td>1</td>\n<td>700k</td>\n</tr>\n<tr>\n<td>Synthetic Dataset - Bartley</td>\n<td>25k</td>\n<td>1</td>\n<td>25k</td>\n</tr>\n</tbody>\n</table>\n<ul>\n<li>Datamix 2: scatter specialization</li>\n</ul>\n<table>\n<thead>\n<tr>\n<th>Dataset</th>\n<th>Size</th>\n<th>Multiplier</th>\n<th>Effective Size</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Competition Dataset - Synthetic</td>\n<td>11k</td>\n<td>1</td>\n<td>11k</td>\n</tr>\n<tr>\n<td>Competition Dataset - Extracted</td>\n<td>0.2k</td>\n<td>16</td>\n<td>3.2k</td>\n</tr>\n<tr>\n<td>Synthetic Dataset - Self</td>\n<td>30k</td>\n<td>1</td>\n<td>30k</td>\n</tr>\n<tr>\n<td>Pseudo Labelled Dataset</td>\n<td>0.1k</td>\n<td>16</td>\n<td>1.6k</td>\n</tr>\n<tr>\n<td>ICDAR Dataset</td>\n<td>0.2k</td>\n<td>16</td>\n<td>3.2k</td>\n</tr>\n</tbody>\n</table>\n<ul>\n<li>Datamix 3: non-scatter specialization</li>\n</ul>\n<table>\n<thead>\n<tr>\n<th>Dataset</th>\n<th>Size</th>\n<th>Multiplier</th>\n<th>Effective Size</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Competition Dataset - Synthetic</td>\n<td>48k</td>\n<td>1</td>\n<td>48k</td>\n</tr>\n<tr>\n<td>Competition Dataset - Extracted</td>\n<td>0.9k</td>\n<td>8</td>\n<td>7.2k</td>\n</tr>\n<tr>\n<td>Synthetic Dataset - Self</td>\n<td>20k</td>\n<td>1</td>\n<td>20k</td>\n</tr>\n<tr>\n<td>Pseudo Labelled Dataset</td>\n<td>0.5k</td>\n<td>8</td>\n<td>4k</td>\n</tr>\n<tr>\n<td>ICDAR Dataset</td>\n<td>1k</td>\n<td>8</td>\n<td>8k</td>\n</tr>\n</tbody>\n</table>\n<h2>5 Training</h2>\n<p>The main hyper-parameters for training were <code>max_patches</code> and <code>max_length</code>. I used the following settings at various phases of training:</p>\n<h5>Phase 1 Training</h5>\n<ul>\n<li>max_patches: 2048</li>\n<li>max length: 1024</li>\n<li>lr: 5e-5</li>\n<li>batch size: 2</li>\n<li>gradient accumulation: 16</li>\n</ul>\n<h5>Phase 2 training - non-scatter</h5>\n<ul>\n<li>max_patches: 4096</li>\n<li>max length: 512</li>\n<li>lr: 2e-5</li>\n<li>batch size: 4</li>\n<li>gradient accumulation: 2</li>\n</ul>\n<h5>Phase 2 training - scatter</h5>\n<ul>\n<li>max_patches: 3072</li>\n<li>max length: 1024</li>\n<li>lr: 2e-5</li>\n<li>batch size: 8</li>\n<li>gradient accumulation: 1</li>\n<li>AWP</li>\n</ul>\n<p>As minor detail, I used Exponential Moving Average (EMA) of model weights, gradient clipping, cosine scheduler with liner warmup during training.</p>\n<h2>6 Augmentation</h2>\n<p>Since I was repeating the extracted images many times, I decided to include the following augmentation</p>\n<pre><code>transforms = A.Compose(\n        [\n            A.OneOf(\n                [\n                    A.RandomToneCurve(=0.3),\n                    A.RandomBrightnessContrast(\n                        brightness_limit=(-0.1, 0.2),\n                        contrast_limit=(-0.4, 0.5),\n                        =,\n                    ),\n                    A.HueSaturationValue(\n                        hue_shift_limit=(-20, 20),\n                        sat_shift_limit=(-30, 30),\n                        val_shift_limit=(-20, 20)\n                    )\n                ],\n                =0.5,\n            ),\n\n            A.OneOf(\n                [\n                    A.MotionBlur(=3),\n                    A.MedianBlur(=3),\n                    A.GaussianBlur(=3),\n                    A.GaussNoise(var_limit=(3.0, 9.0)),\n                ],\n                =0.5,\n            ),\n\n            A.Downscale(=, =0.1, =0.90, =0.99),\n        ],\n\n        =0.5,\n    )\n</code></pre>\n<h2>7 References</h2>\n<ul>\n<li>Matcha Paper: <a href=\"https://arxiv.org/pdf/2212.09662v2.pdf\" target=\"_blank\">https://arxiv.org/pdf/2212.09662v2.pdf</a></li>\n<li><a href=\"https://www.kaggle.com/code/nbroad/donut-train-benetech\" target=\"_blank\">https://www.kaggle.com/code/nbroad/donut-train-benetech</a></li>\n<li><a href=\"https://www.kaggle.com/code/nbroad/donut-infer-lb-0-44-benetech\" target=\"_blank\">https://www.kaggle.com/code/nbroad/donut-infer-lb-0-44-benetech</a></li>\n<li><a href=\"https://www.kaggle.com/datasets/brendanartley/benetech-extra-generated-data\" target=\"_blank\">https://www.kaggle.com/datasets/brendanartley/benetech-extra-generated-data</a></li>\n<li>AWP: <a href=\"https://www.kaggle.com/code/wht1996/feedback-nn-train/notebook\" target=\"_blank\">https://www.kaggle.com/code/wht1996/feedback-nn-train/notebook</a></li>\n</ul>\n<p>Sorry for the long write up. Please let me know if you have any queries / suggestions. I plan to release all scripts, configs and datasets by next week. [Edit: code released at <a href=\"https://github.com/rbiswasfc/benetech-mga\" target=\"_blank\">https://github.com/rbiswasfc/benetech-mga</a>]</p>",
  "messages": [
    {
      "id": 2310677,
      "postDate": "2023-06-20T14:38:52.023Z",
      "content": "<p>First of all, I would like to thank the Kaggle community for sharing great ideas and engaging discussions. Special shout outs to <a href=\"https://www.kaggle.com/nbroad\" target=\"_blank\">@nbroad</a>  and <a href=\"https://www.kaggle.com/brendanartley\" target=\"_blank\">@brendanartley</a>. Congratulations to the winning teams - looking forward to your write ups.</p>\n<p>Thank you Kaggle and hosts for organizing this interesting competition.</p>\n<h2>Links</h2>\n<ul>\n<li>Inference notebook: <a href=\"https://www.kaggle.com/code/conjuring92/a05-mga-split-pipe\" target=\"_blank\">https://www.kaggle.com/code/conjuring92/a05-mga-split-pipe</a></li>\n<li>Github Repo: <a href=\"https://github.com/rbiswasfc/benetech-mga\" target=\"_blank\">https://github.com/rbiswasfc/benetech-mga</a></li>\n</ul>\n<p>The following is a detailed summary of my solution:</p>\n<h2>1 Overview</h2>\n<p>My solution is entirely based on image-to-text models finetuned from the <code>google/matcha-base</code> backbone. The training pipeline, as depicted below, is a sequence of two phases. In the first phase, I leveraged a large number of synthetic plots to adapt the backbone for the current task.  In the second phase, I used oversampled extracted / non-generated plots to specialize the pipeline for real world graphs. In this phase, I created separate models for scatter and non-scatter plots, primarily to mitigate the difficulty in predicting scatter data points.</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F2125251%2F232cced3276ad6561fe6a56d2e7509ad%2Fmga_flow.png?generation=1687269107458839&amp;alt=media\" alt=\"\"></p>\n<h2>2 Model</h2>\n<p>All models share the same architecture (image-to-text transformer) and input-output pattern. Model input is simply the plot image itself without any prompts. The output text has the following template:</p>\n<p><code>&lt;|bos|&gt; &lt;|chart_type_start|&gt; {chart_type} &lt;|chart_type_end|&gt; &lt;|num_point_start|&gt; {n_x} | {n_y} &lt;|num_point_end|&gt; &lt;|x_span_start|&gt; {x0} | {x1} | {x2} | … | {xn} &lt;|x_span_end|&gt; &lt;|y_span_start|&gt; {y0} | {y1} | {y2} | … | {ym}  &lt;|y_span_end|&gt; &lt;|eos|&gt;</code></p>\n<p>Some minor details:</p>\n<ul>\n<li>Numeric values are cast into scientific notation using <code>val = \"{:.2e}\".format(float(val))</code>.</li>\n<li>Added histogram as additional chart type, which later converted to vertical_bar during post processing</li>\n</ul>\n<h2>3 Data</h2>\n<p>Apart from the competition data, I used the following sources.</p>\n<h3>Synthetic Dataset</h3>\n<p>I spent majority of my competition time creating the synthetic dataset. For the underlying data in synthetic plots, I used</p>\n<ul>\n<li>Wikitables data i.e. tables from wikipedia (25%)<ul>\n<li><a href=\"http://websail-fe.cs.northwestern.edu/TabEL/\" target=\"_blank\">http://websail-fe.cs.northwestern.edu/TabEL/</a></li>\n<li><a href=\"https://github.com/sunlab-osu/TURL\" target=\"_blank\">https://github.com/sunlab-osu/TURL</a></li></ul></li>\n<li>Synthetic XY data (75%)<ul>\n<li>Categorical series: I created a list of categories using wikipedia glossary pages in STEM domain (<a href=\"https://www.kaggle.com/code/conjuring92/w03-stem-glossary/notebook\" target=\"_blank\">https://www.kaggle.com/code/conjuring92/w03-stem-glossary/notebook</a>)</li>\n<li>Numerical series: random function generators ensuring all combinations of narrow to wide min-max range, small (1e-6) - large values (1e6), inclusion of outliers etc</li></ul></li>\n</ul>\n<p>I generated the plots using matplotlib ensuring they capture all aspects of the graph conventions. For example, in the case of line plots, the generated graphs included shared origin plots, having tick labels that are not included in the data-series, additional point markers in between two tick labels, unequal spacing between x tick labels etc. I tried to maximize the diversity in the graphs by -</p>\n<ul>\n<li>customizing tick marks, tick labels, tick direction, formatting of numerical tick labels (e.g. scientific notation, different rounding, European style formatting, adding % as suffix, currency symbol as prefix etc), major / minor grids, titles, axis limits, spines (e.g. setting bottom spine at y=0),  legends, markers etc</li>\n<li>grayscale, background textures, aspect ratio (very wide to very narrow)</li>\n<li>number of data points (4-24 points for non-scatter, 4-64 for scatter)</li>\n<li>random special effects: text boxes with stats on y values, horizontal / vertical bands, insets, random texts, random equations, annotating min/max points, error bands, adding random shapes, varying line width, color, data point marker size, hatches, error bars, slopes etc</li>\n<li>log-log, semi-log plots, reverse y axis (although these weren’t part of test set, my hypothesis (?) was they would help in model generalization)</li>\n</ul>\n<p>The synthetic dataset consisted of</p>\n<ul>\n<li>100k horizontal bars</li>\n<li>100k vertical bars + histograms</li>\n<li>100k dot plots</li>\n<li>200k line plots</li>\n<li>200k scatter plots</li>\n</ul>\n<h3>Synthetic Dataset - Bartley</h3>\n<ul>\n<li>Random selection of 25k data points from the synthetic dataset shared by <a href=\"https://www.kaggle.com/brendanartley\" target=\"_blank\">@brendanartley</a>: <a href=\"https://www.kaggle.com/datasets/brendanartley/benetech-extra-generated-data\" target=\"_blank\">https://www.kaggle.com/datasets/brendanartley/benetech-extra-generated-data</a></li>\n</ul>\n<h3>Pseudo Labelling</h3>\n<p>I took screenshot of around 700 images from wikimedia commons (e.g. <a href=\"https://commons.wikimedia.org/w/index.php?search=line+plots&amp;title=Special:MediaSearch&amp;go=Go&amp;type=image)\" target=\"_blank\">https://commons.wikimedia.org/w/index.php?search=line+plots&amp;title=Special:MediaSearch&amp;go=Go&amp;type=image)</a>. I used pseudo labelling, followed by manual correction, to generate the annotations.</p>\n<h3>ICDAR dataset</h3>\n<p>I used around 1100 images from ICDAR, only those having 1 XY series (250 horizontal bar + 450 vertical bar + 250 lines + 150 scatter). I also did post-processing to ensure annotations match competition graph conventions (e.g. handling percentages, interpolation of line plot data to match tick labels etc).</p>\n<h2>4 Datamix</h2>\n<ul>\n<li>Datamix 1: used for domain adaptation</li>\n</ul>\n<table>\n<thead>\n<tr>\n<th>Dataset</th>\n<th>Size</th>\n<th>Multiplier</th>\n<th>Effective Size</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Competition Dataset - Synthetic</td>\n<td>60k</td>\n<td>3</td>\n<td>180k</td>\n</tr>\n<tr>\n<td>Competition Dataset - Extracted</td>\n<td>1.1k</td>\n<td>16</td>\n<td>17k</td>\n</tr>\n<tr>\n<td>Synthetic Dataset - Self</td>\n<td>700k</td>\n<td>1</td>\n<td>700k</td>\n</tr>\n<tr>\n<td>Synthetic Dataset - Bartley</td>\n<td>25k</td>\n<td>1</td>\n<td>25k</td>\n</tr>\n</tbody>\n</table>\n<ul>\n<li>Datamix 2: scatter specialization</li>\n</ul>\n<table>\n<thead>\n<tr>\n<th>Dataset</th>\n<th>Size</th>\n<th>Multiplier</th>\n<th>Effective Size</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Competition Dataset - Synthetic</td>\n<td>11k</td>\n<td>1</td>\n<td>11k</td>\n</tr>\n<tr>\n<td>Competition Dataset - Extracted</td>\n<td>0.2k</td>\n<td>16</td>\n<td>3.2k</td>\n</tr>\n<tr>\n<td>Synthetic Dataset - Self</td>\n<td>30k</td>\n<td>1</td>\n<td>30k</td>\n</tr>\n<tr>\n<td>Pseudo Labelled Dataset</td>\n<td>0.1k</td>\n<td>16</td>\n<td>1.6k</td>\n</tr>\n<tr>\n<td>ICDAR Dataset</td>\n<td>0.2k</td>\n<td>16</td>\n<td>3.2k</td>\n</tr>\n</tbody>\n</table>\n<ul>\n<li>Datamix 3: non-scatter specialization</li>\n</ul>\n<table>\n<thead>\n<tr>\n<th>Dataset</th>\n<th>Size</th>\n<th>Multiplier</th>\n<th>Effective Size</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Competition Dataset - Synthetic</td>\n<td>48k</td>\n<td>1</td>\n<td>48k</td>\n</tr>\n<tr>\n<td>Competition Dataset - Extracted</td>\n<td>0.9k</td>\n<td>8</td>\n<td>7.2k</td>\n</tr>\n<tr>\n<td>Synthetic Dataset - Self</td>\n<td>20k</td>\n<td>1</td>\n<td>20k</td>\n</tr>\n<tr>\n<td>Pseudo Labelled Dataset</td>\n<td>0.5k</td>\n<td>8</td>\n<td>4k</td>\n</tr>\n<tr>\n<td>ICDAR Dataset</td>\n<td>1k</td>\n<td>8</td>\n<td>8k</td>\n</tr>\n</tbody>\n</table>\n<h2>5 Training</h2>\n<p>The main hyper-parameters for training were <code>max_patches</code> and <code>max_length</code>. I used the following settings at various phases of training:</p>\n<h5>Phase 1 Training</h5>\n<ul>\n<li>max_patches: 2048</li>\n<li>max length: 1024</li>\n<li>lr: 5e-5</li>\n<li>batch size: 2</li>\n<li>gradient accumulation: 16</li>\n</ul>\n<h5>Phase 2 training - non-scatter</h5>\n<ul>\n<li>max_patches: 4096</li>\n<li>max length: 512</li>\n<li>lr: 2e-5</li>\n<li>batch size: 4</li>\n<li>gradient accumulation: 2</li>\n</ul>\n<h5>Phase 2 training - scatter</h5>\n<ul>\n<li>max_patches: 3072</li>\n<li>max length: 1024</li>\n<li>lr: 2e-5</li>\n<li>batch size: 8</li>\n<li>gradient accumulation: 1</li>\n<li>AWP</li>\n</ul>\n<p>As minor detail, I used Exponential Moving Average (EMA) of model weights, gradient clipping, cosine scheduler with liner warmup during training.</p>\n<h2>6 Augmentation</h2>\n<p>Since I was repeating the extracted images many times, I decided to include the following augmentation</p>\n<pre><code>transforms = A.Compose(\n        [\n            A.OneOf(\n                [\n                    A.RandomToneCurve(=0.3),\n                    A.RandomBrightnessContrast(\n                        brightness_limit=(-0.1, 0.2),\n                        contrast_limit=(-0.4, 0.5),\n                        =,\n                    ),\n                    A.HueSaturationValue(\n                        hue_shift_limit=(-20, 20),\n                        sat_shift_limit=(-30, 30),\n                        val_shift_limit=(-20, 20)\n                    )\n                ],\n                =0.5,\n            ),\n\n            A.OneOf(\n                [\n                    A.MotionBlur(=3),\n                    A.MedianBlur(=3),\n                    A.GaussianBlur(=3),\n                    A.GaussNoise(var_limit=(3.0, 9.0)),\n                ],\n                =0.5,\n            ),\n\n            A.Downscale(=, =0.1, =0.90, =0.99),\n        ],\n\n        =0.5,\n    )\n</code></pre>\n<h2>7 References</h2>\n<ul>\n<li>Matcha Paper: <a href=\"https://arxiv.org/pdf/2212.09662v2.pdf\" target=\"_blank\">https://arxiv.org/pdf/2212.09662v2.pdf</a></li>\n<li><a href=\"https://www.kaggle.com/code/nbroad/donut-train-benetech\" target=\"_blank\">https://www.kaggle.com/code/nbroad/donut-train-benetech</a></li>\n<li><a href=\"https://www.kaggle.com/code/nbroad/donut-infer-lb-0-44-benetech\" target=\"_blank\">https://www.kaggle.com/code/nbroad/donut-infer-lb-0-44-benetech</a></li>\n<li><a href=\"https://www.kaggle.com/datasets/brendanartley/benetech-extra-generated-data\" target=\"_blank\">https://www.kaggle.com/datasets/brendanartley/benetech-extra-generated-data</a></li>\n<li>AWP: <a href=\"https://www.kaggle.com/code/wht1996/feedback-nn-train/notebook\" target=\"_blank\">https://www.kaggle.com/code/wht1996/feedback-nn-train/notebook</a></li>\n</ul>\n<p>Sorry for the long write up. Please let me know if you have any queries / suggestions. I plan to release all scripts, configs and datasets by next week. [Edit: code released at <a href=\"https://github.com/rbiswasfc/benetech-mga\" target=\"_blank\">https://github.com/rbiswasfc/benetech-mga</a>]</p>",
      "rawMarkdown": "First of all, I would like to thank the Kaggle community for sharing great ideas and engaging discussions. Special shout outs to @nbroad  and @brendanartley. Congratulations to the winning teams - looking forward to your write ups.\n\nThank you Kaggle and hosts for organizing this interesting competition.\n\n## Links\n\n- Inference notebook: https://www.kaggle.com/code/conjuring92/a05-mga-split-pipe\n- Github Repo: https://github.com/rbiswasfc/benetech-mga\n\n\nThe following is a detailed summary of my solution:\n\n## 1 Overview\n\nMy solution is entirely based on image-to-text models finetuned from the `google/matcha-base` backbone. The training pipeline, as depicted below, is a sequence of two phases. In the first phase, I leveraged a large number of synthetic plots to adapt the backbone for the current task.  In the second phase, I used oversampled extracted / non-generated plots to specialize the pipeline for real world graphs. In this phase, I created separate models for scatter and non-scatter plots, primarily to mitigate the difficulty in predicting scatter data points.\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F2125251%2F232cced3276ad6561fe6a56d2e7509ad%2Fmga_flow.png?generation=1687269107458839&alt=media)\n\n## 2 Model\n\nAll models share the same architecture (image-to-text transformer) and input-output pattern. Model input is simply the plot image itself without any prompts. The output text has the following template:\n\n```<|bos|> <|chart_type_start|> {chart_type} <|chart_type_end|> <|num_point_start|> {n_x} | {n_y} <|num_point_end|> <|x_span_start|> {x0} | {x1} | {x2} | … | {xn} <|x_span_end|> <|y_span_start|> {y0} | {y1} | {y2} | … | {ym}  <|y_span_end|> <|eos|>```\n\nSome minor details:\n- Numeric values are cast into scientific notation using `val = \"{:.2e}\".format(float(val))`.\n- Added histogram as additional chart type, which later converted to vertical_bar during post processing\n\n## 3 Data\nApart from the competition data, I used the following sources.\n\n### Synthetic Dataset\n\nI spent majority of my competition time creating the synthetic dataset. For the underlying data in synthetic plots, I used\n\n- Wikitables data i.e. tables from wikipedia (25%)\n    - http://websail-fe.cs.northwestern.edu/TabEL/\n    - https://github.com/sunlab-osu/TURL\n- Synthetic XY data (75%)\n    - Categorical series: I created a list of categories using wikipedia glossary pages in STEM domain (https://www.kaggle.com/code/conjuring92/w03-stem-glossary/notebook)\n    - Numerical series: random function generators ensuring all combinations of narrow to wide min-max range, small (1e-6) - large values (1e6), inclusion of outliers etc\n\nI generated the plots using matplotlib ensuring they capture all aspects of the graph conventions. For example, in the case of line plots, the generated graphs included shared origin plots, having tick labels that are not included in the data-series, additional point markers in between two tick labels, unequal spacing between x tick labels etc. I tried to maximize the diversity in the graphs by -\n\n- customizing tick marks, tick labels, tick direction, formatting of numerical tick labels (e.g. scientific notation, different rounding, European style formatting, adding % as suffix, currency symbol as prefix etc), major / minor grids, titles, axis limits, spines (e.g. setting bottom spine at y=0),  legends, markers etc\n- grayscale, background textures, aspect ratio (very wide to very narrow)\n- number of data points (4-24 points for non-scatter, 4-64 for scatter)\n- random special effects: text boxes with stats on y values, horizontal / vertical bands, insets, random texts, random equations, annotating min/max points, error bands, adding random shapes, varying line width, color, data point marker size, hatches, error bars, slopes etc\n- log-log, semi-log plots, reverse y axis (although these weren’t part of test set, my hypothesis (?) was they would help in model generalization)\n\nThe synthetic dataset consisted of\n\n- 100k horizontal bars\n- 100k vertical bars + histograms\n- 100k dot plots\n- 200k line plots\n- 200k scatter plots\n\n### Synthetic Dataset - Bartley\n- Random selection of 25k data points from the synthetic dataset shared by @brendanartley: https://www.kaggle.com/datasets/brendanartley/benetech-extra-generated-data\n\n### Pseudo Labelling\nI took screenshot of around 700 images from wikimedia commons (e.g. https://commons.wikimedia.org/w/index.php?search=line+plots&title=Special:MediaSearch&go=Go&type=image). I used pseudo labelling, followed by manual correction, to generate the annotations.\n\n### ICDAR dataset\nI used around 1100 images from ICDAR, only those having 1 XY series (250 horizontal bar + 450 vertical bar + 250 lines + 150 scatter). I also did post-processing to ensure annotations match competition graph conventions (e.g. handling percentages, interpolation of line plot data to match tick labels etc).\n\n## 4 Datamix\n- Datamix 1: used for domain adaptation\n\n| Dataset                         | Size | Multiplier | Effective Size |\n| ------------------------------- | ---- | ---------- | -------------- |\n| Competition Dataset - Synthetic | 60k  | 3          | 180k           |\n| Competition Dataset - Extracted | 1.1k | 16         | 17k            |\n| Synthetic Dataset - Self        | 700k | 1          | 700k           |\n| Synthetic Dataset - Bartley     | 25k  | 1          | 25k            |\n\n- Datamix 2: scatter specialization\n\n| Dataset                         | Size | Multiplier | Effective Size |\n| ------------------------------- | ---- | ---------- | -------------- |\n| Competition Dataset - Synthetic | 11k  | 1          | 11k            |\n| Competition Dataset - Extracted | 0.2k | 16         | 3.2k           |\n| Synthetic Dataset - Self        | 30k  | 1          | 30k            |\n| Pseudo Labelled Dataset         | 0.1k | 16         | 1.6k           |\n| ICDAR Dataset                   | 0.2k | 16         | 3.2k           |\n\n- Datamix 3: non-scatter specialization\n\n| Dataset                         | Size | Multiplier | Effective Size |\n| ------------------------------- | ---- | ---------- | -------------- |\n| Competition Dataset - Synthetic | 48k  | 1          | 48k            |\n| Competition Dataset - Extracted | 0.9k | 8          | 7.2k           |\n| Synthetic Dataset - Self        | 20k  | 1          | 20k            |\n| Pseudo Labelled Dataset         | 0.5k | 8          | 4k             |\n| ICDAR Dataset                   | 1k   | 8          | 8k             |\n\n## 5 Training\n\nThe main hyper-parameters for training were `max_patches` and `max_length`. I used the following settings at various phases of training:\n\n##### Phase 1 Training\n\n- max_patches: 2048\n- max length: 1024\n- lr: 5e-5\n- batch size: 2\n- gradient accumulation: 16\n\n##### Phase 2 training - non-scatter\n- max_patches: 4096\n- max length: 512\n- lr: 2e-5\n- batch size: 4\n- gradient accumulation: 2\n\n##### Phase 2 training - scatter\n- max_patches: 3072\n- max length: 1024\n- lr: 2e-5\n- batch size: 8\n- gradient accumulation: 1\n- AWP\n\nAs minor detail, I used Exponential Moving Average (EMA) of model weights, gradient clipping, cosine scheduler with liner warmup during training.\n\n## 6 Augmentation\n\nSince I was repeating the extracted images many times, I decided to include the following augmentation\n\n```\ntransforms = A.Compose(\n        [\n            A.OneOf(\n                [\n                    A.RandomToneCurve(scale=0.3),\n                    A.RandomBrightnessContrast(\n                        brightness_limit=(-0.1, 0.2),\n                        contrast_limit=(-0.4, 0.5),\n                        brightness_by_max=True,\n                    ),\n                    A.HueSaturationValue(\n                        hue_shift_limit=(-20, 20),\n                        sat_shift_limit=(-30, 30),\n                        val_shift_limit=(-20, 20)\n                    )\n                ],\n                p=0.5,\n            ),\n\n            A.OneOf(\n                [\n                    A.MotionBlur(blur_limit=3),\n                    A.MedianBlur(blur_limit=3),\n                    A.GaussianBlur(blur_limit=3),\n                    A.GaussNoise(var_limit=(3.0, 9.0)),\n                ],\n                p=0.5,\n            ),\n\n            A.Downscale(always_apply=False, p=0.1, scale_min=0.90, scale_max=0.99),\n        ],\n\n        p=0.5,\n    )\n```\n\n## 7 References\n* Matcha Paper: https://arxiv.org/pdf/2212.09662v2.pdf\n* https://www.kaggle.com/code/nbroad/donut-train-benetech\n* https://www.kaggle.com/code/nbroad/donut-infer-lb-0-44-benetech\n* https://www.kaggle.com/datasets/brendanartley/benetech-extra-generated-data\n* AWP: https://www.kaggle.com/code/wht1996/feedback-nn-train/notebook\n\n\nSorry for the long write up. Please let me know if you have any queries / suggestions. I plan to release all scripts, configs and datasets by next week. [Edit: code released at https://github.com/rbiswasfc/benetech-mga]",
      "votes": 64
    },
    {
      "id": 2310978,
      "postDate": "2023-06-20T19:31:30.927Z",
      "content": "<p>Great work! Congrats on becoming a GM 🎉🎉🎉</p>\n<p>I can't believe you got the scatter score to be so high for matcha!!</p>\n<p>2 Questions:</p>\n<ol>\n<li>It looks like your training runs were very long 😄  Did you use any tricks to speed it up? </li>\n<li>How did you decide what augmentations to use and how often to apply them?</li>\n</ol>",
      "rawMarkdown": "Great work! Congrats on becoming a GM 🎉🎉🎉\n\nI can't believe you got the scatter score to be so high for matcha!!\n\n2 Questions:\n1. It looks like your training runs were very long 😄  Did you use any tricks to speed it up? \n2. How did you decide what augmentations to use and how often to apply them?",
      "votes": 3,
      "replies": [
        {
          "id": 2311174,
          "postDate": "2023-06-21T01:40:11.967Z",
          "content": "<p>Thanks Nicholas! </p>\n<ol>\n<li><p>Yes, very long, as compared to any other models I trained for Kaggle comps. Phase I training was around 36hrs in A100. I didn't do anything special to speed it up (only using bf16, turned off gradient checkpointing for phase I - hence batch size of 2). I plan to experiment with torch 2.0, fsdp, maybe LoRA later.</p></li>\n<li><p>I wanted to avoid geometric transformations (I felt it may make training more difficult). Rest was just manual observation to make sure augmented images look reasonable. Since training runs were long and benefit of augmentation wasn't likely to show up early in training, I couldn't really tune any aspect of it. It was applied at 50% rate.</p></li>\n</ol>\n<p>On scatter plots, I think key was to include a large number of synthetic plots with many data points. In post-processing, I didn't force x and y series to have same number of points, which also helped. I wasn't able to explore any other strategies for scatter, mainly due to my lack of knowledge in object detection. I also couldn't allocate research time on it, as my focus is LLM these days. </p>",
          "rawMarkdown": "Thanks Nicholas! \n\n1. Yes, very long, as compared to any other models I trained for Kaggle comps. Phase I training was around 36hrs in A100. I didn't do anything special to speed it up (only using bf16, turned off gradient checkpointing for phase I - hence batch size of 2). I plan to experiment with torch 2.0, fsdp, maybe LoRA later.\n\n2. I wanted to avoid geometric transformations (I felt it may make training more difficult). Rest was just manual observation to make sure augmented images look reasonable. Since training runs were long and benefit of augmentation wasn't likely to show up early in training, I couldn't really tune any aspect of it. It was applied at 50% rate.\n\nOn scatter plots, I think key was to include a large number of synthetic plots with many data points. In post-processing, I didn't force x and y series to have same number of points, which also helped. I wasn't able to explore any other strategies for scatter, mainly due to my lack of knowledge in object detection. I also couldn't allocate research time on it, as my focus is LLM these days. ",
          "votes": 2
        }
      ]
    },
    {
      "id": 2310695,
      "postDate": "2023-06-20T14:53:45.253Z",
      "content": "<p>Congratz on the 2nd place and on the GM title !</p>\n<p>Can you share your LB scores by chart type ?<br>\nI'm mostly curious about scatter, matcha was not good for us so I'm impressed that you could get a competitive solution with only matcha.</p>",
      "rawMarkdown": "Congratz on the 2nd place and on the GM title !\n\nCan you share your LB scores by chart type ?\nI'm mostly curious about scatter, matcha was not good for us so I'm impressed that you could get a competitive solution with only matcha.",
      "votes": 3,
      "replies": [
        {
          "id": 2310735,
          "postDate": "2023-06-20T15:18:48.747Z",
          "content": "<p>Thanks <a href=\"https://www.kaggle.com/theoviel\" target=\"_blank\">@theoviel</a> ! Congratulations to you too!</p>\n<p>I only tried separate sub for scatter plots. The best I could get for scatter was: 0.24 private LB (phase I training), 0.29 (phase I + scatter only train). <br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F2125251%2F21abaaae41c1d4422e4b64a654bac9cc%2FScreenshot%202023-06-20%20at%2011.12.58%20PM.png?generation=1687273996904154&amp;alt=media\" alt=\"\"></p>\n<p>The following gave good boosts - </p>\n<ul>\n<li>Inclusion of a large number of synthetic scatter plots with high number of data points (36-64)</li>\n<li>longer training (performance of bar plots saturate very fast, whereas line &amp; scatter continues to improve with longer training) </li>\n</ul>",
          "rawMarkdown": "Thanks @theoviel ! Congratulations to you too!\n\nI only tried separate sub for scatter plots. The best I could get for scatter was: 0.24 private LB (phase I training), 0.29 (phase I + scatter only train). \n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F2125251%2F21abaaae41c1d4422e4b64a654bac9cc%2FScreenshot%202023-06-20%20at%2011.12.58%20PM.png?generation=1687273996904154&alt=media)\n\nThe following gave good boosts - \n- Inclusion of a large number of synthetic scatter plots with high number of data points (36-64)\n- longer training (performance of bar plots saturate very fast, whereas line & scatter continues to improve with longer training) \n\n",
          "votes": 3,
          "replies": [
            {
              "id": 2310746,
              "postDate": "2023-06-20T15:25:52.700Z",
              "content": "<p>Thanks ! We have the same scatter score it seems :) </p>",
              "rawMarkdown": "Thanks ! We have the same scatter score it seems :) ",
              "votes": 1
            },
            {
              "id": 2310767,
              "postDate": "2023-06-20T15:39:48.140Z",
              "content": "<p>yes! I will try late subs for other plot types to see if we have same scores for them too</p>",
              "rawMarkdown": "yes! I will try late subs for other plot types to see if we have same scores for them too",
              "votes": 1
            }
          ]
        }
      ]
    },
    {
      "id": 2311591,
      "postDate": "2023-06-21T09:15:26.870Z",
      "content": "<p>What a way to become a kaggle GM. Well deserved!</p>",
      "rawMarkdown": "What a way to become a kaggle GM. Well deserved!",
      "votes": 4,
      "replies": [
        {
          "id": 2311876,
          "postDate": "2023-06-21T14:04:47.917Z",
          "content": "<p>Thanks <a href=\"https://www.kaggle.com/crodoc\" target=\"_blank\">@crodoc</a>! Congratulations to you too, you became GM in such a short time &amp; always performing well in diverse competitions 👍</p>",
          "rawMarkdown": "Thanks @crodoc! Congratulations to you too, you became GM in such a short time & always performing well in diverse competitions 👍",
          "votes": 2
        }
      ]
    },
    {
      "id": 2310696,
      "postDate": "2023-06-20T14:54:47.097Z",
      "content": "<p>Congratulations <a href=\"https://www.kaggle.com/conjuring92\" target=\"_blank\">@conjuring92</a>, your solution is excellent and your data generation strategy is impressive! Well deserved!</p>",
      "rawMarkdown": "Congratulations @conjuring92, your solution is excellent and your data generation strategy is impressive! Well deserved!\n",
      "votes": 4,
      "replies": [
        {
          "id": 2310738,
          "postDate": "2023-06-20T15:20:23.650Z",
          "content": "<p>Thanks <a href=\"https://www.kaggle.com/thanhhau097a\" target=\"_blank\">@thanhhau097a</a>! Congratulations to you on solo gold, I was trying to catch your score entire competition (also in LECR previously…)!</p>",
          "rawMarkdown": "Thanks @thanhhau097a! Congratulations to you on solo gold, I was trying to catch your score entire competition (also in LECR previously...)!",
          "votes": 1
        }
      ]
    },
    {
      "id": 2319400,
      "postDate": "2023-06-27T05:30:04.310Z",
      "content": "<p><a href=\"https://www.kaggle.com/conjuring92\" target=\"_blank\">@conjuring92</a> congrats with 2 place! Very good solution!</p>",
      "rawMarkdown": "@conjuring92 congrats with 2 place! Very good solution!",
      "votes": 1
    },
    {
      "id": 2314496,
      "postDate": "2023-06-23T12:52:39.027Z",
      "content": "<p>Good Work   </p>",
      "rawMarkdown": "Good Work   ",
      "votes": 1
    },
    {
      "id": 2311540,
      "postDate": "2023-06-21T08:25:53.533Z",
      "content": "<p>Great work! Thanks a lot for sharing :) <a href=\"https://www.kaggle.com/conjuring92\" target=\"_blank\">@conjuring92</a> </p>",
      "rawMarkdown": "Great work! Thanks a lot for sharing :) @conjuring92 ",
      "votes": 1
    },
    {
      "id": 2311217,
      "postDate": "2023-06-21T02:49:45.243Z",
      "content": "<p><a href=\"https://www.kaggle.com/conjuring92\" target=\"_blank\">@conjuring92</a> Congratulations for the strong 2nd solo finish and becoming GM 🎉🎉 You are strong, well deserved !!</p>",
      "rawMarkdown": "@conjuring92 Congratulations for the strong 2nd solo finish and becoming GM 🎉🎉 You are strong, well deserved !!",
      "votes": 1,
      "replies": [
        {
          "id": 2311320,
          "postDate": "2023-06-21T05:21:00.373Z",
          "content": "<p>Thanks <a href=\"https://www.kaggle.com/chumajin\" target=\"_blank\">@chumajin</a>! One more to go for you 😊</p>",
          "rawMarkdown": "Thanks @chumajin! One more to go for you 😊",
          "votes": 1
        }
      ]
    },
    {
      "id": 2311049,
      "postDate": "2023-06-20T21:33:07.593Z",
      "content": "<p>nice work, looks very insightful</p>",
      "rawMarkdown": "nice work, looks very insightful",
      "votes": 1
    },
    {
      "id": 2310992,
      "postDate": "2023-06-20T20:02:28.710Z",
      "content": "<p>Congratulations on the strong finish and becoming GM!</p>\n<p>It's interesting that your solution and ours are really similar (the key parts being synthetic data generation and multi stages matcha training). Only we didn't manage to reach satisfying score for scatter and had to build custom pipeline for it. The fact that you managed to reach such scatter score with only matcha is amazing.</p>",
      "rawMarkdown": "Congratulations on the strong finish and becoming GM!\n\nIt's interesting that your solution and ours are really similar (the key parts being synthetic data generation and multi stages matcha training). Only we didn't manage to reach satisfying score for scatter and had to build custom pipeline for it. The fact that you managed to reach such scatter score with only matcha is amazing.",
      "votes": 1,
      "replies": [
        {
          "id": 2311178,
          "postDate": "2023-06-21T01:46:31.820Z",
          "content": "<p>Thanks <a href=\"https://www.kaggle.com/qdv206\" target=\"_blank\">@qdv206</a>! Congratulations to you too! </p>\n<p>Indeed, our solution and thought process were very similar. I tried a few things to boost score for scatter but all within matcha model. Since the public LB score was decent, my main fear was model robustness against unseen examples.</p>",
          "rawMarkdown": "Thanks @qdv206! Congratulations to you too! \n\nIndeed, our solution and thought process were very similar. I tried a few things to boost score for scatter but all within matcha model. Since the public LB score was decent, my main fear was model robustness against unseen examples.",
          "votes": 1
        }
      ]
    },
    {
      "id": 2310839,
      "postDate": "2023-06-20T16:33:50.070Z",
      "content": "<p>great work</p>",
      "rawMarkdown": "great work",
      "votes": 1
    },
    {
      "id": 2312760,
      "postDate": "2023-06-22T07:14:57.510Z",
      "content": "<p>great work   </p>",
      "rawMarkdown": "great work   ",
      "votes": 2
    },
    {
      "id": 2312607,
      "postDate": "2023-06-22T04:13:03.327Z",
      "content": "<p>Impressive work! Your solution demonstrates a thorough understanding of the problem and showcases your dedication to achieving high-quality results. The detailed explanations and references provided add credibility to your approach. Well done!</p>",
      "rawMarkdown": "Impressive work! Your solution demonstrates a thorough understanding of the problem and showcases your dedication to achieving high-quality results. The detailed explanations and references provided add credibility to your approach. Well done!",
      "votes": 2
    },
    {
      "id": 2312396,
      "postDate": "2023-06-21T21:25:00.357Z",
      "content": "<p>Great work </p>",
      "rawMarkdown": "Great work ",
      "votes": 2
    },
    {
      "id": 2311503,
      "postDate": "2023-06-21T07:44:39.907Z",
      "content": "<p>Amazing solution Raja, congrats on becoming GM, this is extremely well deserved!!! Awesome how you were able to achieve such a high score with image-to-text models only, a very elegant solution!</p>",
      "rawMarkdown": "Amazing solution Raja, congrats on becoming GM, this is extremely well deserved!!! Awesome how you were able to achieve such a high score with image-to-text models only, a very elegant solution!",
      "votes": 2,
      "replies": [
        {
          "id": 2311867,
          "postDate": "2023-06-21T13:59:15.490Z",
          "content": "<p>Thanks a lot Darek😊 The performance of these image-to-text models is truly insane and can handle wide range of tasks. It was great experience teaming up in LECR, looking forward to future collaborations!</p>",
          "rawMarkdown": "Thanks a lot Darek😊 The performance of these image-to-text models is truly insane and can handle wide range of tasks. It was great experience teaming up in LECR, looking forward to future collaborations!",
          "votes": 2
        }
      ]
    },
    {
      "id": 2310806,
      "postDate": "2023-06-20T16:03:02.157Z",
      "content": "<p>Congrats on the solo gold and for the comprehensive write-up <a href=\"https://www.kaggle.com/conjuring92\" target=\"_blank\">@conjuring92</a>!</p>\n<p>I like your approach of using the Wikipedia Glossary Pages to generate X-Y labels, and the usage of scientific notation. Very creative. </p>",
      "rawMarkdown": "Congrats on the solo gold and for the comprehensive write-up @conjuring92!\n\nI like your approach of using the Wikipedia Glossary Pages to generate X-Y labels, and the usage of scientific notation. Very creative. ",
      "votes": 2
    },
    {
      "id": 2310689,
      "postDate": "2023-06-20T14:47:59.317Z",
      "content": "<p>congratulations <a href=\"https://www.kaggle.com/conjuring92\" target=\"_blank\">@conjuring92</a>. When you say <code>patch size</code> you mean <code>max_patches</code> right? In that case, what hardware did you use? I trained with 1536 and 2048 and quickly went OOM even though i had 40gb VRAM. Did you find an increase in performance by using such large <code>max_patches</code>?</p>",
      "rawMarkdown": "congratulations @conjuring92. When you say `patch size` you mean `max_patches` right? In that case, what hardware did you use? I trained with 1536 and 2048 and quickly went OOM even though i had 40gb VRAM. Did you find an increase in performance by using such large `max_patches`?",
      "votes": 2,
      "replies": [
        {
          "id": 2310751,
          "postDate": "2023-06-20T15:27:51.803Z",
          "content": "<p>Thanks <a href=\"https://www.kaggle.com/alejopaullier\" target=\"_blank\">@alejopaullier</a> ! Yes, you're right, it should be max_patches, will update soon. I used A100/ A6000. Gradient checkpointing dramatically reduced the memory requirements:</p>\n<pre><code>model()\n\nmodel()\n</code></pre>\n<p>as shared by Nicholas previously 😊</p>\n<p>Increasing max_patches definitely gave boosts until 2048. For my phase II, i used up to 4096, but I didn't do ablation study to check its impact.</p>",
          "rawMarkdown": "Thanks @alejopaullier ! Yes, you're right, it should be max_patches, will update soon. I used A100/ A6000. Gradient checkpointing dramatically reduced the memory requirements:\n\n```\nmodel.encoder.gradient_checkpointing_enable()\n\nmodel.decoder.gradient_checkpointing_enable()\n```\n\nas shared by Nicholas previously 😊\n\nIncreasing max_patches definitely gave boosts until 2048. For my phase II, i used up to 4096, but I didn't do ablation study to check its impact.",
          "votes": 3,
          "replies": [
            {
              "id": 2310964,
              "postDate": "2023-06-20T18:46:36.213Z",
              "rawMarkdown": "",
              "votes": 1,
              "isDeleted": true
            }
          ]
        }
      ]
    },
    {
      "id": 2310684,
      "postDate": "2023-06-20T14:44:54.303Z",
      "content": "<p>Man, that's an amazing effort! Thank you for the detailed write up of your solution! And huge congratulations on becoming a GM. Very well deserved! </p>",
      "rawMarkdown": "Man, that's an amazing effort! Thank you for the detailed write up of your solution! And huge congratulations on becoming a GM. Very well deserved! ",
      "votes": 2,
      "replies": [
        {
          "id": 2310753,
          "postDate": "2023-06-20T15:28:33.333Z",
          "content": "<p>thanks <a href=\"https://www.kaggle.com/snnclsr\" target=\"_blank\">@snnclsr</a> 😊</p>",
          "rawMarkdown": "thanks @snnclsr 😊",
          "votes": 1
        }
      ]
    },
    {
      "id": 2312363,
      "postDate": "2023-06-21T20:52:41.940Z",
      "content": "<p>Well done and thank you for sharing</p>",
      "rawMarkdown": "Well done and thank you for sharing",
      "votes": 1
    },
    {
      "id": 2312085,
      "postDate": "2023-06-21T16:57:56.037Z",
      "content": "<p>Thanks for sharing this information </p>",
      "rawMarkdown": "Thanks for sharing this information ",
      "votes": 1
    }
  ],
  "comments": [
    {
      "id": 2310978,
      "author_name": "Nicholas Broad",
      "author_url": "",
      "post_date": "2023-06-20T19:31:30.927000",
      "content": "<p>Great work! Congrats on becoming a GM 🎉🎉🎉</p>\n<p>I can't believe you got the scatter score to be so high for matcha!!</p>\n<p>2 Questions:</p>\n<ol>\n<li>It looks like your training runs were very long 😄  Did you use any tricks to speed it up? </li>\n<li>How did you decide what augmentations to use and how often to apply them?</li>\n</ol>",
      "votes": 3,
      "replies": [
        {
          "id": 2311174,
          "author_name": "Raja Biswas",
          "author_url": "",
          "post_date": "2023-06-21T01:40:11.967000",
          "content": "<p>Thanks Nicholas! </p>\n<ol>\n<li><p>Yes, very long, as compared to any other models I trained for Kaggle comps. Phase I training was around 36hrs in A100. I didn't do anything special to speed it up (only using bf16, turned off gradient checkpointing for phase I - hence batch size of 2). I plan to experiment with torch 2.0, fsdp, maybe LoRA later.</p></li>\n<li><p>I wanted to avoid geometric transformations (I felt it may make training more difficult). Rest was just manual observation to make sure augmented images look reasonable. Since training runs were long and benefit of augmentation wasn't likely to show up early in training, I couldn't really tune any aspect of it. It was applied at 50% rate.</p></li>\n</ol>\n<p>On scatter plots, I think key was to include a large number of synthetic plots with many data points. In post-processing, I didn't force x and y series to have same number of points, which also helped. I wasn't able to explore any other strategies for scatter, mainly due to my lack of knowledge in object detection. I also couldn't allocate research time on it, as my focus is LLM these days. </p>",
          "votes": 2,
          "replies": []
        }
      ]
    },
    {
      "id": 2310695,
      "author_name": "Theo Viel",
      "author_url": "",
      "post_date": "2023-06-20T14:53:45.253000",
      "content": "<p>Congratz on the 2nd place and on the GM title !</p>\n<p>Can you share your LB scores by chart type ?<br>\nI'm mostly curious about scatter, matcha was not good for us so I'm impressed that you could get a competitive solution with only matcha.</p>",
      "votes": 3,
      "replies": [
        {
          "id": 2310735,
          "author_name": "Raja Biswas",
          "author_url": "",
          "post_date": "2023-06-20T15:18:48.747000",
          "content": "<p>Thanks <a href=\"https://www.kaggle.com/theoviel\" target=\"_blank\">@theoviel</a> ! Congratulations to you too!</p>\n<p>I only tried separate sub for scatter plots. The best I could get for scatter was: 0.24 private LB (phase I training), 0.29 (phase I + scatter only train). <br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F2125251%2F21abaaae41c1d4422e4b64a654bac9cc%2FScreenshot%202023-06-20%20at%2011.12.58%20PM.png?generation=1687273996904154&amp;alt=media\" alt=\"\"></p>\n<p>The following gave good boosts - </p>\n<ul>\n<li>Inclusion of a large number of synthetic scatter plots with high number of data points (36-64)</li>\n<li>longer training (performance of bar plots saturate very fast, whereas line &amp; scatter continues to improve with longer training) </li>\n</ul>",
          "votes": 3,
          "replies": [
            {
              "id": 2310746,
              "author_name": "Theo Viel",
              "author_url": "",
              "post_date": "2023-06-20T15:25:52.700000",
              "content": "<p>Thanks ! We have the same scatter score it seems :) </p>",
              "votes": 1,
              "replies": []
            },
            {
              "id": 2310767,
              "author_name": "Raja Biswas",
              "author_url": "",
              "post_date": "2023-06-20T15:39:48.140000",
              "content": "<p>yes! I will try late subs for other plot types to see if we have same scores for them too</p>",
              "votes": 1,
              "replies": []
            }
          ]
        }
      ]
    },
    {
      "id": 2311591,
      "author_name": "CroDoc",
      "author_url": "",
      "post_date": "2023-06-21T09:15:26.870000",
      "content": "<p>What a way to become a kaggle GM. Well deserved!</p>",
      "votes": 4,
      "replies": [
        {
          "id": 2311876,
          "author_name": "Raja Biswas",
          "author_url": "",
          "post_date": "2023-06-21T14:04:47.917000",
          "content": "<p>Thanks <a href=\"https://www.kaggle.com/crodoc\" target=\"_blank\">@crodoc</a>! Congratulations to you too, you became GM in such a short time &amp; always performing well in diverse competitions 👍</p>",
          "votes": 2,
          "replies": []
        }
      ]
    },
    {
      "id": 2310696,
      "author_name": "Thanh Hau Nguyen",
      "author_url": "",
      "post_date": "2023-06-20T14:54:47.097000",
      "content": "<p>Congratulations <a href=\"https://www.kaggle.com/conjuring92\" target=\"_blank\">@conjuring92</a>, your solution is excellent and your data generation strategy is impressive! Well deserved!</p>",
      "votes": 4,
      "replies": [
        {
          "id": 2310738,
          "author_name": "Raja Biswas",
          "author_url": "",
          "post_date": "2023-06-20T15:20:23.650000",
          "content": "<p>Thanks <a href=\"https://www.kaggle.com/thanhhau097a\" target=\"_blank\">@thanhhau097a</a>! Congratulations to you on solo gold, I was trying to catch your score entire competition (also in LECR previously…)!</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 2319400,
      "author_name": "serangu",
      "author_url": "",
      "post_date": "2023-06-27T05:30:04.310000",
      "content": "<p><a href=\"https://www.kaggle.com/conjuring92\" target=\"_blank\">@conjuring92</a> congrats with 2 place! Very good solution!</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 2314496,
      "author_name": "Reashin Pillay",
      "author_url": "",
      "post_date": "2023-06-23T12:52:39.027000",
      "content": "<p>Good Work   </p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 2311540,
      "author_name": "Akshit Sharma",
      "author_url": "",
      "post_date": "2023-06-21T08:25:53.533000",
      "content": "<p>Great work! Thanks a lot for sharing :) <a href=\"https://www.kaggle.com/conjuring92\" target=\"_blank\">@conjuring92</a> </p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 2311217,
      "author_name": "chumajin",
      "author_url": "",
      "post_date": "2023-06-21T02:49:45.243000",
      "content": "<p><a href=\"https://www.kaggle.com/conjuring92\" target=\"_blank\">@conjuring92</a> Congratulations for the strong 2nd solo finish and becoming GM 🎉🎉 You are strong, well deserved !!</p>",
      "votes": 1,
      "replies": [
        {
          "id": 2311320,
          "author_name": "Raja Biswas",
          "author_url": "",
          "post_date": "2023-06-21T05:21:00.373000",
          "content": "<p>Thanks <a href=\"https://www.kaggle.com/chumajin\" target=\"_blank\">@chumajin</a>! One more to go for you 😊</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 2311049,
      "author_name": "Jonathan Grace",
      "author_url": "",
      "post_date": "2023-06-20T21:33:07.593000",
      "content": "<p>nice work, looks very insightful</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 2310992,
      "author_name": "qdv206",
      "author_url": "",
      "post_date": "2023-06-20T20:02:28.710000",
      "content": "<p>Congratulations on the strong finish and becoming GM!</p>\n<p>It's interesting that your solution and ours are really similar (the key parts being synthetic data generation and multi stages matcha training). Only we didn't manage to reach satisfying score for scatter and had to build custom pipeline for it. The fact that you managed to reach such scatter score with only matcha is amazing.</p>",
      "votes": 1,
      "replies": [
        {
          "id": 2311178,
          "author_name": "Raja Biswas",
          "author_url": "",
          "post_date": "2023-06-21T01:46:31.820000",
          "content": "<p>Thanks <a href=\"https://www.kaggle.com/qdv206\" target=\"_blank\">@qdv206</a>! Congratulations to you too! </p>\n<p>Indeed, our solution and thought process were very similar. I tried a few things to boost score for scatter but all within matcha model. Since the public LB score was decent, my main fear was model robustness against unseen examples.</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 2310839,
      "author_name": "Liam Nguyen",
      "author_url": "",
      "post_date": "2023-06-20T16:33:50.070000",
      "content": "<p>great work</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 2312760,
      "author_name": "Chinmayee Gamre",
      "author_url": "",
      "post_date": "2023-06-22T07:14:57.510000",
      "content": "<p>great work   </p>",
      "votes": 2,
      "replies": []
    },
    {
      "id": 2312607,
      "author_name": "Pooja Chauhan",
      "author_url": "",
      "post_date": "2023-06-22T04:13:03.327000",
      "content": "<p>Impressive work! Your solution demonstrates a thorough understanding of the problem and showcases your dedication to achieving high-quality results. The detailed explanations and references provided add credibility to your approach. Well done!</p>",
      "votes": 2,
      "replies": []
    },
    {
      "id": 2312396,
      "author_name": "Hozaifa Ahmed",
      "author_url": "",
      "post_date": "2023-06-21T21:25:00.357000",
      "content": "<p>Great work </p>",
      "votes": 2,
      "replies": []
    },
    {
      "id": 2311503,
      "author_name": "Darek Kłeczek",
      "author_url": "",
      "post_date": "2023-06-21T07:44:39.907000",
      "content": "<p>Amazing solution Raja, congrats on becoming GM, this is extremely well deserved!!! Awesome how you were able to achieve such a high score with image-to-text models only, a very elegant solution!</p>",
      "votes": 2,
      "replies": [
        {
          "id": 2311867,
          "author_name": "Raja Biswas",
          "author_url": "",
          "post_date": "2023-06-21T13:59:15.490000",
          "content": "<p>Thanks a lot Darek😊 The performance of these image-to-text models is truly insane and can handle wide range of tasks. It was great experience teaming up in LECR, looking forward to future collaborations!</p>",
          "votes": 2,
          "replies": []
        }
      ]
    },
    {
      "id": 2310806,
      "author_name": "Bartley",
      "author_url": "",
      "post_date": "2023-06-20T16:03:02.157000",
      "content": "<p>Congrats on the solo gold and for the comprehensive write-up <a href=\"https://www.kaggle.com/conjuring92\" target=\"_blank\">@conjuring92</a>!</p>\n<p>I like your approach of using the Wikipedia Glossary Pages to generate X-Y labels, and the usage of scientific notation. Very creative. </p>",
      "votes": 2,
      "replies": []
    },
    {
      "id": 2310689,
      "author_name": "moth",
      "author_url": "",
      "post_date": "2023-06-20T14:47:59.317000",
      "content": "<p>congratulations <a href=\"https://www.kaggle.com/conjuring92\" target=\"_blank\">@conjuring92</a>. When you say <code>patch size</code> you mean <code>max_patches</code> right? In that case, what hardware did you use? I trained with 1536 and 2048 and quickly went OOM even though i had 40gb VRAM. Did you find an increase in performance by using such large <code>max_patches</code>?</p>",
      "votes": 2,
      "replies": [
        {
          "id": 2310751,
          "author_name": "Raja Biswas",
          "author_url": "",
          "post_date": "2023-06-20T15:27:51.803000",
          "content": "<p>Thanks <a href=\"https://www.kaggle.com/alejopaullier\" target=\"_blank\">@alejopaullier</a> ! Yes, you're right, it should be max_patches, will update soon. I used A100/ A6000. Gradient checkpointing dramatically reduced the memory requirements:</p>\n<pre><code>model()\n\nmodel()\n</code></pre>\n<p>as shared by Nicholas previously 😊</p>\n<p>Increasing max_patches definitely gave boosts until 2048. For my phase II, i used up to 4096, but I didn't do ablation study to check its impact.</p>",
          "votes": 3,
          "replies": [
            {
              "id": 2310964,
              "author_name": "",
              "author_url": "",
              "post_date": "2023-06-20T18:46:36.213000",
              "content": "",
              "votes": 1,
              "replies": []
            }
          ]
        }
      ]
    },
    {
      "id": 2310684,
      "author_name": "Sinan Calisir",
      "author_url": "",
      "post_date": "2023-06-20T14:44:54.303000",
      "content": "<p>Man, that's an amazing effort! Thank you for the detailed write up of your solution! And huge congratulations on becoming a GM. Very well deserved! </p>",
      "votes": 2,
      "replies": [
        {
          "id": 2310753,
          "author_name": "Raja Biswas",
          "author_url": "",
          "post_date": "2023-06-20T15:28:33.333000",
          "content": "<p>thanks <a href=\"https://www.kaggle.com/snnclsr\" target=\"_blank\">@snnclsr</a> 😊</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 2312363,
      "author_name": "Travis Ruddy",
      "author_url": "",
      "post_date": "2023-06-21T20:52:41.940000",
      "content": "<p>Well done and thank you for sharing</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 2312085,
      "author_name": "Talla.Lakshmi Narayana ",
      "author_url": "",
      "post_date": "2023-06-21T16:57:56.037000",
      "content": "<p>Thanks for sharing this information </p>",
      "votes": 1,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "2310677": "First of all, I would like to thank the Kaggle community for sharing great ideas and engaging discussions. Special shout outs to @nbroad  and @brendanartley. Congratulations to the winning teams - looking forward to your write ups.\n\nThank you Kaggle and hosts for organizing this interesting competition.\n\n## Links\n\n- Inference notebook: https://www.kaggle.com/code/conjuring92/a05-mga-split-pipe\n- Github Repo: https://github.com/rbiswasfc/benetech-mga\n\n\nThe following is a detailed summary of my solution:\n\n## 1 Overview\n\nMy solution is entirely based on image-to-text models finetuned from the `google/matcha-base` backbone. The training pipeline, as depicted below, is a sequence of two phases. In the first phase, I leveraged a large number of synthetic plots to adapt the backbone for the current task.  In the second phase, I used oversampled extracted / non-generated plots to specialize the pipeline for real world graphs. In this phase, I created separate models for scatter and non-scatter plots, primarily to mitigate the difficulty in predicting scatter data points.\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F2125251%2F232cced3276ad6561fe6a56d2e7509ad%2Fmga_flow.png?generation=1687269107458839&alt=media)\n\n## 2 Model\n\nAll models share the same architecture (image-to-text transformer) and input-output pattern. Model input is simply the plot image itself without any prompts. The output text has the following template:\n\n```<|bos|> <|chart_type_start|> {chart_type} <|chart_type_end|> <|num_point_start|> {n_x} | {n_y} <|num_point_end|> <|x_span_start|> {x0} | {x1} | {x2} | … | {xn} <|x_span_end|> <|y_span_start|> {y0} | {y1} | {y2} | … | {ym}  <|y_span_end|> <|eos|>```\n\nSome minor details:\n- Numeric values are cast into scientific notation using `val = \"{:.2e}\".format(float(val))`.\n- Added histogram as additional chart type, which later converted to vertical_bar during post processing\n\n## 3 Data\nApart from the competition data, I used the following sources.\n\n### Synthetic Dataset\n\nI spent majority of my competition time creating the synthetic dataset. For the underlying data in synthetic plots, I used\n\n- Wikitables data i.e. tables from wikipedia (25%)\n    - http://websail-fe.cs.northwestern.edu/TabEL/\n    - https://github.com/sunlab-osu/TURL\n- Synthetic XY data (75%)\n    - Categorical series: I created a list of categories using wikipedia glossary pages in STEM domain (https://www.kaggle.com/code/conjuring92/w03-stem-glossary/notebook)\n    - Numerical series: random function generators ensuring all combinations of narrow to wide min-max range, small (1e-6) - large values (1e6), inclusion of outliers etc\n\nI generated the plots using matplotlib ensuring they capture all aspects of the graph conventions. For example, in the case of line plots, the generated graphs included shared origin plots, having tick labels that are not included in the data-series, additional point markers in between two tick labels, unequal spacing between x tick labels etc. I tried to maximize the diversity in the graphs by -\n\n- customizing tick marks, tick labels, tick direction, formatting of numerical tick labels (e.g. scientific notation, different rounding, European style formatting, adding % as suffix, currency symbol as prefix etc), major / minor grids, titles, axis limits, spines (e.g. setting bottom spine at y=0),  legends, markers etc\n- grayscale, background textures, aspect ratio (very wide to very narrow)\n- number of data points (4-24 points for non-scatter, 4-64 for scatter)\n- random special effects: text boxes with stats on y values, horizontal / vertical bands, insets, random texts, random equations, annotating min/max points, error bands, adding random shapes, varying line width, color, data point marker size, hatches, error bars, slopes etc\n- log-log, semi-log plots, reverse y axis (although these weren’t part of test set, my hypothesis (?) was they would help in model generalization)\n\nThe synthetic dataset consisted of\n\n- 100k horizontal bars\n- 100k vertical bars + histograms\n- 100k dot plots\n- 200k line plots\n- 200k scatter plots\n\n### Synthetic Dataset - Bartley\n- Random selection of 25k data points from the synthetic dataset shared by @brendanartley: https://www.kaggle.com/datasets/brendanartley/benetech-extra-generated-data\n\n### Pseudo Labelling\nI took screenshot of around 700 images from wikimedia commons (e.g. https://commons.wikimedia.org/w/index.php?search=line+plots&title=Special:MediaSearch&go=Go&type=image). I used pseudo labelling, followed by manual correction, to generate the annotations.\n\n### ICDAR dataset\nI used around 1100 images from ICDAR, only those having 1 XY series (250 horizontal bar + 450 vertical bar + 250 lines + 150 scatter). I also did post-processing to ensure annotations match competition graph conventions (e.g. handling percentages, interpolation of line plot data to match tick labels etc).\n\n## 4 Datamix\n- Datamix 1: used for domain adaptation\n\n| Dataset                         | Size | Multiplier | Effective Size |\n| ------------------------------- | ---- | ---------- | -------------- |\n| Competition Dataset - Synthetic | 60k  | 3          | 180k           |\n| Competition Dataset - Extracted | 1.1k | 16         | 17k            |\n| Synthetic Dataset - Self        | 700k | 1          | 700k           |\n| Synthetic Dataset - Bartley     | 25k  | 1          | 25k            |\n\n- Datamix 2: scatter specialization\n\n| Dataset                         | Size | Multiplier | Effective Size |\n| ------------------------------- | ---- | ---------- | -------------- |\n| Competition Dataset - Synthetic | 11k  | 1          | 11k            |\n| Competition Dataset - Extracted | 0.2k | 16         | 3.2k           |\n| Synthetic Dataset - Self        | 30k  | 1          | 30k            |\n| Pseudo Labelled Dataset         | 0.1k | 16         | 1.6k           |\n| ICDAR Dataset                   | 0.2k | 16         | 3.2k           |\n\n- Datamix 3: non-scatter specialization\n\n| Dataset                         | Size | Multiplier | Effective Size |\n| ------------------------------- | ---- | ---------- | -------------- |\n| Competition Dataset - Synthetic | 48k  | 1          | 48k            |\n| Competition Dataset - Extracted | 0.9k | 8          | 7.2k           |\n| Synthetic Dataset - Self        | 20k  | 1          | 20k            |\n| Pseudo Labelled Dataset         | 0.5k | 8          | 4k             |\n| ICDAR Dataset                   | 1k   | 8          | 8k             |\n\n## 5 Training\n\nThe main hyper-parameters for training were `max_patches` and `max_length`. I used the following settings at various phases of training:\n\n##### Phase 1 Training\n\n- max_patches: 2048\n- max length: 1024\n- lr: 5e-5\n- batch size: 2\n- gradient accumulation: 16\n\n##### Phase 2 training - non-scatter\n- max_patches: 4096\n- max length: 512\n- lr: 2e-5\n- batch size: 4\n- gradient accumulation: 2\n\n##### Phase 2 training - scatter\n- max_patches: 3072\n- max length: 1024\n- lr: 2e-5\n- batch size: 8\n- gradient accumulation: 1\n- AWP\n\nAs minor detail, I used Exponential Moving Average (EMA) of model weights, gradient clipping, cosine scheduler with liner warmup during training.\n\n## 6 Augmentation\n\nSince I was repeating the extracted images many times, I decided to include the following augmentation\n\n```\ntransforms = A.Compose(\n        [\n            A.OneOf(\n                [\n                    A.RandomToneCurve(scale=0.3),\n                    A.RandomBrightnessContrast(\n                        brightness_limit=(-0.1, 0.2),\n                        contrast_limit=(-0.4, 0.5),\n                        brightness_by_max=True,\n                    ),\n                    A.HueSaturationValue(\n                        hue_shift_limit=(-20, 20),\n                        sat_shift_limit=(-30, 30),\n                        val_shift_limit=(-20, 20)\n                    )\n                ],\n                p=0.5,\n            ),\n\n            A.OneOf(\n                [\n                    A.MotionBlur(blur_limit=3),\n                    A.MedianBlur(blur_limit=3),\n                    A.GaussianBlur(blur_limit=3),\n                    A.GaussNoise(var_limit=(3.0, 9.0)),\n                ],\n                p=0.5,\n            ),\n\n            A.Downscale(always_apply=False, p=0.1, scale_min=0.90, scale_max=0.99),\n        ],\n\n        p=0.5,\n    )\n```\n\n## 7 References\n* Matcha Paper: https://arxiv.org/pdf/2212.09662v2.pdf\n* https://www.kaggle.com/code/nbroad/donut-train-benetech\n* https://www.kaggle.com/code/nbroad/donut-infer-lb-0-44-benetech\n* https://www.kaggle.com/datasets/brendanartley/benetech-extra-generated-data\n* AWP: https://www.kaggle.com/code/wht1996/feedback-nn-train/notebook\n\n\nSorry for the long write up. Please let me know if you have any queries / suggestions. I plan to release all scripts, configs and datasets by next week. [Edit: code released at https://github.com/rbiswasfc/benetech-mga]",
    "2310978": "Great work! Congrats on becoming a GM 🎉🎉🎉\n\nI can't believe you got the scatter score to be so high for matcha!!\n\n2 Questions:\n1. It looks like your training runs were very long 😄  Did you use any tricks to speed it up? \n2. How did you decide what augmentations to use and how often to apply them?",
    "2310695": "Congratz on the 2nd place and on the GM title !\n\nCan you share your LB scores by chart type ?\nI'm mostly curious about scatter, matcha was not good for us so I'm impressed that you could get a competitive solution with only matcha.",
    "2311591": "What a way to become a kaggle GM. Well deserved!",
    "2310696": "Congratulations @conjuring92, your solution is excellent and your data generation strategy is impressive! Well deserved!\n",
    "2319400": "@conjuring92 congrats with 2 place! Very good solution!",
    "2314496": "Good Work   ",
    "2311540": "Great work! Thanks a lot for sharing :) @conjuring92 ",
    "2311217": "@conjuring92 Congratulations for the strong 2nd solo finish and becoming GM 🎉🎉 You are strong, well deserved !!",
    "2311049": "nice work, looks very insightful",
    "2310992": "Congratulations on the strong finish and becoming GM!\n\nIt's interesting that your solution and ours are really similar (the key parts being synthetic data generation and multi stages matcha training). Only we didn't manage to reach satisfying score for scatter and had to build custom pipeline for it. The fact that you managed to reach such scatter score with only matcha is amazing.",
    "2310839": "great work",
    "2312760": "great work   ",
    "2312607": "Impressive work! Your solution demonstrates a thorough understanding of the problem and showcases your dedication to achieving high-quality results. The detailed explanations and references provided add credibility to your approach. Well done!",
    "2312396": "Great work ",
    "2311503": "Amazing solution Raja, congrats on becoming GM, this is extremely well deserved!!! Awesome how you were able to achieve such a high score with image-to-text models only, a very elegant solution!",
    "2310806": "Congrats on the solo gold and for the comprehensive write-up @conjuring92!\n\nI like your approach of using the Wikipedia Glossary Pages to generate X-Y labels, and the usage of scientific notation. Very creative. ",
    "2310689": "congratulations @conjuring92. When you say `patch size` you mean `max_patches` right? In that case, what hardware did you use? I trained with 1536 and 2048 and quickly went OOM even though i had 40gb VRAM. Did you find an increase in performance by using such large `max_patches`?",
    "2310684": "Man, that's an amazing effort! Thank you for the detailed write up of your solution! And huge congratulations on becoming a GM. Very well deserved! ",
    "2312363": "Well done and thank you for sharing",
    "2312085": "Thanks for sharing this information "
  }
}