diff --git a/models/internal_priming.pth b/models/internal_priming.pth index 7eb6ff99f2a924ff4bc1a60a12fc26199d0b0e09..c11ec4e8f00da9f030e529dda0343bf445ccdc29 100644 Binary files a/models/internal_priming.pth and b/models/internal_priming.pth differ diff --git a/notebooks/internal_priming.ipynb b/notebooks/internal_priming.ipynb index 55fd43adb98a8c02168d59027944348527e9e485..3728c62592ed2d0fabd0bc190acbdd2a28db4d73 100644 --- a/notebooks/internal_priming.ipynb +++ b/notebooks/internal_priming.ipynb @@ -22,32 +22,13 @@ }, { "cell_type": "code", -<<<<<<< HEAD -<<<<<<< HEAD - "execution_count": 80, -======= - "execution_count": null, ->>>>>>> d2ef840 (chore: started cnn notebook) -======= - "execution_count": 80, ->>>>>>> fb8e822ed92fba85e584305fcb18bdf45ad601df + "execution_count": 26, "outputs": [], "source": [ "# importing the libraries\n", "import pandas as pd\n", "import numpy as np\n", -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD "import matplotlib.pyplot as plt\n", -======= ->>>>>>> d2ef840 (chore: started cnn notebook) -======= - "import matplotlib.pyplot as plt\n", ->>>>>>> 93ea318 (chore: added training function for cnn) -======= - "import matplotlib.pyplot as plt\n", ->>>>>>> fb8e822ed92fba85e584305fcb18bdf45ad601df "\n", "# for creating validation set\n", "from sklearn.model_selection import train_test_split\n", @@ -59,18 +40,9 @@ "# PyTorch libraries and modules\n", "import torch\n", "from torch.autograd import Variable\n", -<<<<<<< HEAD -<<<<<<< HEAD "from torch.nn import Linear, ReLU, CrossEntropyLoss, Sequential, MaxPool1d, Module, Softmax, BatchNorm1d, Dropout, Conv1d\n", - "from torch.optim import Adam\n", -======= - "from torch.nn import Linear, ReLU, CrossEntropyLoss, Sequential, Conv2d, MaxPool2d, Module, Softmax, BatchNorm2d, Dropout\n", "from torch.optim import Adam, SGD\n", ->>>>>>> d2ef840 (chore: started cnn notebook) -======= - "from torch.nn import Linear, ReLU, CrossEntropyLoss, Sequential, MaxPool1d, Module, Softmax, BatchNorm1d, Dropout, Conv1d\n", - "from torch.optim import Adam\n", ->>>>>>> fb8e822ed92fba85e584305fcb18bdf45ad601df + "from torchsummary import summary\n", "\n", "\n", "# adding the nn\n", @@ -79,12 +51,8 @@ " super(Net, self).__init__()\n", "\n", " self.cnn_layers = Sequential(\n", -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> fb8e822ed92fba85e584305fcb18bdf45ad601df " # Defining a 1D convolution layer\n", - " Conv1d(1, 4, kernel_size=3, stride=1, padding=1),\n", + " Conv1d(4, 4, kernel_size=3, stride=1, padding=1),\n", " BatchNorm1d(4),\n", " ReLU(inplace=True),\n", " MaxPool1d(kernel_size=2, stride=2),\n", @@ -97,25 +65,6 @@ "\n", " self.linear_layers = Sequential(\n", " Linear(4 * 50, 10)\n", -<<<<<<< HEAD -======= - " # Defining a 2D convolution layer\n", - " Conv2d(1, 4, kernel_size=3, stride=1, padding=1),\n", - " BatchNorm2d(4),\n", - " ReLU(inplace=True),\n", - " MaxPool2d(kernel_size=2, stride=2),\n", - " # Defining another 2D convolution layer\n", - " Conv2d(4, 4, kernel_size=3, stride=1, padding=1),\n", - " BatchNorm2d(4),\n", - " ReLU(inplace=True),\n", - " MaxPool2d(kernel_size=2, stride=2),\n", - " )\n", - "\n", - " self.linear_layers = Sequential(\n", - " Linear(4 * 7 * 7, 10)\n", ->>>>>>> d2ef840 (chore: started cnn notebook) -======= ->>>>>>> fb8e822ed92fba85e584305fcb18bdf45ad601df " )\n", "\n", " # Defining the forward pass\n", @@ -123,13 +72,6 @@ " x = self.cnn_layers(x)\n", " x = x.view(x.size(0), -1)\n", " x = self.linear_layers(x)\n", -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> 93ea318 (chore: added training function for cnn) -======= ->>>>>>> fb8e822ed92fba85e584305fcb18bdf45ad601df " return x\n", "\n", "# defining training function\n", @@ -164,15 +106,6 @@ " tr_loss = loss_train.item()\n", "\n", " return loss_train, loss_val" -<<<<<<< HEAD -<<<<<<< HEAD -======= - " return x" ->>>>>>> d2ef840 (chore: started cnn notebook) -======= ->>>>>>> 93ea318 (chore: added training function for cnn) -======= ->>>>>>> fb8e822ed92fba85e584305fcb18bdf45ad601df ], "metadata": { "collapsed": false, @@ -195,26 +128,22 @@ }, { "cell_type": "code", -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> fb8e822ed92fba85e584305fcb18bdf45ad601df - "execution_count": 81, + "execution_count": 27, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "100%|██████████| 20000/20000 [00:00<00:00, 97752.58it/s]\n" + "100%|██████████| 20000/20000 [00:00<00:00, 23948.83it/s]\n" ] } ], "source": [ "enum = {\n", - " 'A': 0.0,\n", - " 'U': 1/3,\n", - " 'G': 2/3,\n", - " 'C': 1.0\n", + " 'A': [1, 0, 0, 0],\n", + " 'U': [0, 1, 0, 0],\n", + " 'G': [0, 0, 1, 0],\n", + " 'C': [0, 0, 0, 1]\n", "}\n", "\n", "# TODO: Get test data from issues 25 and 26\n", @@ -256,7 +185,7 @@ }, { "cell_type": "code", - "execution_count": 82, + "execution_count": 28, "outputs": [], "source": [ "# TODO: reshape shape from [n, l] to [n, 1, l]\n", @@ -270,31 +199,14 @@ "train_shape = train_x.shape\n", "val_shape = val_x.shape\n", "\n", - "train_x = train_x.reshape(train_shape[0], 1, train_shape[1])\n", - "val_x = val_x.reshape(val_shape[0], 1, val_shape[1])\n", + "train_x = train_x.reshape(train_shape[0], 4, train_shape[1])\n", + "val_x = val_x.reshape(val_shape[0], 4, val_shape[1])\n", "\n", "train_x = torch.from_numpy(train_x)\n", "train_y = torch.from_numpy(train_y)\n", "\n", "val_x = torch.from_numpy(val_x)\n", "val_y = torch.from_numpy(val_y)" -<<<<<<< HEAD -======= - "execution_count": null, - "outputs": [], - "source": [ - "# TODO: Get test data from issues 25 and 26\n", - "train_x = []\n", - "train_y = []\n", - "test_x = []\n", - "test_y = []\n", - "\n", - "train_x, val_x, train_y, val_y = train_test_split(train_x, train_y, test_size = 0.1)\n", - "\n", - "# TODO: reshape shape from [n, l] to [n, 1, l]\n" ->>>>>>> d2ef840 (chore: started cnn notebook) -======= ->>>>>>> fb8e822ed92fba85e584305fcb18bdf45ad601df ], "metadata": { "collapsed": false, @@ -317,17 +229,13 @@ }, { "cell_type": "code", -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> fb8e822ed92fba85e584305fcb18bdf45ad601df - "execution_count": 83, + "execution_count": 29, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "100%|██████████| 25/25 [00:18<00:00, 1.34it/s]\n" + "100%|██████████| 25/25 [00:19<00:00, 1.25it/s]\n" ] } ], @@ -341,37 +249,10 @@ "# defining the loss function\n", "criterion = CrossEntropyLoss()\n", "\n", -<<<<<<< HEAD -======= - "execution_count": null, - "outputs": [], - "source": [ - "# defining the model\n", - "model = Net()\n", - "\n", - "# defining the optimizer\n", - "optimizer = Adam(model.parameters(), lr=0.07)\n", - "\n", - "# defining the loss function\n", - "criterion = CrossEntropyLoss()\n", -<<<<<<< HEAD ->>>>>>> d2ef840 (chore: started cnn notebook) -======= - "\n", ->>>>>>> 93ea318 (chore: added training function for cnn) -======= ->>>>>>> fb8e822ed92fba85e584305fcb18bdf45ad601df "# checking if GPU is available\n", "if torch.cuda.is_available():\n", " model = model.cuda()\n", " criterion = criterion.cuda()\n", -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> 93ea318 (chore: added training function for cnn) -======= ->>>>>>> fb8e822ed92fba85e584305fcb18bdf45ad601df "\n", "# defining the number of epochs\n", "n_epochs = 25\n", @@ -383,10 +264,6 @@ "val_losses = []\n", "\n", "# training the model\n", -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> fb8e822ed92fba85e584305fcb18bdf45ad601df "for epoch in tqdm(range(n_epochs)):\n", " train_loss, val_loss = train()\n", " train_losses.append(train_loss)\n", @@ -413,12 +290,12 @@ }, { "cell_type": "code", - "execution_count": 84, + "execution_count": 30, "outputs": [ { "data": { "text/plain": "<Figure size 432x288 with 1 Axes>", - "image/png": "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pfKwatUq1q1bd9CydevW5dTwC9JdIKuqqsa070MD/tvf/jaf/OQnx7StUlGSAQ8QcVbjiWnAK1VKVq5cyZNPPjk4uUdzczN79uzh3HPP5dZbb6WpqYk5c+Zw9913D/v+mTNn0t6e/v/9Pffcw4knnsg555wz2FIY0mPcFy9ezLx587jqqqvo7e1l06ZNPP744/z93/898+fP57333mP16tU89thjADz77LMsWLCA008/nRtuuIH+/v7B/d19990sXLiQ008/nR07dhzx+I62tsIlOQ4eoMddQ/mAtitQasyeugv2vVHYbU49HS787ogv19TUcMYZZ/DUU09x2WWXsW7dOq655hpEhHvuuYeamhqSySSf+MQneP3115k7d+6w29myZQvr1q1j27ZtJBIJFi5cyKJFiwC48sorufHGGwH45je/yU9/+lO++MUvcumll3LJJZewcuXKg7YVi8VYvXo1zz77LCeeeCLXXXcdDzzwAHfccQcAdXV1bN26lR/+8Ifce++9/OQnPxnx+I62tsIl+w2+31tLZVIDXqlSM/Q0zdDTM7/61a9YuHAhCxYsYPv27QedTjnUiy++yBVXXEF5eTmVlZVceumlg6+9+eabnHvuuZx++uk88sgjbN++/Yj1vPPOO8yaNYsTTzwRgOuvv56NGzcOvn7llVcCsGjRosEGZSN56aWX+NznPgcM31b4/vvvJxQK4XK5WLx4MQ8++CBr1qzhjTfeoKKi4ojbHouS/QafLK+nOhQmmTI4HTpLvFJ5O8I37Yl02WWXceedd7J161Z6e3tZtGgRH3zwAffeey+vvfYa1dXVrF69mlgsNqbtr169mvXr1zNv3jweeughXnjhhXHVm205PJ52w1a1FS7Zb/D4G6iQPrrCYasrUUrlIRAIsHz5cm644YbBb++RSAS/308wGGT//v089dRTR9zGeeedx/r16+nr6yMajfLEE08MvhaNRpk2bRrxeHywxS9ARUUF0Wj0sG2ddNJJNDc3s3PnTgB+8Ytf8PGPf3xMx3a0tRUu2W/w2XYF4bZW6qqrrC1GKZWXVatWccUVVwyeqsm21z355JOZMWMGS5cuPeL7Fy5cyGc+8xnmzZtHQ0MDixcvHnztO9/5DkuWLKG+vp4lS5YMhvq1117LjTfeyP333z94cRXA5/Px4IMPcvXVV5NIJFi8eDG33HLL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\n" + "image/png": "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\n" }, "metadata": { "needs_background": "light" @@ -445,14 +322,14 @@ }, { "cell_type": "code", - "execution_count": 85, + "execution_count": 31, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "0.9995\n", - "0.9995\n" + "0.9966111111111111\n", + "0.998\n" ] } ], @@ -499,28 +376,74 @@ }, { "cell_type": "code", - "execution_count": 86, - "outputs": [], + "execution_count": 32, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "cnn_layers.0.weight tensor([[[-0.0161, -0.1727, -0.0706],\n", + " [-0.1442, -0.2347, -0.1731],\n", + " [ 0.0937, -0.2319, 0.0297],\n", + " [ 0.4707, 1.2928, -0.7642]],\n", + "\n", + " [[ 0.6057, 0.1347, -0.0041],\n", + " [ 0.0967, -0.9823, -0.6446],\n", + " [ 0.5267, 0.5432, 0.1329],\n", + " [-0.0482, -0.0046, -0.0177]],\n", + "\n", + " [[-0.3372, -0.1560, -0.0196],\n", + " [ 0.1110, -0.3352, -0.1544],\n", + " [-0.4499, -0.2293, 0.0253],\n", + " [ 0.9977, -0.9843, -1.0379]],\n", + "\n", + " [[-0.1263, -0.5871, -0.0511],\n", + " [-0.1365, -0.1569, 0.0979],\n", + " [-0.3475, -0.3901, 0.0927],\n", + " [-0.6534, -0.9329, 0.6516]]])\n", + "cnn_layers.0.bias tensor([-0.0021, -0.1551, -1.0721, 0.4632])\n", + "cnn_layers.1.weight tensor([1.8590, 0.1158, 1.1549, 0.8114])\n", + "cnn_layers.1.bias tensor([ 0.7813, -0.7185, 0.1945, 0.2015])\n", + "cnn_layers.4.weight tensor([[[-1.0589, 0.3008, -1.0521],\n", + " [ 0.2243, 0.5245, 0.1523],\n", + " [ 0.0767, 0.6713, -0.4829],\n", + " [-0.6312, -0.4684, -0.3525]],\n", + "\n", + " [[ 0.6076, 0.0118, 0.3328],\n", + " [-0.6541, 0.2015, 0.1579],\n", + " [-0.8182, 0.1377, -0.8822],\n", + " [ 0.5961, -0.2152, 0.7089]],\n", + "\n", + " [[ 0.5840, 0.3963, -0.3982],\n", + " [ 0.4481, 0.1088, 0.2149],\n", + " [ 0.4938, 0.3682, 0.5467],\n", + " [-0.1666, 0.2545, 0.4419]],\n", + "\n", + " [[ 0.2782, -0.2773, -0.6268],\n", + " [ 0.1686, 0.1611, -0.3611],\n", + " [-0.9431, -0.2470, -0.1781],\n", + " [-0.2127, 0.1223, -0.0467]]])\n", + "cnn_layers.4.bias tensor([ 0.0243, 0.1496, -0.2523, -0.1505])\n", + "cnn_layers.5.weight tensor([0.9917, 1.0135, 0.2734, 0.0942])\n", + "cnn_layers.5.bias tensor([-0.2346, -0.1730, -0.6458, -0.8736])\n", + "linear_layers.0.weight tensor([[ 0.2819, 0.3333, 0.3363, ..., 0.3874, 0.3519, 0.2827],\n", + " [ 0.3381, 0.3392, 0.2918, ..., 0.3641, 0.2983, 0.3425],\n", + " [-0.3373, -0.3675, -0.4146, ..., -0.3503, -0.4156, -0.3663],\n", + " ...,\n", + " [-0.3867, -0.3346, -0.3592, ..., -0.4135, -0.3362, -0.3592],\n", + " [-0.3415, -0.3677, -0.3740, ..., -0.4074, -0.3575, -0.3526],\n", + " [-0.4087, -0.3892, -0.3258, ..., -0.3189, -0.4211, -0.3985]])\n", + "linear_layers.0.bias tensor([ 0.1986, 0.3250, -0.4212, -0.3442, -0.3814, -0.3203, -0.3380, -0.4000,\n", + " -0.3805, -0.4522])\n" + ] + } + ], "source": [ - "torch.save(model.state_dict(), '../models/internal_priming.pth')" -<<<<<<< HEAD -======= - "\n" ->>>>>>> d2ef840 (chore: started cnn notebook) -======= - "for epoch in range(n_epochs):\n", - " train_loss, val_loss = train()\n", - " train_losses.append(train_loss)\n", - " val_losses.append(val_loss)\n", + "torch.save(model.state_dict(), '../models/internal_priming.pth')\n", "\n", - "# plotting the training and validation loss\n", - "plt.plot(train_losses, label='Training loss')\n", - "plt.plot(val_losses, label='Validation loss')\n", - "plt.legend()\n", - "plt.show()" ->>>>>>> 93ea318 (chore: added training function for cnn) -======= ->>>>>>> fb8e822ed92fba85e584305fcb18bdf45ad601df + "for name, param in model.named_parameters():\n", + " if param.requires_grad:\n", + " print(name, param.data)" ], "metadata": { "collapsed": false, diff --git a/src/polyA_classifier/polyA_classifier.py b/src/polyA_classifier/polyA_classifier.py index 4570e9d9b70b7e0bd582b2073cd61f15090672e7..31766e973a4f1485a6fa1989055fa830f61f7a8f 100644 --- a/src/polyA_classifier/polyA_classifier.py +++ b/src/polyA_classifier/polyA_classifier.py @@ -15,7 +15,7 @@ class Net(Module): self.cnn_layers = Sequential( # Defining a 1D convolution layer - Conv1d(1, 4, kernel_size=3, stride=1, padding=1), + Conv1d(4, 4, kernel_size=3, stride=1, padding=1), BatchNorm1d(4), ReLU(inplace=True), MaxPool1d(kernel_size=2, stride=2), @@ -42,11 +42,11 @@ class PolyAClassifier: """Classifier object using the state-dict of a pretrained pytorch model.""" enum = { - 'A': 0.0, - 'U': 1 / 3, - 'T': 1 / 3, - 'G': 2 / 3, - 'C': 1.0 + 'A': [1, 0, 0, 0], + 'U': [0, 1, 0, 0], + 'T': [0, 1, 0, 0], + 'G': [0, 0, 1, 0], + 'C': [0, 0, 0, 1] } def __init__(self, model=Net, state_dict_path: str = './models/internal_priming.pth'): @@ -103,7 +103,7 @@ class PolyAClassifier: raise ValueError('Not all sequences of length 200') test_shape = test.shape - test = test.reshape(test_shape[0], 1, test_shape[1]) + test = test.reshape(test_shape[0], 4, test_shape[1]) if test_shape[1] != 200: raise ValueError('Sequences not of length 200') diff --git a/tests/resources/internal_priming_test_model.pth b/tests/resources/internal_priming_test_model.pth index 7eb6ff99f2a924ff4bc1a60a12fc26199d0b0e09..c11ec4e8f00da9f030e529dda0343bf445ccdc29 100644 Binary files a/tests/resources/internal_priming_test_model.pth and b/tests/resources/internal_priming_test_model.pth differ