├── Accident Detection from CCTV └── spinal-tl-for-accident-detection-from-cctv-images.ipynb ├── Hyperspectral Image Classification ├── HSI.ipynb ├── HSI_Confusion Matrix.png ├── HSI_KSC.py ├── HSI_cmap.png └── HSI_gt.png └── README.md /Accident Detection from CCTV/spinal-tl-for-accident-detection-from-cctv-images.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "municipal-constitutional", 6 | "metadata": { 7 | "papermill": { 8 | "duration": 0.010268, 9 | "end_time": "2021-06-17T06:12:08.694665", 10 | "exception": false, 11 | "start_time": "2021-06-17T06:12:08.684397", 12 | "status": "completed" 13 | }, 14 | "tags": [] 15 | }, 16 | "source": [ 17 | "# Transfer learning with SpinalNet fully connected layer for accident detection from CCTV footage.\n", 18 | "\n", 19 | "### We write this code with the help of PyTorch demo:\n", 20 | "### https://pytorch.org/tutorials/beginner/transfer_learning_tutorial.html\n", 21 | "\n", 22 | "## More scripts are available in earlier versions of the notebook.\n", 23 | "\n", 24 | "### For more code of SpinalNet, please visit: https://github.com/dipuk0506/SpinalNet" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "id": "architectural-browse", 30 | "metadata": { 31 | "papermill": { 32 | "duration": 0.008843, 33 | "end_time": "2021-06-17T06:12:08.712718", 34 | "exception": false, 35 | "start_time": "2021-06-17T06:12:08.703875", 36 | "status": "completed" 37 | }, 38 | "tags": [] 39 | }, 40 | "source": [ 41 | "# Dataloader and Visualization" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 1, 47 | "id": "thousand-drawing", 48 | "metadata": { 49 | "execution": { 50 | "iopub.execute_input": "2021-06-17T06:12:08.747498Z", 51 | "iopub.status.busy": "2021-06-17T06:12:08.744374Z", 52 | "iopub.status.idle": "2021-06-17T06:12:12.004408Z", 53 | "shell.execute_reply": "2021-06-17T06:12:12.003464Z", 54 | "shell.execute_reply.started": "2021-06-17T06:04:24.072558Z" 55 | }, 56 | "papermill": { 57 | "duration": 3.282871, 58 | "end_time": "2021-06-17T06:12:12.004559", 59 | "exception": false, 60 | "start_time": "2021-06-17T06:12:08.721688", 61 | "status": "completed" 62 | }, 63 | "tags": [] 64 | }, 65 | "outputs": [ 66 | { 67 | "data": { 68 | "image/png": "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\n", 69 | "text/plain": [ 70 | "
" 71 | ] 72 | }, 73 | "metadata": { 74 | "needs_background": "light" 75 | }, 76 | "output_type": "display_data" 77 | } 78 | ], 79 | "source": [ 80 | "\n", 81 | "from __future__ import print_function, division\n", 82 | "\n", 83 | "import torch\n", 84 | "import torch.nn as nn\n", 85 | "import torch.optim as optim\n", 86 | "from torch.optim import lr_scheduler\n", 87 | "import numpy as np\n", 88 | "import torchvision\n", 89 | "from torchvision import datasets, models, transforms\n", 90 | "import matplotlib.pyplot as plt\n", 91 | "import time\n", 92 | "import os\n", 93 | "import copy\n", 94 | "\n", 95 | "\n", 96 | "\n", 97 | "\n", 98 | "plt.ion() # interactive mode\n", 99 | "\n", 100 | "# Data augmentation and normalization for training\n", 101 | "# Just normalization for validation\n", 102 | "data_transforms = {\n", 103 | " 'train': transforms.Compose([\n", 104 | " transforms.Resize((512,512)),\n", 105 | " transforms.RandomRotation(15,),\n", 106 | " transforms.RandomHorizontalFlip(),\n", 107 | " transforms.ToTensor(),\n", 108 | " transforms.Normalize(mean=[0.507, 0.487, 0.441], std=[0.267, 0.256, 0.276])\n", 109 | " ]),\n", 110 | " 'val': transforms.Compose([\n", 111 | " transforms.Resize((512,512)),\n", 112 | " transforms.ToTensor(),\n", 113 | " transforms.Normalize(mean=[0.507, 0.487, 0.441], std=[0.267, 0.256, 0.276])\n", 114 | " ]),\n", 115 | " 'test': transforms.Compose([\n", 116 | " transforms.Resize((512,512)),\n", 117 | " transforms.ToTensor(),\n", 118 | " transforms.Normalize(mean=[0.507, 0.487, 0.441], std=[0.267, 0.256, 0.276])\n", 119 | " ]),\n", 120 | "}\n", 121 | "\n", 122 | "data_dir = '../input/accident-detection-from-cctv-footage/data'\n", 123 | "image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x),\n", 124 | " data_transforms[x])\n", 125 | " for x in ['train', 'val', 'test']}\n", 126 | "dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=8,\n", 127 | " shuffle=True, num_workers=0)\n", 128 | " for x in ['train', 'val', 'test']}\n", 129 | "dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val', 'test']}\n", 130 | "class_names = image_datasets['train'].classes\n", 131 | "\n", 132 | "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n", 133 | "\n", 134 | "def imshow(inp, title=None):\n", 135 | " \"\"\"Imshow for Tensor.\"\"\"\n", 136 | " inp = inp.numpy().transpose((1, 2, 0))\n", 137 | " mean = np.array([0.485, 0.456, 0.406])\n", 138 | " std = np.array([0.229, 0.224, 0.225])\n", 139 | " inp = std * inp + mean\n", 140 | " inp = np.clip(inp, 0, 1)\n", 141 | " plt.imshow(inp)\n", 142 | " if title is not None:\n", 143 | " plt.title(title)\n", 144 | " plt.pause(0.001) # pause a bit so that plots are updated\n", 145 | "\n", 146 | "\n", 147 | "# Get a batch of training data\n", 148 | "inputs, classes = next(iter(dataloaders['train']))\n", 149 | "\n", 150 | "# Make a grid from batch\n", 151 | "out = torchvision.utils.make_grid(inputs)\n", 152 | "\n", 153 | "imshow(out)#, title=[class_names[x] for x in classes])" 154 | ] 155 | }, 156 | { 157 | "cell_type": "markdown", 158 | "id": "acting-immune", 159 | "metadata": { 160 | "papermill": { 161 | "duration": 0.010411, 162 | "end_time": "2021-06-17T06:12:12.026314", 163 | "exception": false, 164 | "start_time": "2021-06-17T06:12:12.015903", 165 | "status": "completed" 166 | }, 167 | "tags": [] 168 | }, 169 | "source": [ 170 | "# Downloading Model and Changing Fully-connected/ Classifier Layer" 171 | ] 172 | }, 173 | { 174 | "cell_type": "code", 175 | "execution_count": 2, 176 | "id": "driving-newfoundland", 177 | "metadata": { 178 | "execution": { 179 | "iopub.execute_input": "2021-06-17T06:12:12.072560Z", 180 | "iopub.status.busy": "2021-06-17T06:12:12.071720Z", 181 | "iopub.status.idle": "2021-06-17T06:12:38.510818Z", 182 | "shell.execute_reply": "2021-06-17T06:12:38.510343Z", 183 | "shell.execute_reply.started": "2021-06-17T06:04:26.954454Z" 184 | }, 185 | "papermill": { 186 | "duration": 26.474321, 187 | "end_time": "2021-06-17T06:12:38.510950", 188 | "exception": false, 189 | "start_time": "2021-06-17T06:12:12.036629", 190 | "status": "completed" 191 | }, 192 | "tags": [] 193 | }, 194 | "outputs": [ 195 | { 196 | "name": "stderr", 197 | "output_type": "stream", 198 | "text": [ 199 | "Downloading: \"https://download.pytorch.org/models/vgg19_bn-c79401a0.pth\" to /root/.cache/torch/hub/checkpoints/vgg19_bn-c79401a0.pth\n" 200 | ] 201 | }, 202 | { 203 | "data": { 204 | "application/vnd.jupyter.widget-view+json": { 205 | "model_id": "1534c8af727a4f6bbfee39b99b598433", 206 | "version_major": 2, 207 | "version_minor": 0 208 | }, 209 | "text/plain": [ 210 | " 0%| | 0.00/548M [00:00 best_acc:\n", 443 | " best_acc = epoch_acc\n", 444 | " best_model_wts = copy.deepcopy(model.state_dict())\n", 445 | " test_token =1\n", 446 | " print()\n", 447 | "\n", 448 | " time_elapsed = time.time() - since\n", 449 | " print('Training complete in {:.0f}m {:.0f}s'.format(\n", 450 | " time_elapsed // 60, time_elapsed % 60))\n", 451 | " print('Best val Acc: {:4f}'.format(best_acc))\n", 452 | "\n", 453 | " # load best model weights\n", 454 | " model.load_state_dict(best_model_wts)\n", 455 | " return model\n", 456 | "\n" 457 | ] 458 | }, 459 | { 460 | "cell_type": "markdown", 461 | "id": "random-triple", 462 | "metadata": { 463 | "papermill": { 464 | "duration": 0.010677, 465 | "end_time": "2021-06-17T06:12:38.591815", 466 | "exception": false, 467 | "start_time": "2021-06-17T06:12:38.581138", 468 | "status": "completed" 469 | }, 470 | "tags": [] 471 | }, 472 | "source": [ 473 | "# Training with lr=0.01" 474 | ] 475 | }, 476 | { 477 | "cell_type": "code", 478 | "execution_count": 4, 479 | "id": "suited-japan", 480 | "metadata": { 481 | "execution": { 482 | "iopub.execute_input": "2021-06-17T06:12:38.621711Z", 483 | "iopub.status.busy": "2021-06-17T06:12:38.621108Z", 484 | "iopub.status.idle": "2021-06-17T06:19:05.241260Z", 485 | "shell.execute_reply": "2021-06-17T06:19:05.240637Z", 486 | "shell.execute_reply.started": "2021-06-17T06:04:54.039059Z" 487 | }, 488 | "papermill": { 489 | "duration": 386.638834, 490 | "end_time": "2021-06-17T06:19:05.241402", 491 | "exception": false, 492 | "start_time": "2021-06-17T06:12:38.602568", 493 | "status": "completed" 494 | }, 495 | "tags": [] 496 | }, 497 | "outputs": [ 498 | { 499 | "name": "stdout", 500 | "output_type": "stream", 501 | "text": [ 502 | "Epoch 0/4\n", 503 | "----------\n", 504 | "train Loss: 0.6149 Acc: 0.6726\n", 505 | "val Loss: 0.4118 Acc: 0.8265\n", 506 | "test Loss: 0.4686 Acc: 0.7600\n", 507 | "\n", 508 | "Epoch 1/4\n", 509 | "----------\n", 510 | "train Loss: 0.4793 Acc: 0.7737\n", 511 | "val Loss: 0.3923 Acc: 0.8265\n", 512 | "\n", 513 | "Epoch 2/4\n", 514 | "----------\n", 515 | "train Loss: 0.3616 Acc: 0.8420\n", 516 | "val Loss: 0.4368 Acc: 0.7755\n", 517 | "\n", 518 | "Epoch 3/4\n", 519 | "----------\n", 520 | "train Loss: 0.3238 Acc: 0.8710\n", 521 | "val Loss: 0.3438 Acc: 0.8878\n", 522 | "test Loss: 0.3077 Acc: 0.8800\n", 523 | "\n", 524 | "Epoch 4/4\n", 525 | "----------\n", 526 | "train Loss: 0.2772 Acc: 0.9014\n", 527 | "val Loss: 0.2953 Acc: 0.8980\n", 528 | "test Loss: 0.3144 Acc: 0.8600\n", 529 | "\n", 530 | "Training complete in 6m 23s\n", 531 | "Best val Acc: 0.897959\n" 532 | ] 533 | } 534 | ], 535 | "source": [ 536 | "model_ft = model_ft.to(device)\n", 537 | "\n", 538 | "criterion = nn.CrossEntropyLoss()\n", 539 | "\n", 540 | "# Observe that all parameters are being optimized\n", 541 | "optimizer_ft = optim.SGD(model_ft.parameters(), lr=0.01, momentum=0.9)\n", 542 | "\n", 543 | "# Decay LR by a factor of 0.1 every 7 epochs\n", 544 | "exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=0.1)\n", 545 | "\n", 546 | "model_ft = train_model(model_ft, criterion, optimizer_ft, exp_lr_scheduler,\n", 547 | " num_epochs=5)" 548 | ] 549 | }, 550 | { 551 | "cell_type": "markdown", 552 | "id": "brown-suite", 553 | "metadata": { 554 | "papermill": { 555 | "duration": 0.014777, 556 | "end_time": "2021-06-17T06:19:05.270913", 557 | "exception": false, 558 | "start_time": "2021-06-17T06:19:05.256136", 559 | "status": "completed" 560 | }, 561 | "tags": [] 562 | }, 563 | "source": [ 564 | "# Training with lr=0.001" 565 | ] 566 | }, 567 | { 568 | "cell_type": "code", 569 | "execution_count": 5, 570 | "id": "union-grammar", 571 | "metadata": { 572 | "execution": { 573 | "iopub.execute_input": "2021-06-17T06:19:05.306597Z", 574 | "iopub.status.busy": "2021-06-17T06:19:05.305860Z", 575 | "iopub.status.idle": "2021-06-17T06:25:00.723039Z", 576 | "shell.execute_reply": "2021-06-17T06:25:00.723448Z", 577 | "shell.execute_reply.started": "2021-06-17T06:04:58.031104Z" 578 | }, 579 | "papermill": { 580 | "duration": 355.437759, 581 | "end_time": "2021-06-17T06:25:00.723626", 582 | "exception": false, 583 | "start_time": "2021-06-17T06:19:05.285867", 584 | "status": "completed" 585 | }, 586 | "tags": [] 587 | }, 588 | "outputs": [ 589 | { 590 | "name": "stdout", 591 | "output_type": "stream", 592 | "text": [ 593 | "Epoch 0/4\n", 594 | "----------\n", 595 | "train Loss: 0.1904 Acc: 0.9191\n", 596 | "val Loss: 0.1863 Acc: 0.9490\n", 597 | "test Loss: 0.1356 Acc: 0.9500\n", 598 | "\n", 599 | "Epoch 1/4\n", 600 | "----------\n", 601 | "train Loss: 0.1159 Acc: 0.9558\n", 602 | "val Loss: 0.1612 Acc: 0.9490\n", 603 | "\n", 604 | "Epoch 2/4\n", 605 | "----------\n", 606 | "train Loss: 0.1196 Acc: 0.9570\n", 607 | "val Loss: 0.1808 Acc: 0.9490\n", 608 | "\n", 609 | "Epoch 3/4\n", 610 | "----------\n", 611 | "train Loss: 0.0949 Acc: 0.9583\n", 612 | "val Loss: 0.1228 Acc: 0.9490\n", 613 | "\n", 614 | "Epoch 4/4\n", 615 | "----------\n", 616 | "train Loss: 0.0810 Acc: 0.9697\n", 617 | "val Loss: 0.1396 Acc: 0.9490\n", 618 | "\n", 619 | "Training complete in 5m 55s\n", 620 | "Best val Acc: 0.948980\n" 621 | ] 622 | } 623 | ], 624 | "source": [ 625 | "# Observe that all parameters are being optimized\n", 626 | "optimizer_ft = optim.SGD(model_ft.parameters(), lr=0.001, momentum=0.9)\n", 627 | "\n", 628 | "# Decay LR by a factor of 0.1 every 7 epochs\n", 629 | "exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=0.1)\n", 630 | "\n", 631 | "model_ft = train_model(model_ft, criterion, optimizer_ft, exp_lr_scheduler,\n", 632 | " num_epochs=5)" 633 | ] 634 | }, 635 | { 636 | "cell_type": "markdown", 637 | "id": "finite-chester", 638 | "metadata": { 639 | "papermill": { 640 | "duration": 0.017422, 641 | "end_time": "2021-06-17T06:25:00.758656", 642 | "exception": false, 643 | "start_time": "2021-06-17T06:25:00.741234", 644 | "status": "completed" 645 | }, 646 | "tags": [] 647 | }, 648 | "source": [ 649 | "## Confusion Matrix\n", 650 | "\n", 651 | "### Validation Data" 652 | ] 653 | }, 654 | { 655 | "cell_type": "code", 656 | "execution_count": 6, 657 | "id": "above-fellow", 658 | "metadata": { 659 | "execution": { 660 | "iopub.execute_input": "2021-06-17T06:25:00.801299Z", 661 | "iopub.status.busy": "2021-06-17T06:25:00.800697Z", 662 | "iopub.status.idle": "2021-06-17T06:25:06.244961Z", 663 | "shell.execute_reply": "2021-06-17T06:25:06.245333Z", 664 | "shell.execute_reply.started": "2021-06-17T06:11:18.983248Z" 665 | }, 666 | "papermill": { 667 | "duration": 5.469343, 668 | "end_time": "2021-06-17T06:25:06.245480", 669 | "exception": false, 670 | "start_time": "2021-06-17T06:25:00.776137", 671 | "status": "completed" 672 | }, 673 | "tags": [] 674 | }, 675 | "outputs": [ 676 | { 677 | "data": { 678 | "text/plain": [ 679 | "" 680 | ] 681 | }, 682 | "execution_count": 6, 683 | "metadata": {}, 684 | "output_type": "execute_result" 685 | }, 686 | { 687 | "data": { 688 | "image/png": "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\n", 689 | "text/plain": [ 690 | "
" 691 | ] 692 | }, 693 | "metadata": { 694 | "needs_background": "light" 695 | }, 696 | "output_type": "display_data" 697 | } 698 | ], 699 | "source": [ 700 | "from sklearn.metrics import confusion_matrix\n", 701 | "import seaborn as sn\n", 702 | "import pandas as pd\n", 703 | "\n", 704 | "y_pred = []\n", 705 | "y_true = []\n", 706 | "\n", 707 | "# iterate over test data\n", 708 | "for inputs, labels in dataloaders['val']:\n", 709 | " inputs = inputs.to(device)\n", 710 | " labels = labels.to(device)\n", 711 | " \n", 712 | " output = model_ft(inputs) # Feed Network\n", 713 | "\n", 714 | " output = (torch.max(torch.exp(output), 1)[1]).data.cpu().numpy()\n", 715 | " y_pred.extend(output) # Save Prediction\n", 716 | " \n", 717 | " labels = labels.data.cpu().numpy()\n", 718 | " y_true.extend(labels) # Save Truth\n", 719 | "\n", 720 | "# constant for classes\n", 721 | "classes = ('Accident', 'Normal')\n", 722 | "\n", 723 | "# Build confusion matrix\n", 724 | "cf_matrix = confusion_matrix(y_true, y_pred)\n", 725 | "df_cm = pd.DataFrame(cf_matrix, index = [i for i in classes],\n", 726 | " columns = [i for i in classes])\n", 727 | "\n", 728 | "\n", 729 | "\n", 730 | "plt.figure(figsize = (6,2),dpi=100)\n", 731 | "plt.rcParams['font.size'] = '16'\n", 732 | "sn.heatmap(df_cm, annot=True, fmt=\".0f\")" 733 | ] 734 | }, 735 | { 736 | "cell_type": "markdown", 737 | "id": "constitutional-equity", 738 | "metadata": { 739 | "papermill": { 740 | "duration": 0.01864, 741 | "end_time": "2021-06-17T06:25:06.283530", 742 | "exception": false, 743 | "start_time": "2021-06-17T06:25:06.264890", 744 | "status": "completed" 745 | }, 746 | "tags": [] 747 | }, 748 | "source": [ 749 | "### Test Data" 750 | ] 751 | }, 752 | { 753 | "cell_type": "code", 754 | "execution_count": 7, 755 | "id": "shaped-journalist", 756 | "metadata": { 757 | "execution": { 758 | "iopub.execute_input": "2021-06-17T06:25:06.328395Z", 759 | "iopub.status.busy": "2021-06-17T06:25:06.327868Z", 760 | "iopub.status.idle": "2021-06-17T06:25:10.858779Z", 761 | "shell.execute_reply": "2021-06-17T06:25:10.859207Z", 762 | "shell.execute_reply.started": "2021-06-17T06:11:07.062855Z" 763 | }, 764 | "papermill": { 765 | "duration": 4.556761, 766 | "end_time": "2021-06-17T06:25:10.859362", 767 | "exception": false, 768 | "start_time": "2021-06-17T06:25:06.302601", 769 | "status": "completed" 770 | }, 771 | "tags": [] 772 | }, 773 | "outputs": [ 774 | { 775 | "data": { 776 | "text/plain": [ 777 | "" 778 | ] 779 | }, 780 | "execution_count": 7, 781 | "metadata": {}, 782 | "output_type": "execute_result" 783 | }, 784 | { 785 | "data": { 786 | "image/png": "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\n", 787 | "text/plain": [ 788 | "
" 789 | ] 790 | }, 791 | "metadata": { 792 | "needs_background": "light" 793 | }, 794 | "output_type": "display_data" 795 | } 796 | ], 797 | "source": [ 798 | "y_pred = []\n", 799 | "y_true = []\n", 800 | "\n", 801 | "# iterate over test data\n", 802 | "for inputs, labels in dataloaders['test']:\n", 803 | " inputs = inputs.to(device)\n", 804 | " labels = labels.to(device)\n", 805 | " \n", 806 | " output = model_ft(inputs) # Feed Network\n", 807 | "\n", 808 | " output = (torch.max(torch.exp(output), 1)[1]).data.cpu().numpy()\n", 809 | " y_pred.extend(output) # Save Prediction\n", 810 | " \n", 811 | " labels = labels.data.cpu().numpy()\n", 812 | " y_true.extend(labels) # Save Truth\n", 813 | "\n", 814 | "\n", 815 | "# Build confusion matrix\n", 816 | "cf_matrix = confusion_matrix(y_true, y_pred)\n", 817 | "df_cm = pd.DataFrame(cf_matrix, index = [i for i in classes],\n", 818 | " columns = [i for i in classes])\n", 819 | "\n", 820 | "\n", 821 | "\n", 822 | "plt.figure(figsize = (6,2),dpi=100)\n", 823 | "plt.rcParams['font.size'] = '16'\n", 824 | "sn.heatmap(df_cm, annot=True, fmt=\".0f\")" 825 | ] 826 | } 827 | ], 828 | "metadata": { 829 | "kernelspec": { 830 | "display_name": "Python 3", 831 | "language": "python", 832 | "name": "python3" 833 | }, 834 | "language_info": { 835 | "codemirror_mode": { 836 | "name": "ipython", 837 | "version": 3 838 | }, 839 | "file_extension": ".py", 840 | "mimetype": "text/x-python", 841 | "name": "python", 842 | "nbconvert_exporter": "python", 843 | "pygments_lexer": "ipython3", 844 | "version": "3.7.9" 845 | }, 846 | "papermill": { 847 | "default_parameters": {}, 848 | "duration": 788.176224, 849 | "end_time": "2021-06-17T06:25:11.789186", 850 | "environment_variables": {}, 851 | "exception": null, 852 | "input_path": "__notebook__.ipynb", 853 | "output_path": "__notebook__.ipynb", 854 | "parameters": {}, 855 | "start_time": "2021-06-17T06:12:03.612962", 856 | "version": "2.3.2" 857 | }, 858 | "widgets": { 859 | "application/vnd.jupyter.widget-state+json": { 860 | "state": { 861 | "1534c8af727a4f6bbfee39b99b598433": { 862 | "model_module": "@jupyter-widgets/controls", 863 | "model_module_version": "1.5.0", 864 | "model_name": "HBoxModel", 865 | "state": { 866 | "_dom_classes": [], 867 | "_model_module": "@jupyter-widgets/controls", 868 | "_model_module_version": "1.5.0", 869 | "_model_name": "HBoxModel", 870 | "_view_count": null, 871 | "_view_module": "@jupyter-widgets/controls", 872 | "_view_module_version": "1.5.0", 873 | "_view_name": "HBoxView", 874 | "box_style": "", 875 | "children": [ 876 | "IPY_MODEL_a7c6dcfddd614bb68dd82e716d8377a0", 877 | "IPY_MODEL_9a4dca1f75454ba5837c55beec9286f3", 878 | "IPY_MODEL_93dc77cdf0b74bf1bc5ca2b837f8019d" 879 | ], 880 | "layout": "IPY_MODEL_f23b1483f4124b3b8abb31c800ff57e0" 881 | } 882 | }, 883 | "93dc77cdf0b74bf1bc5ca2b837f8019d": { 884 | "model_module": "@jupyter-widgets/controls", 885 | "model_module_version": "1.5.0", 886 | "model_name": "HTMLModel", 887 | "state": { 888 | "_dom_classes": [], 889 | "_model_module": "@jupyter-widgets/controls", 890 | "_model_module_version": "1.5.0", 891 | "_model_name": "HTMLModel", 892 | "_view_count": null, 893 | "_view_module": "@jupyter-widgets/controls", 894 | "_view_module_version": "1.5.0", 895 | "_view_name": "HTMLView", 896 | "description": "", 897 | "description_tooltip": null, 898 | "layout": "IPY_MODEL_f9f319b591d04a5582ba154669f8fcae", 899 | "placeholder": "​", 900 | "style": "IPY_MODEL_dc73a049f79145518f4b7616c1bf787b", 901 | "value": " 548M/548M [00:23<00:00, 25.6MB/s]" 902 | } 903 | }, 904 | "9a4dca1f75454ba5837c55beec9286f3": { 905 | "model_module": "@jupyter-widgets/controls", 906 | "model_module_version": "1.5.0", 907 | "model_name": "FloatProgressModel", 908 | "state": { 909 | "_dom_classes": [], 910 | "_model_module": "@jupyter-widgets/controls", 911 | "_model_module_version": "1.5.0", 912 | "_model_name": "FloatProgressModel", 913 | "_view_count": null, 914 | "_view_module": "@jupyter-widgets/controls", 915 | "_view_module_version": "1.5.0", 916 | "_view_name": "ProgressView", 917 | "bar_style": "success", 918 | "description": "", 919 | "description_tooltip": null, 920 | "layout": "IPY_MODEL_bb7f62c39f984afeb9e825e138110ef4", 921 | "max": 574769405.0, 922 | "min": 0.0, 923 | "orientation": "horizontal", 924 | "style": "IPY_MODEL_b29fe8088a5f478a896b84d4dd19975c", 925 | "value": 574769405.0 926 | } 927 | }, 928 | "a7c6dcfddd614bb68dd82e716d8377a0": { 929 | "model_module": "@jupyter-widgets/controls", 930 | "model_module_version": "1.5.0", 931 | "model_name": "HTMLModel", 932 | "state": { 933 | "_dom_classes": [], 934 | "_model_module": "@jupyter-widgets/controls", 935 | "_model_module_version": "1.5.0", 936 | "_model_name": "HTMLModel", 937 | "_view_count": null, 938 | "_view_module": "@jupyter-widgets/controls", 939 | "_view_module_version": "1.5.0", 940 | "_view_name": "HTMLView", 941 | "description": "", 942 | "description_tooltip": null, 943 | "layout": "IPY_MODEL_f0ede7f0058949e6962971a3aafea582", 944 | "placeholder": "​", 945 | "style": "IPY_MODEL_cf8a8d029ee94ba39d73afc14fbd7dcf", 946 | "value": "100%" 947 | } 948 | }, 949 | "b29fe8088a5f478a896b84d4dd19975c": { 950 | "model_module": "@jupyter-widgets/controls", 951 | "model_module_version": "1.5.0", 952 | "model_name": "ProgressStyleModel", 953 | "state": { 954 | "_model_module": "@jupyter-widgets/controls", 955 | "_model_module_version": "1.5.0", 956 | "_model_name": "ProgressStyleModel", 957 | "_view_count": null, 958 | "_view_module": "@jupyter-widgets/base", 959 | "_view_module_version": "1.2.0", 960 | "_view_name": "StyleView", 961 | "bar_color": null, 962 | "description_width": "" 963 | } 964 | }, 965 | "bb7f62c39f984afeb9e825e138110ef4": { 966 | "model_module": "@jupyter-widgets/base", 967 | "model_module_version": "1.2.0", 968 | "model_name": "LayoutModel", 969 | "state": { 970 | "_model_module": "@jupyter-widgets/base", 971 | "_model_module_version": "1.2.0", 972 | "_model_name": "LayoutModel", 973 | "_view_count": null, 974 | "_view_module": "@jupyter-widgets/base", 975 | "_view_module_version": "1.2.0", 976 | "_view_name": "LayoutView", 977 | "align_content": null, 978 | "align_items": null, 979 | "align_self": null, 980 | "border": null, 981 | "bottom": null, 982 | "display": null, 983 | "flex": null, 984 | "flex_flow": null, 985 | "grid_area": null, 986 | "grid_auto_columns": null, 987 | "grid_auto_flow": null, 988 | "grid_auto_rows": null, 989 | "grid_column": null, 990 | "grid_gap": null, 991 | "grid_row": null, 992 | "grid_template_areas": null, 993 | "grid_template_columns": null, 994 | "grid_template_rows": null, 995 | "height": null, 996 | "justify_content": null, 997 | "justify_items": null, 998 | "left": null, 999 | "margin": null, 1000 | "max_height": null, 1001 | "max_width": null, 1002 | "min_height": null, 1003 | "min_width": null, 1004 | "object_fit": null, 1005 | "object_position": null, 1006 | "order": null, 1007 | "overflow": null, 1008 | "overflow_x": null, 1009 | "overflow_y": null, 1010 | "padding": null, 1011 | "right": null, 1012 | "top": null, 1013 | "visibility": null, 1014 | "width": null 1015 | } 1016 | }, 1017 | "cf8a8d029ee94ba39d73afc14fbd7dcf": { 1018 | "model_module": "@jupyter-widgets/controls", 1019 | "model_module_version": "1.5.0", 1020 | "model_name": "DescriptionStyleModel", 1021 | "state": { 1022 | "_model_module": "@jupyter-widgets/controls", 1023 | "_model_module_version": "1.5.0", 1024 | "_model_name": "DescriptionStyleModel", 1025 | "_view_count": null, 1026 | "_view_module": "@jupyter-widgets/base", 1027 | "_view_module_version": "1.2.0", 1028 | "_view_name": "StyleView", 1029 | "description_width": "" 1030 | } 1031 | }, 1032 | "dc73a049f79145518f4b7616c1bf787b": { 1033 | "model_module": "@jupyter-widgets/controls", 1034 | "model_module_version": "1.5.0", 1035 | "model_name": "DescriptionStyleModel", 1036 | "state": { 1037 | "_model_module": "@jupyter-widgets/controls", 1038 | "_model_module_version": "1.5.0", 1039 | "_model_name": "DescriptionStyleModel", 1040 | "_view_count": null, 1041 | "_view_module": "@jupyter-widgets/base", 1042 | "_view_module_version": "1.2.0", 1043 | "_view_name": "StyleView", 1044 | "description_width": "" 1045 | } 1046 | }, 1047 | "f0ede7f0058949e6962971a3aafea582": { 1048 | "model_module": "@jupyter-widgets/base", 1049 | "model_module_version": "1.2.0", 1050 | "model_name": "LayoutModel", 1051 | "state": { 1052 | "_model_module": "@jupyter-widgets/base", 1053 | "_model_module_version": "1.2.0", 1054 | "_model_name": "LayoutModel", 1055 | "_view_count": null, 1056 | "_view_module": "@jupyter-widgets/base", 1057 | "_view_module_version": "1.2.0", 1058 | "_view_name": "LayoutView", 1059 | "align_content": null, 1060 | "align_items": null, 1061 | "align_self": null, 1062 | "border": null, 1063 | "bottom": null, 1064 | "display": null, 1065 | "flex": null, 1066 | "flex_flow": null, 1067 | "grid_area": null, 1068 | "grid_auto_columns": null, 1069 | "grid_auto_flow": null, 1070 | "grid_auto_rows": null, 1071 | "grid_column": null, 1072 | "grid_gap": null, 1073 | "grid_row": null, 1074 | "grid_template_areas": null, 1075 | "grid_template_columns": null, 1076 | "grid_template_rows": null, 1077 | "height": null, 1078 | "justify_content": null, 1079 | "justify_items": null, 1080 | "left": null, 1081 | "margin": null, 1082 | "max_height": null, 1083 | "max_width": null, 1084 | "min_height": null, 1085 | "min_width": null, 1086 | "object_fit": null, 1087 | "object_position": null, 1088 | "order": null, 1089 | "overflow": null, 1090 | "overflow_x": null, 1091 | "overflow_y": null, 1092 | "padding": null, 1093 | "right": null, 1094 | "top": null, 1095 | "visibility": null, 1096 | "width": null 1097 | } 1098 | }, 1099 | "f23b1483f4124b3b8abb31c800ff57e0": { 1100 | "model_module": "@jupyter-widgets/base", 1101 | "model_module_version": "1.2.0", 1102 | "model_name": "LayoutModel", 1103 | "state": { 1104 | "_model_module": "@jupyter-widgets/base", 1105 | "_model_module_version": "1.2.0", 1106 | "_model_name": "LayoutModel", 1107 | "_view_count": null, 1108 | "_view_module": "@jupyter-widgets/base", 1109 | "_view_module_version": "1.2.0", 1110 | "_view_name": "LayoutView", 1111 | "align_content": null, 1112 | "align_items": null, 1113 | "align_self": null, 1114 | "border": null, 1115 | "bottom": null, 1116 | "display": null, 1117 | "flex": null, 1118 | "flex_flow": null, 1119 | "grid_area": null, 1120 | "grid_auto_columns": null, 1121 | "grid_auto_flow": null, 1122 | "grid_auto_rows": null, 1123 | "grid_column": null, 1124 | "grid_gap": null, 1125 | "grid_row": null, 1126 | "grid_template_areas": null, 1127 | "grid_template_columns": null, 1128 | "grid_template_rows": null, 1129 | "height": null, 1130 | "justify_content": null, 1131 | "justify_items": null, 1132 | "left": null, 1133 | "margin": null, 1134 | "max_height": null, 1135 | "max_width": null, 1136 | "min_height": null, 1137 | "min_width": null, 1138 | "object_fit": null, 1139 | "object_position": null, 1140 | "order": null, 1141 | "overflow": null, 1142 | "overflow_x": null, 1143 | "overflow_y": null, 1144 | "padding": null, 1145 | "right": null, 1146 | "top": null, 1147 | "visibility": null, 1148 | "width": null 1149 | } 1150 | }, 1151 | "f9f319b591d04a5582ba154669f8fcae": { 1152 | "model_module": "@jupyter-widgets/base", 1153 | "model_module_version": "1.2.0", 1154 | "model_name": "LayoutModel", 1155 | "state": { 1156 | "_model_module": "@jupyter-widgets/base", 1157 | "_model_module_version": "1.2.0", 1158 | "_model_name": "LayoutModel", 1159 | "_view_count": null, 1160 | "_view_module": "@jupyter-widgets/base", 1161 | "_view_module_version": "1.2.0", 1162 | "_view_name": "LayoutView", 1163 | "align_content": null, 1164 | "align_items": null, 1165 | "align_self": null, 1166 | "border": null, 1167 | "bottom": null, 1168 | "display": null, 1169 | "flex": null, 1170 | "flex_flow": null, 1171 | "grid_area": null, 1172 | "grid_auto_columns": null, 1173 | "grid_auto_flow": null, 1174 | "grid_auto_rows": null, 1175 | "grid_column": null, 1176 | "grid_gap": null, 1177 | "grid_row": null, 1178 | "grid_template_areas": null, 1179 | "grid_template_columns": null, 1180 | "grid_template_rows": null, 1181 | "height": null, 1182 | "justify_content": null, 1183 | "justify_items": null, 1184 | "left": null, 1185 | "margin": null, 1186 | "max_height": null, 1187 | "max_width": null, 1188 | "min_height": null, 1189 | "min_width": null, 1190 | "object_fit": null, 1191 | "object_position": null, 1192 | "order": null, 1193 | "overflow": null, 1194 | "overflow_x": null, 1195 | "overflow_y": null, 1196 | "padding": null, 1197 | "right": null, 1198 | "top": null, 1199 | "visibility": null, 1200 | "width": null 1201 | } 1202 | } 1203 | }, 1204 | "version_major": 2, 1205 | "version_minor": 0 1206 | } 1207 | } 1208 | }, 1209 | "nbformat": 4, 1210 | "nbformat_minor": 5 1211 | } 1212 | -------------------------------------------------------------------------------- /Hyperspectral Image Classification/HSI_Confusion Matrix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipuk0506/SpinalNet-Applications/08912f00345b1912476b6f62cd8a3b7823ed0fa5/Hyperspectral Image Classification/HSI_Confusion Matrix.png -------------------------------------------------------------------------------- /Hyperspectral Image Classification/HSI_KSC.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """KSC_PCA.ipynb 3 | 4 | Automatically generated by Colaboratory. 5 | 6 | Original file is located at 7 | https://colab.research.google.com/drive/13bVyVdv-yBFo30C4Ce_Q4eKjwpb5Sm8y 8 | """ 9 | 10 | # Commented out IPython magic to ensure Python compatibility. 11 | import numpy as np 12 | from sklearn.decomposition import PCA 13 | import scipy.io as sio 14 | from sklearn.model_selection import train_test_split 15 | from sklearn import preprocessing 16 | import os 17 | import random 18 | from random import shuffle 19 | from skimage.transform import rotate 20 | import scipy.ndimage 21 | import matplotlib.pyplot as plt 22 | # %matplotlib inline 23 | 24 | import torch 25 | 26 | from torch.utils.data import Dataset, DataLoader 27 | 28 | hsi_data= sio.loadmat('KSC.mat')['KSC'] 29 | labels = sio.loadmat('KSC_gt.mat')['KSC_gt'] 30 | 31 | [height,width,depth]=hsi_data.shape 32 | 33 | def splitTrainTestSet(X, y, testRatio=0.10): 34 | X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=testRatio, random_state=345, 35 | stratify=y) 36 | return X_train, X_test, y_train, y_test 37 | 38 | def oversampleWeakClasses(X, y): 39 | uniqueLabels, labelCounts = np.unique(y, return_counts=True) 40 | maxCount = np.max(labelCounts) 41 | labelInverseRatios = maxCount / labelCounts 42 | # repeat for every label and concat 43 | newX = X[y == uniqueLabels[0], :, :, :].repeat(round(labelInverseRatios[0]), axis=0) 44 | newY = y[y == uniqueLabels[0]].repeat(round(labelInverseRatios[0]), axis=0) 45 | for label, labelInverseRatio in zip(uniqueLabels[1:], labelInverseRatios[1:]): 46 | cX = X[y== label,:,:,:].repeat(round(labelInverseRatio), axis=0) 47 | cY = y[y == label].repeat(round(labelInverseRatio), axis=0) 48 | newX = np.concatenate((newX, cX)) 49 | newY = np.concatenate((newY, cY)) 50 | np.random.seed(seed=42) 51 | rand_perm = np.random.permutation(newY.shape[0]) 52 | newX = newX[rand_perm, :, :, :] 53 | newY = newY[rand_perm] 54 | return newX, newY 55 | 56 | def standartizeData(X): 57 | newX = np.reshape(X, (-1, X.shape[2])) 58 | scaler = preprocessing.StandardScaler().fit(newX) 59 | newX = scaler.transform(newX) 60 | newX = np.reshape(newX, (X.shape[0],X.shape[1],X.shape[2])) 61 | return newX, scaler 62 | 63 | def applyPCA(X, numComponents=75): 64 | newX = np.reshape(X, (-1, X.shape[2])) 65 | pca = PCA(n_components=numComponents, whiten=True) 66 | newX = pca.fit_transform(newX) 67 | newX = np.reshape(newX, (X.shape[0],X.shape[1], numComponents)) 68 | return newX, pca 69 | 70 | def padWithZeros(X, margin=2): 71 | newX = np.zeros((X.shape[0] + 2 * margin, X.shape[1] + 2* margin, X.shape[2])) 72 | x_offset = margin 73 | y_offset = margin 74 | newX[x_offset:X.shape[0] + x_offset, y_offset:X.shape[1] + y_offset, :] = X 75 | return newX 76 | 77 | def createPatches(X, y, windowSize=11, removeZeroLabels = True): 78 | margin = int((windowSize - 1) / 2) 79 | zeroPaddedX = padWithZeros(X, margin=margin) 80 | # split patches 81 | patchesData = np.zeros((X.shape[0] * X.shape[1], windowSize, windowSize, X.shape[2])) 82 | patchesLabels = np.zeros((X.shape[0] * X.shape[1])) 83 | patchIndex = 0 84 | for r in range(margin, zeroPaddedX.shape[0] - margin): 85 | for c in range(margin, zeroPaddedX.shape[1] - margin): 86 | patch = zeroPaddedX[r - margin:r + margin + 1, c - margin:c + margin + 1] 87 | patchesData[patchIndex, :, :, :] = patch 88 | patchesLabels[patchIndex] = y[r-margin, c-margin] 89 | patchIndex = patchIndex + 1 90 | if removeZeroLabels: 91 | patchesData = patchesData[patchesLabels>0,:,:,:] 92 | patchesLabels = patchesLabels[patchesLabels>0] 93 | patchesLabels -= 1 94 | return patchesData, patchesLabels 95 | 96 | 97 | def AugmentData(X_train): 98 | for i in range(int(X_train.shape[0]/2)): 99 | patch = X_train[i,:,:,:] 100 | num = random.randint(0,2) 101 | if (num == 0): 102 | 103 | flipped_patch = np.flipud(patch) 104 | if (num == 1): 105 | 106 | flipped_patch = np.fliplr(patch) 107 | if (num == 2): 108 | 109 | no = random.randrange(-180,180,30) 110 | flipped_patch = scipy.ndimage.interpolation.rotate(patch, no,axes=(1, 0), 111 | reshape=False, output=None, order=3, mode='constant', cval=0.0, prefilter=False) 112 | 113 | 114 | patch2 = flipped_patch 115 | X_train[i,:,:,:] = patch2 116 | 117 | return X_train 118 | 119 | import numpy as np 120 | import scipy 121 | import os 122 | from keras.models import Sequential 123 | from keras.layers import Dense, Dropout, Flatten 124 | from keras.layers import Conv2D, MaxPooling2D,BatchNormalization 125 | from tensorflow.keras.callbacks import EarlyStopping 126 | from tensorflow.keras.optimizers import SGD 127 | from keras import backend as K 128 | from keras.utils import np_utils 129 | from keras.utils.vis_utils import plot_model 130 | 131 | weight_of_size=10 132 | 133 | X=hsi_data 134 | y=labels 135 | 136 | X,pca = applyPCA(X,30) 137 | 138 | X.shape 139 | 140 | XPatches, yPatches = createPatches(X, y, windowSize=15) 141 | 142 | XPatches.shape 143 | 144 | X_train, X_test, y_train, y_test = splitTrainTestSet(XPatches, yPatches, testRatio=0.2) 145 | 146 | X_train=np.reshape(X_train,(X_train.shape[0],X_train.shape[3],X_train.shape[1],X_train.shape[1])) 147 | 148 | X_test=np.reshape(X_test,(X_test.shape[0],X_test.shape[3],X_test.shape[1],X_test.shape[1])) 149 | 150 | X_train.shape 151 | 152 | X_train.shape 153 | 154 | y_train 155 | 156 | class MyDataset(Dataset): 157 | def __init__(self, data, target, transform=None): 158 | self.data = torch.from_numpy(data).float() 159 | self.target = torch.from_numpy(target).int() 160 | self.transform = transform 161 | 162 | def __getitem__(self, index): 163 | x = self.data[index] 164 | y = self.target[index] 165 | 166 | if self.transform: 167 | x = self.transform(x) 168 | 169 | return x, y 170 | 171 | def __len__(self): 172 | return len(self.data) 173 | 174 | data_train = MyDataset(X_train, y_train) 175 | 176 | input_shape= X_train[0].shape 177 | print(input_shape) 178 | 179 | data_train.__getitem__(0)[0].shape 180 | 181 | n_epochs = 8 182 | batch_size_train = 16 183 | batch_size_test = 10 184 | learning_rate = 0.01 185 | momentum = 0.5 186 | log_interval = 100 187 | first_HL = 8 188 | 189 | import torch 190 | import torchvision 191 | 192 | ## Call the Dataset Class 193 | #data_train = torchvision.datasets.IndianPines('./data',download=True,PATCH_LENGTH=2) 194 | 195 | ## Check the shapes 196 | print(data_train.__getitem__(0)[0].shape) 197 | print(data_train.__len__()) 198 | 199 | 200 | ## Wrap it around a Torch Dataloader 201 | train_loader = torch.utils.data.DataLoader(data_train,batch_size=16,shuffle=True, num_workers=2) 202 | 203 | len(data_train) 204 | 205 | data_test=MyDataset(X_test, y_test) 206 | 207 | import torch 208 | import torchvision 209 | 210 | ## Call the Dataset Class 211 | #data_test = torchvision.datasets.IndianPines('./data',download=True,PATCH_LENGTH=2) 212 | 213 | ## Check the shapes 214 | print(data_test.__getitem__(0)[0].shape) 215 | print(data_test.__len__()) 216 | 217 | test_loader = torch.utils.data.DataLoader(data_test,batch_size=10,shuffle=False, num_workers=2) 218 | 219 | examples = enumerate(test_loader) 220 | batch_idx, (example_data, example_targets) = next(examples) 221 | 222 | print(example_data.shape) 223 | 224 | import matplotlib.pyplot as plt 225 | 226 | fig = plt.figure() 227 | for i in range(6): 228 | plt.subplot(2,3,i+1) 229 | plt.tight_layout() 230 | plt.imshow(example_data[i][0], interpolation='none') 231 | plt.title("Ground Truth: {}".format(example_targets[i])) 232 | plt.xticks([]) 233 | plt.yticks([]) 234 | fig 235 | 236 | import torch 237 | import torch.nn as nn 238 | import torchvision 239 | import torchvision.transforms as transforms 240 | 241 | import random 242 | 243 | device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') 244 | 245 | # Hyper-parameters 246 | num_epochs = 16 247 | learning_rate = 0.001 248 | 249 | torch.manual_seed(0) 250 | random.seed(0) 251 | 252 | Half_width =60 253 | layer_width = 20 254 | 255 | class SpinalCNN(nn.Module): 256 | """CNN.""" 257 | 258 | def __init__(self): 259 | """CNN Builder.""" 260 | super(SpinalCNN, self).__init__() 261 | 262 | self.conv_layer = nn.Sequential( 263 | 264 | # Conv Layer block 1 265 | nn.Conv2d(in_channels=30, out_channels=15, kernel_size=3, padding=1), 266 | nn.BatchNorm2d(15), 267 | nn.ReLU(inplace=True), 268 | nn.Conv2d(in_channels=15, out_channels=30, kernel_size=3, padding=1), 269 | nn.ReLU(inplace=True), 270 | nn.MaxPool2d(kernel_size=2, stride=2), 271 | 272 | # Conv Layer block 2 273 | nn.Conv2d(in_channels=30, out_channels=60, kernel_size=3, padding=1), 274 | nn.BatchNorm2d(60), 275 | nn.ReLU(inplace=True), 276 | nn.Conv2d(in_channels=60, out_channels=60, kernel_size=3, padding=1), 277 | nn.ReLU(inplace=True), 278 | nn.MaxPool2d(kernel_size=2, stride=2), 279 | nn.Dropout2d(p=0.05), 280 | 281 | # Conv Layer block 3 282 | nn.Conv2d(in_channels=60, out_channels=120, kernel_size=3, padding=1), 283 | nn.BatchNorm2d(120), 284 | nn.ReLU(inplace=True), 285 | nn.Conv2d(in_channels=120, out_channels=120, kernel_size=3, padding=1), 286 | nn.ReLU(inplace=True), 287 | nn.MaxPool2d(kernel_size=2, stride=2), 288 | ) 289 | 290 | self.fc_spinal_layer1 = nn.Sequential( 291 | nn.Dropout(p=0.1), nn.Linear(Half_width, layer_width), 292 | nn.ReLU(inplace=True), 293 | ) 294 | self.fc_spinal_layer2 = nn.Sequential( 295 | nn.Dropout(p=0.1), nn.Linear(Half_width + layer_width, layer_width), 296 | nn.ReLU(inplace=True), 297 | ) 298 | self.fc_spinal_layer3 = nn.Sequential( 299 | nn.Dropout(p=0.1), nn.Linear(Half_width + layer_width, layer_width), 300 | nn.ReLU(inplace=True), 301 | ) 302 | self.fc_spinal_layer4 = nn.Sequential( 303 | nn.Dropout(p=0.1), nn.Linear(Half_width + layer_width, layer_width), 304 | nn.ReLU(inplace=True), 305 | ) 306 | self.fc_out = nn.Sequential( 307 | nn.Dropout(p=0.1), nn.Linear(layer_width*4, 16) 308 | ) 309 | 310 | 311 | def forward(self, x): 312 | """Perform forward.""" 313 | 314 | # conv layers 315 | x = self.conv_layer(x) 316 | 317 | # flatten 318 | x = x.view(x.size(0), -1) 319 | 320 | x1 = self.fc_spinal_layer1(x[:, 0:Half_width]) 321 | x2 = self.fc_spinal_layer2(torch.cat([ x[:,Half_width:2*Half_width], x1], dim=1)) 322 | x3 = self.fc_spinal_layer3(torch.cat([ x[:,0:Half_width], x2], dim=1)) 323 | x4 = self.fc_spinal_layer4(torch.cat([ x[:,Half_width:2*Half_width], x3], dim=1)) 324 | 325 | x = torch.cat([x1, x2], dim=1) 326 | x = torch.cat([x, x3], dim=1) 327 | x = torch.cat([x, x4], dim=1) 328 | 329 | x = self.fc_out(x) 330 | 331 | return x 332 | 333 | from tensorflow.keras.optimizers import Adam 334 | model = SpinalCNN().to(device) 335 | # defining the optimizer 336 | optimizer = Adam(model.parameters(), lr=0.07) 337 | # defining the loss function 338 | criterion = nn.CrossEntropyLoss() 339 | # checking if GPU is available 340 | if torch.cuda.is_available(): 341 | model = model.cuda() 342 | criterion = criterion.cuda() 343 | 344 | print(model) 345 | 346 | from torchvision import models 347 | from torchsummary import summary 348 | model = SpinalCNN().to(device) 349 | summary(model, (30, 15, 15)) 350 | 351 | model = SpinalCNN().to(device) 352 | 353 | 354 | 355 | # Loss and optimizer 356 | criterion = nn.CrossEntropyLoss() 357 | optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate) 358 | 359 | # For updating learning rate 360 | def update_lr(optimizer, lr): 361 | for param_group in optimizer.param_groups: 362 | param_group['lr'] = lr 363 | 364 | # Train the model 365 | total_step = len(train_loader) 366 | curr_lr = learning_rate 367 | for epoch in range(num_epochs): 368 | for i, (images, labels) in enumerate(train_loader): 369 | images = images.to(device) 370 | labels = labels.to(device) 371 | 372 | #print(images.shape) 373 | # Forward pass 374 | outputs = model(images) 375 | labels = torch.tensor(labels, dtype=torch.long, device=device) 376 | loss = criterion(outputs, labels) 377 | 378 | # Backward and optimize 379 | optimizer.zero_grad() 380 | loss.backward() 381 | optimizer.step() 382 | 383 | 384 | if (i+1) % 500 == 0: 385 | print("Epoch [{}/{}], Step [{}/{}] Loss: {:.4f}" 386 | .format(epoch+1, num_epochs, i+1, total_step, loss.item())) 387 | 388 | 389 | # Decay learning rate 390 | if (epoch) == 1 or epoch>20: 391 | curr_lr /= 3 392 | update_lr(optimizer, curr_lr) 393 | 394 | # Test the model 395 | model.eval() 396 | with torch.no_grad(): 397 | correct = 0 398 | total = 0 399 | predicted_numpy=[] 400 | for images, labels in test_loader: 401 | 402 | images = images.to(device) 403 | labels = labels.to(device) 404 | outputs = model(images) 405 | _, predicted = torch.max(outputs.data, 1) 406 | predicted_numpy.append(predicted.cpu().numpy()) 407 | 408 | total += labels.size(0) 409 | correct += (predicted == labels).sum().item() 410 | 411 | print('Accuracy of the model on the test images: {} %'.format(100 * correct / total)) 412 | 413 | model.train() 414 | 415 | len(predicted_numpy) 416 | 417 | predicted_numpy = np.concatenate(predicted_numpy) 418 | 419 | predicted_numpy.shape 420 | 421 | from sklearn.metrics import confusion_matrix 422 | from sklearn.metrics import plot_confusion_matrix 423 | y_true = y_test 424 | y_pred = predicted_numpy 425 | print(confusion_matrix(y_true, y_pred), end='\n') 426 | 427 | from sklearn.metrics import confusion_matrix 428 | from sklearn.metrics import plot_confusion_matrix 429 | import seaborn as sn 430 | y_true = y_test 431 | y_pred = predicted_numpy 432 | plt.figure(figsize = (10,7)) 433 | print(sn.heatmap(confusion_matrix(y_true, y_pred),annot=True,cmap="OrRd",fmt='d')) 434 | plt.savefig('KSC_pca_Confusion Matrix') 435 | 436 | from sklearn.metrics import cohen_kappa_score 437 | print(cohen_kappa_score(y_true, y_pred, labels=None, weights=None, sample_weight=None)) 438 | 439 | from sklearn.metrics import classification_report 440 | 441 | from sklearn.metrics import confusion_matrix 442 | from sklearn.metrics import plot_confusion_matrix 443 | y_true = y_test 444 | y_pred = predicted_numpy 445 | target_names = ['class 0', 'class 1', 'class 2', 'class 3', 'class 4', 'class 5', 'class 6', 'class 7', 'class 8', 'class 9', 'class 10', 'class 11', 'class 12'] 446 | print(classification_report(y_true, y_pred, target_names=target_names, digits=4)) 447 | 448 | f = sio.loadmat('KSC.mat')['KSC'] 449 | g = sio.loadmat('KSC_gt.mat')['KSC_gt'] 450 | 451 | F,pca = applyPCA(f,30) 452 | 453 | FPatches, gPatches = createPatches(F,g, windowSize=15) 454 | 455 | import itertools 456 | 457 | def classified_pixels(FPatches,gPatches,g): 458 | FPatches=np.reshape(FPatches,(FPatches.shape[0],FPatches.shape[3],FPatches.shape[1],FPatches.shape[2])) 459 | data_test=MyDataset(FPatches, gPatches) 460 | test_loader = torch.utils.data.DataLoader(data_test,batch_size=10,shuffle=False, num_workers=2) 461 | with torch.no_grad(): 462 | correct = 0 463 | total = 0 464 | predicted_numpy=[] 465 | for images, labels in test_loader: 466 | images = images.to(device) 467 | labels = labels.to(device) 468 | outputs = model(images) 469 | _, predicted = torch.max(outputs.data, 1) 470 | predicted_numpy.append(predicted.cpu().numpy()) 471 | total += labels.size(0) 472 | correct += (predicted == labels).sum().item() 473 | classification_map=np.array(predicted_numpy) 474 | cm=[] 475 | for arr in classification_map: 476 | cm.append(arr.tolist()) 477 | cm=list(itertools.chain.from_iterable(cm)) 478 | classification_map=np.array(cm) 479 | 480 | height=g.shape[0] 481 | width=g.shape[1] 482 | outputs = np.zeros((height,width)) 483 | k=0 484 | for i in range(height): 485 | for j in range(width): 486 | target = g[i][j] 487 | if target == 0 : 488 | continue 489 | else : 490 | outputs[i][j]=classification_map[k] 491 | k=k+1 492 | return classification_map,outputs 493 | 494 | cma,out=classified_pixels(FPatches,gPatches,g) 495 | 496 | plt.figure(figsize=(7,7)) 497 | a=plt.imshow(out) 498 | plt.savefig('KSC_pca_cmap') 499 | 500 | plt.figure(figsize=(7,7)) 501 | plt.imshow(g) 502 | plt.savefig('KSC_pca_gt') 503 | -------------------------------------------------------------------------------- /Hyperspectral Image Classification/HSI_cmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipuk0506/SpinalNet-Applications/08912f00345b1912476b6f62cd8a3b7823ed0fa5/Hyperspectral Image Classification/HSI_cmap.png -------------------------------------------------------------------------------- /Hyperspectral Image Classification/HSI_gt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipuk0506/SpinalNet-Applications/08912f00345b1912476b6f62cd8a3b7823ed0fa5/Hyperspectral Image Classification/HSI_gt.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [SpinalNet](https://github.com/dipuk0506/SpinalNet): New Applications and Improvements 2 | 3 | ## Steps to share codes. 4 | ### 1. Fork this repository. 5 | ### 2. Upload codes, and other files as a folder in your repository. 6 | #### a. The folder name needs to be meaningful. 7 | #### b. The folder name needs to be unique to avoid overwriting. 8 | ### 3. Send us a pull request. 9 | 10 | #### To know about the process, please visit: [Collaborating with pull requests](https://docs.github.com/en/github/collaborating-with-pull-requests) 11 | --------------------------------------------------------------------------------