{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import os\nfrom PIL import Image\nimport matplotlib\nimport matplotlib.pyplot as plt\nfrom tqdm import tqdm_notebook \nimport copy\nimport pickle\nimport pandas as pd\n\nimport torch\nimport torchvision\nfrom torch.utils.data import DataLoader, Dataset, random_split\nimport torchvision.transforms as transforms\nfrom torchvision import datasets\n\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.optim as optim\n\nimport numpy as np\nimport pandas as pd\nfrom sklearn import preprocessing","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\nprint(device)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Pre-processing audio data to image files"},{"metadata":{"trusted":true},"cell_type":"code","source":"def label(source_path):\n  file_name = []\n  label = []\n  filedir=[root+'/'+file for root,dirs,files in os.walk(source_path) for file in files]\n  for count,file in enumerate(filedir[:100000]):\n      if (file[-5]) == '1':\n          file_name.append(file)\n          label.append(1)\n      else:\n          file_name.append(file)\n          label.append(0)\n  \n  df = pd.DataFrame({'name':file_name})\n  df1=pd.DataFrame({'label':label})\n  df=pd.concat([df,df1], axis=1)\n  #print(df.groupby('label')['label'].count())\n  return df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"label('/kaggle/input')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Dataloader","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#For converting the dataset to torchvision dataset format\nclass CancerDataset(Dataset):\n    def __init__(self, panda, transform=None):\n        self.transform = transform\n        self.panda = panda\n        y=self.panda['name']\n        self.file_names=list(y)\n        self.len = len(self.file_names)\n        if self.panda is not None:\n            self.classes_mapping, self.classes_encoding = self.get_classes(panda)\n            \n    def __len__(self):\n        return len(self.file_names)\n    \n    def __getitem__(self, index):\n        file_name = self.file_names[index]\n        image_data = self.pil_loader(file_name).resize((50,50)) \n        if self.transform:\n            image_data = self.transform(image_data)\n                  \n        row = self.classes_mapping.iloc[:,:]  \n        class_, class_code = int(row.iloc[[index],0]), int(row.iloc[[index],1])\n        return image_data, class_, class_code\n          \n    def pil_loader(self,path):\n        with open(path, 'rb') as f:\n            img = Image.open(f)\n            return img.convert('RGB')\n      \n    def get_classes(self, panda):\n        classes_mapping = pd.DataFrame(panda).iloc[:,1:]\n        le = preprocessing.LabelEncoder()\n        classes_mapping['Class_code'] = le.fit_transform(classes_mapping['label'])\n        classes_encoding = {}\n        for code, class_ in enumerate(list(le.classes_)):\n            classes_encoding[code] = class_\n        return classes_mapping, classes_encoding","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"transform = transforms.Compose([ \n                transforms.ToTensor()\n])\n#,transforms.Normalize((0.5,), (0.5,))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"full_data = CancerDataset(label('/kaggle/input'), transform)\n\nfull_data.classes_encoding","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Splitting the training data into 80 % training and 20 % validation datasets"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_size = int(0.8 * len(full_data))\ntest_size = len(full_data) - train_size\ntrain_data, validation_data = torch.utils.data.random_split(full_data, [train_size, test_size])\n\nprint(len(full_data), len(train_data), len(validation_data))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Data loaders for training and validation datasets. Dataloaders provide shuffled data in batches\ntrain_loader = torch.utils.data.DataLoader(train_data, batch_size=20, shuffle=True)\nvalidation_loader = torch.utils.data.DataLoader(validation_data, batch_size=20, shuffle=False)\ndataiter = iter(train_loader)\nimages,_, labels = dataiter.next()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# CNN Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"class BreastcancerCNN(nn.Module):\n    def __init__(self, p=0):\n        super(BreastcancerCNN, self).__init__()\n        self.p = p\n        self.features = nn.Sequential(\n            # layer 1 (3 , 50, 50 ) to (64, 25, 25)\n            nn.Conv2d(3, 64, 4,2,1),  # 41 x 85 -> 21 x 43\n            nn.BatchNorm2d(64),\n            nn.ReLU(),\n            #pooling (64 , 50, 50 ) to (64, 25, 25)\n            #nn.MaxPool2d(kernel_size=2, stride=2, padding=0),  # 11 x 22 -> 6 x 12\n\n            # layer 2   (64 , 25, 25 ) to (128, 12, 12)         \n            nn.Conv2d(64, 128,3,2,0),  # 21 x 43 -> 11 x 22\n            nn.BatchNorm2d(128),\n            nn.ReLU(),  \n            #pooling (128 , 12, 12 ) to (128, 6, 6)\n            nn.MaxPool2d(2,2,0),  # 11 x 22 -> 6 x 12\n            #nn.Dropout2d(p=self.p),\n\n            # layer 3 (128 , 6, 6 ) to (256, 4, 4)\n            nn.Conv2d(128, 256, 2,2,1),  # 6 x 12 -> 4 x 7\n            nn.BatchNorm2d(256),\n            nn.ReLU()         \n        )\n\n        self.fc = nn.Sequential(\n            # Fully connected layer            \n            nn.Linear(256*4*4, 512),\n            nn.Sigmoid(),\n            #nn.Dropout(p=self.p),\n\n            # Classifier layer\n            nn.Linear(512, 2),\n            nn.Sigmoid()\n        )\n\n    def forward(self, x):\n        x = self.features(x)\n        #print(x.shape)\n        x = x.view(x.size(0), -1)\n        #print(x.shape)\n        x = self.fc(x)\n        return x","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#Training and Validation"},{"metadata":{"trusted":true},"cell_type":"code","source":"def train(model, loss_fn, opt, epoch, batch_log_interval, dropout_prob):\n    \n    model.train()\n    model.p = dropout_prob\n    loss_avg = 0\n    \n    for batch_id, data in enumerate(train_loader):\n        inputs, _, labels = data\n        inputs = inputs.to(device)\n        labels = labels.to(device)\n        #print(labels)\n        \n        opt.zero_grad()\n        outputs = model(inputs)\n        loss = loss_fn(outputs,labels)        \n        loss_avg += loss.data.item()*len(inputs) # as 'loss' is avg of total mini-batch loss\n        loss.backward()\n        opt.step()\n\n        '''if batch_id % batch_log_interval == 0:            \n            print('Train Epoch: {} [{}/{} ({:.0f}%)]\\tAvg batch loss: {:.3f}'.format(\n                epoch, batch_id * len(inputs), len(train_loader.dataset),\n                100. * batch_id / len(train_loader), loss.data.item()/len(inputs)))'''\n            \n        del inputs, labels, outputs\n        torch.cuda.empty_cache()\n        \n    loss_avg /= len(train_loader.dataset)\n    print('\\nEpoch: {}, Train set: Average loss: {:.4f}'.format(epoch, loss_avg)) \n    return loss_avg","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def validate(model, loss_fn, opt, epoch):    \n    model.eval()\n    model.p = 0\n    validation_loss = 0\n    correct = 0\n\n    with torch.no_grad():\n        for inputs, _, labels in validation_loader:\n            inputs = inputs.to(device)\n            labels = labels.to(device)\n               \n            outputs = model(inputs)\n            loss = loss_fn(outputs, labels)\n            validation_loss += loss.data.item()*len(inputs)\n            output_pred = outputs.data.max(1)[1]\n            correct += output_pred.eq(labels).sum().item()\n          \n        validation_loss /= len(validation_loader.dataset)\n        validation_accuracy = 100.0 * correct / len(validation_loader.dataset)\n        print('\\nEpoch: {}, Validation set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)'.\n              format(epoch, validation_loss, correct, len(validation_loader.dataset), validation_accuracy))  \n        \n        return validation_loss, validation_accuracy","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def main(lr, momentum, best_model=None, max_validation_accuracy=0, dropout_prob=0):    \n    train_loss = []\n    validation_loss = []\n    validation_accuracy = []\n\n    print('\\nLR = {}, Momentum = {}\\n'.format(lr, momentum))\n    torch.manual_seed(0)\n    model = BreastcancerCNN(dropout_prob)\n    if best_model:\n        model.load_state_dict(best_model)\n    model.to(device)\n    loss_fn = nn.CrossEntropyLoss()\n    opt = optim.SGD(model.parameters(), lr=lr, momentum = momentum)    \n\n    for epoch in tqdm_notebook(range(1, epochs + 1), total=epochs, unit=\"epoch\"):\n        train_loss_epoch = train(model,loss_fn, opt, epoch, 1, dropout_prob)             \n        if epoch % 1 == 0:\n            train_loss.append(train_loss_epoch)\n            valid_loss_epoch, valid_accuracy_epoch = validate(model,loss_fn, opt, epoch)\n            validation_loss.append(valid_loss_epoch)\n            validation_accuracy.append(valid_accuracy_epoch)\n\n            if valid_accuracy_epoch > max_validation_accuracy:\n                max_validation_accuracy = valid_accuracy_epoch\n                best_model = copy.deepcopy(model.state_dict())\n                best_epoch = epoch\n            print(\"Maximum validation accuracy so far: {:.0f}%\".format(max_validation_accuracy))\n        print(\"-----------------------------------------------------------------\\n\")\n\n    return best_model, best_epoch, train_loss, validation_loss, validation_accuracy","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"lr = 0.001\nmomentum = 0.9\nepochs = 30","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#model = torch.load('models/model_e1.pt')\nbest_model, best_epoch, train_loss, validation_loss, validation_accuracy = main(lr, momentum)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!mkdir models/\n\n# model_e2 means lr=1e-2, similar names will be used\ntorch.save(best_model, 'models/model.pt')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_loss(epochs, metric, lr, batch_size, data_type, metric_type):\n    plt.plot(epochs,metric)\n    plt.title(\" {} {}, lr={}, batch size={}\".format(data_type, metric_type, lr, batch_size))\n    plt.xlabel(\"epochs\")\n    if metric_type == \"loss\":\n        ylabel = \"Avergae CE loss\"\n    else:\n        ylabel = \"Accuracy (%)\"\n    plt.ylabel(\"Avergae CE loss\")  \n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"lr = 0.01\nplot_loss(range(1,31), validation_accuracy, lr, 20, \"validation\", \"accuracy\")\n\nplt.plot(range(1,31), train_loss, c='r', label=\"train\")\nplt.plot(range(1,31), validation_loss, c='g', label=\"validation\")\nplt.title(\"Drop out (p=0.5), lr=0.01(60 epochs)/0.001(30 epochs), batch size={}\".format(20))\nplt.xlabel(\"epochs\")\nplt.ylabel(\"Avergae CE loss\")\nplt.legend(loc='upper right')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":""}],"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":1}