Skip to content

Instantly share code, notes, and snippets.

@tims457
Created May 24, 2020 20:42
Show Gist options
  • Save tims457/60d1b1688dfab3e02cbd9bbd83b49a66 to your computer and use it in GitHub Desktop.
Save tims457/60d1b1688dfab3e02cbd9bbd83b49a66 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [],
"source": [
"import torch\n",
"import torch.nn as nn\n",
"import numpy as np\n",
"import torch.nn.functional as F\n",
"import matplotlib.pyplot as plt\n",
"from torch.utils.data import DataLoader, Dataset\n"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [],
"source": [
"class RNNCell(nn.Module):\n",
" \n",
" def __init__(self, inputSize, hiddenSize, outputSize):\n",
" super(RNNCell, self).__init__()\n",
" self.Wx = torch.randn(hiddenSize, inputSize) # input weights\n",
" self.Wh = torch.randn(hiddenSize, hiddenSize) # hidden weights\n",
" self.Wy = torch.randn(outputSize,recurhiddenSizerentSize) # output weights\n",
" self.h = torch.zeros(hiddenSize,1) # initial hidden state\n",
" self.bh = torch.zeros(hiddenSize,1) # hidden state bias\n",
" self.by = torch.zeros(outputSize,1) # output bias\n",
"\n",
" def forward(self, x):\n",
" self.h = torch.tanh(self.bh + torch.matmul(self.Wx, x) + torch.matmul(self.Wh,self.h))\n",
" output = nn.Softmax(self.by + torch.matmul(self.Wy,self.h))\n",
" \n",
" return output, self.h"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Text(0.5, 0, 'x')"
]
},
"execution_count": 49,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"X = torch.sin(torch.linspace(0,100,100000))\n",
"plt.plot(X)\n",
"plt.ylabel('Sin x')\n",
"plt.xlabel('x')"
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {},
"outputs": [],
"source": [
"\n",
"class RNNData(Dataset):\n",
" def __init__(self, X, sequenceLength):\n",
" 'Initialization'\n",
" self.X = X\n",
" self.sequenceLength = sequenceLength\n",
"\n",
" def __len__(self):\n",
" 'Denotes the total number of samples'\n",
" return int(torch.floor(torch.tensor(len(self.X)/self.sequenceLength)))\n",
" \n",
" def __getitem__(self, index):\n",
" sequence = self.X[index:index+self.sequenceLength]\n",
" y = self.X[index+self.sequenceLength+1]\n",
" return sequence, y"
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {},
"outputs": [],
"source": [
"#hyperparameters\n",
"batchSize = 100 \n",
"sequenceLength = 50\n",
"numLayers = 1\n",
"hiddenSize = 4\n",
"learningRate = 0.01\n",
"epochs = 100"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tensor([[0.1977, 0.1987, 0.1997, ..., 0.2435, 0.2445, 0.2455],\n",
" [0.4059, 0.4069, 0.4078, ..., 0.4484, 0.4493, 0.4502],\n",
" [0.8912, 0.8917, 0.8921, ..., 0.9115, 0.9119, 0.9124],\n",
" ...,\n",
" [0.8117, 0.8123, 0.8128, ..., 0.8382, 0.8388, 0.8393],\n",
" [0.9963, 0.9964, 0.9965, ..., 0.9992, 0.9993, 0.9993],\n",
" [0.3977, 0.3986, 0.3995, ..., 0.4404, 0.4413, 0.4422]])\n",
"tensor([0.2474, 0.4520, 0.9132, 0.9972, 0.4132, 0.9986, 0.2580, 0.6272, 0.7695,\n",
" 0.9936, 0.9777, 0.9785, 0.9365, 0.8152, 0.9614, 0.7420, 0.9471, 0.9474,\n",
" 0.9379, 0.9659, 0.5778, 0.9697, 0.8966, 0.9992, 0.9080, 0.7901, 0.8930,\n",
" 0.3485, 0.8537, 0.3012, 0.9874, 0.8338, 0.8894, 0.5819, 0.6020, 0.9029,\n",
" 0.9625, 0.8928, 0.9428, 0.9291, 0.9977, 0.8644, 0.3728, 0.6233, 0.1018,\n",
" 0.5346, 0.9990, 0.5505, 0.9744, 0.9530, 0.9150, 0.7413, 0.9313, 0.5932,\n",
" 0.9987, 0.9499, 0.0580, 0.9286, 0.1425, 0.9862, 0.9980, 0.9687, 0.2026,\n",
" 0.9423, 0.7004, 0.6846, 0.9855, 0.8238, 0.7033, 0.2812, 0.2974, 0.8624,\n",
" 0.8140, 0.8669, 0.6713, 0.9928, 0.9338, 0.9842, 0.5996, 0.9275, 0.9999,\n",
" 0.9997, 0.9934, 0.9819, 0.1237, 0.9384, 0.5972, 0.9973, 0.1455, 0.2888,\n",
" 0.9461, 0.9804, 0.9983, 0.9956, 0.8076, 0.1207, 0.4368, 0.8404, 0.9994,\n",
" 0.4440])\n"
]
}
],
"source": [
"data = RNNData(X,sequenceLength)\n",
"dataLoader = DataLoader(data, batch_size=batchSize, shuffle=True)\n",
"for x,y in dataLoader:\n",
" print(x)\n",
" print(y)\n",
" break"
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [],
"source": [
"# create our RNN based network with an RNN followed by a linear layer\n",
"class RNN(nn.Module):\n",
" def __init__(self, inputSize, hiddenSize, numLayers):\n",
" super().__init__()\n",
" self.RNN = nn.RNN(input_size=inputSize, \n",
" hidden_size=hiddenSize, \n",
" num_layers=numLayers, \n",
" nonlinearity='tanh', \n",
" batch_first=True) #inputs and outputs are (batch, seq, feature)\n",
" self.linear = nn.Linear(hiddenSize,1)\n",
" \n",
" def forward(self,x,hState):\n",
" x, h = self.RNN(x,hState)\n",
" out = self.linear(x[:,-1,:]) # gets last output\n",
" return out"
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {},
"outputs": [],
"source": [
"# create our network instance, pick loss function and optimizer\n",
"model = RNN(1,hiddenSize,numLayers)\n",
"lossFn = nn.MSELoss()\n",
"optimizer = torch.optim.Adam(model.parameters(), lr=learningRate)"
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"torch.Size([100, 1])"
]
},
"execution_count": 55,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# check output to see if everything is setup correctly\n",
"ytest = model(torch.randn(batchSize,sequenceLength,1),torch.zeros([numLayers, batchSize, hiddenSize]))\n",
"ytest.shape"
]
},
{
"cell_type": "code",
"execution_count": 56,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"11.319549560546875\n",
"1.7751704454421997\n",
"1.4014699459075928\n",
"1.1168690919876099\n",
"0.5675828456878662\n",
"0.05716589093208313\n",
"0.010280625894665718\n",
"0.004087743349373341\n",
"0.0029274208936840296\n",
"0.0025021100882440805\n",
"0.002253422513604164\n",
"0.002016317332163453\n",
"0.0018425789894536138\n",
"0.0017580073326826096\n",
"0.0015311933821067214\n",
"0.0013432155828922987\n",
"0.001226308522745967\n",
"0.0011239354498684406\n",
"0.0010009920224547386\n",
"0.0009049549116753042\n",
"0.0008012366015464067\n",
"0.0007353670080192387\n",
"0.0006402007420547307\n",
"0.0005788293201476336\n",
"0.0005184737383387983\n",
"0.0004636308876797557\n",
"0.00041253535891883075\n",
"0.00036798190558329225\n",
"0.00034769228659570217\n",
"0.0002972030488308519\n",
"0.0002639765734784305\n",
"0.00022841084864921868\n",
"0.00021119693701621145\n",
"0.00018246164836455137\n",
"0.00017494821804575622\n",
"0.0001459053164580837\n",
"0.00012809678446501493\n",
"0.00011152001388836652\n",
"0.00010181981633650139\n",
"9.421376307727769e-05\n",
"8.516746311215684e-05\n",
"9.344099089503288e-05\n",
"7.571556488983333e-05\n",
"6.939681770745665e-05\n",
"6.255778134800494e-05\n",
"6.651831790804863e-05\n",
"6.726705760229379e-05\n",
"5.616387352347374e-05\n",
"5.658273585140705e-05\n",
"6.0519552789628506e-05\n",
"5.55058904865291e-05\n",
"5.864330523763783e-05\n",
"5.548787521547638e-05\n",
"5.9752503148047253e-05\n",
"4.80966227769386e-05\n",
"5.113997031003237e-05\n",
"7.44025019230321e-05\n",
"5.991280704620294e-05\n",
"4.653463838621974e-05\n",
"5.885814243811183e-05\n",
"4.6151482820278034e-05\n",
"4.450901906238869e-05\n",
"4.508296478888951e-05\n",
"4.469474151846953e-05\n",
"4.367278961581178e-05\n",
"4.332353637437336e-05\n",
"4.1468832932878286e-05\n",
"4.0118800825439394e-05\n",
"4.7187353629851714e-05\n",
"4.421977064339444e-05\n",
"4.5634435082320124e-05\n",
"6.0528047470143065e-05\n",
"5.609228537650779e-05\n",
"4.7935765906004235e-05\n",
"4.159270611125976e-05\n",
"4.1005550883710384e-05\n",
"4.603252455126494e-05\n",
"4.5191103708930314e-05\n",
"4.270176577847451e-05\n",
"4.48863283963874e-05\n",
"4.341293970355764e-05\n",
"4.052995427628048e-05\n",
"3.95571296394337e-05\n",
"4.4394877477316186e-05\n",
"4.054577220813371e-05\n",
"3.578514952096157e-05\n",
"3.6663273931480944e-05\n",
"5.189451258047484e-05\n",
"3.78264558094088e-05\n",
"3.903014658135362e-05\n",
"4.4174295908305794e-05\n",
"3.90354725823272e-05\n",
"4.6599816414527595e-05\n",
"4.038702536490746e-05\n",
"4.039769555674866e-05\n",
"3.597330942284316e-05\n",
"5.0886817916762084e-05\n",
"3.824286250164732e-05\n",
"4.622007327270694e-05\n",
"3.545684376149438e-05\n"
]
},
{
"data": {
"text/plain": [
"Text(0, 0.5, 'Loss')"
]
},
"execution_count": 56,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# train the model!\n",
"model.train()\n",
"lossHistory = []\n",
"for epoch in range(epochs):\n",
" lossTotal = 0\n",
" for x,y in dataLoader:\n",
" hState = torch.zeros([numLayers, batchSize, hiddenSize])\n",
" yhat= model(x.reshape([batchSize,sequenceLength, 1]),hState)\n",
" \n",
" loss = lossFn(yhat.view(-1),y)\n",
" \n",
" model.zero_grad()\n",
" loss.backward()\n",
" optimizer.step()\n",
" \n",
" lossTotal +=loss\n",
" lossHistory.append(lossTotal)\n",
" print(lossTotal.item())\n",
" \n",
"plt.plot(lossHistory)\n",
"plt.title('Loss')\n",
"plt.xlabel('Epoch')\n",
"plt.ylabel('Loss')"
]
},
{
"cell_type": "code",
"execution_count": 57,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tensor([0.0000, 0.0010, 0.0020, 0.0030, 0.0040, 0.0050, 0.0060, 0.0070, 0.0080,\n",
" 0.0090, 0.0100, 0.0110, 0.0120, 0.0130, 0.0140, 0.0150, 0.0160, 0.0170,\n",
" 0.0180, 0.0190, 0.0200, 0.0210, 0.0220, 0.0230, 0.0240, 0.0250, 0.0260,\n",
" 0.0270, 0.0280, 0.0290, 0.0300, 0.0310, 0.0320, 0.0330, 0.0340, 0.0350,\n",
" 0.0360, 0.0370, 0.0380, 0.0390, 0.0400, 0.0410, 0.0420, 0.0430, 0.0440,\n",
" 0.0450, 0.0460, 0.0470, 0.0480, 0.0490])\n",
"tensor(0.0510)\n"
]
}
],
"source": [
"print(X[:sequenceLength])\n",
"print(X[sequenceLength+1])"
]
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"tensor([[0.0509]], grad_fn=<AddmmBackward>)"
]
},
"execution_count": 58,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model.eval()\n",
"model(X[:sequenceLength].reshape(1,sequenceLength,1),torch.zeros([numLayers, 1, hiddenSize]))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment