From 7e18dac73d4cd8699f40f0e6dd545a51b970e1f0 Mon Sep 17 00:00:00 2001 From: SamueleBolotta Date: Fri, 12 Jan 2024 15:08:05 +0100 Subject: [PATCH] created draft for t5 --- .../W1D1_Generalization/W1D1_Tutorial5.ipynb | 309 ++++++++++++++++++ .../simple_model_checkpoint.pth | Bin 0 -> 25431 bytes 2 files changed, 309 insertions(+) create mode 100644 tutorials/W1D1_Generalization/W1D1_Tutorial5.ipynb create mode 100644 tutorials/W1D1_Generalization/simple_model_checkpoint.pth diff --git a/tutorials/W1D1_Generalization/W1D1_Tutorial5.ipynb b/tutorials/W1D1_Generalization/W1D1_Tutorial5.ipynb new file mode 100644 index 000000000..9044dc409 --- /dev/null +++ b/tutorials/W1D1_Generalization/W1D1_Tutorial5.ipynb @@ -0,0 +1,309 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "3dcd8e2d-94c3-4972-a2de-e0813bc02689", + "metadata": {}, + "outputs": [], + "source": [ + "# Imports\n", + "import scipy.io\n", + "import numpy as np\n", + "import torch\n", + "import torch.nn as nn" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "7ff3167f-9472-492d-a236-6f254d075378", + "metadata": {}, + "outputs": [], + "source": [ + "# Load the .mat file\n", + "data = scipy.io.loadmat('data/condsForSimJ2moMuscles.mat')\n", + "\n", + "# Extract condsForSim struct\n", + "conds_for_sim = data['condsForSim']" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "e42fa7c4-279a-4ae1-922d-53207ed26455", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_204181/828212273.py:27: UserWarning: Creating a tensor from a list of numpy.ndarrays is extremely slow. Please consider converting the list to a single numpy.ndarray with numpy.array() before converting to a tensor. (Triggered internally at ../torch/csrc/utils/tensor_new.cpp:230.)\n", + " go_envelope_all.append(torch.tensor(go_envelope_condition, dtype=torch.float32))\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Go Envelope Tensor Shape: torch.Size([216, 296, 1])\n", + "Plan Tensor Shape: torch.Size([216, 296, 15])\n", + "Muscle Tensor Shape: torch.Size([216, 296, 8])\n" + ] + } + ], + "source": [ + "# Initialize lists to store data for all conditions\n", + "go_envelope_all = []\n", + "plan_all = []\n", + "muscle_all = []\n", + "\n", + "# Get the number of conditions (rows) and delay durations (columns)\n", + "num_conditions, num_delays = conds_for_sim.shape\n", + "\n", + "# Loop through each condition and extract data\n", + "for i in range(num_conditions): # 27 conditions\n", + " go_envelope_condition = []\n", + " plan_condition = []\n", + " muscle_condition = []\n", + "\n", + " for j in range(num_delays): # 8 delay durations\n", + " condition = conds_for_sim[i, j]\n", + "\n", + " go_envelope = condition['goEnvelope']\n", + " plan = condition['plan']\n", + " muscle = condition['muscle']\n", + "\n", + " go_envelope_condition.append(go_envelope)\n", + " plan_condition.append(plan)\n", + " muscle_condition.append(muscle)\n", + "\n", + " # Stack data for each condition\n", + " go_envelope_all.append(torch.tensor(go_envelope_condition, dtype=torch.float32))\n", + " plan_all.append(torch.tensor(plan_condition, dtype=torch.float32))\n", + " muscle_all.append(torch.tensor(muscle_condition, dtype=torch.float32))\n", + "\n", + "# Stack data for all conditions\n", + "go_envelope_tensor = torch.stack(go_envelope_all)\n", + "plan_tensor = torch.stack(plan_all)\n", + "muscle_tensor = torch.stack(muscle_all)\n", + "\n", + "# Reshape to merge the first two dimensions\n", + "go_envelope_tensor = go_envelope_tensor.reshape(-1, *go_envelope_tensor.shape[2:])\n", + "plan_tensor = plan_tensor.reshape(-1, *plan_tensor.shape[2:])\n", + "muscle_tensor = muscle_tensor.reshape(-1, *muscle_tensor.shape[2:])\n", + "\n", + "# Print shapes\n", + "print(f\"Go Envelope Tensor Shape: {go_envelope_tensor.shape}\")\n", + "print(f\"Plan Tensor Shape: {plan_tensor.shape}\")\n", + "print(f\"Muscle Tensor Shape: {muscle_tensor.shape}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "d84ac60b-be75-45af-8d22-eca9c41fec6c", + "metadata": {}, + "outputs": [], + "source": [ + "# Define a RNN model\n", + "\n", + "class SimpleRNN(nn.Module):\n", + " def __init__(self, input_size, hidden_size, output_size):\n", + " super(SimpleRNN, self).__init__()\n", + " self.rnn = nn.RNN(input_size, hidden_size, batch_first=True)\n", + " self.fc = nn.Linear(hidden_size, output_size)\n", + "\n", + " def forward(self, x):\n", + " out, _ = self.rnn(x)\n", + " out = self.fc(out)\n", + " return out\n", + "\n", + "# Assuming the sizes from data\n", + "input_size = 16 # Calculated based on input shapes\n", + "hidden_size = 64 \n", + "output_size = 8 # Based on the output shape\n", + "\n", + "model = SimpleRNN(input_size, hidden_size, output_size)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "e8ecaf47-96ba-4120-87e6-39b6c9d08188", + "metadata": {}, + "outputs": [], + "source": [ + "# Adjust the shape of go_envelope_tensor\n", + "go_envelope_tensor_adjusted = go_envelope_tensor.squeeze(-1) # Removes the last dimension\n", + "\n", + "# Check dimensions after squeezing\n", + "if go_envelope_tensor_adjusted.dim() == plan_tensor.dim() - 1:\n", + " # Add an extra dimension to go_envelope_tensor_adjusted to match plan_tensor\n", + " go_envelope_tensor_adjusted = go_envelope_tensor_adjusted.unsqueeze(-1)\n", + "\n", + " # Now concatenate along the last dimension\n", + " input_tensor = torch.cat((go_envelope_tensor_adjusted, plan_tensor), dim=-1)\n", + "else:\n", + " raise RuntimeError(\"Dimension mismatch after adjustment\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "160bdb5c-2056-40f8-a2f3-597a7e771c53", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Train Input Size: torch.Size([172, 296, 16])\n", + "Test Input Size: torch.Size([44, 296, 16])\n", + "Train Target Size: torch.Size([172, 296, 8])\n", + "Test Target Size: torch.Size([44, 296, 8])\n" + ] + } + ], + "source": [ + "# Split data into training and testing sets\n", + "train_size = int(0.8 * input_tensor.size(0))\n", + "train_input = input_tensor[:train_size]\n", + "test_input = input_tensor[train_size:]\n", + "train_target = muscle_tensor[:train_size]\n", + "test_target = muscle_tensor[train_size:]\n", + "\n", + "# Verify the sizes\n", + "print(f\"Train Input Size: {train_input.size()}\")\n", + "print(f\"Test Input Size: {test_input.size()}\")\n", + "print(f\"Train Target Size: {train_target.size()}\")\n", + "print(f\"Test Target Size: {test_target.size()}\")\n", + "\n", + "# Define loss function and optimizer\n", + "criterion = nn.MSELoss()\n", + "optimizer = torch.optim.Adam(model.parameters(), lr=0.001)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "1d4aab79-08da-4fc1-be1c-cc580a5f2d70", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch [0/500], Loss: 0.06945484131574631, Test Loss: 0.06215358525514603\n", + "Epoch [10/500], Loss: 0.021324191242456436, Test Loss: 0.0196370966732502\n", + "Epoch [20/500], Loss: 0.019416367635130882, Test Loss: 0.01877027191221714\n", + "Epoch [30/500], Loss: 0.01791669800877571, Test Loss: 0.016670530661940575\n", + "Epoch [40/500], Loss: 0.017395811155438423, Test Loss: 0.01648167334496975\n", + "Epoch [50/500], Loss: 0.01716764271259308, Test Loss: 0.016113314777612686\n", + "Epoch [60/500], Loss: 0.016996093094348907, Test Loss: 0.016008485108613968\n", + "Epoch [70/500], Loss: 0.016899049282073975, Test Loss: 0.015784764662384987\n", + "Epoch [80/500], Loss: 0.016822611913084984, Test Loss: 0.01577206887304783\n", + "Epoch [90/500], Loss: 0.016755780205130577, Test Loss: 0.01563873328268528\n", + "Epoch [100/500], Loss: 0.016685090959072113, Test Loss: 0.01555646862834692\n", + "Epoch [110/500], Loss: 0.01658358983695507, Test Loss: 0.015401231124997139\n", + "Epoch [120/500], Loss: 0.016355616971850395, Test Loss: 0.015009786002337933\n", + "Epoch [130/500], Loss: 0.01487487368285656, Test Loss: 0.02703819051384926\n", + "Epoch [140/500], Loss: 0.016456956043839455, Test Loss: 0.01516042836010456\n", + "Epoch [150/500], Loss: 0.016544444486498833, Test Loss: 0.015271191485226154\n", + "Epoch [160/500], Loss: 0.016446998342871666, Test Loss: 0.01525502372533083\n", + "Epoch [170/500], Loss: 0.016341326758265495, Test Loss: 0.01504436507821083\n", + "Epoch [180/500], Loss: 0.01623906008899212, Test Loss: 0.014940104447305202\n", + "Epoch [190/500], Loss: 0.016118096187710762, Test Loss: 0.014749975875020027\n", + "Epoch [200/500], Loss: 0.015950532630085945, Test Loss: 0.014500990509986877\n", + "Epoch [210/500], Loss: 0.01567700505256653, Test Loss: 0.014078512787818909\n", + "Epoch [220/500], Loss: 0.015037690289318562, Test Loss: 0.013052952475845814\n", + "Epoch [230/500], Loss: 0.02549377828836441, Test Loss: 0.014654227532446384\n", + "Epoch [240/500], Loss: 0.017849242314696312, Test Loss: 0.01578238233923912\n", + "Epoch [250/500], Loss: 0.01701129786670208, Test Loss: 0.016172470524907112\n", + "Epoch [260/500], Loss: 0.016579564660787582, Test Loss: 0.015089149586856365\n", + "Epoch [270/500], Loss: 0.01641070283949375, Test Loss: 0.01525115966796875\n", + "Epoch [280/500], Loss: 0.01629340648651123, Test Loss: 0.014967095106840134\n", + "Epoch [290/500], Loss: 0.01620139181613922, Test Loss: 0.014865301549434662\n", + "Epoch [300/500], Loss: 0.01611190102994442, Test Loss: 0.014730663038790226\n", + "Epoch [310/500], Loss: 0.016006972640752792, Test Loss: 0.014566123485565186\n", + "Epoch [320/500], Loss: 0.0158640518784523, Test Loss: 0.014335619285702705\n", + "Epoch [330/500], Loss: 0.015639012679457664, Test Loss: 0.013991651125252247\n", + "Epoch [340/500], Loss: 0.015176555141806602, Test Loss: 0.013243998400866985\n", + "Epoch [350/500], Loss: 0.013796578161418438, Test Loss: 0.0115931062027812\n", + "Epoch [360/500], Loss: 0.015857117250561714, Test Loss: 0.014362258836627007\n", + "Epoch [370/500], Loss: 0.01589975878596306, Test Loss: 0.014321285299956799\n", + "Epoch [380/500], Loss: 0.015759805217385292, Test Loss: 0.014182702638208866\n", + "Epoch [390/500], Loss: 0.015622653998434544, Test Loss: 0.013964013196527958\n", + "Epoch [400/500], Loss: 0.015410303138196468, Test Loss: 0.013604477979242802\n", + "Epoch [410/500], Loss: 0.01506776176393032, Test Loss: 0.013094850815832615\n", + "Epoch [420/500], Loss: 0.014383680187165737, Test Loss: 0.011991310864686966\n", + "Epoch [430/500], Loss: 0.013644035905599594, Test Loss: 0.010731290094554424\n", + "Epoch [440/500], Loss: 0.013392072170972824, Test Loss: 0.010501268319785595\n", + "Epoch [450/500], Loss: 0.013526298105716705, Test Loss: 0.010595179162919521\n", + "Epoch [460/500], Loss: 0.013375792652368546, Test Loss: 0.010180925950407982\n", + "Epoch [470/500], Loss: 0.013830088078975677, Test Loss: 0.010914870537817478\n", + "Epoch [480/500], Loss: 0.013349335640668869, Test Loss: 0.01034696213901043\n", + "Epoch [490/500], Loss: 0.013634550385177135, Test Loss: 0.011291691102087498\n" + ] + } + ], + "source": [ + "criterion = nn.MSELoss()\n", + "optimizer = torch.optim.Adam(model.parameters(), lr=0.001)\n", + "\n", + "num_epochs = 500\n", + "\n", + "# Training loop\n", + "for epoch in range(num_epochs):\n", + " model.train()\n", + " optimizer.zero_grad()\n", + " output = model(train_input)\n", + " loss = criterion(output, train_target)\n", + " loss.backward()\n", + " optimizer.step()\n", + "\n", + " # Evaluation on test data\n", + " model.eval()\n", + " with torch.no_grad():\n", + " test_output = model(test_input)\n", + " test_loss = criterion(test_output, test_target)\n", + "\n", + " # Print loss every few epochs for monitoring\n", + " if epoch % 10 == 0:\n", + " print(f'Epoch [{epoch}/{num_epochs}], Loss: {loss.item()}, Test Loss: {test_loss.item()}')\n", + "\n", + "# Save the model\n", + "torch.save(model.state_dict(), 'simple_model_checkpoint.pth')\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8e0c04e1-5944-4e14-b058-740f0af10007", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.10.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/tutorials/W1D1_Generalization/simple_model_checkpoint.pth b/tutorials/W1D1_Generalization/simple_model_checkpoint.pth new file mode 100644 index 0000000000000000000000000000000000000000..eeba2a007d51a50ae1e7dab0e6bc244e069d590b GIT binary patch literal 25431 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 literal 0 HcmV?d00001