{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Introduction\nMany of the highest scoring competitors have identified a 0.5 pixel shift in the dataset, which led to spatial data augmentations not working well, for example in the [1st](https://www.kaggle.com/competitions/google-research-identify-contrails-reduce-global-warming/discussion/430618) and [9th](https://www.kaggle.com/competitions/google-research-identify-contrails-reduce-global-warming/discussion/430479) place writeups. \n\nA great visualization done by [hengck23](https://www.kaggle.com/hengck23) of how this problem might look like: \n![pixelshift.png](attachment:f32e0742-15b7-4576-ac94-905548933a4f.png)\n\n* This notebook creates a 0.5 pixel right and bottom shifted [Ash color scheme](https://eumetrain.org/sites/default/files/2020-05/RGB_recipes.pdf) which you should be able to use immediately with data augmentation. \n* Note that the labels here are created as mean of annotators (soft labels) vs as a majority vote (hard labels). You can get hard labels with y = y > 0.51. \n* You also need to apply the shift at inference when loading the test data if you want to submit your trained model.","metadata":{},"attachments":{"f32e0742-15b7-4576-ac94-905548933a4f.png":{"image/png":"iVBORw0KGgoAAAANSUhEUgAAAvwAAAJCCAYAAAC8mBOKAAAAinpUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjaVY7LDcQwCETvVJES+IyxKSeyYikdbPmLY0tR3mEYEBqg63cPOibCIJTaPNw5QSD0TNN4YcyiLLOmLnY1SafZ7p5Ml/FolfEuAvyhmDcfFbV68e5dM10vs0fFQM/WDJuvxBs0Oq8T9p1D93xDfwXjLUpxH2UAAAAKBmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNC40LjAtRXhpdjIiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iCiAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249Ijc2NCIKICAgZXhpZjpQaXhlbFlEaW1lbnNpb249IjU3OCIKICAgdGlmZjpJbWFnZVdpZHRoPSI3NjQiCiAgIHRpZmY6SW1hZ2VIZWlnaHQ9IjU3OCIKICAgdGlmZjpPcmllbnRhdGlvbj0iMSIvPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg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xybfO3HihCZNmqSbb775gu9/eoDt2Nb2zYXqLVw4bfoM/7hx47Rr1y5J0pgxY7Rr1y5NnTpVkZGRio+P13fffad169YpNjZW0dHRWrp0qdxut+f2GRkZWrhwoS6++GJFRERo2LBhWr9+fZWmmj9/vnr27KlLLrlEa9eu1dy5c/X+++9LksrKyvTAAw+oX79+ioyM1IwZM/Tdd98xqtAixowZo02bNik+Pl5RUVGaPHmykpKSPJcXFBRoxYoVGjRokKKiojRjxgx9/fXX59V58skntWDBgirLTp8+rauuukpffvllg3qhvvsaM2aM3nvvPV133XXq1q2bRo8erU2bNtX62Orrzfrq1Xd5Xet7//33a9++fdq4caNmzpxZ7/rUdP3KxyZvbxucPcO5e/du7dixQ2PGjNGxY8fq3Efl5eUaM2aMPv30U0+NimWff/55ldrV92dD+qOmQFZbv7hcLo0ZM0Zvvvmm+vfvryuuuEK5ubl1jpOGrH994yg3N1cLFy5Ujx49NHjwYG3fvr3W7Vt9G9S0zidPnqxznWrqC0k6dOiQpk+frsjISA0dOlRvvfVWncc4bz+v79ixQ2PHjlVkZKQGDRqkRx99tMrtKysoKNCcOXN03333yeVy1Xid4uJiLV++XP369VPPnj01d+5c/fDDD5JU676uLzs09nhTX73G7PvqvfXDDz80erw2dd91pOe4C8J40Z6kNONL1etbrVbz1ltvmXN/S8D07NnT/PGPfzS7d+82l19+uYmOjjYTJ040O3fuNM8//7zx8/MzmzZtMsYY43K5TGxsrLn22mvN559/bvbt22eWLFlirFar+eGHH4zb7TZjx441w4YNM7t27TIffPCBGTRokLFarWb9+vXGGGNuuukmc8kll5h3333XfPHFF2bRokWmW7duJi8vr1VsH+q37/qSTOfOnc0f//hHk5qaan7+85+bkJAQc+zYMeN2u8348ePNwIEDzTvvvGM+//xzc/PNN5vOnTub9PR0U1JSYiSZbdu2mQ8//NBIMmlpP9Vfu3at6dmzp3E6nfX2Qn33VbGu3bp1My+99JLZtWuXmT17tvH39zcnT54873HW15sNqVfX5fWt71dffWWuuOIKM2fOHPPPf/6z3vWpfv3KxyZvbxvG/1l79+418fHxZtq0aWbXrl2msLCwzn1UebxXqFj23nvvVbm8+v6srz+qq69fHA6HkWSioqLMo48+an7zm980ql9rWv+GjPn4+HgzfPhws3v3bvPee++ZAQMGVLl9ZdW3QU3rXN861dQXkkxISIj5/e9/bz799FNzxx13GJvNZo4dO1bjPvf28/rx48dNQECAeeGFF8z3339v/va3v5mQkBCzdu3a83JFYWGhGTdunBkzZkytz+nGGDN9+nTTv39/s337drN//34zZcoUM3jwYON2u2vcbvVlh6Ycb+qq19h9X723zpw50+jx2pR9V9v+b4/PcRfq+NmuAv9DDz3kuez55583kszRo0c9y4YNG2ZWrlxpjDEmNzfXrFixwmRkZHgurxjY7733ntm9e7eRZFJSUjyX79+/30gy69evNwcOHDCSTGJiYpWg0r9/f/PEE08QaKnfIoH/17/+ted3p9Np+vbta1atWmU+/vhjI8l88cUXnssdDofp16+fWbp0aZWDodvtNjExMeaRRx7xXHfs2LGe2vX1Qn33VbGuK1as8FyenZ19XlioUF9vNqReXZc3ZH0nTpzo+bkh61P5+pWPTd7eNoz/n8yaNcssXLiwQfuoMYG/+v6srz+qq69fKkLg/fff77m8Mf1aV+CvbRx99tlnRpI5cOCA5/Jdu3bVGvqqb4Oa1rkh61S9L6o/T58+fdpIMlu3bq018Hnzeb3iMe/bt89z+c6dO83Bgwer9O66devMxIkTzfjx482ZM2dqHZPff/+9kWT+7//+z7MsIyPDLFq0yGRlZdW43erLDo093tRXryn7vnJvNWW8NmXf1bb/2+Nz3IU6ftra09u8l156qefn0NBQhYSEKDo62rMsODhYpaWlkqTw8HA9+eST2rlzpzZs2KDU1FTPJ9adTqeSkpIUFRWlgQMHem4/bNgwde7cWZL0r3/9S5L04osvau3atZ7rlJWV1fiWEuALkydP9vxstVoVFxen/fv3Kzw8XKGhoRoxYoTncpvNpgkTJmj//v1ValgsFi1cuFBvvPGGVq1apbS0NH3++ef64x//KEn19sL+/fsbdF+XX3655+euXbt6+qW6+nqzofVqu/zQoUMN3jaNWZ+aeHvboGbN2Uf1qa8/qquvXypcccUVjR4n9altHO3bt0/BwcFVLh83bpz8/Bo3q7fyOjfVkCFDPD+HhYXJarWquLi4RZ7Xx44dqwkTJmjkyJEaPny4rrvuOs2dO7fKOknSsmXLlJOTo9WrVys0NLTWdfvqq69ksVh01VVXeZb17t3b84HairFXebvVlx0aO5brq9e5c2ev7/uGjtfG7LuO9Bx3obSrwO/v71/ld6vVWut1S0pKNG3aNH333XdKSEjQ0KFDNW/ePF1zzTV13raiSSwWi2w2m0aOHFnl8mHDhuniiy/mGRgtolOnTlUb2maT2+2W1Wo9rx8kyW63y2KxnLd80aJFeuyxx7R371699957Gj16tAYNGtSgXmjofQUGBtY0pbDRvdnQerVd3tht09D1qYm3tw2adjyvSW1zsmtSV3/UtM/r6pcKXbp0afQ4qW/9axtHTqdTdrv9vGNFTdevS+V1buo2tdlsjRrr3nxeDwgI0EcffaR33nlH27dv17p16/T444/r6aef1rJlyzx1RowYoYSEBD388MOaNWtWlSBY036tvm3r2m71ZYfGjuX66p04ccLr+76h47Ux+64jPccR+FvY9u3blZiYqMOHD3sC+qFDhzw7aOjQoTp16pSOHDmiPn36SJL+/e9/Ky8vT5I0cOBAOZ1OzZgxo8qBf926derRowfPwGgRBw8e1IQJEzy/HzhwQNddd50GDhyonJwcHTt2rMoZlf3792vo0KHn1enXr58mTJigzZs3691339U999zjuawhvdCY+2pubzZXQ9a38kG8IetTWyjz9rZB08ZMRcgsKSnx3CYzM7PWetX3Z139UV19/dKUcdLY9a9u0KBBysvLU0ZGhmJiYiRJR44cqfPMem1junpwr2ud6qvR0uPg4MGDSkxM1JIlSzR79mwZY7RkyRI988wzVQL/3XffrZtuuklvv/22Fi9erD179tR4RnzAgAFyuVxKTU315IDi4mJNmTJFa9eu1WWXXVbjvq4rOzT2eFNfvS5dujR633vjGMpzXOvTYf/SrsVikTFGWVlZks5+in3p0qWSzr4Fc/XVV2vUqFGaP3++vvjiCyUlJWn+/Pme21511VUaMWKElixZ4vnO3o0bN2rx4sXKycnhGRgt4ne/+51SU1Pldrv17LPPKiUlRYsXL9aUKVM0ePBgLVmyRKdPn5bL5dLTTz+tffv26Wc/+1mNtRYvXqz//d//1aFDh6p893J9vdCU+2pObzZXQ9a3U6dOSk1NVVpaWoPWp/L1G3tf8P3x3Gaz6dJLL9X69etVXFysnJwc/epXv6p1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mjp1qiIjIxUfH6/vvvtO69atU2xsrKKjo7V06VK53W7P7TMyMrRw4UJdfPHFioiI0LBhw7R+/XrP5Tk5OZo/f7569uypSy65RGvXrtXcuXP1/vvvN3o7NOT+xowZo/fee0/XXXedunXrptGjR2vTpk2ey3Nzc7Vw4UL16NFDgwcP1vbt2+vc/77YJjt27NDYsWMVGRmpQYMG6dFHH61y+8oKCgo0Z84c3XfffXK5XJKk3/72t5o9ezadDwAACPze8PnnnysnJ0fLli3T4MGDNXLkSD355JPq2rVrlet1795db7zxhuf3f/zjH9q7d68n2Lrdbv3hD3/QJZdcIkm67bbbtHnzZr300kv64IMPFBUVpUmTJik/P/+8dah+3xERETWuoyTt3btXd911l/7zP/9T//znPxUbG6urr776vBcJtd32jjvu8KxbQUGBrrnmGv3pT3/S2rVr9etf/1ovvvii/v73v3se0zXXXKOsrCxt2rRJO3fu1NixY7V48WJlZGTIGKMbbrhBBw8e1IYNG/T73/9ezz//vP7xj394piM1ZjvUd38Vj2HRokW64YYbtGnTJkVHR2v+/Pn68ccfZYzRzJkz9fXXX2vjxo169tln9cADD9S5/729TU6cOKEbb7xRt99+uz799FP9z//8j5566im98sor5913UVGRrr/+eh0/flyPPfaYrFarJCkoKEidO3em8wEAQMfhyz8cYLVazVtvvWWMMWbWrFlm4cKFNd5u9+7dxmq1mry8PGOMMZdccokZN26cmTFjhjHGmMTERBMQEGAKCgrMgQMHjCSTmJjoub3L5TL9+/c3TzzxRI31K993SUmJkWS2bdt23jpKMr/+9a89t3M6naZv375m1apVNdatftuHHnrIc9nzzz9vJJmjR496lg0bNsysXLnSGGNMbm6uWbFihcnIyPBcfubMGSPJvPfee2b37t1GkklJSfFcvn//fiPJrF+/vtHbob77q3gMK1as8FyenZ3t2VafffaZkWQOHDjguXzXrl1Vbl+dt7dJxf3t27fPc/nOnTvNwYMHq+yTdevWmYkTJ5rx48ebM2fO8Ie3qE996lOf+tSnfoeub2sNLzri4+MVFhamnTt3auTIkTp69KieffZZ3X777XK5XHrnnXeUkJCgkJAQ/etf/5Ikvfjii1WmAZWVlenrr79u9rpMnjzZ87PValVcXJz279/foNteeumlnp9DQ0MVEhKi6Ohoz7Lg4GDPZwjCw8P15JNPaufOndqwYYNSU1M933bjdDqVlJSkqKgoDRw40HP7YcOGec5ON3Y71Hd/FS6//HLPzxXvxJSVlWnfvn0KDg6ucvm4cePk5+fXYttk7NixmjBhgkaOHKnhw4fruuuu09y5czVkyJDz3tXJycnR6tWrFRoayqt6AADQobWKwG+1WnX99dfrgw8+UG5uruLj45WQkKDy8nIlJSXpnXfe0dKlSyVJFotFNptNI0eOrFJj2LBhuvjii5u9Lp06daq6gWy2WueIV+fv73/e46pNSUmJpk2bpu+++04JCQkaOnSo5s2bp2uuuabO21YE7MZuh/rur0JgYGBN7wLJ6XTKbreft21qur6vtklAQIA++ugjvfPOO9q+fbvWrVunxx9/XE8//bSWLVvmqTNixAglJCTo4Ycf1qxZs6q8aAIAACDwXyAzZ87Uf/3Xfyk/P18JCQkKDAxUfHy8/vSnP+nbb7/VzJkzJUkDBw6U0+nUjBkzNGjQIM/t161bpx49ejR7PQ4ePKgJEyZ4fj9w4ICuu+46rz/e7du3KzExUYcPH/YE9EOHDnkC9tChQ3Xq1CkdOXJEffr0kST9+9//Vl5eXpO2Q333V59BgwYpLy9PGRkZiomJkSQdOXJExcXFLbZNDh48qMTERC1ZskSzZ8+WMUZLlizRM888UyXw33333brpppv09ttva/HixdqzZ0+970QAAAC0V60mBV177bU6efKktmzZoilTpkiSpk6dqtdff11jx45Vt27dJElXXXWVRowYoSVLlni+b33jxo1avHix5wO0zfG73/1OqampcrvdevbZZ5WSkqLFixd7/fFaLBYZY5SVlSXp7DfgVLyLUVZWpquvvlqjRo3S/Pnz9cUXXygpKUnz58/33Lax26G++6vP5MmTFRsbq3vvvVcFBQUqLCz03L6ltkl+fr5++ctfej7kW1JSoszMzBrP4Pv5+em1115TcnKynnvuOc/yt99+W2vWrKHzAQAAgb+lhYSEaPLkyQoMDPRMU5k6dapcLpduvPHGKkFu48aNKisrU48ePRQaGqq7775bzzzzjGbNmtXs9Rg3bpyGDx+ukJAQPfXUU9q0aVOVeejecuONN+qWW27R2LFj1bt3bw0ePFiTJ0/WiBEjPF8FunnzZnXp0kXjx4/XzJkzddttt3mm8jR2OzTk/upit9u1detWZWRkqGvXruratauio6MVHBzcYtskPj5ejz/+uBYuXKjQ0FCFhYXpxx9/1GuvvVZjvcGDB2vlypV66KGHlJKSQuAHAAAdU1v6lHF1J0+eNGlpaaa8vNwr9SSZt956yxQUFJhDhw4Zh8Ph88eQk5NjMjIyjNvtPu9bdXbt2mWcTud535qza9euJm+H2u6vMX744QeTlZXV4tukQllZmUlLSzPHjx83rQnfEkB96lOf+tSnPvX5lh4v6969u8/ebQgJCWmRxxAREXHe3waQzn4rzdSpU/XCCy/o5z//uUpKSrRy5Up169ZNcXFxTd4Otd1fY1TM4W/pbVLB399f/fr149U6AABAA/BJxkqsVmur+XBnVFSUXn/9df33f/+3AgMDFRoaqk8//VTbtm3z6jQaAAAAtG8WU8NXtCQmp7NlAAAAgPaAOU7Upz71qU996lOf+tSnfvutz5QeAAAAoB0j8AMAAAAEfgAAAAAE/jYiIyND06ZNU1pamtdqut1uvfLKK7rhhhs0bdo0vfDCC3I6nV6r73K59Prrr2vOnDm65pprtGLFCmVnZ/tk+7z66qt64oknvF5327Ztmj17thISErR69Wo5HA46EAAA8g/5h8DvXW63WwsWLNAHH3yggoICr9Vdvny5Vq1apeuvv15z587V6tWrddddd3mt/n333acHH3xQV111lW6//XYlJiYqLi5O+fn5Xt0+b7/9tu69916vHgwkacOGDZo7d65GjBihm266SWvWrNGdd97J0RcAAPIP+cfHbB1twK9evVpHjx71as3c3Fy9+OKLnp0qSV27dtWcOXP09NNPq2vXrs2qn52drZdffllbtmzRDTfcIEmaM2eOevfurb/+9a9asmRJsx9DXl6eVq1apT/84Q/q3LmzV7ePMUYPPvigHn74YT344IOSpNGjRysuLk4PPvigBg8ezJEYAADyD/nHRzrUGf59+/bp6aef1ssvv+zVuuHh4UpNTdXMmTM9y1wulywWi2r4MwdNGjAvvfSSJk2a5FkWEhKi8PBwnThxwiuPYceOHUpOTtYnn3yikSNHenX7pKSkKCMjQzNmzPAsGzVqlHr16qX333+fozAAAOQf8o8PdZgz/CUlJbr99tu1evVq9e3b16u1LRaLp2Zqaqp2796t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"}}},{"cell_type":"markdown","source":"## Band Summary\nA lot of information about bands is already contained in other EDAs, especially [this EDA](https://www.kaggle.com/code/pranavnadimpali/comprehensive-eda-submission), a short summary:\n\nThe Advanced Baseline Imager (ABI) is a key instrument on the Geostationary Operational Environmental Satellite (GOES) series. It captures images of the Earth using 16 spectral bands, with each band focusing on a specific wavelength. This provides a wealth of information about the Earth's atmosphere, clouds, land, and water, significantly improving weather analysis and forecasting. In this dataset, you have access to 9 bands for each example.\n\nEach band provides a series of images taken at 10-minute intervals, leading to 8 images for each band spanning 80 minutes. This temporal data captures how contrails evolve over time. Two types of segmentation masks are provided: 'human_pixel_masks' that represent the consolidated ground truth, and 'human_individual_masks' that represent annotations from multiple labellers. The ground truth corresponds to the 5th image in the bands.\n\nThe image that labellers annotate is a false color image, which is not directly provided in the spectral bands but can be generated from them. The false color image uses the [Ash color scheme](https://eumetrain.org/sites/default/files/2020-05/RGB_recipes.pdf), using bands 15,14 and 11, making contrails appear darker and thus easier to detect. The ash color scheme combines red, green, and blue channels to represent different features. \n","metadata":{}},{"cell_type":"markdown","source":"## Imports","metadata":{}},{"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom pathlib import Path\nfrom tqdm.notebook import tqdm\nimport cv2","metadata":{"execution":{"iopub.status.busy":"2023-08-24T10:05:55.76172Z","iopub.execute_input":"2023-08-24T10:05:55.762129Z","iopub.status.idle":"2023-08-24T10:05:55.988078Z","shell.execute_reply.started":"2023-08-24T10:05:55.762086Z","shell.execute_reply":"2023-08-24T10:05:55.986943Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_dir = '/kaggle/input/google-research-identify-contrails-reduce-global-warming/'\n\ntrain_rs = os.listdir(data_dir + 'train')\nvalid_rs = os.listdir(data_dir + 'validation')\n\ntrain_df = pd.DataFrame(train_rs, columns=['record_id'])\nvalid_df = pd.DataFrame(valid_rs, columns=['record_id'])\n\ntrain_df['train'] = 'train'\nvalid_df['train'] = 'valid'","metadata":{"execution":{"iopub.status.busy":"2023-08-24T10:05:55.990929Z","iopub.execute_input":"2023-08-24T10:05:55.9914Z","iopub.status.idle":"2023-08-24T10:05:56.013583Z","shell.execute_reply.started":"2023-08-24T10:05:55.991359Z","shell.execute_reply":"2023-08-24T10:05:56.011022Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Dataset Creation","metadata":{}},{"cell_type":"markdown","source":"## Save csvs","metadata":{}},{"cell_type":"code","source":"# Save the csvs\ntrain_df.to_csv('train_df.csv', index=False)\nvalid_df.to_csv('valid_df.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-08-24T10:05:56.24787Z","iopub.execute_input":"2023-08-24T10:05:56.248242Z","iopub.status.idle":"2023-08-24T10:05:56.302124Z","shell.execute_reply.started":"2023-08-24T10:05:56.248213Z","shell.execute_reply":"2023-08-24T10:05:56.301207Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Save Images as Numpy","metadata":{}},{"cell_type":"code","source":"def read_record(record_id, directory, mode):\n    record_data = {}\n    read = [\"band_11\", \"band_14\", \"band_15\"]\n    if mode == 'train':\n        read.append('human_individual_masks')\n    elif mode == 'val':\n        read.append('human_pixel_masks')\n    for x in read:\n        if x == 'human_individual_masks':\n            individual = np.load(os.path.join(directory, record_id, x + \".npy\"))\n            record_data['human_pixel_masks'] = individual.sum(axis=3) / individual.shape[3]\n        else:\n            record_data[x] = np.load(os.path.join(directory, record_id, x + \".npy\"))\n    return record_data","metadata":{"execution":{"iopub.status.busy":"2023-08-24T10:05:56.599361Z","iopub.execute_input":"2023-08-24T10:05:56.600146Z","iopub.status.idle":"2023-08-24T10:05:56.607271Z","shell.execute_reply.started":"2023-08-24T10:05:56.600108Z","shell.execute_reply":"2023-08-24T10:05:56.606279Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def shift(img):\n    shift_matrix = np.array([[1.0, 0.0, 0.5], [0.0, 1.0, 0.5]], dtype=np.float32)\n\n    # Apply the affine transformation using cv2.warpAffine\n    shifted_img = cv2.warpAffine(\n        img,\n        shift_matrix,\n        (img.shape[1], img.shape[0]), # Keep the same size\n        flags=cv2.INTER_LINEAR,\n        borderMode=cv2.BORDER_CONSTANT,\n        borderValue=0,\n    )\n    return shifted_img","metadata":{"execution":{"iopub.status.busy":"2023-08-24T10:05:57.972718Z","iopub.execute_input":"2023-08-24T10:05:57.973075Z","iopub.status.idle":"2023-08-24T10:05:57.97904Z","shell.execute_reply.started":"2023-08-24T10:05:57.973047Z","shell.execute_reply":"2023-08-24T10:05:57.977977Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def normalize_range(data, bounds):\n    return (data - bounds[0]) / (bounds[1] - bounds[0])\n\ndef get_false_color(record_data):\n    _T11_BOUNDS = (243, 303)\n    _CLOUD_TOP_TDIFF_BOUNDS = (-4, 5)\n    _TDIFF_BOUNDS = (-4, 2)\n    N_TIMES_BEFORE = 4\n\n    r = normalize_range(record_data[\"band_15\"] - record_data[\"band_14\"], _TDIFF_BOUNDS)\n    g = normalize_range(record_data[\"band_14\"] - record_data[\"band_11\"], _CLOUD_TOP_TDIFF_BOUNDS)\n    b = normalize_range(record_data[\"band_14\"], _T11_BOUNDS)\n\n    false_color = np.stack([r, g, b], axis=2)\n    img = false_color[..., N_TIMES_BEFORE]\n    img = shift(img)\n    return img","metadata":{"execution":{"iopub.status.busy":"2023-08-24T10:05:57.163065Z","iopub.execute_input":"2023-08-24T10:05:57.163686Z","iopub.status.idle":"2023-08-24T10:05:57.172074Z","shell.execute_reply.started":"2023-08-24T10:05:57.163651Z","shell.execute_reply":"2023-08-24T10:05:57.170983Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path = Path('contrails')\npath.mkdir(exist_ok=True, parents=True)","metadata":{"execution":{"iopub.status.busy":"2023-08-24T10:05:57.796013Z","iopub.execute_input":"2023-08-24T10:05:57.796636Z","iopub.status.idle":"2023-08-24T10:05:57.801304Z","shell.execute_reply.started":"2023-08-24T10:05:57.7966Z","shell.execute_reply":"2023-08-24T10:05:57.800074Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Val\nfor i in tqdm(valid_rs):\n    data = read_record(str(i), data_dir+'validation', mode='val')\n    img = get_false_color(data)\n    final = np.dstack([img, data['human_pixel_masks']])\n    final = final.astype(np.float16)\n    \n    pathc = path/f\"{i}.npy\"\n    np.save(str(pathc), final)","metadata":{"execution":{"iopub.status.busy":"2023-08-24T10:23:29.193731Z","iopub.execute_input":"2023-08-24T10:23:29.194111Z","iopub.status.idle":"2023-08-24T10:23:29.242348Z","shell.execute_reply.started":"2023-08-24T10:23:29.194081Z","shell.execute_reply":"2023-08-24T10:23:29.241203Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Train\nfor i in tqdm(train_rs):\n    data = read_record(str(i), data_dir+'train', mode='train')\n    img = get_false_color(data)\n    final = np.dstack([img, data['human_pixel_masks']])\n    final = final.astype(np.float16)\n\n    pathc = path/f\"{i}.npy\"\n    np.save(str(pathc), final)","metadata":{"execution":{"iopub.status.busy":"2023-08-21T12:00:31.74809Z","iopub.execute_input":"2023-08-21T12:00:31.748523Z","iopub.status.idle":"2023-08-21T12:59:46.611983Z","shell.execute_reply.started":"2023-08-21T12:00:31.748491Z","shell.execute_reply":"2023-08-21T12:59:46.60714Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}