{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Data Description\n\nThe data consists of 48x48 pixel grayscale images of faces. The faces have been automatically registered so that the face is more or less centered and occupies about the same amount of space in each image. The task is to categorize each face based on the emotion shown in the facial expression in to one of seven categories (0=Angry, 1=Disgust, 2=Fear, 3=Happy, 4=Sad, 5=Surprise, 6=Neutral).\n\ntrain.csv contains two columns, \"emotion\" and \"pixels\". The \"emotion\" column contains a numeric code ranging from 0 to 6, inclusive, for the emotion that is present in the image. The \"pixels\" column contains a string surrounded in quotes for each image. The contents of this string a space-separated pixel values in row major order. test.csv contains only the \"pixels\" column and your task is to predict the emotion column.\n\nDataset from kaggle : challenges-in-representation-learning-facial-expression-recognition-challenge\n\nIt is also known as FER2013 from google\n\n# Generate Data","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport os\nimport numpy as np\nfrom PIL import Image \nfrom tqdm import tqdm\n\n'''\nFunction to convert raw data(csv file) into appropriate data(images)\n'''\ndef dfTOimg(dataType, csvPath):\n    '''search for required data file and foler'''\n    folder_name = r'./' + dataType\n    \n    '''if folder is not created then create'''\n    if not(os.path.exists(folder_name)):\n        os.mkdir(folder_name)\n     \n    '''read csv file and its data'''   \n    csvFile = pd.read_csv(csvPath)\n    images = csvFile['pixels']\n    \n    '''test file does not contain emotion column '''\n    if csvFile.shape[1] != 1:\n        emotion = csvFile['emotion']\n    \n    '''emotions in dataset'''\n    classes = ('Angry', 'Disgust', 'Fear', 'Happy','Sad', 'Surprise', 'Neutral')\n    \n    '''convert pixels to image and save it '''\n    totalImages = images.shape[0]\n    for index in tqdm(range(totalImages)):\n        \n        str_img = images[index]\n        img_array_str = str_img.split(' ')\n        img_array = np.asarray(img_array_str, dtype=np.uint8).reshape(48,48)\n        img = Image.fromarray(img_array)\n        \n#         if csvFile.shape[1] != 1:\n#             subFolder = folder_name +'/'+ classes[emotion[index]]\n#         else:\n        subFolder = folder_name\n        \n#         if not(os.path.exists(subFolder)):\n#             os.mkdir(subFolder)\n  \n        save_path = os.path.join(subFolder, f\"{dataType}{index}.jpg\")\n        img.save(save_path, 'JPEG')\n\n    print(f\"Done saving {folder_name} data\")\n    \n'''create image files'''    \ntrainCsv_path =  r'../input/challenges-in-representation-learning-facial-expression-recognition-challenge/train.csv'\n#'../input/challenges-in-representation-learning-facial-expression-recognition-challenge/train.csv'\ndfTOimg(dataType ='train', csvPath = trainCsv_path)\n\ntestCsv_path = r'../input/challenges-in-representation-learning-facial-expression-recognition-challenge/test.csv'\ndfTOimg(dataType='test', csvPath = testCsv_path)\n","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:31:09.915751Z","iopub.execute_input":"2022-07-15T06:31:09.916805Z","iopub.status.idle":"2022-07-15T06:31:40.103418Z","shell.execute_reply.started":"2022-07-15T06:31:09.916705Z","shell.execute_reply":"2022-07-15T06:31:40.102465Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load The Data\n\nAfter creating data it's time to convert image into tensor and other required processes  ","metadata":{"execution":{"iopub.status.busy":"2022-07-13T11:26:10.779147Z","iopub.execute_input":"2022-07-13T11:26:10.779579Z","iopub.status.idle":"2022-07-13T11:26:10.806540Z","shell.execute_reply.started":"2022-07-13T11:26:10.779543Z","shell.execute_reply":"2022-07-13T11:26:10.804846Z"}}},{"cell_type":"code","source":"import torch\nfrom torch.utils.data import Dataset, DataLoader, random_split\nimport torchvision.transforms as transforms\n\n'''class for to make dataset'''\nclass to_dataset(Dataset):\n    def __init__(self,csv_file, img_dir, datatype, transform=None):\n        '''\n        Pytorch Dataset class\n        params:-\n                 csv_file : the path of the csv file    (train, validation, test)\n                 img_dir  : the directory of the images (train, validation, test)\n                 datatype : string for searching along the image_dir (train, val, test)\n                 transform: pytorch transformation over the data\n        return :-\n                 image, labels\n        '''        \n        self.csv_file = pd.read_csv(csv_file)\n        '''In our test dataset we dont have the emotion column so for \n        labeliing purpose we have to specify some conditiopns'''\n\n            \n        self.img_dir = img_dir\n        self.datatype = datatype\n        self.transform = transform\n    \n    '''length of dataset'''\n    def __len__(self):\n        return len(self.csv_file)\n    \n    '''take items in dataset'''\n    def __getitem__(self,idx):\n        if torch.is_tensor(idx):\n            idx = idx.tolist()\n        img = Image.open(self.img_dir+self.datatype+str(idx)+'.jpg')\n        if self.transform :\n            img = self.transform(img)\n        lables = None\n        if self.csv_file.shape[1] == 1:\n            lebles = None\n\n        else:\n            self.lables = self.csv_file['emotion']\n            lables = np.array(self.lables[idx])\n            lables = torch.from_numpy(lables).long()\n        return img,lables\n\n\n        \n\n'''Create Dataset'''    \ntransform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,),(0.5,))])\ntrain_validation_dataset =   to_dataset(csv_file = trainCsv_path,\n                          img_dir = './train/',\n                          datatype = 'train',\n                        transform=transform)\ntest_dataset =   to_dataset(csv_file = testCsv_path,\n                          img_dir = './test/',\n                          datatype = 'test',\n                        transform=transform)\n\n'''Divide validation and train dataset'''\nvalidation_size = len(train_validation_dataset) - 20000\ntrain_size = 20000\ntrain_dataset, validation_dataset = random_split(train_validation_dataset,\n                                                (train_size, validation_size))\n\n'''Load the Data'''\nbatch_size = 1024\ntrain_loader = DataLoader(train_dataset, batch_size*2, shuffle=True, num_workers=4, pin_memory=True)\ntest_loader = DataLoader(test_dataset, batch_size*2, shuffle=True, num_workers=4, pin_memory=True)\nvalidation_loader = DataLoader(validation_dataset, batch_size, num_workers=4, pin_memory=True)\n","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:31:40.105477Z","iopub.execute_input":"2022-07-15T06:31:40.106072Z","iopub.status.idle":"2022-07-15T06:31:44.612955Z","shell.execute_reply.started":"2022-07-15T06:31:40.106033Z","shell.execute_reply":"2022-07-15T06:31:44.611827Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Display Images","metadata":{"execution":{"iopub.status.busy":"2022-07-13T12:35:16.942982Z","iopub.execute_input":"2022-07-13T12:35:16.943371Z","iopub.status.idle":"2022-07-13T12:35:16.950542Z","shell.execute_reply.started":"2022-07-13T12:35:16.943339Z","shell.execute_reply":"2022-07-13T12:35:16.949477Z"}}},{"cell_type":"code","source":"import matplotlib\nimport matplotlib.pyplot as plt\n%matplotlib inline\nfrom torchvision.utils import make_grid\n\n'''Helper function to display image easily'''\ndef showImage(image, lable):\n    plt.imshow(image.permute((1,2,0)))\n    if lable != None:\n        emotions = ('Angry', 'Disgust', 'Fear', 'Happy','Sad', 'Surprise', 'Neutral')\n        print(f\"Emotion : {emotions[lable]}\")\n        print(f\"Label : {lable}\")\n        \n        \n'''Helper function to display images in one batch'''\ndef show_batch(dl):\n    for images, labels in dl:\n        print(\"Image Shape : \", images.shape)\n        plt.figure(figsize=(128,128))\n        plt.axis('off')\n        plt.imshow(make_grid(images, nrows=8).permute(1,2,0))\n        break","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:31:44.614336Z","iopub.execute_input":"2022-07-15T06:31:44.615026Z","iopub.status.idle":"2022-07-15T06:31:44.628516Z","shell.execute_reply.started":"2022-07-15T06:31:44.614986Z","shell.execute_reply":"2022-07-15T06:31:44.627415Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"showImage(*test_dataset[500])","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:31:44.632969Z","iopub.execute_input":"2022-07-15T06:31:44.633756Z","iopub.status.idle":"2022-07-15T06:31:44.816105Z","shell.execute_reply.started":"2022-07-15T06:31:44.633720Z","shell.execute_reply":"2022-07-15T06:31:44.815237Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"showImage(*train_dataset[5000])","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:31:44.817593Z","iopub.execute_input":"2022-07-15T06:31:44.817928Z","iopub.status.idle":"2022-07-15T06:31:44.984114Z","shell.execute_reply.started":"2022-07-15T06:31:44.817894Z","shell.execute_reply":"2022-07-15T06:31:44.983001Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"showImage(*validation_dataset[700])","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:31:44.985716Z","iopub.execute_input":"2022-07-15T06:31:44.986370Z","iopub.status.idle":"2022-07-15T06:31:45.144892Z","shell.execute_reply.started":"2022-07-15T06:31:44.986332Z","shell.execute_reply":"2022-07-15T06:31:45.143949Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_batch(train_loader)","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:31:45.146814Z","iopub.execute_input":"2022-07-15T06:31:45.147659Z","iopub.status.idle":"2022-07-15T06:31:56.853682Z","shell.execute_reply.started":"2022-07-15T06:31:45.147611Z","shell.execute_reply":"2022-07-15T06:31:56.852573Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Create Models & Other Helpping Functions","metadata":{}},{"cell_type":"code","source":"'''\nLet's define the model by extending ImageClassificationBase class which contains helper methods for training & validation\n'''\n\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nclass ImageClassificationBase(nn.Module):\n    def training_step(self, batch):\n        images, labels = batch\n        out = self(images)\n        loss = F.cross_entropy(out, labels)\n        return loss\n    \n    def validation_step(self, batch):\n        images, labels = batch\n        out = self(images)\n        loss = F.cross_entropy(out, labels)\n        acc = accuracy(out, labels)\n        return {'val_loss' : loss.detach(), 'val_acc' : acc}\n    \n    def validation_epoch_end(self, outputs):\n        batch_loss = [x['val_loss'] for x in outputs]\n        epoch_loss = torch.stack(batch_loss).mean()\n        batch_acc = [x['val_acc'] for x in outputs]\n        epoch_acc = torch.stack(batch_acc).mean()\n        return {'val_loss' : epoch_loss.item(), 'val_acc' : epoch_acc.item()}\n    \n    def epoch_end(self, epoch, result):\n        print(\"Epoch [{}], train_loss: {:.4f}, val_loss: {:.4f},val_acc: {:.4f}\".format(epoch, result[\"train_loss\"], result[\"val_loss\"], result[\"val_acc\"] ))\n        \ndef accuracy(outputs, labels):\n    _, preds = torch.max(outputs, dim=1)\n    return torch.tensor(torch.sum(preds == labels).item() / len(preds))\n        ","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:31:56.855172Z","iopub.execute_input":"2022-07-15T06:31:56.855615Z","iopub.status.idle":"2022-07-15T06:31:56.870222Z","shell.execute_reply.started":"2022-07-15T06:31:56.855569Z","shell.execute_reply":"2022-07-15T06:31:56.868840Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''CONVOLUTION NEURAL NETWORK'''\n\nclass Deep_Emotion(ImageClassificationBase):\n    def __init__(self):\n        super().__init__()\n        '''\n        Deep_Emotion class contains the network architecture.\n        '''\n        super(Deep_Emotion,self).__init__()\n        self.conv1 = nn.Conv2d(1,10,3)\n        self.conv2 = nn.Conv2d(10,10,3)\n        self.pool2 = nn.MaxPool2d(2,2)\n\n        self.conv3 = nn.Conv2d(10,10,3)\n        self.conv4 = nn.Conv2d(10,10,3)\n        self.pool4 = nn.MaxPool2d(2,2)\n\n        self.norm = nn.BatchNorm2d(10)\n\n        self.fc1 = nn.Linear(810,50)\n        self.fc2 = nn.Linear(50,7)\n\n        self.localization = nn.Sequential(\n            nn.Conv2d(1, 8, kernel_size=7),\n            nn.MaxPool2d(2, stride=2),\n            nn.ReLU(True),\n            nn.Conv2d(8, 10, kernel_size=5),\n            nn.MaxPool2d(2, stride=2),\n            nn.ReLU(True)\n        )\n\n        self.fc_loc = nn.Sequential(\n            nn.Linear(640, 32),\n            nn.ReLU(True),\n            nn.Linear(32, 3 * 2)\n        )\n        self.fc_loc[2].weight.data.zero_()\n        self.fc_loc[2].bias.data.copy_(torch.tensor([1, 0, 0, 0, 1, 0], dtype=torch.float))\n\n    def stn(self, x):\n        xs = self.localization(x)\n        xs = xs.view(-1, 640)\n        theta = self.fc_loc(xs)\n        theta = theta.view(-1, 2, 3)\n\n        grid = F.affine_grid(theta, x.size())\n        x = F.grid_sample(x, grid)\n        return x\n\n    def forward(self,input):\n        out = self.stn(input)\n\n        out = F.relu(self.conv1(out))\n        out = self.conv2(out)\n        out = F.relu(self.pool2(out))\n\n        out = F.relu(self.conv3(out))\n        out = self.norm(self.conv4(out))\n        out = F.relu(self.pool4(out))\n\n        out = F.dropout(out)\n        out = out.view(-1, 810)\n        out = F.relu(self.fc1(out))\n        out = self.fc2(out)\n\n        return out\n\n","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:31:56.871990Z","iopub.execute_input":"2022-07-15T06:31:56.872651Z","iopub.status.idle":"2022-07-15T06:31:56.895350Z","shell.execute_reply.started":"2022-07-15T06:31:56.872615Z","shell.execute_reply":"2022-07-15T06:31:56.894541Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Use Of GPU\n\nTo seamlessly use a GPU, if one is available, we define a couple of helper functions (get_default_device & to_device) and a helper class DeviceDataLoader to move our model & data to the GPU as required.","metadata":{}},{"cell_type":"code","source":"def get_default_device():\n    if torch.cuda.is_available():\n        return torch.device('cuda')\n    else:\n        return torch.device('cpu')\n    \ndef to_device(data, device):\n    if isinstance(data, (list, tuple)):\n        return [to_device(x, device) for x in data]\n    return data.to(device, non_blocking=True)\n\nclass deviceDataLoader():\n    def __init__(self, dl, device):\n        self.dl = dl\n        self.device = device\n        \n    def __iter__(self):\n        for b in self.dl:\n            yield to_device(b, self.device)\n            \n    def __len__(self):\n        return len(self.dl)","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:31:56.896994Z","iopub.execute_input":"2022-07-15T06:31:56.897643Z","iopub.status.idle":"2022-07-15T06:31:56.908586Z","shell.execute_reply.started":"2022-07-15T06:31:56.897609Z","shell.execute_reply":"2022-07-15T06:31:56.907606Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Based on where you're running this notebook, your default device could be a CPU (torch.device('cpu')) or a GPU (torch.device('cuda'))","metadata":{}},{"cell_type":"code","source":"device = get_default_device()\ndevice","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:31:56.915104Z","iopub.execute_input":"2022-07-15T06:31:56.915843Z","iopub.status.idle":"2022-07-15T06:31:56.923201Z","shell.execute_reply.started":"2022-07-15T06:31:56.915808Z","shell.execute_reply":"2022-07-15T06:31:56.921989Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We can now wrap our training and validation data loaders using DeviceDataLoader for automatically transferring batches of data to the GPU (if available), and use to_device to move our model to the GPU (if available)","metadata":{}},{"cell_type":"code","source":"train_dl = deviceDataLoader(train_loader, device)\nval_dl = deviceDataLoader(validation_loader, device)\nto_device(Deep_Emotion(), device);","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:31:56.925107Z","iopub.execute_input":"2022-07-15T06:31:56.925848Z","iopub.status.idle":"2022-07-15T06:31:56.942001Z","shell.execute_reply.started":"2022-07-15T06:31:56.925809Z","shell.execute_reply":"2022-07-15T06:31:56.941154Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training Model\n\nWe'll define two functions: fit and evaluate to train the model using gradient descent and evaluate its performance on the validation set.","metadata":{}},{"cell_type":"code","source":"@torch.no_grad()\ndef evaluate(model, val_loader):\n    model.eval()\n    outputs = [model.validation_step(batch) for batch in val_loader]\n    return model.validation_epoch_end(outputs)\n\ndef fit(epochs, lr, model, train_loader, val_loader, opt_func=torch.optim.SGD):\n    history = []\n    optimizer = opt_func(model.parameters(), lr)\n    for epoch in range(epochs):\n        model.train()\n        train_losses = []\n        for batch in train_loader:\n            loss = model.training_step(batch)\n            train_losses.append(loss)\n            loss.backward()\n            optimizer.step()\n            optimizer.zero_grad()\n        result = evaluate(model, val_loader)\n        result['train_loss'] = torch.stack(train_losses).mean().item()\n        model.epoch_end(epoch, result)\n        history.append(result)\n    return history\n\ndef get_lr(optimizer):\n    for param_group in optimizer.param_groups:\n        return param_group['lr']\n    \ndef fit_one_cycle(epochs, max_lr, model, train_loader,\n                  val_loader, weight_decay=0,\n                  grad_clip=None,\n                  opt_func=torch.optim.SGD):\n    torch.cuda.empty_cache()\n    history=[]\n    \n    #setup custom optimizer\n    optimizer = opt_func(model.parameters(),\n                        max_lr, weight_decay=weight_decay)\n    #setup one cycle learning rate scheduler\n    sched = torch.optim.lr_scheduler.OneCycleLR(optimizer, \n                                                max_lr,\n                                               epochs=epochs,\n                                               steps_per_epoch=len(train_loader))\n    \n    for epoch in range(epochs):\n        model.train()\n        train_losses = []\n        lrs = []\n        for batch in train_loader:\n            loss = model.training_step(batch)\n            train_losses.append(loss)\n            loss.backward\n            \n            #gradient clipping\n            if grad_clip:\n                nn.utils.clip_grad_value_(model.parameters(),\n                                        grad_clip)\n          \n            optimizer.step()\n            optimizer.zero_grad()\n\n            #recod nd update learning rate\n            lrs.append(get_lr(optimizer))\n            sched.step()\n\n        #validation step\n        result = evaluate(model, val_loader)\n        result['train_loss'] = torch.stack(train_losses).mean().item()\n        result['lrs'] = lrs\n        model.epoch_end(epoch,result)\n        history.append(result)\n    \n    return history\n","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:31:56.943478Z","iopub.execute_input":"2022-07-15T06:31:56.944104Z","iopub.status.idle":"2022-07-15T06:31:56.964573Z","shell.execute_reply.started":"2022-07-15T06:31:56.944069Z","shell.execute_reply":"2022-07-15T06:31:56.963588Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = to_device(Deep_Emotion(), device)","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:31:56.966363Z","iopub.execute_input":"2022-07-15T06:31:56.967223Z","iopub.status.idle":"2022-07-15T06:31:56.980486Z","shell.execute_reply.started":"2022-07-15T06:31:56.967187Z","shell.execute_reply":"2022-07-15T06:31:56.979488Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"evaluate(model, val_dl)","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:31:56.982254Z","iopub.execute_input":"2022-07-15T06:31:56.982653Z","iopub.status.idle":"2022-07-15T06:32:05.867780Z","shell.execute_reply.started":"2022-07-15T06:31:56.982619Z","shell.execute_reply":"2022-07-15T06:32:05.866744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nhistory = fit(50, 0.001, model, train_dl, val_dl,opt_func = torch.optim.Adam)","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:32:05.869697Z","iopub.execute_input":"2022-07-15T06:32:05.870693Z","iopub.status.idle":"2022-07-15T06:41:15.408042Z","shell.execute_reply.started":"2022-07-15T06:32:05.870650Z","shell.execute_reply":"2022-07-15T06:41:15.406987Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nhistory += fit(50, 0.001, model, train_dl, val_dl,opt_func = torch.optim.Adam)","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:44:31.367999Z","iopub.execute_input":"2022-07-15T06:44:31.368893Z","iopub.status.idle":"2022-07-15T06:53:36.536479Z","shell.execute_reply.started":"2022-07-15T06:44:31.368853Z","shell.execute_reply":"2022-07-15T06:53:36.535075Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nhistory += fit(10, 0.0001, model, train_dl, val_dl,opt_func = torch.optim.Adam)","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:55:00.396930Z","iopub.execute_input":"2022-07-15T06:55:00.397315Z","iopub.status.idle":"2022-07-15T06:56:47.886161Z","shell.execute_reply.started":"2022-07-15T06:55:00.397282Z","shell.execute_reply":"2022-07-15T06:56:47.884929Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model Analysis","metadata":{}},{"cell_type":"code","source":"def plot_accuracies(history):\n    accuracies = [x['val_acc'] for x in history]\n    plt.plot(accuracies, '-x')\n    plt.xlabel('epoch')\n    plt.ylabel('accuracy')\n    plt.title('Accuracy vs. No. of epochs');","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:58:22.527825Z","iopub.execute_input":"2022-07-15T06:58:22.528188Z","iopub.status.idle":"2022-07-15T06:58:22.533866Z","shell.execute_reply.started":"2022-07-15T06:58:22.528157Z","shell.execute_reply":"2022-07-15T06:58:22.532901Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_accuracies(history)","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:58:22.835323Z","iopub.execute_input":"2022-07-15T06:58:22.836037Z","iopub.status.idle":"2022-07-15T06:58:23.009110Z","shell.execute_reply.started":"2022-07-15T06:58:22.835988Z","shell.execute_reply":"2022-07-15T06:58:23.008189Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"So from above graph we can say that after running the epocs we get the highest accuracy around 46% accuracy.\n\n","metadata":{}},{"cell_type":"code","source":"def plot_losses(history):\n    train_losses = [x.get('train_loss') for x in history]\n    val_losses = [x['val_loss'] for x in history]\n    plt.plot(train_losses, '-bx')\n    plt.plot(val_losses, '-rx')\n    plt.xlabel('epoch')\n    plt.ylabel('loss')\n    plt.legend(['Training', 'Validation'])\n    plt.title('Loss vs. No. of epochs');\n\nplot_losses(history)","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:58:23.929133Z","iopub.execute_input":"2022-07-15T06:58:23.930061Z","iopub.status.idle":"2022-07-15T06:58:24.121388Z","shell.execute_reply.started":"2022-07-15T06:58:23.930022Z","shell.execute_reply":"2022-07-15T06:58:24.120506Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"so from above graph  model performed terrible. it leads to the overfitting.\n\nNow lets start some prediction.\n\n# Prediction","metadata":{}},{"cell_type":"code","source":"def predict_image(img, model):\n    # Convert to a batch of 1\n    xb = to_device(img.unsqueeze(0), device)\n    # Get predictions from model\n    yb = model(xb)\n    # Pick index with highest probability\n    _, preds  = torch.max(yb, dim=1)\n    # Retrieve the class label\n    #classes = ('Angry', 'Disgust', 'Fear', 'Happy','Sad', 'Surprise', 'Neutral')\n    return preds[0]\n\n\n'''Emotions'''\nclasses = ('Angry', 'Disgust', 'Fear', 'Happy','Sad', 'Surprise', 'Neutral')\n","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:58:24.961448Z","iopub.execute_input":"2022-07-15T06:58:24.962223Z","iopub.status.idle":"2022-07-15T06:58:24.968631Z","shell.execute_reply.started":"2022-07-15T06:58:24.962185Z","shell.execute_reply":"2022-07-15T06:58:24.967505Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img, label = test_dataset[0]\nplt.imshow(img.permute(1, 2, 0))\nprint('Predicted:', classes[predict_image(img, model)])","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:58:30.109317Z","iopub.execute_input":"2022-07-15T06:58:30.109951Z","iopub.status.idle":"2022-07-15T06:58:30.280403Z","shell.execute_reply.started":"2022-07-15T06:58:30.109913Z","shell.execute_reply":"2022-07-15T06:58:30.279447Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img, label = test_dataset[100]\nplt.imshow(img.permute(1, 2, 0))\nprint('Predicted:', classes[predict_image(img, model)])","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:58:32.906974Z","iopub.execute_input":"2022-07-15T06:58:32.907923Z","iopub.status.idle":"2022-07-15T06:58:33.066685Z","shell.execute_reply.started":"2022-07-15T06:58:32.907874Z","shell.execute_reply":"2022-07-15T06:58:33.065651Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img, label = test_dataset[1000]\nplt.imshow(img.permute(1, 2, 0))\nprint('Predicted:', classes[predict_image(img, model)])","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:58:35.170201Z","iopub.execute_input":"2022-07-15T06:58:35.170567Z","iopub.status.idle":"2022-07-15T06:58:35.332592Z","shell.execute_reply.started":"2022-07-15T06:58:35.170524Z","shell.execute_reply":"2022-07-15T06:58:35.331620Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img, label = test_dataset[200]\nplt.imshow(img.permute(1, 2, 0))\nprint('Predicted:', classes[predict_image(img, model)])","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:58:37.534056Z","iopub.execute_input":"2022-07-15T06:58:37.534425Z","iopub.status.idle":"2022-07-15T06:58:37.696439Z","shell.execute_reply.started":"2022-07-15T06:58:37.534394Z","shell.execute_reply":"2022-07-15T06:58:37.695273Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img, label = test_dataset[4000]\nplt.imshow(img.permute(1, 2, 0))\n\nprint('Predicted:', classes[predict_image(img, model)])","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:58:39.624435Z","iopub.execute_input":"2022-07-15T06:58:39.624803Z","iopub.status.idle":"2022-07-15T06:58:39.785255Z","shell.execute_reply.started":"2022-07-15T06:58:39.624772Z","shell.execute_reply":"2022-07-15T06:58:39.784369Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"After getting  only 50% accuracy but model works vcery good it predicted images right.\nSo we can say model works good. \n\n\n# Saving and loading the model\n\nSince we've trained our model for a long time and achieved a resonable accuracy, it would be a good idea to save the weights of the model to disk, so that we can reuse the model later and avoid retraining from scratch. Here's how you can save the model.","metadata":{}},{"cell_type":"code","source":"torch.save(model.state_dict(), 'Deep_Emotion_Model.pth')","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:58:43.602082Z","iopub.execute_input":"2022-07-15T06:58:43.602734Z","iopub.status.idle":"2022-07-15T06:58:43.613872Z","shell.execute_reply.started":"2022-07-15T06:58:43.602697Z","shell.execute_reply":"2022-07-15T06:58:43.612867Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":" # importing file to jovian","metadata":{}},{"cell_type":"code","source":"!pip install jovian\nimport jovian\njovian.commit(project_name='Deep_Emotion_Model',\n              privacy='secret',\n              environment=None)","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:59:02.463392Z","iopub.execute_input":"2022-07-15T06:59:02.463770Z","iopub.status.idle":"2022-07-15T06:59:29.850221Z","shell.execute_reply.started":"2022-07-15T06:59:02.463738Z","shell.execute_reply":"2022-07-15T06:59:29.848611Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"execution":{"iopub.status.busy":"2022-07-15T06:43:05.598938Z","iopub.status.idle":"2022-07-15T06:43:05.599923Z","shell.execute_reply.started":"2022-07-15T06:43:05.599665Z","shell.execute_reply":"2022-07-15T06:43:05.599690Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}