From ce03e8d12efbd4d314b8c745665d3318de0d53c1 Mon Sep 17 00:00:00 2001 From: glibesyck Date: Thu, 8 Aug 2024 12:45:57 +0300 Subject: [PATCH] plot & explanations upd --- .../W2D4_Macrolearning/W2D4_Tutorial2.ipynb | 4 +- .../W2D4_Macrolearning/W2D4_Tutorial3.ipynb | 166 ++++++++---------- 2 files changed, 78 insertions(+), 92 deletions(-) diff --git a/tutorials/W2D4_Macrolearning/W2D4_Tutorial2.ipynb b/tutorials/W2D4_Macrolearning/W2D4_Tutorial2.ipynb index 74ac80a8d..a5b497d9e 100644 --- a/tutorials/W2D4_Macrolearning/W2D4_Tutorial2.ipynb +++ b/tutorials/W2D4_Macrolearning/W2D4_Tutorial2.ipynb @@ -392,7 +392,7 @@ "execution": {} }, "source": [ - "Now, let's incrementally fit the autumn data to the trained model and monitor the R-squared values for the summer and autumn data test sets during each iteration. In the following code snippet, you are requested to complete further training using the `partial_fit` function, which allows us to train the existing model on new data. As we iterate through the epochs, we can append new R-squared values for each epoch." + "Now, let's incrementally fit the autumn data to the trained model and monitor the R-squared values for the summer and autumn data test sets during each iteration. In the following code snippet, you are requested to complete further training using the `partial_fit` function, which allows us to train the existing model on new data (it runs through the data only once, and thus, we can control for the number of iterations). As we iterate through the epochs, we can append new R-squared values for each epoch." ] }, { @@ -913,7 +913,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.19" + "version": "3.11.5" } }, "nbformat": 4, diff --git a/tutorials/W2D4_Macrolearning/W2D4_Tutorial3.ipynb b/tutorials/W2D4_Macrolearning/W2D4_Tutorial3.ipynb index 1d8a9105f..98d0dced1 100644 --- a/tutorials/W2D4_Macrolearning/W2D4_Tutorial3.ipynb +++ b/tutorials/W2D4_Macrolearning/W2D4_Tutorial3.ipynb @@ -50,8 +50,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -85,8 +84,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -114,8 +112,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -150,8 +147,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -168,8 +164,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -273,13 +268,14 @@ " saturation = 0.2 + 0.8 * norm_value\n", " return saturation\n", "\n", - "def plot_sensitivity_r_squared(name, list_gradient_steps, list_num_samples_finetune):\n", + "def plot_sensitivity_r_squared(name, list_gradient_steps, list_num_samples_finetune, fix_scale = False):\n", " \"\"\"Performs fine-tuning for a couple of tasks for different hyperparameter values and plots 3D sensitivity plot.\n", "\n", " Inputs:\n", " - name (str): name of the model's file.\n", " - gradient_steps (np.ndarray): list of number of steps to perform gradient descent.\n", " - num_samples_finetune (np.ndarray) list of number of samples.\n", + " - fix_scale (bool, default = False): whether to fix the same values of R-squared metric for both plots.\n", " \"\"\"\n", " model_path = name + '.pt'\n", " meta_model = MetaLearningModel(model = model_path, mean = days_mean, std = days_std)\n", @@ -297,10 +293,11 @@ " for num_samples_finetune in list_num_samples_finetune:\n", " x_finetune, y_finetune = dataset.sample_particular_task(*tasks[0], num_samples_finetune)\n", " for gradient_steps in list_gradient_steps:\n", - " prediction = finetune(meta_model, torch.tensor(x_finetune).type(torch.float32), torch.tensor(y_finetune).type(torch.float32), gradient_steps)(torch.tensor((np.expand_dims(days, 1) - days_mean) / days_std).type(torch.float32)).detach().numpy()\n", - " legend_num_samples_finetune.append(num_samples_finetune)\n", - " legend_gradient_steps.append(gradient_steps)\n", - " legend_r_squared_score.append(r2_score(prices, prediction))\n", + " if gradient_steps:\n", + " prediction = finetune(meta_model, torch.tensor(x_finetune).type(torch.float32), torch.tensor(y_finetune).type(torch.float32), gradient_steps)(torch.tensor((np.expand_dims(days, 1) - days_mean) / days_std).type(torch.float32)).detach().numpy()\n", + " legend_num_samples_finetune.append(num_samples_finetune)\n", + " legend_gradient_steps.append(gradient_steps)\n", + " legend_r_squared_score.append(r2_score(prices, prediction))\n", "\n", "\n", " fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6), subplot_kw={'projection': '3d'})\n", @@ -322,10 +319,11 @@ " for num_samples_finetune in list_num_samples_finetune:\n", " x_finetune, y_finetune = dataset.sample_particular_task(*tasks[1], num_samples_finetune)\n", " for gradient_steps in list_gradient_steps:\n", - " prediction = finetune(meta_model, torch.tensor(x_finetune).type(torch.float32), torch.tensor(y_finetune).type(torch.float32), gradient_steps)(torch.tensor((np.expand_dims(days, 1) - days_mean) / days_std).type(torch.float32)).detach().numpy()\n", - " legend_num_samples_finetune.append(num_samples_finetune)\n", - " legend_gradient_steps.append(gradient_steps)\n", - " legend_r_squared_score.append(r2_score(prices, prediction))\n", + " if gradient_steps:\n", + " prediction = finetune(meta_model, torch.tensor(x_finetune).type(torch.float32), torch.tensor(y_finetune).type(torch.float32), gradient_steps)(torch.tensor((np.expand_dims(days, 1) - days_mean) / days_std).type(torch.float32)).detach().numpy()\n", + " legend_num_samples_finetune.append(num_samples_finetune)\n", + " legend_gradient_steps.append(gradient_steps)\n", + " legend_r_squared_score.append(r2_score(prices, prediction))\n", "\n", " vmin = np.min(legend_r_squared_score)\n", " vmax = np.max(legend_r_squared_score)\n", @@ -336,6 +334,11 @@ " ax2.set_ylabel('Number of gradient steps')\n", " ax2.set_zlabel('R-squared score')\n", " ax2.set_title('Negative Squared Term Task')\n", + " \n", + " if fix_scale:\n", + " ax1.set_zlim(0.65, 1)\n", + " ax2.set_zlim(0.65, 1)\n", + " \n", " plt.show()" ] }, @@ -343,8 +346,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -496,8 +498,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -537,8 +538,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -567,8 +567,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -621,8 +620,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -640,7 +638,9 @@ "\n", "# Section 1: Introducing meta-learning task\n", "\n", - "In this section, we introduce the meta-learning approach. We will discuss its main components and then focus on defining the task before proceeding to training." + "In this section, we introduce the meta-learning approach. We will discuss its main components and then focus on defining the task before proceeding to training.\n", + "\n", + "The idea behind meta-learning is that we can \"learn to learn\". Meta-learning is a phrase that is used to describe a lot of different approaches to making more flexible and adaptable systems. The MAML approach is essentially finding good initialization weights, and because those initial weights are learned based on the task set, the model is technically \"learning to find a good place to learn from\". \"Learning to learn\" is a shorter, snappier description that can encompass many different meta-learning approaches." ] }, { @@ -651,7 +651,7 @@ "source": [ "## Coding Exercise 1: Task space\n", "\n", - "The idea behind meta-learning is that we can \"learn to learn\". We aim to develop a model that, in its desired state, can generalize knowledge about a particular set of similar tasks and adapt to a new task from this set extremely rapidly. Specifically, we aim to identify model weights such that the weights can be robustly and easily fine-tuned to create valid predictions on a specific task in just a few learning steps. This is similar to what humans excel at: performing one-shot tasks without much specific training.\n", + "We aim to develop a model that, in its desired state, can generalize knowledge about a particular set of similar tasks and adapt to a new task from this set extremely rapidly. Specifically, we aim to identify model weights such that the weights can be robustly and easily fine-tuned to create valid predictions on a specific task in just a few learning steps. This is similar to what humans excel at: performing one-shot tasks without much specific training.\n", "\n", "For this, we first need to define the **task space** -- the set of tasks we want the model to learn. Formally, we consider a distribution over tasks $p(\\tau)$ that we want our model to be able to adapt to. In the $K$-shot learning setting, the model is trained to learn a new task $\\tau_{i}$ drawn from $p(\\tau)$ using only $K$ samples drawn from $\\tau_{i}$.\n", "\n", @@ -669,7 +669,6 @@ "execution_count": null, "metadata": { "cellView": "form", - "execution": {}, "pycharm": { "name": "#%%\n" } @@ -711,9 +710,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "class FruitSupplyDataset(Dataset):\n", @@ -786,9 +783,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# to_remove solution\n", @@ -868,8 +863,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -898,9 +892,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "#to_remove explanation\n", @@ -918,8 +910,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -982,9 +973,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "class MetaLearningModel(UtilModel):\n", @@ -1069,9 +1058,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# to_remove solution\n", @@ -1159,9 +1146,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "class MLP(nn.Module):\n", @@ -1194,9 +1179,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "def train(name, num_epochs, num_tasks, num_samples):\n", @@ -1267,9 +1250,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "set_seed(42)\n", @@ -1289,8 +1270,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -1319,8 +1299,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -1344,9 +1323,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "#make sure you have downloaded model in your files\n", @@ -1381,8 +1358,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -1429,9 +1405,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "def finetune(model, x_finetune, y_finetune, finetune_gradient_steps):\n", @@ -1468,9 +1442,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# to_remove solution\n", @@ -1513,9 +1485,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "def plot_performance(task, meta_model, gradient_steps, num_samples_finetune):\n", @@ -1571,9 +1541,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "set_seed(42)\n", @@ -1584,8 +1552,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -1610,8 +1577,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -1638,8 +1604,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -1652,12 +1617,33 @@ "plot_sensitivity_r_squared(\"SummerAutumnModel\", gradient_steps, num_samples)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice that the z-axis (R-squared score) has a different scale for the plots (for the positive squared term constant, it starts with 0.84 while for the negative one, with -0.75). For a better comparison between these two cases, let us fix the scale as in a positive plot, but it means that we are going to lose some data points for the negative plot." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# @title Make sure you execute this cell to observe the plot!\n", + "\n", + "set_seed(42)\n", + "\n", + "gradient_steps = np.arange(11)\n", + "num_samples = np.arange(5, 155, 5)\n", + "plot_sensitivity_r_squared(\"SummerAutumnModel\", gradient_steps, num_samples, fix_scale = True)" + ] + }, { "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -1712,7 +1698,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.19" + "version": "3.11.5" } }, "nbformat": 4,