{"cells":[{"cell_type":"markdown","metadata":{"_cell_guid":"7064ba1c-6db3-fec8-2e0c-9c67c9159ea5","_uuid":"96403c032284b1bcb6c0d118782cc099737b6114"},"source":"AI for Screening\n================","outputs":[],"execution_count":null},{"cell_type":"code","execution_count":1,"metadata":{"_cell_guid":"9572f5fb-74c7-bd85-db16-690ae73451f7","_uuid":"995a514d2036958b244c5dca580561a7b381bf51","_execution_state":"idle"},"outputs":[{"output_type":"stream","name":"stdout","text":"8215 512 512\n"}],"source":"import numpy as np\nimport pandas as pd\nimport glob\n\ntrain = glob.glob('../input/train/**/*.jpg') + glob.glob('../input/additional/**/*.jpg')\ntrain = pd.DataFrame([[p.split('/')[3],p.split('/')[4],p] for p in train], columns = ['type','image','path'])\n\ntest = glob.glob('../input/test/*.jpg')\ntest = pd.DataFrame([[p.split('/')[3],p] for p in test], columns = ['image','path'])\n\nsub = pd.read_csv('../input/sample_submission.csv')\nprint(len(train),len(test),len(sub))"},{"cell_type":"code","execution_count":2,"metadata":{"_cell_guid":"2e770af1-ab61-0860-2c59-f6edf046582f","_uuid":"ab9a88165d3a75a5cbad528a6c24f4e7702cb2f3","_execution_state":"idle"},"outputs":[{"output_type":"execute_result","data":{"text/plain":"     image                   path\n0    0.jpg    ../input/test/0.jpg\n1    1.jpg    ../input/test/1.jpg\n2   10.jpg   ../input/test/10.jpg\n3  100.jpg  ../input/test/100.jpg\n4  101.jpg  ../input/test/101.jpg","text/html":"<div>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>image</th>\n      <th>path</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>0.jpg</td>\n      <td>../input/test/0.jpg</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>1.jpg</td>\n      <td>../input/test/1.jpg</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>10.jpg</td>\n      <td>../input/test/10.jpg</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>100.jpg</td>\n      <td>../input/test/100.jpg</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>101.jpg</td>\n      <td>../input/test/101.jpg</td>\n    </tr>\n  </tbody>\n</table>\n</div>"},"metadata":{},"execution_count":2}],"source":"test.head()"},{"cell_type":"code","execution_count":3,"metadata":{"_cell_guid":"a6bf536f-8277-fad4-ce32-ff832bbd708b","_uuid":"ef9ef01d3e8d7501ca3314e8844cd80e7cd8f320","_execution_state":"idle"},"outputs":[{"output_type":"display_data","data":{"text/plain":"<matplotlib.figure.Figure at 0x7efe2e92b358>","image/png":"iVBORw0KGgoAAAANSUhEUgAAAbIAAAEeCAYAAADvrZCJAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAEq9JREFUeJzt3XuQXnV9x/H3shsqhNhsYCEYLV7Qb72WQSlVwIZbpZQM\ntRHkYsQEW+vA1ACthgZBYhnSClG5DBouJqLWdDKDkjEDTLhIQEkjtlQRvpS7NdGsJUm5xAQ22z+e\nE1yTTfbCkz3PL/t+zezkPL9znpzvmf1mP/s75+Q8bb29vUiSVKrd6i5AkqRXwiCTJBXNIJMkFc0g\nkyQVzSCTJBXNIJMkFa2j7gL609397Kj/PwGdnXuydu0LdZehmtkHAvsAoKtrXNv21jkja1EdHe11\nl6AWYB8I7IOBGGSSpKIZZJKkohlkkqSiGWSSpKIZZJKkohlkkqSiGWSSpKIZZJKknequu24HYOnS\nJVx11Zea/ve35JM9pFYwY+4ddZfQEm6YdVTdJWgQmt2vzfq+r169imXLbmXy5KOb8vf1xyCTJA3Z\n0qVLWLHiBzz//PN0d6/h5JNPY8yYMSxevIj29t14/evfxGc+M5t58/6Zhx56kK997Vr2228iv/51\nN7Nn/wNPPvkEp546jRNOOPEV1+KpRUnSsDzxxOPMnTuPL3/5K1x77TVs2LCByy+/kmuuuYGnn36S\nxx57lFNPncZBBx3M9Ol/DcCqVb9gzpy5XHrpZSxevKgpdTgjkyQNy0EHHUxHRwfjx49n3Lhx7LXX\nOM4//zwAnnrqCdavX7fNe97+9nfS3t7OPvvsy/PPP9eUOgwySdKwbN7c22d5MxdfPJubblrK3nvv\nw6c/PbPf97S3//YByL29zfmgE08tSpKG5cEH/4uenh7WrVvHmjVr6OzsZO+99+FXv/olDz/8EC+9\n9BK77bYbPT09O7UOZ2SSpGGZOPE1fPazs/jFL37Oeed9hvvvX8nHP/5RDjzwzZx22jSuuGIeV175\nVTIf5oorLufAA9+yU+poa9bUrpn8YE3o6hpHd/ezdZcxqnn7fYO339evFX8eLF26hMcff4yzz+7/\nFGKz+cGakqRdlqcWJUlDdvzxU+ou4WXOyCRJRTPIJElFM8gkSUUb1DWyiNgD+CnweeB24EagHVgN\nTMvMjRFxOjAT2AzMz8zrI2IMsAA4AOgBpmfm400/CknSqDXYGdkFwDPV8hzg6sw8AngUmBERY4EL\ngWOAycA5ETEBOA1Yl5mHA5cAlzaxdkmSBg6yiPhD4G3A96qhycDN1fISGuF1KLAyM9dn5gbgXuAw\n4GjgpmrbZdWYJElNM5gZ2eXAuX1ej83MjdXyGmB/YCLQ3WebbcYzczPQGxG7v9KiJUnaYofXyCLi\no8APM/OJiOhvk+39T+uhjv+Ozs496ehoH3jDXVxX17i6S5Dswxbh92H7BrrZ4y+AN0bECcBrgY3A\ncxGxR3UKcRKwqvqa2Od9k4D7+ow/UN340ZaZmwYqau3aF4Z8ILuaVnwkjUYn+7B+/jzYcZDvMMgy\n88NbliPic8CTwPuAqcA3qj9vAVYA10XEeOAlGtfCZgKvBk4CbgWmAHcO+ygkSerHcP4f2UXAGRGx\nHJgALKxmZ7NoBNYy4OLMXA8sAtoj4h7gLOD85pQtSVLDoJ+1mJmf6/Py2H7WLwYWbzXWA0wfbnGS\nJA3EJ3tIkopmkEmSimaQSZKKZpBJkopmkEmSimaQSZKKZpBJkopmkEmSimaQSZKKZpBJkopmkEmS\nimaQSZKKZpBJkopmkEmSimaQSZKKZpBJkopmkEmSimaQSZKKZpBJkopmkEmSimaQSZKKZpBJkopm\nkEmSimaQSZKKZpBJkopmkEmSimaQSZKKZpBJkopmkEmSimaQSZKKZpBJkopmkEmSimaQSZKKZpBJ\nkopmkEmSimaQSZKKZpBJkopmkEmSimaQSZKK1jHQBhGxJ7AA2A94FfB54AHgRqAdWA1My8yNEXE6\nMBPYDMzPzOsjYkz1/gOAHmB6Zj7e/EORJI1Gg5mRTQF+lJl/CpwMzAPmAFdn5hHAo8CMiBgLXAgc\nA0wGzomICcBpwLrMPBy4BLi06UchSRq1BpyRZeaiPi9fB/wPjaD622psCfD3QAIrM3M9QETcCxwG\nHA18vdp2GXBDMwqXJAkGEWRbRMQPgNcCJwDLMnNjtWoNsD8wEeju85ZtxjNzc0T0RsTumblpe/vq\n7NyTjo72IR3Irqira1zdJUj2YYvw+7B9gw6yzHxfRBwEfANo67OqbTtvGer4y9aufWGwZe2yurrG\n0d39bN1lSPZhC/DnwY6DfMBrZBHx7oh4HUBm/ieN8Hs2IvaoNpkErKq+JvZ56zbj1Y0fbTuajUmS\nNBSDudnj/cB5ABGxH7AXjWtdU6v1U4FbgBXAIRExPiL2onF9bDlwG3BSte0U4M6mVS9JGvUGE2Rf\nAfaNiOXA94CzgIuAM6qxCcDCzNwAzAJupRF0F1c3fiwC2iPinuq95zf/MCRJo9Vg7lrcQOMW+q0d\n28+2i4HFW431ANOHW6AkSTvikz0kSUUzyCRJRTPIJElFM8gkSUUzyCRJRTPIJElFM8gkSUUzyCRJ\nRTPIJElFM8gkSUUzyCRJRTPIJElFM8gkSUUzyCRJRTPIJElFM8gkSUUzyCRJRTPIJElFM8gkSUUz\nyCRJRTPIJElFM8gkSUXrqLsASWp1M+beUXcJtbth1lF1l7BdzsgkSUUzyCRJRTPIJElFM8gkSUUz\nyCRJRTPIJElFM8gkSUUzyCRJRTPIJElFM8gkSUUzyCRJRTPIJElFM8gkSUUzyCRJRTPIJElFG9Tn\nkUXEvwBHVNtfCqwEbgTagdXAtMzcGBGnAzOBzcD8zLw+IsYAC4ADgB5gemY+3uwDkSSNTgPOyCLi\nSOAdmfle4DjgS8Ac4OrMPAJ4FJgREWOBC4FjgMnAORExATgNWJeZhwOX0AhCSZKaYjCnFu8GTqqW\n1wFjaQTVzdXYEhrhdSiwMjPXZ+YG4F7gMOBo4KZq22XVmCRJTTFgkGVmT2Y+X708E1gKjM3MjdXY\nGmB/YCLQ3eet24xn5magNyJ2b075kqTRblDXyAAi4kQaQfZnwH/3WdW2nbcMdfxlnZ170tHRPtjS\ndlldXePqLkGyDwW0dh8M9maPDwCzgeMyc31EPBcRe1SnECcBq6qviX3eNgm4r8/4A9WNH22ZuWlH\n+1u79oWhH8kupqtrHN3dz9ZdhmQfCqi/D3YUpIO52eP3gS8AJ2TmM9XwMmBqtTwVuAVYARwSEeMj\nYi8a18KWA7fx22tsU4A7h3EMkiT1azAzsg8D+wD/FhFbxs4ArouITwBPAQsz88WImAXcCvQCF1ez\nt0XAsRFxD7AR+FiTj0GSNIoNGGSZOR+Y38+qY/vZdjGweKuxHmD6cAuUJGlHfLKHJKloBpkkqWgG\nmSSpaAaZJKloBpkkqWgGmSSpaAaZJKloBpkkqWgGmSSpaAaZJKloBpkkqWgGmSSpaAaZJKloBpkk\nqWgGmSSpaAaZJKloBpkkqWgGmSSpaAaZJKloBpkkqWgGmSSpaAaZJKloHXUX0IpmzL2j7hJqd8Os\no+ouQZIGxRmZJKloBpkkqWgGmSSpaAaZJKloBpkkqWgGmSSpaAaZJKloBpkkqWgGmSSpaAaZJKlo\nBpkkqWgGmSSpaAaZJKloBpkkqWgGmSSpaAaZJKlog/pgzYh4B/Bd4IuZeVVEvA64EWgHVgPTMnNj\nRJwOzAQ2A/Mz8/qIGAMsAA4AeoDpmfl48w9FkjQaDTgji4ixwJXA7X2G5wBXZ+YRwKPAjGq7C4Fj\ngMnAORExATgNWJeZhwOXAJc29QgkSaPaYE4tbgSOB1b1GZsM3FwtL6ERXocCKzNzfWZuAO4FDgOO\nBm6qtl1WjUmS1BQDBllmvlQFU19jM3NjtbwG2B+YCHT32Wab8czcDPRGxO6vtHBJkmCQ18gG0Nak\n8Zd1du5JR0f78CvSK9bVNa7uEtQi7AVBa/fBcIPsuYjYo5qpTaJx2nEVjdnXFpOA+/qMP1Dd+NGW\nmZt29JevXfvCMMtSs3R3P1t3CWoR9oKg/j7YUZAO9/b7ZcDUankqcAuwAjgkIsZHxF40roUtB24D\nTqq2nQLcOcx9SpK0jQFnZBHxbuBy4PXAixHxIeB0YEFEfAJ4CliYmS9GxCzgVqAXuDgz10fEIuDY\niLiHxo0jH9spRyJJGpUGDLLMvJ/GXYpbO7afbRcDi7ca6wGmD7M+SZJ2yCd7SJKKZpBJkopmkEmS\nimaQSZKKZpBJkopmkEmSimaQSZKKZpBJkopmkEmSimaQSZKKZpBJkopmkEmSimaQSZKKZpBJkopm\nkEmSimaQSZKKZpBJkopmkEmSimaQSZKKZpBJkopmkEmSimaQSZKKZpBJkopmkEmSimaQSZKKZpBJ\nkopmkEmSimaQSZKKZpBJkopmkEmSimaQSZKKZpBJkopmkEmSimaQSZKKZpBJkopmkEmSimaQSZKK\nZpBJkopmkEmSitYxEjuJiC8CfwL0Ap/KzJUjsV9J0q5vp8/IIuJPgTdn5nuBM4ErdvY+JUmjx0ic\nWjwa+A5AZj4EdEbEq0dgv5KkUaCtt7d3p+4gIuYD38vM71avlwNnZuYjO3XHkqRRoY6bPdpq2Kck\naRc1EkG2CpjY5/VrgNUjsF9J0igwEkF2G/AhgIg4GFiVmc+OwH4lSaPATr9GBhARc4H3A5uBszLz\ngZ2+U0nSqDAiQSZJ0s7ikz0kSUUzyCRJRTPIJElFM8ikFhcRI/JMVKlU/gNpYRFxS2YeV3cd2vki\n4n3AF4EJwLeAOZnZU62+DTiqrto0ciLiEOCfgJ8DFwALgYOBp4FPZua/11heyzLIahYRx29nVRuw\n/0jWolpdBkwHuoGZwJKIODEzX8Sn4Ywm84DZwB8AdwDnZuYtEfFOYD7w3jqLa1UGWf2+BtwD/F8/\n67pGuBbVpyczf1Ytz46Is4DvRsRf0fj4I40OL2bm3QAR8XeZeQtAZv4kIjbVW1rrMsjqdzJwDjAj\nM3/nB1ZE3FlPSarBYxFxFY3fwDdl5tUR8RvgbhqnGzU6/CYiTsnMbwNTACJiPHAG4BORtsObPWqW\nmd8HzgV+r5/VXxjhclSfM4EfAVuui5GZ1wOnAIvqKkoj7gyqSwqZ+atq7F3AG6p16odP9ihARNyU\nmR+suw7Vyz4Q2Af9cUZWhvF1F6CWYB8I7INtGGRlcNossA/UYB9sxSCTJBXNIJMkFc0gK8PaugtQ\nS7APBPbBNrxrsUVExKuBs4F9M3NmRBwJ/Edmrqu5NI0g+0BgHwyVM7LWsYDGb1qHVK/3pfHMPY0u\nC7APZB8MiUHWOsZl5jXAJoDMXATsUW9JqoF9ILAPhsQgax27RcSbqG6tjYjjgPZ6S1IN7AOBfTAk\nPmuxdZwNfBV4T0SsBh4A/qbeklQD+0BgHwyJN3u0kIiYAGz5LeyRzOzvifjaxdkHAvtgKAyyFhER\n/wh8HPgpjVO+bwWuyczLai1MI8o+ENgHQ+WpxdYxFXhrZm4EiIhX0ficMht3dLEPBPbBkHizR+t4\nmm2/H4/UUYhqZR8I7IMh8dRii4iIpcC7gRU0Gvhg4GfAMwCZeXJ91Wmk2AcC+2CoPLXYOi6jz4cq\natSyDwT2wZAYZK1jPrAU+GZmrqi7GNXGPhDYB0PiqcUWERG7A0cDJwJvA+4CvpWZD9dZl0aWfSCw\nD4bKIGsxEdEOHAPMASYATwDnZOaDtRamEWUfCOyDwfLUYouonm59CnAYcBvwycz8cUS8hcbDQt9T\nZ30aGfaBwD4YKm+/r1lELK4WPwHcDPxRZp6bmT8GyMxHgGvrqk8jwz4Q2AfD5anFmkXEHZl5VN11\nqF72gcA+GC6DrGYR8TTw7e2tz8xPj2A5qol9ILAPhstrZPV7HvDCrewDgX0wLAZZ/X6ZmQvrLkK1\nsw8E9sGweLNH/e6vuwC1BPtAYB8Mi9fIJElFc0YmSSqaQSZJKppBJtUkIj5Sdw3SrsAgk2pQPUPv\nwrrrkHYF3n4v1eMG4ICIuBNYmJkLACLiGuAnwB8DG4A3AvsDCzJzXvVU9KuBA4FxwL9m5uU11C+1\nDGdkUj0uArqrPz8GL8/S/hz4ZrXNpMz8APB+4IKI2Bv4FLAqM48EDgVOiYh3jXDtUksxyKQaZebd\nQFdEvAGYDCzPzPXV6tuqbdYBjwBvBo4EPhgRdwG3A6+iMTuTRi1PLUr1uxb4CPBa4Lo+431/0WwD\neoGNwJzMXIwkwBmZVJfNwJhq+evAX9L4yI7v99nmSICI6KQx60rgHuDkany3iJgXERNGrGqpBRlk\nUj1WAb+MiPtpzLIeA76z1TZrI+I7wPeBi6pTjFcDz0XED4H7gHWZ+cwI1i21HB9RJdUsIsYDPwCO\nyMz/rcYWAPdk5nU7eq8kZ2RSrSJiBrAcuGBLiEkaGmdkkqSiOSOTJBXNIJMkFc0gkyQVzSCTJBXN\nIJMkFc0gkyQV7f8BPe9gWvBHWlIAAAAASUVORK5CYII=\n"},"metadata":{}}],"source":"from PIL import ImageFilter, ImageStat, Image, ImageDraw\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n%matplotlib inline\nimport cv2\n\ntypes = train.groupby('type', as_index=False)['path'].count()\n_ = types.plot(kind='bar', x='type', y='path', figsize=(7,4))"},{"cell_type":"code","execution_count":4,"metadata":{"_cell_guid":"bdec5ec8-d8b6-9c81-3897-302c5c4c844e","_uuid":"f9799083ca6c5aa85164fe28212e0d2d1f763c67","_execution_state":"idle"},"outputs":[{"output_type":"execute_result","data":{"text/plain":"     type  path\n0  Type_1  1441\n1  Type_2  4348\n2  Type_3  2426","text/html":"<div>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>type</th>\n      <th>path</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>Type_1</td>\n      <td>1441</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>Type_2</td>\n      <td>4348</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>Type_3</td>\n      <td>2426</td>\n    </tr>\n  </tbody>\n</table>\n</div>"},"metadata":{},"execution_count":4}],"source":"types"},{"cell_type":"code","execution_count":5,"metadata":{"_cell_guid":"2f78adbb-2467-7f18-26dc-61622489f080","_uuid":"31ed43bae929b66189caeb28f4bc61f6b2941a3b","_execution_state":"idle"},"outputs":[{"output_type":"stream","name":"stdout","text":"../input/additional/Type_2/5892.jpg\n"},{"output_type":"stream","name":"stdout","text":"../input/additional/Type_2/2845.jpg\n"},{"output_type":"stream","name":"stdout","text":"../input/additional/Type_1/5893.jpg\n"},{"output_type":"display_data","data":{"text/plain":"<matplotlib.figure.Figure at 0x7efe270428d0>","image/png":"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\ncyEzM7NScyEzM7NScyEzM7NScyEzM7NScyEzM7NScyEzM7NScyEzM7NScyEzM7NScyEzM7NScyEz\nM7NSa+ptAUmDgGuBTYD1gbOAR4HrgUbgReCIiFguaTxwPLACmBIRUyUNyO6/BdAGTIiIp2v/UszM\nrD/qyxbZOOCRiPg0cAhwIXAmcGlE7A48BRwtaTBwGrA3MBo4QdIGwOHAoojYDfgOMLnmr8LMzPqt\nXrfIImJaxa/vA/5KKlT/ns27Dfg6EMC8iFgMIGkOMArYC/hhtuxM4OpaBDczM4M+FLIOkh4CNgfG\nAjMjYnl20wJgU2AE0Fpxl3fMj4gVktolrRsRb3T3XMOHD6KpqXG1XkhPmpuH1uyxaq3I2fqiyPnz\nylbkdQLFzuds1env2fpcyCJiV0k7AD8CGipuaujmLqs7f6WFC5f2NVavmpuH0tq6pGaPV0tFztZX\nRc6fR7aiv6dFzuds1ekv2XoqiL0eI5O0o6T3AUTE70jFb4mkgdkiI4H52c+Iiru+Y3428KOhp60x\nMzOz1dGXwR6fAk4CkLQJMIR0rOvA7PYDgbuAucBOkoZJGkI6PvYgMAM4OFt2HDCrZunNzKzf60sh\n+wGwsaQHgTuAY4HTgSOzeRsA10XEMmAicDep0E3KBn5MAxolzc7ue3LtX4aZmfVXfRm1uIw0hL6z\nMV0sOx2Y3mleGzCh2oBmZmY9cWcPMzMrNRcyMzMrNRcyMzMrNRcyMzMrNRcyMzMrNRcyMzMrNRcy\nMzMrNRcyMzMrNRcyMzMrNRcyMzMrNRcyMzMrNRcyMzMrNRcyMzMrNRcyMzMrNRcyMzMrNRcyMzMr\nNRcyMzMrtV6vEA0g6Vxg92z5ycDngB2BV7JFzouIOySNB44HVgBTImKqpAHAtcAWQBswISKerumr\nMDOzfqvXQiZpD2D7iPikpA2B3wL3ASdHxO0Vyw0GTgN2Bt4A5km6GRgHLIqI8ZI+QyqEh9b+pZiZ\nWX/Ul12LvwQOzqYXAYOBxi6W2wWYFxGLI2IZMAcYBewF3JwtMzObZ2ZmVhO9bpFFRBvwevbrMcCd\npF2Ex0k6EVgAHAeMAFor7roA2LRyfkSskNQuad2IeKNmr8LMzPqtPh0jA5B0AKmQfQb4OPBKRPxO\n0kTgDOChTndp6Oahupu/0vDhg2hq6mqjrzrNzUNr9li1VuRsfVHk/HllK/I6gWLnc7bq9PdsfR3s\n8VngFGCfiFgM3Ftx863A5cB00tZXh5HAw8D8bP6j2cCPht62xhYuXNrnF9Cb5uahtLYuqdnj1VKR\ns/VVkfPnka3o72mR8zlbdfpLtp4KYq/HyCS9FzgPGBsRr2bzfiZpq2yR0cDjwFxgJ0nDJA0hHQt7\nEJjBqmNs44BZ1b0MMzOzd+rLFtmhwEbAjZI65l0DTJO0FHiNNKR+Wbab8W6gHZgUEYslTQPGSJoN\nLAeOqvFrMDOzfqwvgz2mAFO6uOm6LpadTtrFWDmvDZhQbUAzM7OeuLOHmZmVmguZmZmVmguZmZmV\nmguZmZmVmguZmZmVmguZmZmVmguZmZmVmguZmZmVmguZmZmVmguZmZmVmguZmZmVmguZmZmVmguZ\nmZmVmguZmZmVmguZmZmVmguZmZmVmguZmZmVmguZmZmVWlNfFpJ0LrB7tvxkYB5wPdAIvAgcERHL\nJY0HjgdWAFMiYqqkAcC1wBZAGzAhIp6u9QsxM7P+qdctMkl7ANtHxCeBfYDvAmcCl0bE7sBTwNGS\nBgOnAXsDo4ETJG0AHA4siojdgO+QCqGZmVlN9GXX4i+Bg7PpRcBgUqG6NZt3G6l47QLMi4jFEbEM\nmAOMAvYCbs6WnZnNMzMzq4ledy1GRBvwevbrMcCdwGcjYnk2bwGwKTACaK246zvmR8QKSe2S1o2I\nN7p7zuHDB9HU1Li6r6Vbzc1Da/ZYtVbkbH1R5Px5ZSvyOoFi53O26vT3bH06RgYg6QBSIfsM8KeK\nmxq6ucvqzl9p4cKlfY3Vq+bmobS2LqnZ49VSkbP1VZHz55Gt6O9pkfM5W3X6S7aeCmKfRi1K+ixw\nCrBvRCwGXpM0MLt5JDA/+xlRcbd3zM8GfjT0tDVmZma2Ovoy2OO9wHnA2Ih4NZs9Ezgwmz4QuAuY\nC+wkaZikIaRjYQ8CM1h1jG0cMKt28c3MrL/ry67FQ4GNgBsldcw7ErhK0peB54DrIuJNSROBu4F2\nYFJELJY0DRgjaTawHDiqxq/BzMz6sb4M9pgCTOnipjFdLDsdmN5pXhswodqAZmZmPXFnDzMzKzUX\nMjMzKzUXMjMzKzUXMjMzKzUXMjMzKzUXMjMzKzUXMjMzKzUXMjMzKzUXMjMzKzUXMjMzKzUXMjMz\nKzUXMjMzKzUXMjMzKzUXMjMzKzUXMjMzKzUXMjMzKzUXMjMzK7VerxANIGl74Bbgooi4RNK1wI7A\nK9ki50XEHZLGA8cDK4ApETFV0gDgWmALoA2YEBFP1/ZlmJlZf9VrIZM0GLgYuLfTTSdHxO2dljsN\n2Bl4A5gn6WZgHLAoIsZL+gwwGTi0RvnNzKyf68uuxeXAfsD8XpbbBZgXEYsjYhkwBxgF7AXcnC0z\nM5tnZmZWE70Wsoh4KytMnR0n6T5JP5G0ETACaK24fQGwaeX8iFgBtEta991HNzMz6+Mxsi5cD7wS\nEb+TNBE4A3io0zIN3dy3u/krDR8+iKamxiqjvVNz89CaPVatFTlbXxQ5f17ZirxOoNj5nK06/T1b\nVYUsIiqPl90KXA5MJ219dRgJPEzaJTkCeDQb+NEQEW/09PgLFy6tJlaXmpuH0tq6pGaPV0tFztZX\nRc6fR7aiv6dFzuds1ekv2XoqiFUNv5f0M0lbZb+OBh4H5gI7SRomaQjpWNiDwAzg4GzZccCsap7T\nzMysK30ZtbgjcAGwJfCmpINIoxinSVoKvEYaUr8s2814N9AOTIqIxZKmAWMkzSYNHDlqjbwSMzPr\nl3otZBHxG9JWV2c/62LZ6aRdjJXz2oAJVeYzMzPrkTt7mJlZqbmQmZlZqbmQmZlZqbmQmZlZqbmQ\nmZlZqbmQmZlZqbmQmZlZqbmQmZlZqbmQmZlZqbmQmZlZqbmQmZlZqbmQmZlZqbmQmZlZqbmQmZlZ\nqbmQmZlZqbmQmZlZqbmQmZlZqbmQmZlZqTX1ZSFJ2wO3ABdFxCWS3gdcDzQCLwJHRMRySeOB44EV\nwJSImCppAHAtsAXQBkyIiKdr/1LMzKw/6nWLTNJg4GLg3orZZwKXRsTuwFPA0dlypwF7A6OBEyRt\nABwOLIqI3YDvAJNr+grMzKxf68uuxeXAfsD8inmjgVuz6dtIxWsXYF5ELI6IZcAcYBSwF3BztuzM\nbJ6ZmVlN9LprMSLeAt6SVDl7cEQsz6YXAJsCI4DWimXeMT8iVkhql7RuRLzR3XMOHz6IpqbG1Xoh\nPWluHlqzx6q1ImfriyLnzytbkdcJFDufs1Wnv2fr0zGyXjTUaP5KCxcurT5NJ83NQ2ltXVKzx6ul\nImfrqyLnzyNb0d/TIudztur0l2w9FcRqRy2+JmlgNj2StNtxPmnri+7mZwM/GnraGjMzM1sd1Ray\nmcCB2fSBwF3AXGAnScMkDSEdC3sQmAEcnC07DphVfVwzM7O363XXoqQdgQuALYE3JR0EjAeulfRl\n4Dnguoh4U9JE4G6gHZgUEYslTQPGSJpNGjhy1Bp5JWZm1i/1ZbDHb0ijFDsb08Wy04Hpnea1AROq\nzGdmZtYjd/YwM7NScyEzM7NScyEzM7NScyEzM7NScyEzM7NScyEzM7NScyEzM7NScyEzM7NScyEz\nM7NScyEzM7NScyEzM7NScyEzM7NScyEzM7NScyEzM7NScyEzM7NScyEzM7NScyEzM7NS6/UK0V2R\nNBr4KfBENusx4FzgeqAReBE4IiKWSxoPHA+sAKZExNR3G9rMzKzDu9kieyAiRmc/XwPOBC6NiN2B\np4CjJQ0GTgP2BkYDJ0ja4N2GNjMz61DLXYujgVuz6dtIxWsXYF5ELI6IZcAcYFQNn9PMzPq5qnYt\nZraVdCuwATAJGBwRy7PbFgCbAiOA1or7dMw3MzOriWoL2Z9IxetGYCtgVqfHaujmft3Nf5vhwwfR\n1NRYZbR3am4eWrPHqrUiZ+uLIufPK1uR1wkUO5+zVae/Z6uqkEXEC8C07Nc/S/obsJOkgdkuxJHA\n/OxnRMVdRwIP9/b4CxcurSZWl5qbh9LauqRmj1dLRc7WV0XOn0e2or+nRc7nbNXpL9l6KohVHSOT\nNF7S17PpEcAmwDXAgdkiBwJ3AXNJBW6YpCGk42MPVvOcZmZmXal21+KtwA2SDgDWBb4C/Bb4oaQv\nA88B10XEm5ImAncD7cCkiFhcg9xmdXf0OffV7LGunrhnzR7LrL+rdtfiEmBcFzeN6WLZ6cD0ap7H\nzMysN+7sYWZmpeZCZmZmpeZCZmZmpeZCZmZmpeZCZmZmpeZCZmZmpeZCZmZmpeZCZmZmpeZCZmZm\npeZCZmZmpeZCZmZmpeZCZmZmpeZCZmZmpVbtZVzMrEB8iRnrz7xFZmZmpeZCZmZmpeZdi2uId/WY\nmdWHC5mZWQH5y3Df1aWQSboI+ATQDvxnRMyrx/Oamdnab40XMkmfBraJiE9K+jBwNfDJNf28Zma9\n8VbP2qEegz32An4OEBF/AIZLek8dntfMzPqBhvb29jX6BJKmAHdExC3Z7w8Cx0TEH9foE5uZWb+Q\nx/D7hhye08zM1lL1KGTzgREVv28GvFiH5zUzs36gHoVsBnAQgKSPAfMjYkkdntfMzPqBNX6MDEDS\nOcCngBXAsRHx6Bp/UjMz6xfqUsjMzMzWFPdaNDOzUnMhMzOzUnOvxRxIagI2B16MiOV55+lM0viI\n+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\n"},"metadata":{}}],"source":"from multiprocessing import Pool, cpu_count\n\ndef im_multi(path):\n    try:\n        im_stats_im_ = Image.open(path)\n        return [path, {'size': im_stats_im_.size}]\n    except:\n        print(path)\n        return [path, {'size': [0,0]}]\n\ndef im_stats(im_stats_df):\n    im_stats_d = {}\n    p = Pool(cpu_count())\n    ret = p.map(im_multi, im_stats_df['path'])\n    for i in range(len(ret)):\n        im_stats_d[ret[i][0]] = ret[i][1]\n    im_stats_df['size'] = im_stats_df['path'].map(lambda x: ' '.join(str(s) for s in im_stats_d[x]['size']))\n    return im_stats_df\n\ntrain = im_stats(train)\nsizes = train.groupby('size', as_index=False)['path'].count()\n_ = sizes.plot(kind='bar', x='size', y='path', figsize=(7,4))"},{"cell_type":"code","execution_count":6,"metadata":{"_cell_guid":"e9dc439e-3e27-a97c-aac7-1cf90d44b461","_uuid":"b7367df78de31f650c86179612b4036f6356c390","_execution_state":"idle"},"outputs":[{"output_type":"execute_result","data":{"text/plain":"        size  path\n0        0 0     3\n1  2322 4128    94\n2  2448 3264  3911\n3  3096 4128  3508\n4  3120 4160   430\n5  3264 2448   157\n6  4128 3088     1\n7  4128 3096    38\n8    480 640    72\n9    640 480     1","text/html":"<div>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>size</th>\n      <th>path</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>0 0</td>\n      <td>3</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>2322 4128</td>\n      <td>94</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>2448 3264</td>\n      <td>3911</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>3096 4128</td>\n      <td>3508</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>3120 4160</td>\n      <td>430</td>\n    </tr>\n    <tr>\n      <th>5</th>\n      <td>3264 2448</td>\n      <td>157</td>\n    </tr>\n    <tr>\n      <th>6</th>\n      <td>4128 3088</td>\n      <td>1</td>\n    </tr>\n    <tr>\n      <th>7</th>\n      <td>4128 3096</td>\n      <td>38</td>\n    </tr>\n    <tr>\n      <th>8</th>\n      <td>480 640</td>\n      <td>72</td>\n    </tr>\n    <tr>\n      <th>9</th>\n      <td>640 480</td>\n      <td>1</td>\n    </tr>\n  </tbody>\n</table>\n</div>"},"metadata":{},"execution_count":6}],"source":"sizes"},{"cell_type":"code","execution_count":7,"metadata":{"_cell_guid":"5e0848ba-bc9b-9690-82ce-eaa9be0f1d21","_uuid":"13f0a6780984956b5d687e0d48f2372ee2f27166","_execution_state":"idle"},"outputs":[{"output_type":"execute_result","data":{"text/plain":"     type     image                            path       size\n0  Type_1     0.jpg     ../input/train/Type_1/0.jpg  2448 3264\n1  Type_1    10.jpg    ../input/train/Type_1/10.jpg  3096 4128\n2  Type_1  1013.jpg  ../input/train/Type_1/1013.jpg  2448 3264\n3  Type_1  1014.jpg  ../input/train/Type_1/1014.jpg  3096 4128\n4  Type_1  1019.jpg  ../input/train/Type_1/1019.jpg  2448 3264","text/html":"<div>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>type</th>\n      <th>image</th>\n      <th>path</th>\n      <th>size</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>Type_1</td>\n      <td>0.jpg</td>\n      <td>../input/train/Type_1/0.jpg</td>\n      <td>2448 3264</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>Type_1</td>\n      <td>10.jpg</td>\n      <td>../input/train/Type_1/10.jpg</td>\n      <td>3096 4128</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>Type_1</td>\n      <td>1013.jpg</td>\n      <td>../input/train/Type_1/1013.jpg</td>\n      <td>2448 3264</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>Type_1</td>\n      <td>1014.jpg</td>\n      <td>../input/train/Type_1/1014.jpg</td>\n      <td>3096 4128</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>Type_1</td>\n      <td>1019.jpg</td>\n      <td>../input/train/Type_1/1019.jpg</td>\n      <td>2448 3264</td>\n    </tr>\n  </tbody>\n</table>\n</div>"},"metadata":{},"execution_count":7}],"source":"train.head()"},{"cell_type":"code","execution_count":8,"metadata":{"_cell_guid":"84638367-441e-1d47-cf38-89fc808f5bce","_uuid":"491059f878c5560db7bcc2ed7022ccbe00d8e0fe","_execution_state":"idle"},"outputs":[],"source":"train.to_csv('train4.csv', index=False)"},{"cell_type":"markdown","metadata":{"_cell_guid":"5c799d7e-2d77-4c36-0b05-ec2bbabcb706","_uuid":"e226e829b843b217c2eaa6e9c1ca4ad34ba663a7"},"source":"Train and Test\n==============","outputs":[],"execution_count":null},{"cell_type":"code","execution_count":9,"metadata":{"_cell_guid":"6b76a788-1e32-08c5-f010-604c82fb8b31","_uuid":"d3485c1d0c9087285e6e6454ef3f9bb0244aa534","_execution_state":"idle"},"outputs":[{"output_type":"stream","name":"stderr","text":"Using TensorFlow backend.\n"},{"output_type":"stream","name":"stdout","text":"8215\n"}],"source":"from sklearn.model_selection import GridSearchCV, StratifiedKFold\nfrom sklearn.preprocessing import LabelEncoder\nfrom keras.wrappers.scikit_learn import KerasClassifier\nfrom keras.models import Sequential\nfrom keras.layers.core import Dense, Dropout, Flatten\nfrom keras.layers.convolutional import Convolution2D, ZeroPadding2D, MaxPooling2D\nfrom keras import optimizers\n\ndef get_im_cv2(path):\n    img = cv2.imread(path)\n    resized = cv2.resize(img, (64, 64), cv2.INTER_LINEAR)\n    return [path, resized]\n\ndef normalize_image_features(paths):\n    imf_d = {}\n    p = Pool(cpu_count())\n    ret = p.map(get_im_cv2, paths)\n    for i in range(len(ret)):\n        imf_d[ret[i][0]] = ret[i][1]\n    ret = []\n    fdata = [imf_d[f] for f in paths]\n    fdata = np.array(fdata, dtype=np.uint8)\n    fdata = fdata.transpose((0, 3, 1, 2))\n    fdata = fdata.astype('float32')\n    fdata = fdata / 255\n    return fdata\n\n#train = glob.glob('../input/train/**/*.jpg') + glob.glob('../input/additional/**/*.jpg')\nprint(len(train))\n#train = pd.DataFrame([[p.split('/')[3],p.split('/')[4],p] for p in train], columns = ['type','image','path'])\ntrain = train[train['size'] != '0 0'].reset_index(drop=True) #remove bad images\ntrain_data = normalize_image_features(train['path'])\nle = LabelEncoder()\ntrain_target = le.fit_transform(train['type'].values)"},{"cell_type":"code","execution_count":10,"metadata":{"_cell_guid":"53889cad-abd6-402d-714d-d4f4b10f877d","_uuid":"f2f8ce4c34dd446bff0c7398534836f39a509783","_execution_state":"idle"},"outputs":[],"source":"# Normalize test data\ntest_data = normalize_image_features(test['path'])\ntest_id = test.image.values  \n\nimport pickle\ndef save_object(obj, filename):\n    with open(filename, 'wb') as output:\n        pickle.dump(obj, output, -1)\n   \n# Saving the processed data\nsave_object(train_data, 'processedTrainData_4.pkl')\nsave_object(train_target, 'processeTargetData_4.pkl')\nsave_object(test_data, 'processeTestData_4.pkl')"},{"cell_type":"code","execution_count":11,"metadata":{"_cell_guid":"89954c0c-952b-a092-d2f1-98842222c5f9","_uuid":"b458455be6e52485de2adc7449b97ec8fa6e79fc","_execution_state":"idle"},"outputs":[],"source":"save_object(test_id, 'processeTestID_4.pkl')"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"f23372e9-72ac-9bb4-05e4-a3113238e0d5","_uuid":"410b0d759f5be7e0d4071ed11b50e0b12fc08aff"},"outputs":[],"source":"from sklearn.model_selection import GridSearchCV, StratifiedKFold\nfrom sklearn.preprocessing import LabelEncoder\nfrom keras.wrappers.scikit_learn import KerasClassifier\nfrom keras.models import Sequential\nfrom keras.layers.core import Dense, Dropout, Flatten\nfrom keras.layers.convolutional import Convolution2D, ZeroPadding2D, MaxPooling2D\nfrom keras import optimizers\n\ndef get_im_cv2(path):\n    img = cv2.imread(path)\n    resized = cv2.resize(img, (64, 64), cv2.INTER_LINEAR)\n    return [path, resized]\n\ndef normalize_image_features(paths):\n    imf_d = {}\n    p = Pool(cpu_count())\n    ret = p.map(get_im_cv2, paths)\n    for i in range(len(ret)):\n        imf_d[ret[i][0]] = ret[i][1]\n    ret = []\n    fdata = [imf_d[f] for f in paths]\n    fdata = np.array(fdata, dtype=np.uint8)\n    fdata = fdata.transpose((0, 3, 1, 2))\n    fdata = fdata.astype('float32')\n    fdata = fdata / 255\n    return fdata\n\n#train = glob.glob('../input/train/**/*.jpg') + glob.glob('../input/additional/**/*.jpg')\nprint(len(train))\n#train = pd.DataFrame([[p.split('/')[3],p.split('/')[4],p] for p in train], columns = ['type','image','path'])\ntrain = train[train['size'] != '0 0'].reset_index(drop=True) #remove bad images\ntrain_data = normalize_image_features(train['path'])\nle = LabelEncoder()\ntrain_target = le.fit_transform(train['type'].values)\n\n# Normalize test data\ntest_data = normalize_image_features(test['path'])\ntest_id = test.image.values  "},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"5a47d006-b6a9-f1ee-199e-2537c7524ccc","_uuid":"43d30adfea7dfa29f86ebf017fa5e26639726043"},"outputs":[],"source":"import pickle\n\ndef save_object(obj, filename):\n    with open(filename, 'wb') as output:\n        pickle.dump(obj, output, -1)\n   \n# Save the processed data\nsave_object(train_data, 'processeTtrainData.pkl')\nsave_object(train_target, 'processeTargetData.pkl')\nsave_object(test_data, 'processeTestData.pkl')"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"2023476f-df2c-07e8-b2e0-3ca2f1a63ae1","_uuid":"fd3b195b41ee32f5bff1488ae788cb1f403d2ec8"},"outputs":[],"source":"def create_model(opt_):\n    model = Sequential()\n    model.add(ZeroPadding2D((1, 1), input_shape=(3, 64, 64), dim_ordering='th'))\n    model.add(Convolution2D(8, 3, 3, activation='relu', dim_ordering='th'))\n    model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2), dim_ordering='th'))\n    model.add(Dropout(0.2))\n    model.add(Dense(12, activation='relu'))\n    model.add(Dropout(0.2))\n    model.add(Dense(6, activation='relu'))  \n    model.add(Flatten())\n    model.add(Dense(3, activation='softmax'))\n\n    model.compile(optimizer=opt_, loss='categorical_crossentropy', metrics=['accuracy']) #loss='binary_crossentropy' not working\n    return model\n\nmodel = KerasClassifier(build_fn=create_model, nb_epoch=5, batch_size=20, verbose=2)\nopts_ = ['adamax'] #['adadelta','sgd','adagrad','adam','adamax']\nepochs = np.array([10])\nbatches = np.array([10])\nparam_grid = dict(nb_epoch=epochs, batch_size=batches, opt_=opts_)\ngrid = GridSearchCV(estimator=model, cv=StratifiedKFold(n_splits=2), param_grid=param_grid, verbose=20)\ngrid_result = grid.fit(train_data, train_target)\n\nprint(\"Best: %f using %s\" % (grid_result.best_score_, grid_result.best_params_))\nfor params, mean_score, scores in grid_result.grid_scores_:\n    print(\"%f (%f) with: %r\" % (scores.mean(), scores.std(), params))\n\ntest_data = normalize_image_features(test['path'])\ntest_id = test.image.values\n\npred = grid_result.predict_proba(test_data)\ndf = pd.DataFrame(pred, columns=le.classes_)\ndf['image_name'] = test_id\ndf.to_csv('submission.csv', index=False)"},{"cell_type":"code","execution_count":null,"metadata":{"_cell_guid":"23d35376-f29f-ce66-761e-e8f22d299cdd","_uuid":"fccb8c0cc10f988ded9a6d6612eee5206bc5971c"},"outputs":[],"source":"df.head()"}],"metadata":{"_change_revision":0,"_is_fork":false,"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.0","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":0}