{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Intro into Computer Vision in Biology"},{"metadata":{},"cell_type":"markdown","source":"![](https://storage.googleapis.com/kaggle-competitions/kaggle/11848/logos/header.png?t=2018-11-15-01-52-19)"},{"metadata":{},"cell_type":"markdown","source":"![](https://eenews.cdnartwhere.eu/sites/default/files/styles/facebook/public/sites/default/files/images/2017-11-16-s20_deep_learning_algorithm_x-ray_machine_radiologist.jpg?itok=LCwsyE8T)"},{"metadata":{},"cell_type":"markdown","source":"# Neural networks"},{"metadata":{},"cell_type":"markdown","source":"![Neuron](https://upload.wikimedia.org/wikipedia/commons/6/60/ArtificialNeuronModel_english.png)"},{"metadata":{},"cell_type":"markdown","source":"### Backpropagation"},{"metadata":{},"cell_type":"markdown","source":"* Loss function\n* Function minimization"},{"metadata":{},"cell_type":"markdown","source":"$$ L(\\textbf{w})  = \\frac{1}{2}  \\sum_{n=1}^{N} (\\hat{y_n} - y_n )^2$$"},{"metadata":{},"cell_type":"markdown","source":"$$w_{i}:= w_{i} - \\eta {\\frac{\\partial{L}}{\\partial{w_{i}}}}$$"},{"metadata":{},"cell_type":"markdown","source":"![](https://www-cdn.qwertee.io/media/uploads/blog/backpropagation/backpropagation.png)"},{"metadata":{},"cell_type":"markdown","source":"![](https://upload.wikimedia.org/wikipedia/commons/thumb/1/1e/Extrema_example.svg/1920px-Extrema_example.svg.png)"},{"metadata":{},"cell_type":"markdown","source":"### [Tensorflow playground](https://playground.tensorflow.org/#activation=tanh&batchSize=10&dataset=circle&regDataset=reg-plane&learningRate=0.03&regularizationRate=0&noise=0&networkShape=4,2&seed=0.21509&showTestData=false&discretize=false&percTrainData=50&x=true&y=true&xTimesY=false&xSquared=false&ySquared=false&cosX=false&sinX=false&cosY=false&sinY=false&collectStats=false&problem=classification&initZero=false&hideText=false)"},{"metadata":{},"cell_type":"markdown","source":"# PyTorch"},{"metadata":{},"cell_type":"markdown","source":"![](https://upload.wikimedia.org/wikipedia/commons/9/96/Pytorch_logo.png)"},{"metadata":{"trusted":true},"cell_type":"code","source":"from __future__ import print_function\nimport torch\nimport numpy as np","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Torch tensor"},{"metadata":{},"cell_type":"markdown","source":"torch.Tensor is the central class of the package "},{"metadata":{"trusted":true},"cell_type":"code","source":"x = torch.zeros(5, 3)\nprint(x)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x = torch.zeros(5, 3, 2)\nprint(x)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x = torch.rand(5, 3)\nprint(x)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Converting a Torch Tensor to a NumPy Array"},{"metadata":{"trusted":true},"cell_type":"code","source":"a = torch.ones(5)\nb = a.numpy()\nprint(b)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"a = np.ones(5)\nb = torch.from_numpy(a)\nnp.add(a, 1, out=a)\nprint(a)\nprint(b)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Run on GPU"},{"metadata":{},"cell_type":"markdown","source":"![](https://hyperpc.ru/images/company/news/nvidia-titan-v/content/nvidia-titan-v-shroud-td.png)"},{"metadata":{},"cell_type":"markdown","source":"### CUDA Tensors"},{"metadata":{"trusted":true},"cell_type":"code","source":"# let us run this cell only if CUDA is available\n# We will use ``torch.device`` objects to move tensors in and out of GPU\nif torch.cuda.is_available():\n    device = torch.device(\"cuda\")          # a CUDA device object\n    y = torch.ones_like(x, device=device)  # directly create a tensor on GPU\n    x = x.to(device)                       # or just use strings ``.to(\"cuda\")``\n    z = x + y\n    print(z)\n    print(z.to(\"cpu\", torch.double))       # ``.to`` can also change dtype together!","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## AUTOGRAD: AUTOMATIC DIFFERENTIATION"},{"metadata":{},"cell_type":"markdown","source":"torch.Tensor hass attribute: .requires_grad"},{"metadata":{},"cell_type":"markdown","source":"If you set its attribute .requires_grad as True, it starts to track all operations on it. "},{"metadata":{"trusted":true},"cell_type":"code","source":"x = torch.ones(2, 2, requires_grad=True)\nprint(x)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y = x + 2\nprint(y)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"y was created as a result of an operation, so it has a grad_fn."},{"metadata":{"trusted":true},"cell_type":"code","source":"print(y.grad_fn)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"z = y * y * 3\nout = z.mean()\n\nprint(z, out)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"When you finish your computation you can call .backward() and have all the gradients computed automatically. The gradient for this tensor will be accumulated into .grad attribute."},{"metadata":{},"cell_type":"markdown","source":"### Let’s backprop now"},{"metadata":{"trusted":true},"cell_type":"code","source":"out.backward()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(x.grad) #Print gradients d(out)/dx","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Calculate it manually"},{"metadata":{"trusted":true},"cell_type":"markdown","source":"### [Cheatsheet convolutional neural networks](https://stanford.edu/~shervine/teaching/cs-230/cheatsheet-convolutional-neural-networks)"},{"metadata":{},"cell_type":"markdown","source":"![](https://pytorch.org/tutorials/_images/mnist.png)"},{"metadata":{},"cell_type":"markdown","source":"### Convolution layers"},{"metadata":{},"cell_type":"markdown","source":"![](https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/3D_Convolution_Animation.gif/220px-3D_Convolution_Animation.gif)"},{"metadata":{},"cell_type":"markdown","source":"![](https://miro.medium.com/max/526/1*GcI7G-JLAQiEoCON7xFbhg.gif)"},{"metadata":{},"cell_type":"markdown","source":"![](https://miro.medium.com/max/326/1*NsiYxt8tPDQyjyH3C08PVA@2x.png)"},{"metadata":{},"cell_type":"markdown","source":"![](https://miro.medium.com/max/1280/1*ciDgQEjViWLnCbmX-EeSrA.gif)"},{"metadata":{},"cell_type":"markdown","source":"https://towardsdatascience.com/a-comprehensive-guide-to-convolutional-neural-networks-the-eli5-way-3bd2b1164a53"},{"metadata":{},"cell_type":"markdown","source":"https://stevenrush.github.io/understanding-cnn/ "},{"metadata":{},"cell_type":"markdown","source":"![](https://stevenrush.github.io/assets/cnnvis/filt1.jpeg)"},{"metadata":{},"cell_type":"markdown","source":"https://towardsdatascience.com/simple-introduction-to-convolutional-neural-networks-cdf8d3077bac"},{"metadata":{},"cell_type":"markdown","source":"https://www.researchgate.net/figure/Hierarchical-representation-learning-by-a-Convolutional-Neural-Network-where-the-initial_fig4_317558591"},{"metadata":{},"cell_type":"markdown","source":"![](https://www.researchgate.net/profile/Shoaib_Siddiqui7/publication/317558591/figure/fig4/AS:511878728253445@1499052807279/Hierarchical-representation-learning-by-a-Convolutional-Neural-Network-where-the-initial.png)"},{"metadata":{},"cell_type":"markdown","source":"### Pooling layer"},{"metadata":{},"cell_type":"markdown","source":"![](https://miro.medium.com/max/396/1*uoWYsCV5vBU8SHFPAPao-w.gif)"},{"metadata":{},"cell_type":"markdown","source":"Pooling layer is responsible for reducing the spatial size of the Convolved Feature"},{"metadata":{},"cell_type":"markdown","source":"![](https://miro.medium.com/max/596/1*KQIEqhxzICU7thjaQBfPBQ.png)"},{"metadata":{},"cell_type":"markdown","source":"### Fully connected layers"},{"metadata":{},"cell_type":"markdown","source":"![](https://stanford.edu/~shervine/teaching/cs-230/illustrations/fully-connected.png)"},{"metadata":{},"cell_type":"markdown","source":"![](https://i.stack.imgur.com/Uf4AB.png)"},{"metadata":{"trusted":true},"cell_type":"markdown","source":"Activation functions"},{"metadata":{},"cell_type":"markdown","source":"Relu"},{"metadata":{},"cell_type":"markdown","source":"![](https://miro.medium.com/max/1026/0*g9ypL5M3k-f7EW85.png)"},{"metadata":{},"cell_type":"markdown","source":"## Define the network"},{"metadata":{},"cell_type":"markdown","source":"![](https://upload.wikimedia.org/wikipedia/commons/2/27/MnistExamples.png)"},{"metadata":{},"cell_type":"markdown","source":"![](https://pytorch.org/tutorials/_images/mnist.png)"},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\n\nclass Net(nn.Module):\n\n    def __init__(self):\n        super(Net, self).__init__()\n        # 1 input image channel, 6 output channels, 3x3 square convolution\n        # kernel\n        self.conv1 = nn.Conv2d(1, 6, 3)\n        self.conv2 = nn.Conv2d(6, 16, 3)\n        # an affine operation: y = Wx + b\n        self.fc1 = nn.Linear(16 * 6 * 6, 120)  # 6*6 from image dimension\n        self.fc2 = nn.Linear(120, 84)\n        self.fc3 = nn.Linear(84, 10)\n\n    def forward(self, x):\n        # Max pooling over a (2, 2) window\n        x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))\n        # If the size is a square you can only specify a single number\n        x = F.max_pool2d(F.relu(self.conv2(x)), 2)\n        x = x.view(-1, self.num_flat_features(x))\n        x = F.relu(self.fc1(x))\n        x = F.relu(self.fc2(x))\n        x = self.fc3(x)\n        return x\n\n    #not obligatory \n    def num_flat_features(self, x):\n        size = x.size()[1:]  # all dimensions except the batch dimension\n        num_features = 1\n        for s in size:\n            num_features *= s\n        return num_features\n\n\nnet = Net()\nprint(net)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"params = list(net.parameters())\nprint(len(params))\nprint(params[0].size())  # conv1's .weight","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"input = torch.randn(1, 1, 32, 32)\nprint(input)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nout = net(input)\nprint(out)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Zero the gradient buffers of all parameters and backprops with random gradients:\nnet.zero_grad()\nout.backward(torch.randn(1, 10))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Loss Function"},{"metadata":{},"cell_type":"markdown","source":"A loss function takes the (output, target) pair of inputs, and computes a value that estimates how far away the output is from the target."},{"metadata":{"trusted":true},"cell_type":"code","source":"output = net(input)\ntarget = torch.randn(10)  # a dummy target, for example\ntarget = target.view(1, -1)  # make it the same shape as output\ncriterion = nn.MSELoss()\n\nloss = criterion(output, target)\nprint(loss)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Backprop"},{"metadata":{"trusted":true},"cell_type":"code","source":"net.zero_grad()     # zeroes the gradient buffers of all parameters\n\nprint('conv1.bias.grad before backward')\nprint(net.conv1.bias.grad)\n\nloss.backward()\n\nprint('conv1.bias.grad after backward')\nprint(net.conv1.bias.grad)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Update the weights"},{"metadata":{"trusted":true},"cell_type":"code","source":"learning_rate = 0.01\nfor f in net.parameters():\n    f.data.sub_(f.grad.data * learning_rate)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch.optim as optim\n\n# create your optimizer\noptimizer = optim.SGD(net.parameters(), lr=0.01)\n\n# in your training loop:\noptimizer.zero_grad()   # zero the gradient buffers\noutput = net(input)\nloss = criterion(output, target)\nloss.backward()\noptimizer.step()    # Does the update","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Pretrained neural networks"},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"DATA_FOLDER = '../input'\nLABELS = f'{DATA_FOLDER}/train_labels.csv'\nTRAIN_IMAGES_FOLDER = f'{DATA_FOLDER}/train'\nUSE_GPU = torch.cuda.is_available()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def read_labels(path_to_file):\n    labels = pd.read_csv(path_to_file)\n    return labels\n\n\ndef format_labels_for_dataset(labels):\n    return labels['label'].values.reshape(-1, 1)\n\n\ndef format_path_to_images_for_dataset(pd.DataFrame, path):\n    return [os.path.join(path, f'{f}.tif') for f in labels['id'].values]\n\n\ndef train_valid_split(df):\n    limit_df = 50000\n    df = df.sample(n = df.shape[0])\n    df = df.iloc[:limit_df]\n    split = 40000\n    train = df.iloc[:split]\n    valid = df.iloc[:split]\n    return train, valid","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class MainDataset(Dataset):\n    def __init__(self,\n                 x_dataset,\n                 y_dataset,\n                 x_tfms):\n        self.x_dataset = x_dataset\n        self.y_dataset = y_dataset\n        self.x_tfms = x_tfms\n\n    def __len__(self):\n        return self.x_dataset.__len__()\n\n    def __getitem__(self, index):\n        x = self.x_dataset[index]\n        y = self.y_dataset[index]\n        if self.x_tfms is not None:\n            x = self.x_tfms(x)\n        return x, y\n    \nclass ImageDataset(Dataset):\n    def __init__(self, paths_to_imgs):\n        self.paths_to_imgs = paths_to_imgs\n\n    def __len__(self):\n        return len(self.paths_to_imgs)\n\n    def __getitem__(self, index):\n        img = Image.open(self.paths_to_imgs[index])\n        return img\n\n\nclass LabelDataset(Dataset):\n    def __init__(self, labels):\n        self.labels = labels\n\n    def __len__(self) :\n        return len(self.labels)\n\n    def __getitem__(self, index):\n        return self.labels[index]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels = read_labels(LABELS)\ntrain, valid = train_valid_split(labels)\n\ntrain_labels = format_labels_for_dataset(train)\nvalid_labels = format_labels_for_dataset(valid)\n\ntrain_images = format_path_to_images_for_dataset(train, TRAIN_IMAGES_FOLDER)\nvalid_images = format_path_to_images_for_dataset(valid, TRAIN_IMAGES_FOLDER)\n\ntrain_images_dataset = ImageDataset(train_images)\nvalid_images_dataset = ImageDataset(valid_images)\ntrain_labels_dataset = LabelDataset(train_labels)\nvalid_labels_dataset = LabelDataset(valid_labels)\n\ntrain_dataset = MainDataset(train_images_dataset, train_labels_dataset, x_tfms)\nvalid_dataset = MainDataset(valid_images_dataset, valid_labels_dataset, x_tfms)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}