{"cells":[{"metadata":{},"cell_type":"markdown","source":"# DATA EXPLORATION"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"scrolled":false},"cell_type":"code","source":"import os \nfrom pathlib import Path\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport torchvision\nimport random\nfrom sklearn.model_selection import train_test_split","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"path = Path('../input/cassava-leaf-disease-classification')\nos.listdir(path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"path","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"train = pd.read_csv('../input/cassava-leaf-disease-classification/train.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"train","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"VAMOS A MIRAR SI EL DATASET ESTÁ BALANCEADO"},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"train.label.hist()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"train.label.value_counts()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"CLARAMENTE DESBALANCEADO. EN PRIMERA INSTANCIA SE PROCEDERÁ A TIRAR TAL CUAL. SI NO CARRULA YA VEREMOS"},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"r, c = 3, 5\nfig = plt.figure(figsize=(3*c, 3*r))\nfor _r in range(r):\n    for _c in range(c):\n        ax = plt.subplot(r, c, _r*c + _c + 1)\n        ix = random.randint(0, len(train)-1)\n        img = torchvision.io.read_image(str(path/'train_images'/train['image_id'][ix]))\n        label = train['label'][ix]\n        plt.axis(\"off\")\n        plt.imshow(img.permute(1,2,0))\n        plt.title(label)\nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"img.shape, img.dtype, img.max(), img.min()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"AHORA INSTALAMOS Y CARGAMOS __PYTORCH LIGHTNING__"},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install pytorch-lightning==1.1.8","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install torch==1.8.1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"import torch\nimport pytorch_lightning  as pl\nfrom torch.utils.data import DataLoader","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"# creo primero la clase Dataset\n\nclass Dataset(torch.utils.data.Dataset):\n    \n    def __init__(self,imgs,labels):\n        self.imgs = imgs\n        self.labels = labels\n        \n    def __len__(self):\n        return len(self.imgs)\n    \n    def __getitem__(self,ix):\n        img = torchvision.io.read_image(self.imgs[ix]).float()/255.\n        \n        label = torch.tensor(self.labels[ix], dtype=torch.long)\n        return img, label\n    \n    \n    \n\nclass DataModule(pl.LightningDataModule):\n\n    def __init__(self, \n                 path=Path('../input/cassava-leaf-disease-classification'), \n                 batch_size = 64, \n                 test_size = 0.2, \n                 random_state=42, \n                 subset = 0\n                 ):\n        super().__init__()\n        self.path = path\n        self.batch_size = batch_size\n        self.test_size = test_size\n        self.random_state = random_state\n        self.subset = subset\n\n    def setup(self, stage=None):\n        #dataframe\n        df= pd.read_csv(self.path/'train.csv')\n        #separar en train y validation\n        train, val =train_test_split(\n            df,\n            test_size=self.test_size,\n            shuffle=True,\n            stratify= df['label'],\n            random_state = self.random_state\n        )\n        print('Training samples: ' , len(train))\n        print('Validation samples: ', len(val))\n        if self.subset:\n            _, subset = train_test_split(\n                train,\n                test_size = self.subset,\n                shuffle=True,\n                stratify = train['label'],\n                random_state = self.random_state\n            )\n            \n            print('Training with ', len(subset), 'samples.')\n            train_imgs = [str(self.path/'train_images'/img) for img in subset['image_id'].values]\n            train_labels = subset['label'].values\n        else:\n            train_imgs = [str(self.path/'train_images'/img) for img in train['image_id'].values]\n            train_labels = train['label'].values\n            \n            \n        #definimos los dos dataset\n        self.train_ds = Dataset(train_imgs, train_labels)\n        \n        val_imgs = [str(self.path/'train_images'/img) for img in val['image_id'].values]\n        val_labels = val['label'].values\n        self.val_ds = Dataset(val_imgs, val_labels)\n            \n    def train_dataloader(self):\n        return DataLoader(self.train_ds, batch_size=self.batch_size, shuffle = True) \n\n    def val_dataloader(self):\n        return DataLoader(self.val_ds, batch_size=self.batch_size, shuffle = False)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":" trans = torchvision.transforms.Compose([\n        torchvision.transforms.Resize((32,32))\n ])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dm = DataModule(subset=0)\ndm.setup()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"r, c = 3, 5\nfig = plt.figure(figsize=(3*c, 3*r))\nds = dm.train_ds\nfor _r in range(r):\n    for _c in range(c):\n        ax = plt.subplot(r, c, _r*c + _c + 1)\n        ix = random.randint(0, len(ds)-1)\n        img, lablel = ds[ix]\n        label = train['label'][ix]\n\n        \n        plt.axis(\"off\")\n        plt.imshow(img.permute(1,2,0))\n        plt.title(label.item())\nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img.shape, img.dtype, img.max(), img.min()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"En principio este DataModule ya estaría, imagenes float, en tensor y normalizadas.\nVamos a comprobar los dataloaders."},{"metadata":{"trusted":true},"cell_type":"code","source":"#DataLoader\ndl=dm.train_dataloader()\n\n#Batch de imagenes y etiquetas\nimgs, labels = next(iter(dl))\n\n#64 imagenes\nimgs.shape, imgs.dtype, imgs.max(), imgs.min()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Modelo de prueba, Resnet"},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch.nn.functional as F\nfrom pytorch_lightning.metrics.functional import accuracy\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"m_plus = 0.9\nm_minus = 0.1\nlambda_ = 0.5\ndef margin_loss(y,caps2_output):\n    T = tf.one_hot(y, depth=caps2_n_caps, name=\"T\").numpy()\n    T=torch.from_numpy(T)\n    caps2_output_norm = safe_norm(caps2_output, axis=-2, keep_dims=True)\n\n    \n    present_error_raw = torch.square(torch.max(torch.zeros(1), m_plus - caps2_output_norm))\n    present_error = torch.reshape(present_error_raw, shape=(-1, 4))\n\n    absent_error_raw = torch.square(torch.max(torch.zeros(1), caps2_output_norm - m_minus))\n    absent_error = torch.reshape(absent_error_raw, shape=(-1, 4))\n\n\n    L = torch.add(T * present_error, lambda_ * (1.0 - T) * absent_error)\n\n    margin_loss = torch.mean(torch.sum(L, 1))\n    return(margin_loss)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class Model(pl.LightningModule):\n\n    def __init__(self, config, n_classes=5):\n        super().__init__()\n        self.save_hyperparameters(config)\n        self.resnet = torchvision.models.resnet18(pretrained=True)\n        self.resnet.fc = torch.nn.Linear(self.resnet.fc.in_features, n_classes)\n        #se transforman aqui las imagenes\n        self.trans = torch.nn.Sequential(\n            torchvision.transforms.CenterCrop(self.hparams.size)\n        )\n\n    def forward(self, x):\n        # entra batch de imagenes\n        return self.resnet(x)\n\n    def training_step(self, batch, batch_idx):\n        # training_step defined the train loop.\n        # It is independent of forward\n        x, y = batch\n        x = self.trans(x)\n        y_hat = self(x)\n        loss = F.cross_entropy(y_hat, y)\n        acc = accuracy(y_hat, y)\n        # Logging to TensorBoard by default\n        self.log('loss',loss)\n        self.log('acc', acc, prog_bar=True)\n        return loss\n    \n    def validation_step(self, batch, batch_idx):\n        # training_step defined the train loop.\n        # It is independent of forward\n        x, y = batch\n        y_hat = self(x)\n        loss = F.cross_entropy(y_hat, y)\n        acc = accuracy(y_hat, y)\n        # Logging to TensorBoard by default\n        self.log('val_loss',loss,prog_bar=True)\n        self.log('val_acc', acc, prog_bar=True)\n        return loss\n\n    def configure_optimizers(self):\n        optimizer = torch.optim.Adam(self.parameters(), lr=self.hparams.lr)\n        return optimizer","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"config = {'lr':3e-4,\n          'batch_size':32,\n          'precision':16,\n          'epochs':3,\n          'subset': 0.1,\n          'size':256\n         }\n\ndm = DataModule(batch_size=config['batch_size'], subset=config['subset'])\n\nmodel = Model(config)\n\ntrainer = pl.Trainer(gpus=1,\n    precision=config['precision'],\n    max_epochs=config['epochs'],\n    limit_train_batches = 5,\n    limit_val_batches = 5\n    )\n\n\ntrainer.fit(model,dm)\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#CAPS NET"},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch.nn as nn\n#import pytorch","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"caps2_n_caps = 4\ncaps2_n_dims = 16\n\ncaps1_n_maps = 32\ncaps1_n_caps = caps1_n_maps * 6 * 6  # 1152 primary capsules\ncaps1_n_dims = 8\nbatch_size=1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def squash(s,axis=-1,epsilon=1e-5):\n    sn=torch.sum(s**2,dim=axis,keepdim=True)\n    v=sn/(1+sn)*s/torch.sqrt(sn+epsilon)\n    return v","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def safe_norm(s,epsilon=1e-5):\n    sn=torch.sum(s**2,dim=-2,keepdim=True)\n    v=torch.sqrt(sn+epsilon)\n    return v","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class PrimaryCapsules(nn.Module):\n    def __init__(self,batch_size):\n        super(PrimaryCapsules,self).__init__()\n        self.conv1=nn.Conv2d(1,256,(9,9))\n        self.conv2=nn.Conv2d(256,256,(9,9),2)\n        self.batch_size=batch_size\n        \n    def forward(self,x):\n        out=F.relu(self.conv1(x))\n        out=F.relu(self.conv2(out))\n        out=out.reshape([self.batch_size,32*6*6,8])\n        out=squash(out)\n        \n        return out","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class DigitCapsule(nn.Module):\n    def __init__(self,batch_size,caps1_n_dims,caps2_n_dims,caps2_n_caps,caps1_n_caps,routings=4):\n        super(DigitCapsule,self).__init__()\n        self.caps1_n_caps=caps1_n_caps\n        self.caps2_n_caps=caps2_n_caps\n        self.caps2_n_dims=caps2_n_dims\n        self.caps1_n_dims=caps1_n_dims\n        self.batch_size=batch_size\n        self.W = torch.nn.Parameter(torch.normal(0, 0.1, size=(1, self.caps1_n_caps, self.caps2_n_caps, self.caps2_n_dims, self.caps1_n_dims)))\n        self.routings=routings\n        \n    def forward(self,x):\n        W=self.W.repeat(self.batch_size,1,1,1,1)\n        W=W\n        x=x.unsqueeze(dim=-1)\n        x=x.unsqueeze(dim=2)\n        x=x.repeat([1,1,10,1,1])\n        x_predicted=torch.matmul(W,x)\n        #Cuidao aqui, puede estar mal\n        b = torch.zeros([self.batch_size, self.caps1_n_caps, self.caps2_n_caps, 1, 1]).to(device=device)\n        for i in range(self.routings):\n            b_weights =F.softmax(b,dim=2)\n            if i == self.routings - 1:\n                outputs = squash(torch.sum(torch.mul(b_weights, x_predicted),1, keepdim=True),-2)\n            else:\n                outputs = squash(torch.sum(torch.mul(b_weights, x_predicted),1, keepdim=True),-2)                                 \n                b = b + torch.matmul(torch.transpose(x_predicted,3,4), outputs.repeat(1, self.caps1_n_caps, 1, 1, 1))\n\n        return(safe_norm(outputs))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class CapsuleNet(nn.Module):\n    def __init__(self):\n        super().__init__()\n        self.PC=PrimaryCapsules(batch_size=10)\n        self.DC=DigitCapsule(batch_size=10,caps1_n_caps=1152,caps1_n_dims=8,caps2_n_caps=10,caps2_n_dims=16)\n    \n    def forward(self,x):\n        x=self.PC(x)\n        x=self.DC(x)\n        #x=F.softmax(x,dim=2)\n        x=x.squeeze(1)\n        x=x.squeeze(2)\n        return x","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class CapsuleNet(pl.LightningModule):\n\n    def __init__(self,config):\n        super().__init__()\n        self.save_hyperparameters(config)\n        self.PC=PrimaryCapsules(batch_size=10)\n        self.DC=DigitCapsule(batch_size=10,caps1_n_caps=1152,caps1_n_dims=8,caps2_n_caps=10,caps2_n_dims=16)\n\n    def forward(self,x):\n        x=self.PC(x)\n        x=self.DC(x)\n        #x=F.softmax(x,dim=2)\n        x=x.squeeze(1)\n        x=x.squeeze(2)\n        return x\n\n    def training_step(self, batch, batch_idx):\n        # training_step defined the train loop.\n        # It is independent of forward\n        x, y = batch\n        #x = self.trans(x)\n        y_hat = self(x)\n        loss = F.cross_entropy(y_hat, y)\n        #loss = margin_loss(y,y_hat)\n        acc = accuracy(y_hat, y)\n        # Logging to TensorBoard by default\n        self.log('loss',loss)\n        self.log('acc', acc, prog_bar=True)\n        return loss\n    \n    def validation_step(self, batch, batch_idx):\n        # training_step defined the train loop.\n        # It is independent of forward\n        x, y = batch\n        y_hat = self(x)\n        loss = F.cross_entropy(y_hat, y)\n        acc = accuracy(y_hat, y)\n        # Logging to TensorBoard by default\n        self.log('val_loss',loss,prog_bar=True)\n        self.log('val_acc', acc, prog_bar=True)\n\n\n    def configure_optimizers(self):\n        optimizer = torch.optim.Adam(self.parameters(), lr=self.hparams.lr)\n        return optimizer","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"config_2 = {'lr':3e-4,\n          'batch_size':32,\n          'precision':16,\n          'epochs':3,\n          'subset': 0.1,\n          'size':256\n         }\n\ndm = DataModule(batch_size=config_2['batch_size'], subset=config_2['subset'])\n\nmodel_2 = CapsuleNet(config_2)\n\ntrainer = pl.Trainer(gpus=1,\n    precision=config_2['precision'],\n    max_epochs=config_2['epochs'],\n    limit_train_batches = 5,\n    limit_val_batches = 5\n    )\n\n\ntrainer.fit(model_2,dm)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# SEGUNDA VERSIÓN"},{"metadata":{"trusted":true},"cell_type":"code","source":"caps2_n_caps = 4\ncaps2_n_dims = 16\n\ncaps1_n_maps = 32\ncaps1_n_caps = caps1_n_maps * 6 * 6  # 1152 primary capsules\ncaps1_n_dims = 8\nbatch_size=1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def safe_norm(s, axis=-1, epsilon=1e-7, keep_dims=False):\n    squared_norm = torch.sum(s**2,axis, keepdim=keep_dims)\n    return torch.sqrt(squared_norm + epsilon)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def squash(s, axis=-1, epsilon=1e-7):    \n    squared_norm = torch.sum(s**2,axis, keepdim=True)\n    safe_norm = torch.sqrt(squared_norm + epsilon)\n    squash_factor = squared_norm / (1. + squared_norm)\n    unit_vector = s / safe_norm\n    return squash_factor * unit_vector","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class CapsuleLayer(torch.nn.Module):\n    #Capa capsulada\n    #caps1_n_caps : numero de capsulas\n    #caps1_n_dims: dimension de las capsulas de entrada\n    #caps2_n_caps: numero de capsulas de salida de la capa\n    #caps2_n_dims: dimension de las capsulas de salida\n    #routings: iteraciones del routing\n    def __init__(self, caps1_n_caps, caps1_n_dims, caps2_n_caps, caps2_n_dims, routings=3):\n        super(CapsuleLayer, self).__init__()\n        self.caps1_n_caps = caps1_n_caps \n        self.caps1_n_dims = caps1_n_dims\n        self.caps2_n_caps = caps2_n_caps\n        self.caps2_n_dims = caps2_n_dims\n        self.routings = routings\n        self.W = torch.nn.Parameter(torch.normal(0, 0.1, size=(1, self.caps1_n_caps, self.caps2_n_caps, self.caps2_n_dims, self.caps1_n_dims)))\n        self.ms=torch.nn.Softmax(2).cuda()\n        \n            \n    def forward(self,x):\n        #Las copias para poder multiplicar por la matriz de pesos\n        batch_size=x.shape[0]\n        x_expanded = x.unsqueeze(-1)    \n        x_expanded_tile = x_expanded.unsqueeze(2)\n        x_tiled = x_expanded_tile.repeat(1, 1, self.caps2_n_caps, 1,1)\n        W_tile=self.W.repeat(batch_size,1,1,1,1)\n        W_tile=W_tile.cuda()\n        #Multiplicacion Capsulas W\n        x_tiled = x_tiled.cuda()\n        x_predicted = torch.matmul(W_tile, x_tiled)\n        #x_hat_detached = x_predicted.detach()\n        \n        b = torch.zeros([batch_size, self.caps1_n_caps, self.caps2_n_caps, 1, 1])\n        b =b.cuda()\n        for i in range(self.routings):\n            b_weights =self.ms(b)\n            if i == self.routings - 1:\n                outputs = squash(torch.sum(torch.mul(b_weights, x_predicted),1, keepdim=True))\n            else:\n                outputs = squash(torch.sum(torch.mul(b_weights, x_predicted),1, keepdim=True))                                 \n                b = b + torch.matmul(torch.transpose(x_predicted,3,4), outputs.repeat(1, caps1_n_caps, 1, 1, 1))\n\n        return(outputs)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class PrimaryCapsule(torch.nn.Module):\n    \"\"\"\n    Aplica Convolucion y transforma \n    :param in_channels: inputs conv\n    :param out_channels: output conv\n    :param caps1_n_dims: dimension de la capsula\n    :param caps1_n_caps: numero de capsulas\n    :param kernel_size: kernel size\n    :return: output tensor, size=[batch, caps1_n_caps, caps1_n_dims]\n    \"\"\"\n    def __init__(self, in_channels, out_channels, caps1_n_caps, caps1_n_dims, kernel_size=9, stride=2):\n        super(PrimaryCapsule, self).__init__()\n        self.caps1_n_dims = caps1_n_dims\n        self.caps1_n_caps = caps1_n_caps\n        self.conv2d = torch.nn.Conv2d(in_channels, out_channels, kernel_size=kernel_size, stride=stride)\n\n    def forward(self, x):\n        out = self.conv2d(x)\n        out = out.cuda()\n        outputs = torch.reshape(out, (-1, self.caps1_n_caps, self.caps1_n_dims))\n        return squash(outputs)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class CapsuleNet(torch.nn.Module):\n    \n    \n    \n    def __init__(self,in_channels, out_channels, caps1_n_caps, caps1_n_dims,caps2_n_caps, caps2_n_dims, routings=3):\n        super(CapsuleNet, self).__init__()\n        self.conv=torch.nn.Conv2d(3, 256, (171,227), stride=(22,29))\n        self.relu = torch.nn.ReLU()\n        self.Primary=PrimaryCapsule(in_channels, out_channels, caps1_n_caps, caps1_n_dims)\n        self.Capsule=CapsuleLayer(caps1_n_caps, caps1_n_dims, caps2_n_caps, caps2_n_dims, routings=3)\n        \n        \n    def forward(self,x):\n        out=self.relu(self.conv(x))\n        out=self.Primary(out)\n        out=self.Capsule(out)\n        y_proba = safe_norm(out, axis=-2)\n        y_proba_argmax = torch.argmax(y_proba, axis=2)\n        y_pred = torch.squeeze(torch.squeeze(y_proba_argmax,2),1)\n        return(y_pred,out)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class CapsuleNet(pl.LightningModule):\n#model=CapsuleNet(256, 256, caps1_n_caps, caps1_n_dims,caps2_n_caps, caps2_n_dims, routings=3)\n\n\n    def __init__(self,in_channels=256, out_channels=256, caps1_n_caps=1152, caps1_n_dims=8,caps2_n_caps=4, caps2_n_dims=16, routings=3):\n        super(CapsuleNet, self).__init__()\n        self.conv=torch.nn.Conv2d(3, 256, (171,227), stride=(22,29))\n        self.relu = torch.nn.ReLU()\n        self.Primary=PrimaryCapsule(in_channels, out_channels, caps1_n_caps, caps1_n_dims)\n        self.Capsule=CapsuleLayer(caps1_n_caps, caps1_n_dims, caps2_n_caps, caps2_n_dims, routings=3)\n\n    def forward(self,x):\n        out=self.relu(self.conv(x))\n        out=self.Primary(out)\n        out=self.Capsule(out)\n        y_proba = safe_norm(out, axis=-2)\n        y_proba_argmax = torch.argmax(y_proba, axis=2)\n        y_pred = torch.squeeze(torch.squeeze(y_proba_argmax,2),1)\n        return(y_pred,out)\n\n    def training_step(self, batch, batch_idx):\n        # training_step defined the train loop.\n        # It is independent of forward\n        x, y = batch\n        #x = self.trans(x)\n        y_hat = self(x)\n        loss = F.cross_entropy(y_hat, y)\n        #loss = margin_loss(y,y_hat)\n        acc = accuracy(y_hat, y)\n        # Logging to TensorBoard by default\n        self.log('loss',loss)\n        self.log('acc', acc, prog_bar=True)\n        return loss\n    \n    def validation_step(self, batch, batch_idx):\n        # training_step defined the train loop.\n        # It is independent of forward\n        x, y = batch\n        y_hat = self(x)\n        loss = F.cross_entropy(y_hat, y)\n        acc = accuracy(y_hat, y)\n        # Logging to TensorBoard by default\n        self.log('val_loss',loss,prog_bar=True)\n        self.log('val_acc', acc, prog_bar=True)\n\n\n    def configure_optimizers(self):\n        optimizer = torch.optim.Adam(self.parameters(), lr=self.hparams.lr)\n        return optimizer","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"config_2 = {'lr':3e-4,\n          'batch_size':32,\n          'precision':16,\n          'epochs':3,\n          'subset': 0.1,\n          'size':256\n         }\n\ndm = DataModule(batch_size=config_2['batch_size'], subset=config_2['subset'])\nds=dm.train_ds","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"config_2 = {'lr':3e-4,\n          'batch_size':32,\n          'precision':16,\n          'epochs':3,\n          'subset': 0.1,\n          'size':256\n         }\n\ndm = DataModule(batch_size=config_2['batch_size'], subset=config_2['subset'])\n\nmodel_2 = CapsuleNet(config_2)\n\ntrainer = pl.Trainer(gpus=1,\n    precision=config_2['precision'],\n    max_epochs=config_2['epochs'],\n    limit_train_batches = 5,\n    limit_val_batches = 5\n    )\n\n\ntrainer.fit(model_2,dm)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# TERCER INTENTO"},{"metadata":{"trusted":true},"cell_type":"code","source":"ds = dm.train_ds\nix = random.randint(0, len(ds)-1)\nimg, lablel = ds[ix]\nlabel = train['label'][ix]\n#img=img.permute(1,2,0)#(3x600x800)\nimg.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#r, c = 3, 5\n#fig = plt.figure(figsize=(3*c, 3*r))\nds = dm.train_ds\nix = random.randint(0, len(ds)-1)\nimg, lablel = ds[ix]\nlabel = train['label'][ix]\n#img=img.permute(1,2,0)#(3x600x800)\nimg=torch.reshape(img, (1,3,600,800))\nconv_1 = torch.nn.Conv2d(3, 5, (159,224),(9,9))\nout1=conv_1(img)\nconv_2 = torch.nn.Conv2d(5, 10, (15,30), (7,5))\nout2 = conv_2(out1)\nout3 = torch.reshape(out2, (-1, 20, 1))\nout4 = squash(out3)\n#out4.shape #24x20x1\nu=out4[0,:,:]\nW1 = torch.normal(0,0.01, size=(1, 24,5,16,10))\n#W = torch.nn.Parameter(torch.normal(0, 0.1, size=(5,20)),requires_grad=True)\n#W2 = torch.tile(W1, (2, 2))\nu2 = torch.unsqueeze(out4, 2)\nu3 = torch.tile(u2, (1,1,5,1,1))\n\ntorch.matmul(W1,u3)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nu2 = torch.unsqueeze(out4, 2)\nu3 = torch.tile(u2, (1,1,5,1,1))\n\nu2.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class PrimaryCapsule(torch.nn.Module):\n\n    def __init__(self):\n        super(PrimaryCapsule, self).__init__()\n        self.conv_1 = torch.nn.Conv2d(3, 5, (159,224),(9,9))#salida de un mapa de caracteristicas de 5*(50*65)\n        self.conv_2 = torch.nn.Conv2d(5, 10, (15,30), (7,5))#imagen de salida de 10*(6*8)\n\n    def forward(self, x):\n        out = self.conv_1(x)\n        out = self.conv_2(out)\n        outputs = torch.reshape(out, (-1, 20, 1))#24*20*1, con la intencion de sacar 24  vectores de dimension 20\n        return squash(outputs)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class CapsuleLayer(torch.nn.Module):\n    #Capa capsulada\n    #caps1_n_caps : numero de capsulas de entrada\n    #caps1_n_dims: dimension de las capsulas de entrada\n    #caps2_n_caps: numero de capsulas de salida\n    #caps2_n_dims: dimension de las capsulas de salida\n    #routings: iteraciones del routing\n    def __init__(self):#, caps1_n_caps, caps1_n_dims, caps2_n_caps, caps2_n_dims, routings=3):\n        super(CapsuleLayer, self).__init__()\n        #self.caps1_n_caps = caps1_n_caps \n        #self.caps1_n_dims = caps1_n_dims\n        #self.caps2_n_caps = caps2_n_caps\n        #self.caps2_n_dims = caps2_n_dims\n        #self.routings = routings\n        self.W = torch.nn.Parameter(torch.normal(0, 0.1, size=(5,20)),requires_grad=True)#pasar de 24 vect de dim 20 a 5 \n        self.ms=torch.nn.Softmax(24)\n        self.batch_size=32\n        \n            \n    def forward(self,x):\n        #Las copias para poder multiplicar por la matriz de pesos\n        x_expanded = x.unsqueeze(-1)    \n        x_expanded_tile = x_expanded.unsqueeze(2)\n        x_tiled = x_expanded_tile.repeat(1, 1, self.caps2_n_caps, 1,1)\n        W_tile=self.W.repeat(self.batch_size,1,1,1,1)\n        #Multiplicacion Capsulas W\n        x_tiled = x_tiled.cuda()\n        x_predicted = torch.matmul(W_tile, x_tiled)\n        #x_hat_detached = x_predicted.detach()\n        \n        b = torch.zeros([batch_size, self.caps1_n_caps, self.caps2_n_caps, 1, 1])\n        b =b.cuda()\n        for i in range(self.routings):\n            b_weights =self.ms(b)\n            if i == self.routings - 1:\n                outputs = squash(torch.sum(torch.mul(b_weights, x_predicted),1, keepdim=True))\n            else:\n                outputs = squash(torch.sum(torch.mul(b_weights, x_predicted),1, keepdim=True))                                 \n                b = b + torch.matmul(torch.transpose(x_predicted,3,4), outputs.repeat(1, caps1_n_caps, 1, 1, 1))\n\n        return(outputs)","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}