{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":1196732,"sourceType":"datasetVersion","datasetId":681625}],"dockerImageVersionId":31234,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Introduction\n\nIn this notebook, I will give a brief example of using the `segmentation-models-pytorch` (also known as `smp`) package. You can check the official docs [here](https://smp.readthedocs.io/en/latest/index.html). \n\nShoutout to the package author [**Pavel Iakubovskii**](https://www.kaggle.com/pavel92) for creating such a useful tool!\n\nThere are a number of things that I found really helpful in the package:\n- Huge number of model backbones with pretrained weights (ResNet, VGG, Inception, etc)\n- Implemented loss functions for segmentation tasks ready for use\n- Implemented metrics for segmentation tasks ready for use\n- Intergration with Hugging Face Hub (i.e. the ability to push models directly there)\n\nConsidering leaving an upvote if you find this notebook helpful.\n\n![image.png](attachment:6eac4dd8-c557-442a-a787-cb738bd3b6e9.png)","metadata":{},"attachments":{"6eac4dd8-c557-442a-a787-cb738bd3b6e9.png":{"image/png":"iVBORw0KGgoAAAANSUhEUgAAASwAAABrCAYAAADNV78VAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAABLKADAAQAAAABAAAAawAAAAD579UbAABAAElEQVR4Ae2dB5yUxfnH33d3r3FHtwB2o1QFDPUQDojEhqLGklij8R+NLbELirAi9oIxRg1RYzRRAxo7xBKpUiXBAhxGEQtFUJBy/Xb3//3NvXPu7u1e4yjqO5/Pu/O+M88z5ZmZ3/vMM/POOo7vfAn4EvAl4EvAl4AvAV8CvgR8CfgS8CXgS8CXgC8BXwK+BHwJ+BLwJeBLwJeAL4EmkYDbJKnsuom4kxwnoOItdZxYV8cx9T3NcaIExXbdYvsl8yXgS+CHJoG6wLiu+B+avPz6+hLY5SXwfR20qlcsjHb180H9TgoE3KNiMXcPAr90YpGpnWYteMFrGUO3y7eSX0BfAr4EjAS+j4BlQGhJnz7tgjnBp1zXHZrc1rGY83pZZdHZPea8t444H7SSBeQ/+xLYRSXwfQMsY7M6sFevrOa5GW85rtsPQ1WlZE9FXe6N3Yr7EHczv65wjv5i7txy36a1i/ZOv1i+BJIkYAzSSWHf1Ud3ykEHZQI+kdzczLMNWMViFQInA1COE7T3McJBsILWGbHTRC8+Kk2073wJ+BLYlSXwvRikrAQGBTwS9PsFffbJdEMvObFYdyN4160JyrGYVgmdmOv8tyIWOenQmQs/13N8Onr2nS8BXwK7lgS+04AV9rYs4Een7b9/drt997w04ASuRVfaHcCKoWWlr5+Njznrok70rrWfffnA0JUrS+PT3LWayi+NLwFfAukH9K4tG2OrslrV0sH5JwWd2FhmdT1UbNmt3FgsWBdgxVw3ggBCXlUXO9HITXYF0dO2/P1au3Y/8Ev3A5PAdw2wEoBqyYA+PYOh4E0oUiPUbgIq+dUgZLUoBca7uPBkHvSyFyujkbGHzF7wrlh84IoXnH/vS2DnSuA7A1jx9qWqLQuhkUz4LkR82VwRMCgKcGV44lwcc2L7uI7blnAZ3oOEq67gkRMxdEwFCVlNWE/xGLoqe5doS6NO7KHK0tgdh86f/6Xi4/PXs+98CfgS2PES2OUBKxxnp3qnV6+M5rmhC5jqjQR/9pa4AJpyAEirfGhYsa/4uXtrUcW9zfJCQzIjzpORYGBPxcW7QCS6uiIQPb24KDqX9K5iani1wE008enx8DkId+ua4LxHhk53KsNxZYlPz7/3JeBLYMdIQNrEruo0/QtegkF9OjiybFDfo7IzQ086buDXgFULTyOSmSrDTOtisYmRaMXZXWctnNJhzRrn1E9XfdxlxAl5HTZ8tSoUiWSiTUUEQCUZWa/NOqTnq8c8+8LfRXfKp6tmXdJ+70luyMkl3Z6eliaNTZpYa67jmsf2PuqS/fb6jDQ/UlmmYff6q/DRd74EfAnsUAnUXPLfodmnzkxARUxMRvUlh/fpVjg4f1IgEPwX6NRX4OSBlaZ/2Npjb8ScSEHnmfMu6jZ70WeTTu2WGQbkwqNHD1mxx16fdf/3rLM+LKroVVoR6P5hUWXvnv+ecfbHe+65/sZRo/JF9ye0ti7z5q3sNGPeBU4kOgSN6i2lK+BSPgYM2YAacAOvLR/c/+n3C/p3GVplK4t55YTcd74EfAnsCAnsUlNCz05kVuaW5Oe3CYViV8UC7m8pZB7AFBV4ACTe9M8pjEajN3WdNf8ZCUq8SwG5cDjsnLtyZea+++57fbO1a+85cOLErXY1sZruiitaRvLyLv3yyy9vm9ihQ0Q8XVGvLF1hQf8zoR1LXgeLB+AqpwwZUucAtC1oa/eVR7ZO6D77/Y1EJywEiN53vgR8CWwfCewSGlYY25AHVmbzZ+HAfucFM2LvOAH3eoGVAIPqAxduJvcbuEY7lRv6emDlil9gg+844XB0r333PRkwmzNy4sRNAjFCBczm0nN4woQNpPXfPfbY43jRh4n0+CUPF23t7yWbS/tGY7GbIN+kfAmvAi7XaU5CN2YF8xYuK+j/SwWLV+UPezYu0frOl4AvgaaXgAbxznQJ2knh4H5D3VjgJqBlkAoFMPEJDc58+4du4zp/La+oGH/onEUfKz4e5Hg0dbnhhhs6BAKB82/GeWFmV7vo41xgyJAhgUGDBo0sLi5++J577vnaixO4JaS7bGDfjm4gIG3rDMVJy1PBeNaUlOfY9GgsMrbrzIUz9eyVyd+/JWH4zpdAE0tgp2lYGtjUpcpOlZ9/0PKC/o+7ToAPlp1BAgWBlUBBYCVQqHSjg7EznSewmla12bN6CufJRIAVA6xOx39O9154Sm/69OnaszU1Jzf3VI/WAJ6IpTHhGaN/l9kLPkTjOtOJVg6jTG+rPCqXAVPoWF0cEnSC05lGPlJY0PcAj9e3b0mQvvMl0MQSqB6kTZxu2uTCTJu4BCaxwsM7NXcCrS5Hg7mS51bSXIgQUNkp2P94vqXLzHlPiF4gtxQf/mStScAbRbvqC2D1Rbl6gGcThp/Omfgbb7zx8srKytdvu+02kq7JE/amefhR5X/o4H7nA6yaqu6nhClxnH1L01X37vJNRff3eO+9onhe0frOl4AvgW2TgAbtjnJGYwlXgU1sWUH+GU6ozQLAahwFaKWBj6+pViYosJnn8bIjAVZ/VQG9qZbsVMlgpWjnggsuyAiEQsMBn6d5FBALFGtzinexdU0OhULaKZ8SvMPkp8vm32XG/Inu1vLeMb4/pIzFHrhyazTCNoGAc2t269z5aFynxfOmS59w3/kS8CVQTwmkHKT15K0vWYKdallBnwGuE8Im5BypBDTQq+1UVc9/j0Wj4zQVU7wFCt2ncUZTGj169CloV5Fx48Y9D50JS0MfH2zobhgz5nTmp+vg/XcdvEl1yT/U5RtGQOtkJQoCJn8aNMVxI+FOMxYuVLxXF9++JWH4zpdAIySgAbs9nNINYtjWh8XGTqVjXwoL+j0ccEMzPbDS5sxv7VTYhyKR2E+xF50lsNLghjfZTpVcVqNJjRo1anfA6pCZM2e+DEF9wUppScsKrF+79kVQZMDFF1+cp0BcOiA3dVG8ytdl5tz3Ke8pfMYzAjvbIpjM2VsGhGUHc91j+Qb7bexzf1g6qFd7a9/y5GLls73awFTE//El8H2SQFMPFg10XdIiIjJsx/Z2cj4clH9NyAm9w6d6F6JSBRjQmv5Vbc50nE853uXCZ2bOK+g6e96bYQBElx3c0NXmlFeMKd3pkUjkFc+QXht9cpyZNk6cOLGYDVYz27ZteyIEKrvSrc0Z4Ap7Ze0yY97Lka+2DGCr2OUA11o0LrOpVfU09657KTPdRUsH5RPvZHnlNPIhE+UncPadLwFfAnVIoK6BWQd7QrQBD4WceOKJPfkSuUeLSGSPESVbzjykvKxHM87Mw+BTGQSw0DwEWsXoNw/EyqJ3dlmwwGwrqMf0Lz5Do0ldf/313YPB4DAM7fcS2RDtqkZaGOCvxab19C233PKFF2kALZ4w1X18uQsPP6yDG8oayerBbzzgirCfK5rpOnxC5DqLM7IWPpPX6k3mjs0AyRWoma+99NJLy0m3Wn6p8vDDvrMSkCbt8pLSynO9+lMjauqSR5A8lL7ySecC0AW2c1nS5d0k4U0FWGawHXvsse2ysrL+ABidyGDVdNC0UKtoJHJC8Sb3sLKyQKl2VcVizzF4b9KUSjTxA17P9XQBNn06o6PRG6OVlRNvvfXWtR5fYzqFATqmlh3R1o4F/O4jrYaCX4J9a/ngPn3Q/cZyqulw9kA4G4OB6N/zWsc+CWXqqOZqh6yKeLjrhRdeuAlfear89a2DNs26XevWCEnyW4f2Kq2uvnl8y+jf+RLYyRKIHzuNLYpJ46STTmpDAm9xdWcQarVPg0Jqg1vKFWR4nLF105ohJZvOav/2ommK4yc0tOqN0NDBY8BkzJgxw3mdtLhl3DitDDYUYFSEeGf4R48Z82s0n8WAlgzljUkzAbj4DvLUMnbGP9Si7SEfZ2Q6zZGNNC6bcTWwsyoKaN3YgDwl94bKzWbrhKkbV3U5qiP8m6aSgGkfZhsn08YHsnr9l5dffvkrEt+mdksqnEnrqKOOatOsWbPz6Vpr6EN/S6LRo+nHI0aM6E1ZhkD3Olr9ezY8Bf0uG2S0oG0snYQhA3oYYegcddmnjA1H6WpEZROpf314Pq9Fi30rS0/4dGCfT/ebvXDFUFbVGqFdmUa6/PLLW5F0v80bN96C3xhggS3Bqahu0ZYtz+Xl5f2GbRKLsW3Vpl4nMMc9VNu3pqN+d54+ffLwk07qgaAPbR6NVoLk2niq8lon0BDAX3/cccc9+8orr+jgwLrqU93pCw/v25tJdlu+uawTfPjbIBY1A2UVsa3v2e8glbctiO83qQRMG9GuvyXVAhaF/oW/XQALsNqNtO/kWsZVA7C8aWCUMhxHecZCo77yng3n/jvj4gdOYwqtRokMHz5cx7Ccwr0EoQGp8Gqn0YgNx90SCOR9npn9O8brwiWD8ke92717rmdc19SmvmUxHaF58+angYOv/eEPf0CBaRJnAGtC1XeG77dr1+5YUlV96luuhEKEAQLZCq7Iz89hSniK2dafCFSWXvY85c02stBJClRHspEpfCPb//bs2YrVx1fdUHChTrIIOoHX67p04kQg4EzPDOQuWjawXy/SNn82G5eH0lbetV0JbRvHq9vG8teHr7Yy2bidXbYa+dO02lNYiW3U9CWvbVOV14bVx0/Ih/SlMOhggE2p2s6zbWGJiU3lGo+2N12NRbjKZF192iAhX4+xPny2Tqn4bf718rdVw1IBYhi990EQuyEwM/iS8Kq6IHrBrwpmsNzvtAm4ZoPlmWywHMfWgElh0vG0LQkx3VtfFY/K1gQIth4/btzbPJsw/KZwplOxPWIq3xleSz6z2QG/gYRNPRuRQaywVau22a7bThVCRoimZpspkDiRHKw8bAfTfbKbxoriUDTT7BbZl5ttE47zDikvJFX+a1F/vZjGuSYSW7/bnuxO5MPyhzgQ8fDeixZp75gKJTlKo0yfBpGes5WwtHrWVVvbWV75yku8lj/+XvHb4pLTji+rza+29PVuidesG1o2m7/NQ6vhIZpXM49oEkhYGvnx4BEfnu7evANtpJeHbQMbnOC/+OKL8wnQZZ3N09a5PvKJl6fSaax86pOXLWe1v62AZRKiMXTYna18deLJNyphVizKQiFj19DHusH3D0DrXP4PYmx9N1iiiZxSUV7+lJd+oyqeXLb4ZzpV5YABA/5FPtoQOpEruRPGk6e7NzwlJSVfZWdnb4GoJXVVWW2DV/N5YAX+uMXVgWlu1nuDnMS7I0UWYyMXW7mlYakRjF2tkL+V7RpoFtW0en2Y+nFFjjnmmBaUoXVGRkbKtkRJINqtxP6x2ktUdVGdzIUds21ZWVlebfzEl77++uvr4vmPP/743XjptWRrSgXTlpTtWVFRIXkaB62+GU2g88pWRtnMkdaWFt/QaUEIvsxkPkun9DMzMzdhA/rGhsnH7tOB9sniNpKOV3TKH82lZOrUqTSRcQntjNz2Ia0iaBBPBuSGPgr9KrSuLKZ1e6aTm5ee8cT31VdfrZ87d24JAQIakzd1020mZoW9yMs8qLy6R65bZT8j/+bk34YP/r+mj2+F3rZfBFtbq/Ly8pbpyqB8ia947bXX1igjz7nk14E8MnmuUz7QFHt2PMvfYH9bAct0BjrhSga3KrIPhVchEhrLlipA38ni4tsbtxzFjC+co+qF8BzDBsthANefSyvcW3vOnbtKPJ7GZd92Io2yo/0n+Ktvv/32lfgmDL8pnQZrgFXH/7DNYSBaVme0rEKFcaUcyEmZq+6iNeVu1apVfzp8Bs+SFVVNKRoTQaeYA02tbqk3AA2RN8WUnLp16xZcsmSJlVXaNLRCGItERjB/yI4WBzQ43TBhJ5xwwhV08CspazsxJxdUoEobSxMso3NPx/8Nb+zPIQ1omtO6devbCDuXVeLW+DVUSYWJn2sr/M9/8803lzFoNOgihN2GfxaDTvvWcrmv4QCTMuKs/AUgkrFxNm38ItJ+lcCLAR5NjxwM0q0Bg4e5PYYrR7Sp6ka51TDr4X8Y3pu4N+2ITJ7lvgeXZJKVjl91o/ybAe2nSktLrwKIKsRjHfGajgW8fGRPgjy4IT8/f9+WLVv25nkmtBVe8VJ2EuUNj7PnnnuuBHxuBJzNWXCESRalXD0BnE/wjWwg1zQxi/hHCfs/8jgXOd5CGS7j+a+0m7ZCVNL210H3O8L3UB6p5KP6cZUgnzcBroumTJmylrJnE/YKaXXkqlM+kGxCPk9/+OGHV9JXrXwMhoi/Pq4pACvIG1Md5VEqOo5MEwaNJwBNsl3+LcL9V05zZ30wwzmyeIuzBy/UUuzPMEQCVZstL87OjP2scFD+HWs+X/Nwwv8EhsPO1Vu35tIrBpcUFd1JPmqUBlW2PgLxaAy4AMTP0ohnESbAqo/Tm0311xtrf+Qxhvqf63UAO9jkmzegl6DUFk0ZPi4qKvonYeqsltYjSemZuldyaL1AaNKSJTploj58jv3siVSNDOn8w+nM91IGTQ8/pDzWrladsVcH1U1a2LH4j/Xq1evYRYsWVQBWV/F8NddmrkLi0aLNFJfHKhfHvwf35wLkApTLvegcfLqHWbxR/naKrEGge9XrR1zNuDS1/gSvhChrgpDMpOXvjn868Zp+ncvl5uTkPIR/KmGrif+Uq7ayHUh8mLbTattE6if55BDWDH7tFfykNn7i2kNzCX1mI/6NXPHuUx40SFVmtbnSNqDKcwmX9uJJvqovXqKDXnW0YNKZ9nqSchZSzsVoUHySywhy3VJ4JRvRSnaybWXgW61TddFCtQDfEVjR9mfCezuPennU2nbwyVZ9IqCn/nsCl/LQC6Ze8oFf2t8lHTt2/ALAUp5KR3Wut9tWwFJG6kwB3ph30XH7cT/chlFAI2B5hMmxTBZzZ2Y1c9/PyHJ+UrrVGVhSpNoGkZaII+wqbccwmtBh3/bnLNuv3VjtIjecAFbOjTeeSmvOvPvuu7V3aXsDVuDOO+9cjZb1GdsnhvKd4TQvz1SgYMsSOfLII3N5o2tlSIO4LZfEoDedQEkNTFCVUwR3BLlruT3zzTfftEbTVHlYNuubhPgIW29WrUyKp2ZPt9Rxvv7MY8WiRdEHqzY0RnkDS/sQ/28YAI8zNQwxlU3oSFu2bHEBpwgaSyvqNw/aI3jTd8D/lLJr6V6AMeL555+fhbYX2n333RPq4PFX8obtDD12N+cY6K6l45bzLKDEi12F1vZn8s+w+QM4QWkrDM7ziP8zeUznpNjhgIJ9Qzs2bRZ/DkDDWERaPwVsMvbZZx8NpqPh+5KXTz/SWU14kAWbBDmtX78+QDkqyWME6T8Hz4lcE+PoKgCFI5nO/JcyZyTXzeOvYGrbG43jbdIQ/xiu6nzQnk+mbkuSZcPUTnJehLZzCH6tTvkob8D+FvLQJudhMCwWE88CoYW0X39pvAqTk2zQ+Kr6ihbrKRO01eWi7VVWkoqeR/kmx8te/HJWvtRvH+q3kKAhyKoleW3GV9pa+BpG279bm3zQ5PqS99vQ/oxLgJXQR3iu0zUFYKny2j1bSoXGUCEBlhEYhdNpCEUg8kd0ms7Mn7OwQDq5sWiEXe/B55q1dN7JauYcjbbVs6xEb5YQNZdAeQM5hwFeLxUW5L/YYuuWUSeMHLOxcmnhHoeFxzx56qmnBidPnpwwoOqsacMJTL0YHC8xMC+/+uqrFwCUxSSjBrINrnvV1ZSFwXgq9+qotvNpiqP5vVZO17do0eJjgF12Gk0TjewJjyGXMxkM86Gr843TtSp/CUl/FhvlwLADpjnOEmf//UN75Oam7QAl2dmxHDruZAYmhnYz2IfIUF/l5AcYlB/hx9atWxcFnFKmhQ1jA510I+WWU3nlxB+kHp/hRxn8ZmAoItlt3LjxcwacOnjGgQceGBJgKSGe1f4r8WXXEb/NX740EmkgolvNIJc2ILlbGm4dBw31M16ass2EOE02AEhlAGwq25bPPvtsnWi8etn2U5DDADc+fXWFN71S2tJAYtRVddQq3yf4MZVXcakcU6Uv6P9CXvHE9xORq4+klQ15JdRFDMkOMNA4i1Kmz8lDdjzbfoZUYdykMuzbdjJvx6R0Faf6ruRKlj1B37rVq1ev4ejxrbSFbGHKW2NVZ8MV069N36lNPsjwY2mC0MtEIqfyJsvJRKT7MQ2TLrIB4SZjCmIFaITP8ywq1r3bkCEDDzzooAdI70EI+c8/RybCKMAVXRUMOY80b+38qUVb5/NQBn9dE9MW+aDZXKmpgOucUNIsZ+4dTz85+aA1q95Ck4gAVua4lwaUrzGkqpOj7wzx3uZNLxXYClhCVkPrWdO/XoCV5vKTuARW6tTqoAIrXnClY6j/ODrc1bzFCgibRUPLGX46+ReEqS1Mnvh1u0h0Kr0PTA881X5w/gcd9mv3fmi35kuCbZt/kOrKy81YovhfDM5/F1vh7dP23z9796pPOfR6NfnSmQxQaJpHAdSGqa5UZTP81Ef1lWxUF/nxlwkDQCwN0TWcifM0BMNr7+lLZhrjdfb4dHVv0ubFKJrqwYlcq+XpDSTVxwAHfnXdAAFpeHQ5M5XktoaTfcqWO23dPBoxV+drU0LGtszx/DZafnV50t3H10Gdx7abTURh3Ne4kKHCUjrqbMqKJ9nV4I0P69Chg8BJ5XesbD1+ycfyx9fPpmfCvDzEXkM+CqyPswBTH9q6aOILYe/XvPrqqyu4+IomPKVv377Zb7zxxv28BWUvOVZEHNKueXbg3cwsd3nGbs7hpcXOESVb2QlZGShhPEITqQyGWu7z1bqBe3/15STO0bpj7cy5jw71Np0upfLhqsauq3yNiVcnCrDrfQZTw6uvvfbavZkmriFMRdf0qD1ANop+ciHP6tB2MOhe7nneumPOPPPMzz78+OMLMVRKi9IbBgXz2z4EjehNXmKqzQmwiXc7z57/OMDTgWQu4pV+AOBFstVT7zRJoLnKVuS6h7Tft13O5JUrfydCvfXkU6Z8tORsr/Mpn2pn08aXttOCCIGadYYfPskl/rLx1o8hL9UzpaMchleaDQS6HHuP9iejvYJsnPUVJhdj6hJluqq3frVwuVV+uUxHjuUei4SJNmkbLn4Y+LIrlZN+Rx5tG9po+TJ2x+eXwE+88ovFrbBV5y/mOGfTsPyGD5nvRt79qWMlMhBwqgqWJo6dF3k0ytdtbjcF4hvwiCfgPhVfEsm3j8pIT9RPcrK81reEppysTsaYbdiwBN8DMMtn/Xia+JXddPKJp09535SAJQEmFJRnqX4BvSV5O8zo1KnT9TTOvCuvvHI4HegU4sfAdCiX7FgRJBZ8MyfPWZyV7QwDtAYAXizrBDHSYAQKsJnbOYAWerjD4P7nLotGw11mLXhNtUKtCTKQ4wWu4CZ1aIqv8Ab/OYnew5Q0k2XwC7gXWMmOIyetSsCjN/x/6FhhtCljf+v54x9fy/eO8adJJHQ0b6DCVm9n5Mz+tVuwRz2QEQo1RziEpe8HvI4F/xUosXuT3xTKfc6bffuOG1b14bnRSgi72wOFGgUhrkYY8mjS/lMjg20MYEqopTitLranzlo9VB+tkSo0yWHNkwO207P6gbYD9MR/2ZYjVRlt/pbGe65RcEv3ffW3a4fjTaGBJSAJyObEyQrPb9iw4Zc8T2AwPwt4TaEBLuX5Wl7bMlAb+9ZmNxB8JreVszArx9i3Di0v4zUZc8vYv0VjoiW4/bW7Gw3jKV7z4w+dOW+ZeD3gStAMFL6NLiaA0taG8ePHdzn3V7+6fOPXX59KJxvgpWuBSmAl4/kd//vf/x60c3m2ReRT5k3wLwW4Q970YxuLZNjdaYAj9igZ6s1qUz0T/ZL/V1zDu7RjdgYrH3KaEgaAs1hsCk9ruTQQ1HYpHfUxAw1A0KqgXFraquid80vfUn/RYscWSqAV2FrLCa3i9c9M73slrpXeo9lmj75kpuDk+wmJzeBKKX/JHRrRduGe44y+/SZ1mwvxHUlguwKWlQGDNCpDOXubPmBqNYTrMKZZ72JolvH0Tjb1/YO39fU0wvnSsihUNBSNuCtDma5sW4eVlThHo3HtU1nulvEdtbd/C3L3DFS4EQDXfeXRonvt93EAlz1Pyxahsb46jmxm5dioDsG2cwZ56mRTDW6t/Ol1LaDS/pk/oYXdzreAq5SZVqkwKrvBjIwjK8vL7yfIZYWnKQdAbCjTYuUVpr5ctaZNvCuaaciXtUrqRW8PlBoeqmHeLJR/POWf6zTQib++LGimLlOn+pJvE52mKThltpoVrXMbkVi969WItKtZ0Ma1L0v7Ehay0nZ+dUSaG2YnF0I7ABYpA03iKEJN1bNJUm7aRHYIYKnIMpTjuSxXT8pu1uxCAOw9PbNU62Lb+ZT7C9kT8gSNEEZvH6ZpYiYfCxMeZCXRXZqZ7RSUFjlDAa5WDDXZt0iQbRD8yarrjuZ/Ak9fNqj/+C6z5j0uO4+0raWMynCVhkcyDXICKpU3AlBJ87uSS1sV9B+JesPpzS2gEnBNxQszIBboGRekbqpvBUvEp6C9LGKTq/blSMtssgEwr1+/FqzZ5wS2bt24bsmS6DSTde0/1TRp3szIPo8yZ7HiE2Alr87BwGqetEuBguThYIPRuUwhu/weXxotjWubAKAowJIcdtQAUdlklsjDfqa2S+tYSYyxCuZ6q6S10qZNpJaIZNl42yHMjEAyhDWDhZlMVpODqeQPAGslVttH8pKz8fiVRpB8EmSrfJLp7bP41HZyceVL4Le0KBVKR3nsNLfDAIsaqqIBtgasY7f6MuxZxzDFegVrPJ/jTpeAAuzcfRv/p95mtjCCPIhn7FscqEVDTGXT6X8yc5wjS7Y4/dC62HZs9m9Bp9fDj3hH/aVwcP9fYhbGvjV3hni9aaIGX30ErQZRWdSJXN5k59GeY0h/f57l7PRPhtr3CdeRMGRhnAW5KMDkMP3dk2lWF753vIVYpasypO04JoV6/IRJgyvaOtv9PRU6LhrMGTrUcT6oB2s1CbsDM4GZ6mf1WUBfxt4IIKQtBw11pn7wl9c15cUMoH1j2uZRJyA2tBDJ9J6GJUTVdgBtd6jTMZVPoKGc3woqIaZ+D/CrP0Upi7YbGI04mVPy52UhOtl61cdqdbxE7VTc0Infy0fjWSfZ1sqfFGn6LflXpitfHL32qhm1tapacTE76HZHApaqZAbt8uXLX+rUpcsojoiZfV84bO0vEU0bpYUAXH/H9rMXtqC2vFEuwL5l/gIsl5XnjYFg4G95rZ0F7N86hv1bXSrKtPQTpJW1eqWRNwTlazrA9RcnFr2588wFnyhjNkgFJ+umyiUDmOksRJm3HYA5FPtHmOeCKnJHmxu1Y1j2jXWsRP1zvwMPXHzb+PGTbJktL74ZvPD/nJHyEs+mzl462+wN9tKnj/KP1M5uwVDG7ZyV/wY1Z4kt/eDiXBkhRCWlO4DKdqaLF66tyPxGBaJeSxmVOi1iHB1ygIK4ah2oyCGKtvyI912gbIi9qfO9gDynRwTUqVXvakceAUBeq2BdCdRu69XYwJSPAEW02uuUNk/4ITMbTBPSFX+SUxvyhouE2PO1iRXplTx3o15/gv9T0tEATZmPl4fGxApeRE/iK1P1K9MveK6PkwZkXngihn8pz9q8OgGgmUWQdtqrDkq7ZNOmTQ8Q/wnP6mPDkN9tyGgr9+pHCeWEzsiQuL7Kw8oLXzvZV3H1oJ73Eb+OeOWjsqjPvovN+HniVR6tlFanS7wQ+gSCbqZ80/Br5Eu8yqo67Q/9PtwvRxvdjNnDACTh+ryqOk2eUzraO8bYUTrx8qyTLz6xHQ1YJm9AqfyGG254gynCKQQ8wmWE5E2ZoqNGj/5ZRiDwybPPPnsn4PEYDTgaQZ1FK7NHKxZhM4j7UUZm4I8t2zp9yoqdo4q3Oh34zKeEcYYkIlgmZQ84L+IETlgxsP+9Byz/+PfMPZPfsAZYyFsd2AiRxv4R98rrXHzTuPJ5zuSSBvIYNphbn3rqqRU3hsMj0aJ6YpfTTmOlJWfSVDiAEEO7eteGmdgm+JlRBYButLJ0QjAjezBVHs7/JA4XxJjRnzYPqLw4uusWPii8+rS5C0rClHl+Wdlj7I86gToO4To8bRJxEdA58LxI0Dqum5BNL8J00qx2Tktm8hIc7ZjwbB+gZXbrhIiXvSmlUxx0AsIa0yHLsNtuOjDEba1nBrEWOIoAgMvh/QfhF3BZ0rS+R6N2M4CF35IrTyuOHpMSSTnI9AE1MsmmjOIRjQvfBMJ+QrpH8ayrWjbKi+nfU4DJ55RzJOW8l7CR8TS6j3fQxD820wPbhjbCfxVxT8DP8U1V9bQ+JGqn53nO5ZIMs8SH0xRzAmAzmPAjeD4ijscQ2B8bDu9mZHu59urxLWEO8S2Ja81ew4SCWT7PNzLDFCAataO2xViXVp6WIN7fGYClt0uAc9PnYHwfMHLkyIOw8XykMK7YFVdc0SYYCBy6bNmy22S4RtvSDuezBVy8wW+mFxyunpClw/AQ+JysXPeDjGxnCPYtPjLEyBQJ2v1bjII26zOC46f8uOfpP8vJnQGIlGFoWVBUWvqyvn/08owwd8/DZnA5z1chzFb4KqOM6tZONZ37G3nrziZcLlheUvIU26jP416du9rJDoCqcnxpcfGfCGxQY1QnUstN2AOsrnP++ynfeQwKtW0+HABqLYCsha06ynWiFcjg7a5vvyO5uqQXc6ZO3Yzt6mgGlg54292+uauZUtwwOKRhfaEo5PIxn8UMpOMfQ3iLVPyEG22FDp/NvT7LCGnflPihn0iYPvcR+MuZ8Krbqns0pkJo9HG2WREmLr6+5n716tUVe++9t2yNDtpVsXzA4E1eRH3hK+DRtKfCUznqDpnZ/Py5F69y3EBYK/qenYbF52uTMWHUfwN1uYTAb7jE6zLF/oK+W0Dax1J+fRhu6sazVvy0qXiT6CjnBKbLc8lHJ/aq39Tq4M8mrzkeURD+f3ByQiFl6A2/GdfkB0lUGhbmXCPnfxFWAkjNsInr9AT67DA00eOh241w7YtMl3857TCbhZn/iZ/+on+9uprbTE6AMPJWeApn5MN+w2+on+Sj7zKtSyVPG1fDT1ewGoR1BAhsogi8DwJbwL00Fqmk/6Qzn8y9ice3TvnGsGUdgJ3nNDSROzTQNYfmiOKLOE1gEYCmdMRnnRo6wJvkVwhJK4oHKAICY98SSO0dqUDb2uL0qrJvOTOzm8Wez20ZLWEPBFqZTUf+EgR/oWxmpKeVP2lVXTyCajsVz/+jDjd70wNFB7m0zcFFG4zwf4a/ZH/TGmxxr+uPXNkVX0GdRkCTSdiz+Mn1Ns8MoFfJ71jiVacIHegwOo5U82R6gtI6I8O0sXVEhMmLywweSLcprYbwq50ZHF8i101M+TvXx2ZD+tviGiLTbcknHW99Zbut5Wwsf33LF1+/xuYVn0aj7neGhqWCCj0CDOpPAKh1aFqDtZucqdQhvONyxn8LVnZAiUdgEeFN8gjA+AJIfQ3Pl2BgyEV60TxeXOuCocBjzduw8bTE2bey3HmlWQsZdoIY56O8NqrTAiy68aZ5AeB4l3upwnJaFVIeeiPpbfp7rnsBK70t1ahqJDP3BqzMc1lx8bM5ubkj+T/DOazElGB3a0t6Pfn+8DaPvjpPnpvaSYbm/Pjdq8pX7/RnIK/wt2AlPpMWfgBAUd3q5XjBSB7itfzy63KakkiWjlbkPCO3WdmKSy9VGvafYSTT2uSqNpQzbYUvWtXL5Ml9nY5yqB6W35YtpcE8OTHvxRvPb2VTQ7ZJ+TSmnPGySMtPPpbOyCFJzmnLl1w3PcelZaOT5W3DU/op5JOSLl1gvTtnugS8cHWGhmhYYlPeLp+75HLA3VVr1669c4927X6HdvUE2tVqEeAkzHgnnmrgQDvqCvDcRJhsYUpQ6mygnOmHWohd8gqukQhBpnEVB4/u5UyHxlD1FGr0OG8qqnA1iO28erbO1BmNahggtS+A+xjAeym8C+K0Q5t2Ak8TaVg2zV3BV7vEdFQ2GnZHzUOSC0U7aQoU8aY8mi6/z8ugl0eX3M7J7P6zLwEjATNId5IsTCfl27wtTM9e5wz12ynMYga7VjvMAEhRLvEIPBSveftSNtqdCv9xPC8kMiiLJlbPKJ/6GKBKMxI0eDRRjzAJ18lnLt9vTFvvugMZRGd6YCWgUj6pwIrgKtBDS/w39y30Dz6yI9UCVuL5vjrTjwCrI8GleTILJF8KB6wWIoBHaSJpWVpsUfPszD74fW2P7229dtaU0ArUdFimUwvbtW9/R0lx8a1ECCTqcuITkJjODsC8ioH+dQyuFzEYrmOa2MEAEg/pEtIyIgkEW0ci0aNKtrh9S4u3HFRWus4yTILxtHTMSeEoFM9haH9s04YNstcpiTQ4mcT4/Xk09QWUPkPu2kir6ZMVZXUtEbms2jqe5DleNpM9mnQvhGo+/8aXgJXAzgYsdero7u3a/ZyTZp5kaihD9GNcNTq7LXCSb6ceQS2zct3PisyzDJwJDApNEw0gJvFUPwJskTO3bnS7l5XGNgWDI5ZlZR/NbvkHKstjdx46f772ttiNp7UNKuWxFyPxS/4erAP3hVwC0h8SaJl2QNudS73VhvVxP0Rgr49cfJpaJLAz1XEDVtrWwPxsH2xAE5lS5WJ4/zHl1QBoSNmMtqXPStC2dBTurVxpQUMZMxWMtqusDO7FiR6bq47WiHC4IH9S4F6Zme0uKhzU/6JpjhNCy4qEKYsu2OKdAdXrrruuJQA5jOXpkUyDTtFqYTzRD+xeMpGc6ro03f4hAfoPrBtsv+omD8Ltl1PNlM2AD2VmnsSGO83A2AxZOQk7x7HaPV6TPG2IHSQ6LbEMI/hPevToMZh0ZjP9UDpa/dOmT+N0zxVhtAR2r6x4rmU0UkiA/j5eBx5pbxfTGXcvN+A+2KGg/9uFA/OPDsOji0JauxZJGC0wyvdVpzIlnIkt7gtAUv9nqG0NDQVcpfd9cAIh1b2uy2qskmdD2ro2GakfxLdPbbR+3HdUAjsLsJRvlN3uBfTwtfoHHDSTELvGtT+nUN8ZKp6rrvIp3gwSbYlgle5qQGN/NjT+lU8eTub+PeKl8chkZZzuYQjyR0tP3zpl6inRaPEA4OxWbPRb6PH6WxgDXNDx/4luXz7kmMpxLE8vGdSvq7QtwmN/YkMrvv7B52C0wtYY2mdquZb/M3yV8ndhewM7DUy5NIi2lwsoT11k0Jh84vnrkvP2qoPkacFrW/NQPzDts60J+fy7rgR2hg3LDC52tOcwlSrA0D4B8QTYdClDbQCgebll69YjmWrNuuOOO7QfSvTqjPHOAB4BUbZFdGDH7YkAR5D/KnxW4GcJWWYfomNrABGBVzt87V5fgUb0GEbf+6Fz95v9/kb8G5bn93oylplxA/FnkaHkIi1M56Zr5fEX/JHS8csH9f99Wazo7u6zF4lHaHoau3f/zq05OkabSfk/wykcKSN7/R+rSGqUneAmcclnd6eSU7qMRJvMn462qcNNOTV9x2nHeyanQ1zH/p6t3DekDrZcpi9gu/wp/ekc2vYJzAJvEGn7iKXz/e+BBHYWYEUxUJ8EgMxJ+gccV389r+8M+exFg/7PXOp4FrBsJxRQNc/IztZfdrRjq/i/9T+CXntYGlffWBF2DVrITeTXHjCq5HOQzxkcAkfrzObLTnMXyVh+duHgfo/xnfBYaAeb0QOPCPmoOpeSXJ/p5J2+qk+PUX8YftL6zTk5y+677rqVYbSc8OTJBnBVDjbDDpLGx/0HsNryKJmmcCY9b4D2JkEwv/gp7yPk+uRlaPjQVfulRjDIQ2wLeZNB/g5p1Ye/Keqgo2jU985Hzs1yc3NHNzZR2tb8MQP16K6XDaYAadVv2PDGpuvz7ZoS2NGAZTBAZ6OjEe01/uabn0Ys8YPETAOZYs3RoLffGXonIhi7iO67dOlyNA/d+QhtIfugnvREq3QEbKKT073ys0eL/E+BnpOto3r6YA3rXaHvPGP+NOKmLx/Y7yw+odYnOx3FQ2IecDkHFOfkPPOz+bNWBSpjv7qPuDAAKPvWUsjCpCFbHNscfsXROUu5oGg6ZwciA/TnlO18pcwX8MPRWI7DhqcyGhmnydHIGtrdeVk8TxpUGYaq7xDfsWl7aSid+jgr73ha5ZPOmfKhmbqUWy+UUu98LEtv2sw+1OLHt7U+VGc7nWkj+SldmL6gNk4ZGRdIf1CdlL7vdjEJ1NaxtkdRTWfNzM4+OVJRoS/IU3UKE8YpnZPpyNKyzHd7osVGld+5c+dr6Jy5mzZuvBewelPxXGYgioYr3ulZwGRpRKf7GnaTMJ1UwCXgId7pNHv+k1uLKvTR7GiuDTCFdImX3hxtvXXrXi3Kiv+1vKD/4+8N7HOgeJUG581koFmtIeMVY6LRn0Kvzt9kckY7NHUEZIool44K+Zr7YUx9/6CyAToqv+qY7EyYDohj+8jf4RFYrVMa3JtB7qWtsioPlbs+V3zdlIeu2vgke01Hi8hXvEbe+HI2b9HUdSmP6noqLS5tSK0OU4LWhUmby7Sx2qq2Cx69eOLrRZDvdgUJ7EgNSx1Ahva++Fs54/xDfBOWJAh9XBzEFrUCLWsNICXQ0Pk+2pT5DR8KPwrveo/H8ptBnJRO/KPi66Ix9OrIuhFweeel3wIgPZ0ZDI5iWnge378H2b+lM21Fp8H2y8xAaEThoH4TnOg393WePHmLyp+xdu2Lle3aXYM2OYcVxCLoUg4kwhvkACSXwS6NApG4IaZ1Y/AvQ1v6NdO8/7EX6i5ozIfk8QkLyOCrPPjggwVsAtI34J0O3y34RjZsvg1oPxv/BtQG+9KB0KT8cp/8RK+6f8NU8iN8OdXPpMO3nt2Ymuk0Aa3O1qi3+Ll0NIm+24xvlwhT3ebEHUq5Mpg2xscpD+OI05cK6/SlA3UScNXpwvS9ZQP7oi0HOsQCeufUdG4sxLen0UiZU7zEHrcNVcoy1OT2Q3aEBHYIYDGApSWZP3Ogrw3bsnnzg1SuuoMnVdT8YYUJY7sApzk8xJzleTaWvoxGpSNR5CxQpex4VSTb9usBlzuNgdl99sIVpPbr5QP6TPymefMnW5SWdFLq9ORKDzla8/+A4xy39ekMipu7TJ78NNu4i8OjR88KZGaSlPOoQEwyEF8TOVN35Pke20J+wR6wOQz02wGtjwGtf8aDlr3n28vroLmAwb6aKdk5gNKxKgthplwCK75z1JlIjxK8Xz3KqbPu7ye/a5UMYJNHef4Cv14u+uuoOpOAdg0vIdMP4e8N/98IM/KtjR8ah7I+yokPF9d24kPY05R+XpB/CyxX0+nIK023N9Aa4CTbvBXYMv9P5gHxc223flangHyCBAmkabkEmm1+4DgRAUwFtqfhvHT/c9999+kEBAs6Nn37HL3ssstatGjd+gQimgEIL6Hrrx4HWHlHuMhOs6M6kPmjhzAay1hOJvjNyb8ob1FUeutFU57bWJaVdSsFPoTRLsyq0KjHdeF/pZ7i36rPLXfdcPfx498aNW7clbddccVBoyZM+MgDjiYpuzLzBNeW84lmAxwX8/w4ZdFpFis5rkaLEAYxpFkRfyrPtxOvqdgZnKO/FgDTpleDuUpr2LBhOozNgBV0rxO0hYv9tKnP2oJmEHFXk858tJ1nudexPycTLu35/VS8xEFi/h9wH/x+0DiAZ1SyAaD0UbTAahrXV9CmRDz4JEP9G9H5HTt2nA9g/ZnnGrTSkvXiWTqo73AOIB7JK4ZtM85sBGdlB9u3jpJFeAshA+dIjjv857K+fQ/qsmDBBihE35Qvm28z9e8aJIHtClh0KDW0y5aFCH/1vge9rOP4UOguwiw4qbC285h/1rEGdQjeGTdu3BsiuHHs2FuYSr6DMX61nne0C2vagW2q3Tff/MzduvX3B877z4Z3u3d/K7t1swsZf9r71V5lYoDpQDPw1TmSQ9OP+Ghgnz/O/WzFswt/1GUY0R8N4c8ApouwCR3TJgF4AC3nr2gc+5L/OAb+JLSVAqZra4iL6ZwyyvaImoMXhs4Bm0E4j26FiqIb+RjBpVXpmslH4EcprDZHfhcQ/xDs/fEFWH3wNY08BwCbXxsvhv8WaHgr4MnC/lZKmXeDvie8y8n7CO5rBQgPgJ+BfgC0Aqwabnevb9EkfWgc5r3uDZ35E94ahEkB2CWZNrs9nEynLVFfh6u0rFrLk5SE/7idJNCkgEXnseBjisuzBoQaOpaVk3MKe5qmsGqmt6MAS7S6jMYBIOlviwrgWbHpm2/u1fYGbxoVZZTp+8DTob2bS7w7svMYcI107nwiZZs/fsKEDdo42mPRItml7l2cn/+PnMzYdVTl1wy+7KqBoS9/3IzKUMZvD1/6wQnNS0o+223kyIVjbr99ETwJMuK5KVxUp7My0HUu90HkfQ7yeoqEh3IK5V4CMMJaUP4bAau/aw9Uqj+bAMz0ZwiSrTkFE61Hdi/TPvGFxHAfQqvRGex81RSUsdu0B77aW/9OrD1VAfjNloN4Xu5Vf/2Ls4C2mDI11z8Kt23bVhqSZF2sfNP904v+UWbz5s06z7yIstp+BFstTv1StNHoJk5pzdxEGi1JIxVHSXZ2rNPMeZfFx4V3nEYfn61/n0ICTQlY6rjqhHJ2UO55xBFHtD3imGP2LC0qqhg3duz7Yf4lh0s0BshGhcOd2Qh0LOr4luKiokfuueeerxSJs7Ys/VX8fzHA/0TfGWqfk+K4agwkMTWxM4PrmmuuaUe6HfnzjNvwAxdi68E3+7d6zp27ivvfLhnQ57FgRmgsMtDeMI36SgZIrCIjY7+un3+6349Wf/HMhQP7Xrvn7AXPExexAoJXY0n12Sanv9AigQBHA1/IFHx/yjEY8HoUQNiL+/3xHwfQxkMT5EuAlINVBYCW94qZisU8sDLtpDjr+H9FyV6XmYZBb6ojH6c0FK6VQLwa7STamP6Agv1XMp6LRjIwN8oePtuPTFyqH6aCemHIVSVQdZ/yFxTWvD1KwQLd6vGvNErETidTJugH7jQJNBVgqRPqcDap9fSN6o47mA2b7y1dvPgTphtnKA6wMkAD+LRnr9IINxLhnL3Yi+zJ+ljxOAtGFpDUIbW36Sl2kF+M1vVuExuvTaZpflSvKNqh/gHnRe1k59mCS8wa5uncgW5zFi4m7iTZS4JuQCt3fRkgkkUF0gi0iFQetDgr55+/OX74dBCui0Y0FVNaOiJZg88MevxGOQa5Gbj4pUwHTwcAZlOG87iU3jQA4jf4VrYGaOqZUVpAIO2UcenC4/NjOpjAqz9wwGmLxZ5MNX8HbUp5EC+QKye+M36twMZSssmDyeAKJuo6VP4q/k2pHRYwPr9KXXYYKul4C7rNmrvAK0NCOePr4N/veAk0BWCZQafTPyn+I3Si6gbWPZ2ww9atWzuww/wppi1HDh061OUPLU9gEO9DB3oL7WmhV22lI14LVF6wCQtobxNnqOs7w+FEvMRlB5+la2rfpC+tjnJGKKeMyKnyNMAVropzus5a8Oo7nM2V1yzj//iC8TpAaz+OaHZezG0R/Vd2npvhOEO4qkYSdUVEIfabnUMQSZj08RrtJLsg077VDPpTudcH4Kswap/hTQGtjBudwfZixI4lgCrjkkao/bhpHfEmTj71a56OkBeK5OFuKo/9s1WWcw70Q+HsKymnREMRc0lIywf3u6TTjPkPhnnkSu6TUPhuZ0hgWwFL7RuT/QRgmsj9PlzSQswbnA7CWDcApv9HO/xHBx/8l5YtW85kSrICAJKNRSpXgCsVUJlo70cdJrDqs8+e4xzwMeyAn8U+La00mvzjCZvyHluKVq6O49OXB+vKK+x1ak0l2L+lKeND7wzpNblDRfCKKXktLn05u3nzXGYlzJsjoJSmz2Zs4KluYwGYlUzZHudespMMG+uM/ElrEVPCcwRYWhEksW1Nt7HlqRcfoBpD68qC+AuuCZRb8qnVQZOF/JaKiPtolUgTWNSv3P7z52+ectBBxxzQrs3PaIC9RJ5AVfWA6uZGyLUNL5nLYbuz8PDDXuj89n9XK400PCmS8YO2pwS2FbD0Mopw0qdWiQ7XPVfCdINOJNDS0niU3esnYKy9+plnnvkcOvEKsOr99nr88cdL2Uj6GkfS/ALOhzyj/LYMblOEFD8qW7SgoOB4jLsfeHY1E5aCNiHIThMxzId6T1/0FauL44+vrDyvuRNrwSgReksWCTzIR3PoMFO559COZLDe1gEimWjlcLKXkdJrcjmp2F76CV668Hgi2bAwvFcHoWUKcBSwjnLfWx1Rzxv1L5HiJ5fJgNaxH31U5nzkPF2f5NiW0odkjoo5GR2gX60pv9eu9WH3abajBL7tMY3IBA3E7LqmcXt4gy5lKupExCsuhLayL74M1Q0dROqQMsDPALQGcYRLx1p2y0PaaKdymf9HJMOe69atu5XneoFVXI4xDPMqr3tqefnRkUCgPbU3Rt84GnurtCWc/RBTT/xZXE2hDRl5kZac7uvl1I4QCtz0LzVa5TPyiGPmP2nXq8y6DAiqeRVvfZJQeNDbOV+DX7SeDcvw6ZkXg12hVL4h5aF/1eEfhqtpRJfsRONNd5WPnPIOxJVRda9OQ6uEIkrl1hUVBZyVK7GjcYaatkF49UKFq+ZPxeeH7TgJbBNgxRXTpKPOTqeNC068JSbIkZ7ZhKoTJWhiiZS1P2GgfQYtS9scbq6dslGxqoBOk/gFnXaK/muQZw3OBjkPzDVytZdHLm2nR2ayZWmaaPZzVZE3yW+9gUq5Ma1X+6n+LbnSrtahJVugyoNOZTeNjh+CXYsvuYRH2Dlv6Liv4TwNS1O6qP6xmf1kMhuQRKyZXSUknxp8yQGWBj4LTLJpRQmXYd64ZQX9f0kBf0kpJ3SZMe9lG57OL8QuRlkQRvo2S8frh29fCWwTYNmVKTrLMjq7Om3Kga1eqNFID/pqGadyys6Dip12ANdSZXXKAParj9jmsI5/qhnK5tJpXr4NGpxp8lD5o2hw3Ri5WfzBqxYETFga+lqDVc+H3YxVLXjpk0jqZSlS8MQj+X1Za4JxkZKpBrsGeVxwg25tGjAZ2YEZnwM2X/BcgE1tCr7shHqxpMpD5R3Mpb8X1tE00rAW4w3D/yv2s8WqF8/JvOITkO3NpVMjVsOfheb9FYb39+DtSd5vEreOK13eRJkyS1uajr3uAdJZrD6Ify38PUgnGHIicyc//9K9CKmYjj6UonQvLOj/bzHjapQLHm16bYU/GD1zdWWs6BPo3HBNWvH7bidIYJsAi/Kqo7sY0Wezp6aQe7PUTIMnpMsxB7ESAg8uL9swaf3nmc28qYQHXGnfwmnkoY4WqCgre4ZjB0aee+65c7Ft6W2qgZDcCdMkUWuw1IwT+X/Ex6FqVJqmXuwlmk4CT25Zv/WV5q0r+BuxDDMvRg4ExztjLGagrGE1VQNerj7gq8VGAUKjNVWKkpCGzg/DjvYrQOsx4o5RQWpzlFnuXuxuVNkJcK79zZwE8SPuT+LqXLOqNVODJhuNOUNaFSvN2nqhkySOqEmZOoT8FfEAZZgD/w2A1lief67AiliArubcG54x9583D+53F59cXw2q8q5M76rKHPsChe3/9AF0mHpx1ac90ifqxzSZBJIHT2MSNhoIHX0onWUqDa6VHjWwBQ+XLcmxPdln87stX7utI5Vf8p3dnWs/Xfvg0JUrS8NVg87Bb0inMHlyRPFx5NcGu9YT5GfC8BvrbJpHe2k+RUINSjNc1blV7xhbG1rm5GZd0dypvHRqdvM2k/JaOmw1t3U0cmewCax0H+T+YjSFh3TPVRuIiz6GvDvhHwDfO3w3qM22Jhy/Ps7QMsD1Pd8hpPEBn9J8DqOpL5/y7EZbduHScw2HJqbtKlKav8RAvswjqM6fsh1GdEs0pyjgp/CUjnx12kTFxx9/PM9O4dCOWhGm0x4SlKi1yQAACm9JREFUXnrJCagM4ieftTq1gXiTPzv7D8aA34G9bUGM+mviyufomGveRnsAWrZvJifrRDnJIbQ1sqzTIhZMGibTGmn5AU0vgbSdqYFZ2Y7+EzraPXRkGY+NU0THijLnxK2bYrtHI1HAyuvBsXcxa47tPGu+zsWyO4vjgc7w1/JjBhPfGd7EptKH474zTNsZa0lLcnD56DqPXeJXYui93dPaLMDUwmo2UJmD4Xh1G6BZVpB/BkrlWOTQUYwhjpp4PrdVYHZ2MzOqkhNj4N0GWF1PuJFjcvwOfm5oGeLpbX9qTBuomvFpNabaafnDVS+TerWnMm4ovXh8t/0lUOtbrAHZqyMEeNO/xXdm/ThzaRDbkTuVBQKlnUtL1/y6aOO59ODTBFbQ6dA52V96sPf4BZaQX4w4FTd1m/nOf5WfN02sL3BFOQjwOUDyTFjv3IZtDhpoUc6S179Iv6ntEzyr89flzPEzQ/UZDo6/Bjuct/c4dKaf6OVMNc0pDpVuIHRy0SanVbRi8nO5rSo4KKondBXEazOqPpmRXSXtYFPaKZzoTbnxGwsQ4rf52jQkexvOba1OPPEgYNOwZauVOS7SapQNyduyx5dB/PF5V8eFKSdXvU8cFT1p+W4Xk4A6ZlM62/lrpPleQb9jMzWYHbeXIhms5WQeYuCKp5TP7h6Mlkbu6rZwoTY5WuCyHVlBqZzJDwP8VdiHZnq75tOWIVUChEkGMaaXPwJETyaNO3muMw0PWKs0qv799w9kuqNI6Xx4zZSO+mm6JxsRdXUW8v9hNx4ya+5retZGW1bQNCBs/erMT3y+8yXwQ5eABkpTOvuGDGovDQkH+T4kGAYAus+cP2XFqq8OB5h+qxUYBnOmwErABV02FpErQ82C7/BJxMXTADJNr8Sni/h0Tm9QfWf4N9bkT/TyTEebLrwKtAOB0yiL3WipdFO6sFcmlQ87VbPCQfnXYLVbCFhdAINsUaqPNocCVrFVTix6aeTrzQM9sFJdzL9U4wusBG66/Lc5QvCdL4G6JNDUGlba/OI1kqWDerUPBjJGgTUa5DLSy4JarZGgkiwAAMKdZsybqgRrmybaaSBbEc4AJErY5vA8LPXVWAwd2tUQePdHu3q8Fl5zOkO1nWpQP/11mOxUh8Jjpn/cG0DisQxQfjhSUnl7Go3Ryj0tMCpN3/kS8CWQKAE7cBJDt99TwqBfOqj/jzlN6SayO05ZAlpVJ3dqqlj1PAmb0rhuby80OwjjQU/xcS4AcIU4/C/MR9Z3T5gwYaMXVxsgqO4up5hm82/N13Im090PPvhgMWHiiedLKHPh4X17u6HgWGiqyuzZr0jMlvnliFM5tpE2OZL1nS8BXwLpJCCNYEe6+CNZgl1nzftPpxlz9b3eKYCVNg1maOCbaVWVxnVaMBScz6rbbUvy89tY7UbAlVxojn4ph28qO9TPIE6AI0CqzSk+unu7dieT/2zASt/wyVWDlZePKbO0QhYI7nOCgTnQHAe6aod3hcqrC7Z3meP9rPPMeSMEVh6vNv1o6ledpjLwnS8BXwKNk0Bdg7pxqdaTK1xlD9Jg1r6lZnm5GZdhlL8KqNld6hYROrkzU8nx9Am7Z259eta8x+CLchmw1T3RclXTuzFjbtAJpeOr/rDChFVFJ/yaevPv0vvwh61ns6P9FssvqnBc2pQrIy8v4yL+XPU6Vv86KJ6ysOBZVS6gaB1Hot61sSLwxwFz55bE84rWd74EfAk0nQTMNKbpkmtYSmEPbKSNcCSLpmN3LBnY6+lQMGM09+d7oGDtWwcAZH/+xeD+v/xFLDq288wFbyk38aLFCLSMFsOJEE/zneHZPN+k+DROgBXlU5DTKtkWEUeTMP0zf14QCIYh7i19DaASgGrDpEBU5fpzWVnslh7z53+hNLyySKPynS8BXwLbQQI7ekqYsgretElgEew2e9FnGNv5KyqnAIR4Awaz4iawAJEq0cAGsp3r34WD859gmniQnXLBKzuW+T9Dtjis4TvDI+C1mpgAylxhTxPDSJ9PmP4fsVB88Cu+avo3oPchpD85GAi+QmBv5euBlbYpsBLovBZ1IoOY/l0ksFK5CbfTP25950vAl8D2kIAG6S7lwgBK17jBzx+UnsX2hxvRajqqoACH9m9lEKayf4P96f6i4sp7vT89dcP8gcHXhx7arFWbNqNaFK0Y3/udz8uGxp0RPo3tFu/n5ATX9+17Pd8j3pc9b96WMH/hpaSX9+q1W6xZxjVMLi8BGHPJTP8wqmN7zbSU52WoVeO6zpr/jMoioIrX7hTmO18CvgS2nwR2OcCyVQ0DXFya5sXm9evXonWWewX3VwJULYRaRMTbtz4k7GY+8/kbNMaFR40aUZST0+quMWOemJSfn3NgeXnumg5O8fEvLyq+ety40/JKSsrDt932gogFPIcO6v8rNiVcD1DtT5CySABGnu92Ihvv7/z28i1Eu+Gqy9rPxOI7XwK+BLazBHZZwLL19rQYYxfSX427weBoCi0bldDM/vOypmoCmWmcLDWm0+z5s/X8wGWX3FKw5L322RXlfTkerg0fy2wqD4XmTj/kx19cdv/9Y0RTWND3J2Ajn9O4OjFVaRg7FbdBPfBnBX+pqCy/9dA5iz5WfHx59Ow7XwK+BHacBHZ5wPJEkWAMXz6ozxExN3hTepBxHgJo3g7FIvdEA8F2yeIE1FZzONuV0BzJxPJXik8BfjP44nFsl1lzZyjen/5JCr7zJbBzJfBdASwjpXCcfUsA0p2/hMdUfiOV2E8E6EPfbjcwHFVAhBFeiwuqq766jnLz7eqo0aK+nV6CXCuiTmxcl5nznhC98lmKH/ZWNAnznS8BXwI7SQLfKcCyMoqflhlDeW4GB7M5l1pDOXaumKAJeoKMcd6yVvma6Vnw0p+GiiYW2wyY/b48snWCDm4TL/n4fz6QKDn/yZfATpXAdxKwPIklAMpStiLwx6xhsOdkE2/MTynAyoo7IT72jFNecVOnuYt0aqqd/hm7mSX3fV8CvgR2vgS+y4BlpZcAXBjmj+PvV/5KxVobgvQaFtHuenapn91l5vzXRetpbtWbUA2//+NLwJfALiMB2Xa+6676n5cFOF1mL3gFveo/plLYq1JWrjo89o7AatoQJxT+dvqn6aLvfAn4EtgFJfB9ACwj1jBG8d1RmfADHFTzquxSzPpSApYJl+blxl4VvTPdfD+YktbxnS8BXwK7jAS+D1PCeGGa+vBnmbnB3VpM46E34GSPrNE/DxjtiXBOhHDmbKhwhvHBso5DlvM1qyo5+L++BHZZCXxvNCxPwtp+4HZbsmSrU1l6AhA0E0XKHFlDvP78whwFA4hN43C9k3W6guXzfN/zJeBLYBeWgNFIduHyNbZoqpfZQ9WjoP8pbHA4iv+k24Ogr/gW8F+TZs2fFK7aV2XoGpuJz+dLwJeAL4GmkkBdYFxXfFOVw0/Hl4AvgSaSwPd90JotD5KVdqt3Zbqoe/+EBUnBd74EfAn4EvAl4EvAl4AvAV8CvgR8CfgS8CXgS8CXgC8BXwK+BHwJ+BLwJeBLwJeALwFfAj9YCfw/pIxvcYa4M80AAAAASUVORK5CYII="},"74ded2f6-a8bb-4402-8220-92126d3929b8.png":{"image/png":"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"}}},{"cell_type":"markdown","source":"# Installation","metadata":{}},{"cell_type":"code","source":"!pip install -U segmentation-models-pytorch -q","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Data Exploration\n\nThe dataset is **\"Semantic segmentation of aerial imagery\"**\n\nThe dataset is split into 8 tiles with 9 images per each. Check [here](https://www.kaggle.com/datasets/humansintheloop/semantic-segmentation-of-aerial-imagery/data) for more info.\n\nWe are provided with 72 aerial images of Dubai and their correspondings masks. Our task is to segment various land objects:\n1. Building\n2. Land (unpaved area)\n3. Road\n4. Vegetation\n5. Water\n6. Unlabeled","metadata":{}},{"cell_type":"code","source":"# Import all the required libraries\nimport os\nimport warnings\nwarnings.filterwarnings('ignore')\nimport numpy as np\nimport pandas as pd\nfrom sklearn.model_selection import train_test_split\nimport json\nimport matplotlib.pyplot as plt\nimport torch\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms\nimport segmentation_models_pytorch as smp\nfrom tqdm.auto import tqdm\nfrom PIL import Image","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Get the info on classes (colors for future plotting)\nclasses_path = '/kaggle/input/semantic-segmentation-of-aerial-imagery/Semantic segmentation dataset/classes.json'\n\nwith open(classes_path) as f:\n    classes_dict = json.load(f)['classes']\n\n# Correct the mistakes in the color codes \n# https://www.kaggle.com/datasets/humansintheloop/semantic-segmentation-of-aerial-imagery/discussion/447576\nclasses_dict[0]['color'] = '#E2A929'\nclasses_dict[1]['color'] = '#8429F6'\nclasses_dict[2]['color'] = '#6EC1E4'\nclasses_dict[3]['color'] = '#3C1098'\nclasses_dict[4]['color'] = '#FEDD3A'\nclasses_dict[5]['color'] = '#9B9B9B'\n\n# This will come in useful later when converting masks into tensors\nclasses_dict[0]['color_rgb'] = (226, 169, 41)\nclasses_dict[1]['color_rgb'] = (132, 41, 246)\nclasses_dict[2]['color_rgb'] = (110, 193, 228)\nclasses_dict[3]['color_rgb'] = (60, 16, 152)\nclasses_dict[4]['color_rgb'] = (254, 221, 58)\nclasses_dict[5]['color_rgb'] = (155, 155, 155)\n\ncolor_rgb_to_class = {classes_dict[i]['color_rgb']: i for i in range(6)}\nclass_to_color_rgb = {v: k for k, v in color_rgb_to_class.items()}\n\nclasses = [p['title'] for p in classes_dict]\nclass_colors = [p['color'] for p in classes_dict]","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Create a DataFrame with paths for easier use\n\nfile_names_general = [f'image_part_{i:03d}' for i in range(1, 10)]\nimage_paths, mask_paths, tile_ids = [], [], []\nfor tile_id in range(1, 9):\n    for file_name in file_names_general:\n        tile_ids.append(tile_id)\n        image_paths.append(\n            f'/kaggle/input/semantic-segmentation-of-aerial-imagery/Semantic segmentation dataset/Tile {tile_id}/images/{file_name}.jpg'\n        )\n        mask_paths.append(\n            f'/kaggle/input/semantic-segmentation-of-aerial-imagery/Semantic segmentation dataset/Tile {tile_id}/masks/{file_name}.png'\n        )\n\ndata = pd.DataFrame({\n    'image_path': image_paths,\n    'mask_path': mask_paths,\n    'tile_id': tile_ids,\n})\n\ndata.to_csv(\"data.csv\", index=False)\n\ndata.head()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Plot some of the images\n\nn_rows = 3\n\nplt.figure(figsize=(12, 10))\n\ni = 0\nfor _, row in data.sample(n_rows).iterrows():\n    i += 1\n    plt.subplot(n_rows, 2, i)\n    plt.imshow(Image.open(row['image_path']))\n    plt.title('Image')\n    plt.grid(False)\n    plt.xticks([])\n    plt.yticks([])\n\n    i += 1\n    plt.subplot(n_rows, 2, i)\n    plt.imshow(Image.open(row['mask_path']))\n    plt.title('Mask')\n    plt.grid(False)\n    plt.xticks([])\n    plt.yticks([])\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Dataset Creation\n\nI will now split the data into training and validation data to check our model's performance later on.\n\nLet's also create a `torch.utils.data.Dataset` based `SegmentationDataset` class.\nIt will allow us to later on create a `torch.utils.data.DataLoader` instance to train\nour model in batches.","metadata":{}},{"cell_type":"code","source":"# Split the data into training and validation sets with stratification on tile_id\n\ntrain, valid = train_test_split(data, test_size=2/9, stratify=data['tile_id'], random_state=42)\ntrain, valid = train.reset_index(drop=True), valid.reset_index(drop=True)\n\nlen(train), len(valid)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Create SegmentationDataset class\n\nclass SegmentationDataset(Dataset):\n    def __init__(self, df, transform_image=None, transform_mask=None):\n        self.df = df\n        self.transform_image = transform_image\n        self.transform_mask = transform_mask\n        \n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        row = self.df.iloc[idx]\n        image_path, mask_path = row['image_path'], row['mask_path']\n        image, mask = Image.open(image_path), Image.open(mask_path)\n        mask = self.convert_mask(mask, idx)\n        \n        if self.transform_image is not None:\n            image = self.transform_image(image)\n        if self.transform_mask is not None:\n            mask = self.transform_mask(mask)\n            \n        return image, mask\n\n    def convert_mask(self, mask_pil, idx):\n        mask_pil = mask_pil.resize((512, 512), resample=Image.NEAREST) # important to use NEAREST in order not to mess up our classes (keep integer)\n        mask_np = np.array(mask_pil)\n        if len(mask_np.shape) == 2: # already converted:\n            return mask_np\n        \n        h, w, _ = mask_np.shape\n        \n        label = np.zeros((h, w), dtype=np.uint8)\n        for rgb, class_idx in color_rgb_to_class.items():\n            capture = np.all(mask_np == rgb, axis=-1)\n            label[capture] = class_idx\n            \n        return label","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Create instances\n\ntransform_image = transforms.Compose([\n    transforms.Resize((512, 512)),\n    transforms.ToTensor()\n])\ntransform_mask = transforms.Compose([\n    transforms.Lambda(lambda x: torch.from_numpy(x).long())\n])\n\ntrain_ds = SegmentationDataset(train, transform_image, transform_mask)\nvalid_ds = SegmentationDataset(valid, transform_image, transform_mask)\n\nBATCH_SIZE = 4\n\ntrain_loader = DataLoader(train_ds, batch_size=BATCH_SIZE, shuffle=True)\nvalid_loader = DataLoader(valid_ds, batch_size=BATCH_SIZE, shuffle=False)\n\nlen(train_loader), len(valid_loader)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Model Instantiation and Training\n\nNow comes the most important part - how to use the package and import models,\nloss function and metrics from it. It is really easy to do so!\n\nLet's also accelerate training by using available GPUs.","metadata":{}},{"cell_type":"code","source":"# Instantiate device\ndevice = torch.device('cuda' if torch.cuda.is_available() else \"cpu\")\ndevice","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Instantiate the model\n\nmodel = smp.PSPNet(\n    encoder_name=\"vgg19_bn\",\n    encoder_weights=\"imagenet\",\n    in_channels=3,\n    classes=6,\n)\n\nmodel.to(device)","metadata":{"trusted":true,"scrolled":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Instantiate the loss function and optimizer\n\nloss_fn = smp.losses.JaccardLoss( # IoU Loss\n    mode='multiclass', \n    classes=range(1, 6) # \"Unlabeled\" class doesn't contribute to loss\n)\n\noptimizer = torch.optim.Adam(model.parameters(), lr=1e-4)\n\ndef compute_iou(output, target):\n    tp, fp, fn, tn = smp.metrics.get_stats(output, target, mode='multiclass', num_classes=6)\n    iou_score = smp.metrics.iou_score(tp, fp, fn, tn, reduction=\"micro\")\n    return iou_score","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Train the model\n\nepochs = 50\nlog_rate = 10\n\ntrain_losses, train_iou_scores, valid_losses, valid_iou_scores = [], [], [], []\n\nfor epoch in tqdm(range(epochs), desc='Epoch'):\n    model.train()\n    running_train_loss, running_train_iou_score, i = 0, 0, 0\n    # for X_batch, y_batch in (pbar := tqdm(train_loader, desc='Train DataLoader', leave=False)):\n    for X_batch, y_batch in train_loader:\n        X_batch, y_batch = X_batch.to(device), y_batch.to(device)\n        \n        output = model(X_batch)\n        preds = output.argmax(dim=1)\n        loss = loss_fn(output, y_batch)\n        \n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        i += 1\n        running_train_loss += loss.item()\n        iou = compute_iou(preds.detach(), y_batch)\n        running_train_iou_score += iou.item()\n        \n        # pbar.set_postfix({'loss': f'{running_train_loss/i:.5f}', 'iou': f'{running_train_iou_score/i:.5f}'})\n\n    train_losses.append(running_train_loss/i)\n    train_iou_scores.append(running_train_iou_score/i)\n    \n    if (epoch+1)%log_rate==0:\n        print(f'Epoch: {epoch+1}/{epochs}')\n        print(f'Train Loss: {running_train_loss/i:.5f} | Train IoU: {running_train_iou_score/i:.5f}')\n    \n    model.eval()\n    running_valid_loss, running_valid_iou_score, i = 0, 0, 0\n    # for X_batch, y_batch in (pbar := tqdm(valid_loader, desc='Valid DataLoader', leave=False)):\n    for X_batch, y_batch in valid_loader:\n        X_batch, y_batch = X_batch.to(device), y_batch.to(device)\n\n        with torch.no_grad():\n            output = model(X_batch)\n            preds = output.argmax(dim=1)\n            loss = loss_fn(output, y_batch)\n\n        i += 1\n        running_valid_loss += loss.item()\n        \n        iou = compute_iou(preds.detach(), y_batch)\n        running_valid_iou_score += iou.item()\n        \n        # pbar.set_postfix({'loss': f'{running_valid_loss/i:.5f}', 'iou': f'{running_valid_iou_score/i:.5f}'})\n\n    valid_losses.append(running_valid_loss/i)\n    valid_iou_scores.append(running_valid_iou_score/i)\n    \n    if (epoch+1)%log_rate==0:\n        print(f'Valid Loss: {running_valid_loss/i:.5f} | Valid IoU: {running_valid_iou_score/i:.5f}')","metadata":{"trusted":true,"scrolled":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.save_pretrained('/kaggle/working/aerial-model')","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Plot the loss and metric graphs\n\nplt.figure(figsize=(10, 10))\n\nplt.subplot(2, 1, 1)\nplt.title('Loss')\nplt.plot(range(epochs), train_losses, label='Train')\nplt.plot(range(epochs), valid_losses, label='Valid')\nplt.legend()\nplt.grid(True)\n\nplt.subplot(2, 1, 2)\nplt.title('IoU')\nplt.plot(range(epochs), train_iou_scores, label='Train')\nplt.plot(range(epochs), valid_iou_scores, label='Valid')\nplt.legend()\nplt.grid(True)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Plot how our model is predicting\n\nmodel.eval()\nfor X_batch, y_batch in valid_loader:\n    X_batch, y_batch = X_batch.to(device), y_batch.to(device)\n    with torch.no_grad():\n        output = model(X_batch)\n        preds = np.array(output.argmax(dim=1).detach().cpu(), dtype=np.uint8)\n        targets = np.array(y_batch.detach().cpu(), dtype=np.uint8)\n    break\n\nlut = np.array([v for k, v in class_to_color_rgb.items()], dtype=np.uint8) # lookup table\n\nplt.figure(figsize=(13, 13))\n\nfor i, (pred, target) in enumerate(zip(preds, targets)):\n    plt.subplot(BATCH_SIZE, 2, 2*i+1)\n    plt.title('Original')\n    plt.imshow(lut[target])\n    plt.xticks([])\n    plt.yticks([])\n    \n    plt.subplot(BATCH_SIZE, 2, 2*i+2)\n    plt.title('Predicted')\n    plt.imshow(lut[pred])\n    plt.xticks([])\n    plt.yticks([])\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Conclusion\n\nThe model seems to capture general trends, though there is huge room for improvement.\n\nI hope I did a good job of showing you how the `segmentation_models_pytorch` package makes it easier to train models for segmentation tasks. I wasn't aiming for creating a high-performing model in this notebook *(though if you do have some suggestions, please write a comment!)* - I just wanted to share the package with you. I want to thank the [package author](https://www.kaggle.com/pavel92) again for removing the redundant work that might come with these kinds of tasks and **you**, for reading this. Happy Kaggling!","metadata":{}}]}