{"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":"Lib import","metadata":{"id":"cxnFs8whL-RV"}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport json\nfrom PIL import Image\nfrom sklearn.utils import shuffle\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\nimport os\nimport random","metadata":{"id":"5V4DW2tMMBE_"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torchvision\nimport torchvision.transforms as transforms\nfrom torch.utils.data import Dataset, DataLoader","metadata":{"id":"4WUA4hXCMoZR"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Runtime settings","metadata":{"id":"A0fSkRBMfhxx"}},{"cell_type":"code","source":"#    Data-Splitting\nTRAIN_DATASET_PERCENTAGE_SIZE = 70\nVALIDATION_DATASET_PERCENTAGE_SIZE = 15\n#    Image conversion\nIMAGE_SIZE = 224\n#    Hyperparams\nEPOCHS = 7          # 1 E = 3 datasets (see below)\nBATCH_SIZE = 32\nLEARNING_RATE = 0.0001\nBETA_1 = 0.9\nBETA_2 = 0.999\nEPSILON = 10e-8\nL2_REGULARIZATION_PENALTY = 0\n#   RANDOM\nRANDOM_SEED = 2021\n\nrandom.seed(RANDOM_SEED)","metadata":{"id":"gc81_tozeG7q"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"DEVICE = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\nDEVICE","metadata":{"id":"RnbeTr0x0l95"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Directories","metadata":{"id":"t7g_GmRqNA71"}},{"cell_type":"code","source":"#--- INPUTS ---\n#model\ninpmodel_path = \"../input/pretrained-pytorch-models/resnet50-19c8e357.pth\"\n\n#Root\nroot_dir = \"../input/cassava-leaf-disease-classification\"\n\n#Train\ntrain_dataset_dir = os.path.join(root_dir, \"train_images\")\ntrain_csv_path = os.path.join(root_dir, \"train.csv\")\n\n#Test\ntest_dataset_dir = os.path.join(root_dir, \"test_images\")\n\n#--- OUTPUTS ---\n#Model\nout_dir = \"./\"\nmodel_path = os.path.join(out_dir, \"cassava_saved_model.pth\")\nmodel_fixed = os.path.join(out_dir, \"cassava_saved_model_fixed.pth\")\n\n#Generated Meta\nTRAINDATASET_train_path = os.path.join(out_dir, \"trainds_train.csv\")\nTRAINDATASET_validation_path = os.path.join(out_dir, \"trainds_validation.csv\")\nTRAINDATASET_test_path = os.path.join(out_dir, \"trainds_test.csv\")\n\nwrong_preds_csv_path = os.path.join(out_dir, \"wrong_predictions.csv\")\n\nfixed_train_csv_path = os.path.join(out_dir, \"fixed_train.csv\")\n\nTRAINDATASET_fixed_train_path = os.path.join(out_dir, \"trainds_fixed_train.csv\")\nTRAINDATASET_fixed_validation_path = os.path.join(out_dir, \"trainds_fixed_validation.csv\")\nTRAINDATASET_fixed_test_path = os.path.join(out_dir, \"trainds_fixed_test.csv\")\n\nsub_filepath = os.path.join(out_dir, \"submission.csv\")\n\n#predicted test\ntestfiles_predictions_csv_path = os.path.join(out_dir, \"testfiles_predictions.csv\")","metadata":{"id":"H5UgM-VsMzXK"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Get full train list\ntrain_full = pd.read_csv(train_csv_path)\ntrain_full","metadata":{"id":"DD9-2topNyKu"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Analize data","metadata":{"id":"pXMjn86qEQp3"}},{"cell_type":"code","source":"#Calc class objects\nclass_0_items = 0\nclass_1_items = 0\nclass_2_items = 0\nclass_3_items = 0\nclass_4_items = 0\nfor index, row in train_full.iterrows():\n    if row['label'] == 0:\n      class_0_items += 1\n    elif row['label'] == 1:\n      class_1_items += 1\n    elif row['label'] == 2:\n      class_2_items += 1\n    elif row['label'] == 3:\n      class_3_items += 1\n    elif row['label'] == 4:\n      class_4_items += 1\n#Calc %\nsummary_items = len(train_full.index)\nclass_0_perc = (100 * class_0_items)//summary_items\nclass_1_perc = (100 * class_1_items)//summary_items\nclass_2_perc = (100 * class_2_items)//summary_items\nclass_3_perc = (100 * class_3_items)//summary_items\nclass_4_perc = (100 * class_4_items)//summary_items","metadata":{"id":"UZB_sPrRESGS"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#show class % diagram\nvalues = np.array([class_0_perc, class_1_perc, class_2_perc, class_3_perc, class_4_perc])\nvalue_labels = [\"Class 0 - \" + str(class_0_perc) + \"%\", \"Class 1 - \" + str(class_1_perc) + \"%\", \"Class 2 - \" + str(class_2_perc) + \"%\", \"Class 3 - \" + str(class_3_perc) + \"%\", \"Class 4 - \" + str(class_4_perc) + \"%\"]\nplt.pie(values, labels = value_labels)\nplt.legend(title = \"Legend:\")\nplt.show() ","metadata":{"id":"cRn2re9WGyXF"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Separating test set","metadata":{"id":"ogJ4S1NnsMDI"}},{"cell_type":"code","source":"if (TRAIN_DATASET_PERCENTAGE_SIZE + VALIDATION_DATASET_PERCENTAGE_SIZE) >= 100:\n  raise SPLITSIZEERROR(\"Choose correct dataset sizes!\")\n\n#shuffle full dataset\ntrain_full = shuffle(train_full)\n\n#count items\nsummary_items = len(train_full.index)\ntrain_items = (summary_items * TRAIN_DATASET_PERCENTAGE_SIZE)//100\nvalidation_items = (summary_items * VALIDATION_DATASET_PERCENTAGE_SIZE)//100\ntest_items = summary_items - (train_items + validation_items)\n\n#make 3 sets\ntrain_dataset_csv = train_full.iloc[ 0 : (train_items-1) ]\nvalidation_dataset_csv = train_full.iloc[ (train_items-1) : (train_items-1) + (validation_items-1) ]\ntest_dataset_csv = train_full.iloc[ (train_items-1) + (validation_items-1) : summary_items + 1]","metadata":{"id":"JfQOQS7BeiPB"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset_csv.to_csv(TRAINDATASET_train_path)\ntrain_dataset_csv","metadata":{"id":"6XJT9UHUwqLM"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"validation_dataset_csv.to_csv(TRAINDATASET_validation_path)\nvalidation_dataset_csv","metadata":{"id":"TkLDgKZ6wqSq"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dataset_csv.to_csv(TRAINDATASET_test_path)\ntest_dataset_csv","metadata":{"id":"3iuA_GMuwqZ1"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Making dataset vectors","metadata":{"id":"2pFimtnrwml5"}},{"cell_type":"code","source":"X_Train = train_dataset_csv['image_id'].values\nY_Train = train_dataset_csv['label'].values\n\nX_Val = validation_dataset_csv['image_id'].values\nY_Val = validation_dataset_csv['label'].values\n\nX_Test = test_dataset_csv['image_id'].values\nY_Test = test_dataset_csv['label'].values","metadata":{"id":"kcC5p_h2QXHL"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Pick Transformations","metadata":{"id":"kY3RNETALyXK"}},{"cell_type":"code","source":"#Pick random picture\nrandomrow_index = random.randint(0, summary_items)\nrandomrow = train_full.iloc[randomrow_index]\nrandomname = randomrow['image_id']\nrandomimg = Image.open(os.path.join(train_dataset_dir, randomname))\n\n#raw picked image\nplt.axis('off')\nplt.imshow(randomimg)","metadata":{"id":"XrrUvLyDMSvj"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Resize IMAGE_SIZE\ntrasformation_Res = transforms.Resize((IMAGE_SIZE, IMAGE_SIZE))\npic_tr1 = trasformation_Res(randomimg)\n\nplt.axis('off')\nplt.imshow(pic_tr1)","metadata":{"id":"HeAvyEo_L3Wx"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#RandomRotation\nANGLE = 180\ntrasformation_Rot = transforms.RandomRotation(ANGLE)\npic_tr2 = trasformation_Rot(randomimg)\n\nplt.axis('off')\nplt.imshow(pic_tr2)","metadata":{"id":"txgBkwfFbOox"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#RandomHorizontalFlip\nPROBABILITY = 0.5\ntrasformation_HFlip = transforms.RandomHorizontalFlip(p=PROBABILITY)\npic_tr3 = trasformation_HFlip(randomimg)\n\nplt.axis('off')\nplt.imshow(pic_tr3)","metadata":{"id":"0ep2lvwJb3PP"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Resize in HALF\nSize_Width, Size_Height = randomimg.size\nHalfSize_Width = Size_Width//2\nHalfSize_Height = Size_Height//2\ntransform_ResHalf = transforms.Resize((HalfSize_Height, HalfSize_Width))\n\npic_reshalf = transform_ResHalf(randomimg)\n\nplt.axis('off')\nplt.imshow(pic_reshalf)","metadata":{"id":"SQbbXtG_iQ4R"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Random Crop\ntransform_RCrop = transforms.RandomCrop(size=(224, 224))\npic_rcrop = transform_RCrop(randomimg)\n\nplt.axis('off')\nplt.imshow(pic_rcrop)","metadata":{"id":"tl1uBVk5mQp5"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Defining transformation sets:","metadata":{"id":"ZDVWs5zrw9DH"}},{"cell_type":"code","source":"#Raw\ntransformations_0 = transforms.Compose(\n    [transforms.ToTensor(),\n     trasformation_Res,\n     transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225))])","metadata":{"id":"W6J7rAJX_msy"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transformations_1 = transforms.Compose(\n    [transforms.ToTensor(),\n     trasformation_Res,\n     trasformation_Rot,\n     trasformation_HFlip,\n     transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225))])","metadata":{"id":"jRZn0Mz0sZzf"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#transformations_1 DEMO\npic_tr_all = trasformation_HFlip(trasformation_Rot(trasformation_Res(randomimg)))\n\nplt.axis('off')\nplt.imshow(pic_tr_all)","metadata":{"id":"yhAqGtKYcsXm"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transformations_2 = transforms.Compose(\n    [transforms.ToTensor(),\n     transform_ResHalf,\n     transform_RCrop,\n     trasformation_Rot,\n     trasformation_HFlip,\n     transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225))])","metadata":{"id":"XC8XXc34mFH2"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#transformations_2 DEMO\npic_tr_all = trasformation_HFlip(trasformation_Rot(transform_RCrop(transform_ResHalf(randomimg))))\n\nplt.axis('off')\nplt.imshow(pic_tr_all)","metadata":{"id":"fq-nfNZ1o1sZ"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Using custom dataset class","metadata":{"id":"EzHla9xPtQER"}},{"cell_type":"code","source":"class GetData(Dataset):\n    def __init__(self, Dir, FNames, Labels, Transform):\n        self.dir = Dir\n        self.fnames = FNames\n        self.transform = Transform\n        self.lbs = Labels\n        \n    def __len__(self):\n        return len(self.fnames)\n\n    def __getitem__(self, index):\n        x = Image.open(os.path.join(self.dir, self.fnames[index]))\n        if \"train\" in self.dir:            \n            return self.transform(x), self.lbs[index]            \n        elif \"test\" in self.dir:            \n            return self.transform(x), self.fnames[index]","metadata":{"id":"Yq_urx5xWbDd"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Making Torch readable datasets","metadata":{"id":"tNxDlsKXyhKo"}},{"cell_type":"code","source":"#Resize only\ntrainset_0 = GetData(train_dataset_dir, X_Train, Y_Train, transformations_0)\ntrain_0_loader = DataLoader(trainset_0, batch_size=BATCH_SIZE, shuffle=True, num_workers=4)\n\n#Transformations set 1\ntrainset_1 = GetData(train_dataset_dir, X_Train, Y_Train, transformations_1)\ntrain_1_loader = DataLoader(trainset_1, batch_size=BATCH_SIZE, shuffle=True, num_workers=4)\n\n#Transformations set 2\ntrainset_2 = GetData(train_dataset_dir, X_Train, Y_Train, transformations_2)\ntrain_2_loader = DataLoader(trainset_2, batch_size=BATCH_SIZE, shuffle=True, num_workers=4)\n\n#Valid\nvalidset = GetData(train_dataset_dir, X_Val, Y_Val, transformations_0)\nvalidloader = DataLoader(validset, batch_size=BATCH_SIZE, shuffle=False, num_workers=4)\n\n#Test\ntestset = GetData(train_dataset_dir, X_Test, Y_Test, transformations_0)\ntestloader = DataLoader(testset, batch_size=BATCH_SIZE, shuffle=False, num_workers=4)","metadata":{"id":"sJIgGuTkWb9I"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Model init","metadata":{"id":"kL1sH3pD0tLQ"}},{"cell_type":"code","source":"model = torchvision.models.resnet50()\nmodel.load_state_dict(torch.load(inpmodel_path, map_location=torch.device(DEVICE)))\nmodel.fc = nn.Linear(2048, 5, bias=True)\nmodel = model.to(DEVICE)","metadata":{"id":"-BmQh1vY0oXc"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"loss_func = nn.CrossEntropyLoss()\noptimiser = torch.optim.Adam(model.parameters(), lr=LEARNING_RATE, betas=(BETA_1, BETA_2), eps=EPSILON, weight_decay=L2_REGULARIZATION_PENALTY)","metadata":{"id":"OC8-ESgT1GXM"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Training","metadata":{"id":"XWUn-tiKCJOG"}},{"cell_type":"code","source":"epochs = EPOCHS\nmin_valid_loss = np.inf\nfor e in range(epochs):\n    # TRAINING\n    train_loss = 0.0\n    model.train()\n    # Set 0\n    for data, labels in train_0_loader:\n        if torch.cuda.is_available():\n            data, labels = data.cuda(), labels.cuda()\n        \n        optimiser.zero_grad()\n        target = model(data)\n        loss = loss_func(target,labels)\n        loss.backward()\n        optimiser.step()\n        train_loss = loss.item() * data.size(0)\n    #Set 1\n    for data, labels in train_1_loader:\n        if torch.cuda.is_available():\n            data, labels = data.cuda(), labels.cuda()\n        \n        optimiser.zero_grad()\n        target = model(data)\n        loss = loss_func(target,labels)\n        loss.backward()\n        optimiser.step()\n        train_loss = loss.item() * data.size(0)\n    #Set 2\n    for data, labels in train_2_loader:\n        if torch.cuda.is_available():\n            data, labels = data.cuda(), labels.cuda()\n        \n        optimiser.zero_grad()\n        target = model(data)\n        loss = loss_func(target,labels)\n        loss.backward()\n        optimiser.step()\n        train_loss = loss.item() * data.size(0)\n    #\n    # VALIDATION\n    valid_loss = 0.0\n    model.eval()\n    for data, labels in validloader:\n        if torch.cuda.is_available():\n            data, labels = data.cuda(), labels.cuda()\n        \n        target = model(data)\n        loss = loss_func(target,labels)\n        valid_loss = loss.item() * data.size(0)\n    #\n    # PRINT INFO\n    print(f'Epoch {e+1} \\t\\t Training Loss: {train_loss / len(train_0_loader)} \\t\\t Validation Loss: {valid_loss / len(validloader)}')\n    if min_valid_loss > valid_loss:\n        print(f'Validation Loss Decreased({min_valid_loss:.6f}--->{valid_loss:.6f}) \\t Saving The Model')\n        min_valid_loss = valid_loss\n        # Saving State Dict\n        torch.save(model.state_dict(), model_path)","metadata":{"id":"xS5Z7qxQvDDT"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Testing on validation","metadata":{"id":"v_0lqXkfD-ic"}},{"cell_type":"code","source":"correct = 0\ntotal = 0\nwith torch.no_grad():\n    model.eval()\n    for data in validloader:\n        inputs, labels = data[0].to(DEVICE), data[1].to(DEVICE)\n        outputs = model(inputs)\n        _, predicted = torch.max(outputs.data, 1)\n        total += labels.size(0)\n        correct += (predicted == labels).sum().item()\nprint(\"Accuracy (validation): %d\" %(100 * correct/total))","metadata":{"id":"M5pE-VnACOII"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Testing on test","metadata":{"id":"UVCfyuuNYYpb"}},{"cell_type":"code","source":"correct = 0\ntotal = 0\nwith torch.no_grad():\n    model.eval()\n    for data in testloader:\n        inputs, labels = data[0].to(DEVICE), data[1].to(DEVICE)\n        outputs = model(inputs)\n        _, predicted = torch.max(outputs.data, 1)\n        total += labels.size(0)\n        correct += (predicted == labels).sum().item()\nprint(\"Accuracy (test): %d\" %(100 * correct/total))","metadata":{"id":"7QzMVDQJYUEj"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Post analysis","metadata":{"id":"kiO6qXAg24x2"}},{"cell_type":"markdown","source":"Use all items to form dataset to test wrong predictions","metadata":{"id":"Tojzo_cychSB"}},{"cell_type":"code","source":"X_full_train = train_full['image_id'].values\nY_full_train = train_full['label'].values","metadata":{"id":"tAs8Q9Wlcexw"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fulltrainset = GetData(train_dataset_dir, X_full_train, Y_full_train, transformations_0)\nfulltrainsetloader = DataLoader(fulltrainset, batch_size=1, shuffle=False, num_workers=4)","metadata":{"id":"UNU3waCJc-xK"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Test predictions","metadata":{"id":"OelVVaWjdKVv"}},{"cell_type":"code","source":"wrong_predictions = pd.DataFrame(columns=['image_id', 'predicted', 'neuron_value', 'ground_truth', 'neuron_value_on_gt', 'neuron_value_diff'])\nwrong_predictions","metadata":{"id":"MbvaAllk6C6b"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with torch.no_grad():\n    model.eval()\n    i = 0\n    for data in fulltrainsetloader:\n        inputs, labels = data[0].to(DEVICE), data[1].to(DEVICE)\n        outputs = model(inputs)\n        current_image = train_full['image_id'].iloc[i]\n        current_image_class = train_full['label'].iloc[i]\n        neuron_value, predicted = torch.max(outputs.data, 1)\n        neuron_value_on_gt = outputs[0][current_image_class].item()\n        neuron_value_diff = neuron_value.item() - neuron_value_on_gt\n        if not predicted == current_image_class:\n            #write to csv: current_image, predicted, neuron_value\n            wrong_predictions = wrong_predictions.append({'image_id':current_image, 'predicted':predicted.item(),'neuron_value':neuron_value.item(),'ground_truth':current_image_class,'neuron_value_on_gt':neuron_value_on_gt,'neuron_value_diff':neuron_value_diff}, ignore_index=True)\n        i += 1","metadata":{"id":"or11E_OT3roB"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"wrong_predictions.to_csv(wrong_preds_csv_path)\nsummary_items_wrong = len(wrong_predictions.index)\nwrong_predictions","metadata":{"id":"2F6_kaFV7zR3"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"See which class network mistakenly makes choice","metadata":{"id":"oGszlFbacZZO"}},{"cell_type":"code","source":"#Calc class objects\ncheck1_class_0_items = 0\ncheck1_class_1_items = 0\ncheck1_class_2_items = 0\ncheck1_class_3_items = 0\ncheck1_class_4_items = 0\nfor index, row in wrong_predictions.iterrows():\n    if row['predicted'] == 0:\n      check1_class_0_items += 1\n    elif row['predicted'] == 1:\n      check1_class_1_items += 1\n    elif row['predicted'] == 2:\n      check1_class_2_items += 1\n    elif row['predicted'] == 3:\n      check1_class_3_items += 1\n    elif row['predicted'] == 4:\n      check1_class_4_items += 1\n#Calc %\ncheck1_class_0_perc = (100 * check1_class_0_items)//summary_items_wrong\ncheck1_class_1_perc = (100 * check1_class_1_items)//summary_items_wrong\ncheck1_class_2_perc = (100 * check1_class_2_items)//summary_items_wrong\ncheck1_class_3_perc = (100 * check1_class_3_items)//summary_items_wrong\ncheck1_class_4_perc = (100 * check1_class_4_items)//summary_items_wrong","metadata":{"id":"Fmdu59LK9agS"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Show class % diagram\ncheck1_values = np.array([check1_class_0_perc, check1_class_1_perc, check1_class_2_perc, check1_class_3_perc, check1_class_4_perc])\ncheck1_value_labels = [\"Class 0 - \" + str(check1_class_0_perc) + \"%\", \"Class 1 - \" + str(check1_class_1_perc) + \"%\", \"Class 2 - \" + str(check1_class_2_perc) + \"%\", \"Class 3 - \" + str(check1_class_3_perc) + \"%\", \"Class 4 - \" + str(check1_class_4_perc) + \"%\"]\nplt.pie(check1_values, labels = check1_value_labels)\nplt.legend(title = \"Legend:\")\nplt.show()","metadata":{"id":"2r_E-fw74rYS"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"See in which class network is mistaken the most","metadata":{"id":"gjS2OOXKWLcm"}},{"cell_type":"code","source":"#Calc class objects\ncheck2_class_0_items = 0\ncheck2_class_1_items = 0\ncheck2_class_2_items = 0\ncheck2_class_3_items = 0\ncheck2_class_4_items = 0\nfor index, row in wrong_predictions.iterrows():\n    if row['predicted'] == 0:\n      check2_class_0_items += 1\n    elif row['predicted'] == 1:\n      check2_class_1_items += 1\n    elif row['predicted'] == 2:\n      check2_class_2_items += 1\n    elif row['predicted'] == 3:\n      check2_class_3_items += 1\n    elif row['predicted'] == 4:\n      check2_class_4_items += 1\n#Calc %\ncheck2_class_0_perc = (100 * check2_class_0_items)//summary_items_wrong\ncheck2_class_1_perc = (100 * check2_class_1_items)//summary_items_wrong\ncheck2_class_2_perc = (100 * check2_class_2_items)//summary_items_wrong\ncheck2_class_3_perc = (100 * check2_class_3_items)//summary_items_wrong\ncheck2_class_4_perc = (100 * check2_class_4_items)//summary_items_wrong","metadata":{"id":"7AAWw_xP5J8i"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Show class % diagram\ncheck2_values = np.array([check2_class_0_perc, check2_class_1_perc, check2_class_2_perc, check2_class_3_perc, check2_class_4_perc])\ncheck2_value_labels = [\"Class 0 - \" + str(check2_class_0_perc) + \"%\", \"Class 1 - \" + str(check2_class_1_perc) + \"%\", \"Class 2 - \" + str(check2_class_2_perc) + \"%\", \"Class 3 - \" + str(check2_class_3_perc) + \"%\", \"Class 4 - \" + str(check2_class_4_perc) + \"%\"]\nplt.pie(check2_values, labels = check2_value_labels)\nplt.legend(title = \"Legend:\")\nplt.show()","metadata":{"id":"WyPdg2IW5nX4"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Get visual info","metadata":{"id":"moM3DO-T52yv"}},{"cell_type":"code","source":"values_diff = wrong_predictions['neuron_value_diff'].values","metadata":{"id":"85RV4H0JWxfu"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"diff_min = values_diff.min()\nprint('Min value: ' + str(diff_min))\ndiff_max = values_diff.max()\nprint('Max value: ' + str(diff_max))\ndiff_avg = np.average(values_diff)\nprint('Average value: ' + str(diff_avg))","metadata":{"id":"Z4wnrIRzXbM4"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.hist(values_diff, bins=20)","metadata":{"id":"yGyxgPbVZPMI"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Execluding certain values where network is super sure that dataset is wrong","metadata":{"id":"vp6l8KBr5-rN"}},{"cell_type":"code","source":"exclude_train = pd.DataFrame(columns=['image_id', 'label'])\nexclude_train","metadata":{"id":"7gnFJ5JcasNk"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for index, row in wrong_predictions.iterrows():\n    if row['neuron_value_diff'] >= 2: # 2 was chosen as it will drop about 5-6% of presumably wrong dataset\n        image_id = row['image_id']\n        label = row['ground_truth']\n        exclude_train = exclude_train.append({'image_id':image_id, 'label':label}, ignore_index=True)","metadata":{"id":"1FoNtBmtbTs8"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"exclude_train","metadata":{"id":"6MQC9nQn6pN2"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fixed_train = pd.DataFrame(columns=['image_id', 'label'])\nfixed_train","metadata":{"id":"nAVhUbCWeR81"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for index_exc, row_exc in exclude_train.iterrows():\n    index = train_full[train_full['image_id'] == row_exc['image_id']].index\n    train_full.drop(index, inplace=True)\nfixed_train = train_full","metadata":{"id":"dz7uZhMjez3x"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fixed_train.to_csv(fixed_train_csv_path)\nsummary_items_fixed = len(fixed_train.index)\nfixed_train","metadata":{"id":"K5N7DUljheAz"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Retraining model with new training dataset","metadata":{"id":"ZtmLwAB164yA"}},{"cell_type":"markdown","source":"Analize data","metadata":{"id":"Q5ipIzm17SXH"}},{"cell_type":"code","source":"#Calc class objects\nretrain_class_0_items = 0\nretrain_class_1_items = 0\nretrain_class_2_items = 0\nretrain_class_3_items = 0\nretrain_class_4_items = 0\nfor index, row in fixed_train.iterrows():\n    if row['label'] == 0:\n      retrain_class_0_items += 1\n    elif row['label'] == 1:\n      retrain_class_1_items += 1\n    elif row['label'] == 2:\n      retrain_class_2_items += 1\n    elif row['label'] == 3:\n      retrain_class_3_items += 1\n    elif row['label'] == 4:\n      retrain_class_4_items += 1\n#Calc %\nretrain_class_0_perc = (100 * retrain_class_0_items)//summary_items_fixed\nretrain_class_1_perc = (100 * retrain_class_1_items)//summary_items_fixed\nretrain_class_2_perc = (100 * retrain_class_2_items)//summary_items_fixed\nretrain_class_3_perc = (100 * retrain_class_3_items)//summary_items_fixed\nretrain_class_4_perc = (100 * retrain_class_4_items)//summary_items_fixed","metadata":{"id":"RDyaUvRw7ZUT"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Show class % diagram\nretrain_values = np.array([retrain_class_0_perc, retrain_class_1_perc, retrain_class_2_perc, retrain_class_3_perc, retrain_class_4_perc])\nretrain_value_labels = [\"Class 0 - \" + str(retrain_class_0_perc) + \"%\", \"Class 1 - \" + str(retrain_class_1_perc) + \"%\", \"Class 2 - \" + str(retrain_class_2_perc) + \"%\", \"Class 3 - \" + str(retrain_class_3_perc) + \"%\", \"Class 4 - \" + str(retrain_class_4_perc) + \"%\"]\nplt.pie(retrain_values, labels = retrain_value_labels)\nplt.legend(title = \"Legend:\")\nplt.show()","metadata":{"id":"1dby0op87Afb"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Separating into sets","metadata":{"id":"GTt3xJLA8Adv"}},{"cell_type":"code","source":"#shuffle full dataset\nfixed_train = shuffle(fixed_train)\n\n#count items\nretrain_train_items = (summary_items_fixed * TRAIN_DATASET_PERCENTAGE_SIZE)//100\nretrain_validation_items = (summary_items_fixed * VALIDATION_DATASET_PERCENTAGE_SIZE)//100\nretrain_test_items = summary_items_fixed - (retrain_train_items + retrain_validation_items)\n\n#make 3 sets\nretrain_train_dataset_csv = fixed_train.iloc[ 0 : (retrain_train_items-1) ]\nretrain_validation_dataset_csv = fixed_train.iloc[ (retrain_train_items-1) : (retrain_train_items-1) + (retrain_validation_items-1) ]\nretrain_test_dataset_csv = fixed_train.iloc[ (retrain_train_items-1) + (retrain_validation_items-1) : summary_items_fixed + 1]","metadata":{"id":"xotC7huB8FIE"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"retrain_train_dataset_csv.to_csv(TRAINDATASET_fixed_train_path)\nretrain_train_dataset_csv","metadata":{"id":"z2mnoRrp8peI"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"retrain_validation_dataset_csv.to_csv(TRAINDATASET_fixed_validation_path)\nretrain_validation_dataset_csv","metadata":{"id":"YeJNPszB8r1p"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"retrain_test_dataset_csv.to_csv(TRAINDATASET_fixed_test_path)\nretrain_test_dataset_csv","metadata":{"id":"c94yhoOm8u0m"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Making dataset vectors","metadata":{"id":"N1NLtLW683Iv"}},{"cell_type":"code","source":"X_Train_retrain = retrain_train_dataset_csv['image_id'].values\nY_Train_retrain = retrain_train_dataset_csv['label'].values\n\nX_Val_retrain = retrain_validation_dataset_csv['image_id'].values\nY_Val_retrain = retrain_validation_dataset_csv['label'].values\n\nX_Test_retrain = retrain_test_dataset_csv['image_id'].values\nY_Test_retrain = retrain_test_dataset_csv['label'].values","metadata":{"id":"O3hcL1Gv85RS"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Making Torch readable datasets","metadata":{"id":"lhUv31RZ9REG"}},{"cell_type":"code","source":"#Resize only\nretrain_trainset_0 = GetData(train_dataset_dir, X_Train_retrain, Y_Train_retrain, transformations_0)\nretrain_train_0_loader = DataLoader(retrain_trainset_0, batch_size=BATCH_SIZE, shuffle=True, num_workers=4)\n\n#Transformations set 1\nretrain_trainset_1 = GetData(train_dataset_dir, X_Train_retrain, Y_Train_retrain, transformations_1)\nretrain_train_1_loader = DataLoader(retrain_trainset_1, batch_size=BATCH_SIZE, shuffle=True, num_workers=4)\n\n#Transformations set 2\nretrain_trainset_2 = GetData(train_dataset_dir, X_Train_retrain, Y_Train_retrain, transformations_2)\nretrain_train_2_loader = DataLoader(retrain_trainset_2, batch_size=BATCH_SIZE, shuffle=True, num_workers=4)\n\n#Valid\nretrain_validset = GetData(train_dataset_dir, X_Val_retrain, Y_Val_retrain, transformations_0)\nretrain_validloader = DataLoader(retrain_validset, batch_size=BATCH_SIZE, shuffle=False, num_workers=4)\n\n#Test\nretrain_testset = GetData(train_dataset_dir, X_Test_retrain, Y_Test_retrain, transformations_0)\nretrain_testloader = DataLoader(retrain_testset, batch_size=BATCH_SIZE, shuffle=False, num_workers=4)","metadata":{"id":"1qlMHMkf9Vk0"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Model init","metadata":{"id":"6kVlYi9L96OF"}},{"cell_type":"code","source":"model = torchvision.models.resnet50()\nmodel.load_state_dict(torch.load(inpmodel_path, map_location=torch.device(DEVICE)))\nmodel.fc = nn.Linear(2048, 5, bias=True)\nmodel = model.to(DEVICE)","metadata":{"id":"yXAan_LI98Nj"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"loss_func = nn.CrossEntropyLoss()\noptimiser = torch.optim.Adam(model.parameters(), lr=LEARNING_RATE, betas=(BETA_1, BETA_2), eps=EPSILON, weight_decay=L2_REGULARIZATION_PENALTY)","metadata":{"id":"DDukdvE09-55"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Retraining","metadata":{"id":"OvRezVJq-Dob"}},{"cell_type":"code","source":"epochs = EPOCHS\nmin_valid_loss = np.inf\nfor e in range(epochs):\n    # TRAINING\n    train_loss = 0.0\n    model.train()\n    # Set 0\n    for data, labels in retrain_train_0_loader:\n        if torch.cuda.is_available():\n            data, labels = data.cuda(), labels.cuda()\n        \n        optimiser.zero_grad()\n        target = model(data)\n        loss = loss_func(target,labels)\n        loss.backward()\n        optimiser.step()\n        train_loss = loss.item() * data.size(0)\n    #Set 1\n    for data, labels in retrain_train_1_loader:\n        if torch.cuda.is_available():\n            data, labels = data.cuda(), labels.cuda()\n        \n        optimiser.zero_grad()\n        target = model(data)\n        loss = loss_func(target,labels)\n        loss.backward()\n        optimiser.step()\n        train_loss = loss.item() * data.size(0)\n    #Set 2\n    for data, labels in retrain_train_2_loader:\n        if torch.cuda.is_available():\n            data, labels = data.cuda(), labels.cuda()\n        \n        optimiser.zero_grad()\n        target = model(data)\n        loss = loss_func(target,labels)\n        loss.backward()\n        optimiser.step()\n        train_loss = loss.item() * data.size(0)\n    #\n    # VALIDATION\n    valid_loss = 0.0\n    model.eval()\n    for data, labels in retrain_validloader:\n        if torch.cuda.is_available():\n            data, labels = data.cuda(), labels.cuda()\n        \n        target = model(data)\n        loss = loss_func(target,labels)\n        valid_loss = loss.item() * data.size(0)\n    #\n    # PRINT INFO\n    print(f'Epoch {e+1} \\t\\t Training Loss: {train_loss / len(train_0_loader)} \\t\\t Validation Loss: {valid_loss / len(validloader)}')\n    if min_valid_loss > valid_loss:\n        print(f'Validation Loss Decreased({min_valid_loss:.6f}--->{valid_loss:.6f}) \\t Saving The Model')\n        min_valid_loss = valid_loss\n        # Saving State Dict\n        torch.save(model.state_dict(), model_fixed)","metadata":{"id":"LG7Pl0Ih-E1R"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Testing on test","metadata":{"id":"X2TH5RDI-amm"}},{"cell_type":"code","source":"correct = 0\ntotal = 0\nwith torch.no_grad():\n    model.eval()\n    for data in retrain_testloader:\n        inputs, labels = data[0].to(DEVICE), data[1].to(DEVICE)\n        outputs = model(inputs)\n        _, predicted = torch.max(outputs.data, 1)\n        total += labels.size(0)\n        correct += (predicted == labels).sum().item()\nprint(\"Accuracy retrain (test): %d\" %(100 * correct/total))","metadata":{"id":"whslI7ZC-dAz"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# TestSet predict","metadata":{}},{"cell_type":"code","source":"X_Test_pred = [name for name in (os.listdir(test_dataset_dir))]","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"testset_pred = GetData(test_dataset_dir, X_Test_pred, None, transformations_0)\ntestloader_pred = DataLoader(testset_pred, batch_size=BATCH_SIZE, shuffle=False, num_workers=4)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"to_submit = []\ncorrect = 0\ntotal = 0\nwith torch.no_grad():\n    model.eval()\n    for image, fname in testloader_pred: \n        image = image.to(DEVICE)\n        \n        logits = model(image)        \n        ps = torch.exp(logits)        \n        _, top_class = ps.topk(1, dim=1)\n        \n        for pred in top_class:\n            to_submit.append([fname[0], pred.item()])","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub = pd.DataFrame.from_records(to_submit, columns=['image_id', 'label'])\nsub.head()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub.to_csv('submission.csv', index=False)","metadata":{},"execution_count":null,"outputs":[]}]}