{"cells":[{"metadata":{"_uuid":"b95773e3f997e10b54fb9ff8cc0f4c19649aac21"},"cell_type":"markdown","source":"We all like to play around with data and get things done. In this kernel I'll show you how you can do it yourself.\n## Full Video Explanation of this Notebook\n[KAGGLE KERNELS 2019](https://www.youtube.com/watch?v=AXcTm4gFerE)\n\nI also have a full explanation on how to work with large Image datasets ( like this one :D ) \n[How to Deal with Large Image Datasets](https://www.youtube.com/watch?v=myYMrZXpn6U) and you can check out the [Kernel](https://www.kaggle.com/jhonatansilva31415/loading-all-whales-into-memory)\n\n## Notebook Content\n1. [Resources](#zeroth-bullet)\n2. [Some libraries we need to get things done](#first-bullet)\n3. [How to load the dataset](#second-bullet)\n4. [Looking at 5 random beauties](#third-bullet)\n5. [Preprocessing the data](#forth-bullet)<br/>\n     5.1 [Using python OpenCV](#forth1-bullet)<br/>\n     5.2 [Using torchvision](#forth2-bullet)<br/>\n6. [Cleaning the Data](#fifth-bullet)\n7. [Encoding](#fifth-bullet)\n8. [Handling the dataset](#sixth-bullet)\n9. [Building a very simple sequential model](#seventh-bullet)\n10. [Conclusion](#eighth-bullet)"},{"metadata":{"_uuid":"19e87d7741b836281b2bc24e5a5b23ce4779ff08"},"cell_type":"markdown","source":"### Resources <a class=\"anchor\" id=\"zeroth-bullet\"></a>\nI'm currently making a video series explaining step by step this kernel, if this sounds interesting, here are the links \n1. [Introduction](https://www.youtube.com/watch?v=pD_IR72g5tE&t=1s)\n2. [Libraries](https://www.youtube.com/watch?v=2iRIPjXTGeY&t=1s) "},{"metadata":{"_uuid":"0b54aa34e77a39a4c864b533e577a9cf8565158d"},"cell_type":"markdown","source":"### Some libraries we need to get things done <a class=\"anchor\" id=\"first-bullet\"></a>"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"_kg_hide-output":false},"cell_type":"code","source":"import numpy as np \nimport pandas as pd \nimport matplotlib.pyplot as plt\nimport cv2\nimport os\nfrom PIL import Image\n\nfrom matplotlib.pyplot import imshow\nfrom IPython.display import HTML\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ed191b99b82410112505c26ac5568069af621000"},"cell_type":"markdown","source":"### Working with files\nIt's always a pain in the ass to work with paths, when I was starting I almost have all my paths hardcoded. When working with teams I saw that this approach isn't get me anywhere, it's always, ok, in most cases, a great idea to store your general paths into variables."},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"print(os.listdir('../input'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b7591856ae9cf424679b6485db1f65700ee41f18"},"cell_type":"code","source":"img_train_path = os.path.abspath('../input/train')\nimg_test_path = os.path.abspath('../input/test')\ncsv_train_path = os.path.abspath('../input/train.csv')\ncsv_train_path","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"237d5dc7f70f83858067789f6b23cd06f894e99f"},"cell_type":"markdown","source":"### How to load the dataset <a class=\"anchor\" id=\"second-bullet\"></a>\nWe'll use here the [Pandas](https://pandas.pydata.org/pandas-docs/stable/) to load the dataset into memory"},{"metadata":{"trusted":true,"_uuid":"cd7fac33136c9a7e44578940f590e855ce020f43","_kg_hide-output":true},"cell_type":"code","source":"df = pd.read_csv(csv_train_path)\ndf.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ae7db9eded67319f72b300bd6c9e3a0656945a96"},"cell_type":"markdown","source":"We can see that we have the paths of the images and the labels associated with the whales. To easy the image reading process we can create a aditional column to the dataset with the global path of the images"},{"metadata":{"trusted":true,"_uuid":"531964c6933a4c6be51aca9820398d650006fb5b"},"cell_type":"code","source":"df['Image_path'] = [os.path.join(img_train_path,whale) for whale in df['Image']]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4340760de73ee433710622c2fbe41790f182d1dd"},"cell_type":"code","source":"df.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"c46738add46adc9cb07eeac11538edfe7366a44f"},"cell_type":"markdown","source":"### Looking at 5 random beauties  <a class=\"anchor\" id=\"third-bullet\"></a>\nIt's a great deal of fun to explore the data and play around with *matplotlib*"},{"metadata":{"trusted":true,"_uuid":"34d4cd3d24022ac395cfee7f34ed60f5b73547ad"},"cell_type":"code","source":"full_path_random_whales = np.random.choice(df['Image_path'],5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2b337d50f6ba17f6f12bdc0c8a61265be176fcca"},"cell_type":"code","source":"full_path_random_whales","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"73c9dc60723e69d2536694684355603cecd8178b"},"cell_type":"code","source":"%matplotlib inline\nfor whale in full_path_random_whales:\n    img = Image.open(whale)\n    plt.imshow(img)\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8719866bb4625f1d169bb37af118ce411bb1fa44"},"cell_type":"markdown","source":"### Preprocessing the data <a class=\"anchor\" id=\"forth-bullet\"></a>\nI could find some cool resources to help me put all this together. You'll find it extremely usefull\n* [DATA LOADING AND PROCESSING TUTORIAL](https://pytorch.org/tutorials/beginner/data_loading_tutorial.html)\n* [Lecture Notes: Basic Image Processing](https://www.cs.virginia.edu/~vicente/recognition/notebooks/image_processing_lab.html)\n* [PyTorch quick start: Classifying an image](http://blog.outcome.io/pytorch-quick-start-classifying-an-image/)\n\n\nHere we're going to use 2 approaches, basic OpenCv and PyTorch."},{"metadata":{"trusted":true,"_uuid":"92ae34854974bd5fe683235587e62b5de40ffee1"},"cell_type":"code","source":"from torchvision import transforms","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"3f9bcee9a05e30052b185f0d4df3ac1e1865b998"},"cell_type":"markdown","source":"#### Using python OpenCV <a class=\"anchor\" id=\"forth1-bullet\"></a>\nOpenCV is a great, great, computer vision library. Here I just use the basics of it, but you can go wild with OpenCv. We are going to use to scale the images down and convert to grayscale"},{"metadata":{"trusted":true,"_uuid":"81bd1108a45ca6334045bfcbc2530cbb31efb410"},"cell_type":"code","source":"img = cv2.imread(full_path_random_whales[0])\nimg = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)\nres = cv2.resize(img, dsize=(128, 128), interpolation=cv2.INTER_CUBIC)\nplt.imshow(res,cmap='gray')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"6ef605051312751928b140aa6fe38af821b2ad58"},"cell_type":"markdown","source":"#### Using torchvision <a class=\"anchor\" id=\"forth2-bullet\"></a>\nPyTorch is a library developed by Facebook, the torchvision module has some convenient features, like we're using here\n* Convert to grayscale\n* Resize\n* Corp\n* Transform to tensor\n* Normalize"},{"metadata":{"trusted":true,"_uuid":"df55e56322ec96daefc422b86a4cea5ffca7f9d6"},"cell_type":"code","source":"normalize = transforms.Normalize(\n   mean=[0.485, 0.456, 0.406],\n   std=[0.229, 0.224, 0.225]\n)\npreprocess = transforms.Compose([\n   transforms.Grayscale(num_output_channels=1),\n   transforms.Resize(128),\n   transforms.CenterCrop(128),\n   transforms.ToTensor(),\n   normalize\n])\nimgs = [Image.open(whale) for whale in full_path_random_whales]\nimgs_tensor = [preprocess(whale) for whale in imgs]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e718f5b47b5c7226960d534a2d8c9c74fa286126"},"cell_type":"code","source":"imgs_tensor[0].shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0fcb3d91a5378e3494b55507d1bc6bfd1c460ddf"},"cell_type":"code","source":"img = imgs_tensor[0]\nplt.imshow(img[0],cmap='gray')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"47f6fa6842f01866761a2f0f7af7e168e773d702"},"cell_type":"markdown","source":"### Cleaning the Data <a class=\"anchor\" id=\"fifth-bullet\"></a>\n[Why removing new_whale is a good idea](https://www.kaggle.com/suicaokhoailang/removing-class-new-whale-is-a-good-idea)\n\nWorking with biases datasets is a huge problem, you can look more in this blog I posted a while ago also using data from a Kaggle competition \n\n[Why you should care about bias.](https://jhonatandasilva.com/bias-in-ai/)"},{"metadata":{"trusted":true,"_uuid":"db7521ae4dc62b96980a9dae56e6fa18d41189bd"},"cell_type":"code","source":"df.Id.value_counts().head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"6cffe02397ac009979c88d500fae0e0bdbbbe980"},"cell_type":"markdown","source":"We can create a new dataframe just for testing purposes without the new_whale class"},{"metadata":{"trusted":true,"_uuid":"f62127c324b48331ab1d5675e1f17c72ebff3a26"},"cell_type":"code","source":"I_dont_want_new_whales = df['Id'] != 'new_whale'\ndf = df[I_dont_want_new_whales]\ndf.Id.value_counts().head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"5ba3c7eadbf49b79f166bf8ed731bd4b0ae0a335"},"cell_type":"markdown","source":"### Encoding <a class=\"anchor\" id=\"sixth-bullet\"></a>\nTo further use torchvision we need to encode our data, here's how you can do it"},{"metadata":{"trusted":true,"_uuid":"91cf4c1957c63305158fc2a22934e770f6cb7b9b"},"cell_type":"code","source":"unique_classes = pd.unique(df['Id'])\nencoding = dict(enumerate(unique_classes))\nencoding = {value: key for key, value in encoding.items()}\ndf = df.replace(encoding)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4251b223f858bd063b092f41cd0f376837af13f0"},"cell_type":"code","source":"df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0de2f6f5ea7089df7df297daa97e07baed981d76"},"cell_type":"markdown","source":"### Handling the dataset <a class=\"anchor\" id=\"sixth-bullet\"></a>\n(Don't do this in your personal computer, this isn't a great way to open your images, just for test purposes)"},{"metadata":{"trusted":true,"_uuid":"b56bd9b5fbaaaf9494d693ec2de76d79bfb539b5"},"cell_type":"code","source":"import torch\nimport torch.nn.functional as F\nfrom torchvision import datasets, transforms\nfrom torch import nn\nfrom torch import optim\nfrom torch.utils.data import Dataset, DataLoader","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"0274012ef5d32de0d07ffbbed3a5fcb73ef33740"},"cell_type":"markdown","source":"#### Simple model\nAs we are going to construct a simple sequencial linear model we will load just 1000 images to test it out"},{"metadata":{"trusted":true,"_uuid":"3e7e9ea12194a2e1b2d7ffb42f92a6724bf0bbfe"},"cell_type":"code","source":"test = df['Image_path'][:1000]\nimgs = [Image.open(whale) for whale in test]\nimgs_tensor = torch.stack([preprocess(whale) for whale in imgs])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"981abaa66655138e391d74731377c55107b6105f"},"cell_type":"code","source":"labels = torch.tensor(df['Id'][:1000].values)\nmax_label = int(max(labels)) +1\nmax_label","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"299470e7dfeddf025660ceba60eee62856162da7"},"cell_type":"code","source":"plt.imshow(imgs_tensor[0].reshape(128,128),cmap='gray')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ca40a7803024d5269b28e7abc1de483d52b5cfac"},"cell_type":"markdown","source":"### Building a very simple sequential model <a class=\"anchor\" id=\"seventh-bullet\"></a>\n\nThis is a great way to play around if you are a begginner in the area. If you don't know much from building Neural Networks I have a few resources \n\n1. [Creating a Perceptron](https://jhonatandasilva.com/build-your-own-perceptron/)\n2. [What are the building blocks of Deep Learning](https://jhonatandasilva.com/perceptrons/) \n3. [Play around with Neural Nets](https://jhonatandasilva.com/play-with-nn/)\n4. [Training your Neural Net](https://jhonatandasilva.com/training-your-neural-networks/)\n5. [When all comes together](https://jhonatandasilva.com/mnist-pytorch/) \n\nExploring more on the Vision side there's also\n\n1. [How Neural Nets sees the world ](https://jhonatandasilva.com/how-nn-sees-the-world/)\n2. [How to build your CNN with Keras](https://youtu.be/lkvzqfhgITM)"},{"metadata":{"_uuid":"8cc064d308aa1148199079d694e85c9233cbfb00"},"cell_type":"markdown","source":"### I know I know\nWe are all busy people and don't have time to waste in a bunch of blogs posts, so I'll give it to you straight. I've created some animations to explain better how the model bellow works ( I like art, sue me )\n\n#### THE VISION SIDE\nWe are **NOT** using Convolutional Neural Networks here, so we need to feed our Neural Net a flatten vector, but what does that mean? We get our 128x128 our what side do you choose and transform into a one dimensional vector\n\n<img src=\"https://jhonatandasilva.com/wp-content/uploads/2018/12/flattening.gif\" alt=\"drawing\" width=\"200\"/>\n\n### THE NEURAL NET SIDE\n\nOk, now we have our one dimensional vector, what do we do? We feed one by one into our neural net and it gives out a probability for the whale class\n\n<img src=\"https://jhonatandasilva.com/wp-content/uploads/2018/12/nn.gif\" alt=\"drawing\" width=\"600\"/>\n\n"},{"metadata":{"trusted":true,"_uuid":"c3108ef8c4d373e869f185f9974d2307233ee788"},"cell_type":"code","source":"model = nn.Sequential(nn.Linear(128*128, 256),\n                      nn.Sigmoid(),\n                      nn.Linear(256, 128),\n                      nn.Sigmoid(),\n                      nn.Linear(128, max_label),\n                      nn.LogSoftmax(dim=1))\n\noptimizer = optim.SGD(model.parameters(), lr=0.01)\ncriterion = nn.NLLLoss()\n\nmodel","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e5f31c1983f38f667cc2cc55867df45db7e9479c"},"cell_type":"code","source":"epochs = 5\nbatch_size = 10\niters = int(len(imgs_tensor)/batch_size)\nnext_batch = 0\nfor e in range(epochs):\n    running_loss = 0\n    next_batch = 0\n    for n in range(iters):\n        batch_images = imgs_tensor[next_batch:next_batch+batch_size] \n        batch_images = batch_images.view(batch_images.shape[0], -1)\n        batch_labels = labels[next_batch:next_batch+batch_size]\n        \n        optimizer.zero_grad()\n        \n        output = model(batch_images)\n        loss = criterion(output, batch_labels)\n        \n        loss.backward()\n        optimizer.step()\n        \n        running_loss += loss.item()\n        \n        next_batch += batch_size\n        \n    print(running_loss)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e35f831da1e3b72f9661ebf0dae0851e414829d0"},"cell_type":"markdown","source":"### Huge Loss, but very simple code to play around <a class=\"anchor\" id=\"eighth-bullet\"></a>\nThis is a huuuuge loss (considering we just used 1000 images), but this tutorial is made to make things simple and feel the data. From here you can play around with MLPs or CNNs. Convolutional Neural Nets are great, instead of losing all the spatial information when flattennig the image, we can understand images much better, it solves this problem by working with the weights and biases.\n\n<img src=\"https://jhonatandasilva.com/wp-content/uploads/2018/12/cnns.gif\" alt=\"drawing\" width=\"400\"/>\n\nYou can Look it up more resources on CNNs here\n\n* [CNNs made it easy](https://jhonatandasilva.com/cnns-made-it-easy/) \n* [How the layers of CNNs works](https://jhonatandasilva.com/cnns-layers/)\n* [How to build your CNN with Keras](https://youtu.be/lkvzqfhgITM)\n\n"}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}