From 3ecd9f78ea93c7d7385748806447707458500aeb Mon Sep 17 00:00:00 2001 From: Morten Hjorth-Jensen Date: Wed, 8 Nov 2023 08:44:50 +0100 Subject: [PATCH] update --- .../week45-checkpoint.ipynb | 1855 +++++++++++++++++ doc/LectureNotes/week45.ipynb | 456 ++-- doc/pub/week45/ipynb/week45.ipynb | 314 +-- 3 files changed, 2172 insertions(+), 453 deletions(-) create mode 100644 doc/LectureNotes/.ipynb_checkpoints/week45-checkpoint.ipynb diff --git a/doc/LectureNotes/.ipynb_checkpoints/week45-checkpoint.ipynb b/doc/LectureNotes/.ipynb_checkpoints/week45-checkpoint.ipynb new file mode 100644 index 000000000..10e5812f9 --- /dev/null +++ b/doc/LectureNotes/.ipynb_checkpoints/week45-checkpoint.ipynb @@ -0,0 +1,1855 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "31a10e2b", + "metadata": {}, + "source": [ + "\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "019daa83", + "metadata": {}, + "source": [ + "# Week 45, Recurrent Neural Networks\n", + "**Morten Hjorth-Jensen**, Department of Physics, University of Oslo and Department of Physics and Astronomy and National Superconducting Cyclotron Laboratory, Michigan State University\n", + "\n", + "Date: **November 6-10**" + ] + }, + { + "cell_type": "markdown", + "id": "6ecf1c2b", + "metadata": {}, + "source": [ + "## Plan for week 45\n", + "\n", + "**Material for the active learning sessions on Tuesday and Wednesday.**\n", + "\n", + " * Discussion of project 2\n", + "\n", + " * [Video of lab session from week 43](https://youtu.be/Ia6wwDLxqtM)\n", + "\n", + " * [Video of lab session from week 44](https://youtu.be/EajWMW__k0I)\n", + "\n", + " * [See also whiteboard notes from lab session week 44](https://github.com/CompPhysics/MachineLearning/blob/master/doc/HandWrittenNotes/2023/Exercisesweek44.pdf)\n", + "\n", + " \n", + "\n", + "**Material for the lecture on Thursday November 9, 2023.**\n", + "\n", + " * Short repetition on Convolutional Neural Networks\n", + "\n", + " * Recurrent Neural Networks (RNNs)\n", + "\n", + " * Readings and Videos:\n", + "\n", + " * These lecture notes\n", + "\n", + " * For a more in depth discussion on neural networks we recommend Goodfellow et al chapter 10. See also chapter 11 and 12 on practicalities and applications \n", + "\n", + " * Reading suggestions for implementation of RNNs: [Aurelien Geron's chapter 14](https://github.com/CompPhysics/MachineLearning/blob/master/doc/Textbooks/TensorflowML.pdf).\n", + "\n", + " * [Video on Recurrent Neural Networks from MIT](https://www.youtube.com/watch?v=SEnXr6v2ifU&ab_channel=AlexanderAmini)\n", + "\n", + " * [Video on Deep Learning](https://www.youtube.com/playlist?list=PLZHQObOWTQDNU6R1_67000Dx_ZCJB-3pi)" + ] + }, + { + "cell_type": "markdown", + "id": "d80a4db8", + "metadata": {}, + "source": [ + "## Material for the lab sessions, additional ways to present classification results and other practicalities" + ] + }, + { + "cell_type": "markdown", + "id": "1ded5c92", + "metadata": {}, + "source": [ + "## Searching for Optimal Regularization Parameters $\\lambda$\n", + "\n", + "In project 1, when using Ridge and Lasso regression, we end up\n", + "searching for the optimal parameter $\\lambda$ which minimizes our\n", + "selected scores (MSE or $R2$ values for example). The brute force\n", + "approach, as discussed in the code here for Ridge regression, consists\n", + "in evaluating the MSE as function of different $\\lambda$ values.\n", + "Based on these calculations, one tries then to determine the value of the hyperparameter $\\lambda$\n", + "which results in optimal scores (for example the smallest MSE or an $R2=1$)." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "6dea0513", + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "\n", + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "from sklearn.model_selection import train_test_split\n", + "from sklearn import linear_model\n", + "\n", + "def MSE(y_data,y_model):\n", + " n = np.size(y_model)\n", + " return np.sum((y_data-y_model)**2)/n\n", + "# A seed just to ensure that the random numbers are the same for every run.\n", + "# Useful for eventual debugging.\n", + "np.random.seed(2021)\n", + "\n", + "n = 100\n", + "x = np.random.rand(n)\n", + "y = np.exp(-x**2) + 1.5 * np.exp(-(x-2)**2)+ np.random.randn(n)\n", + "\n", + "Maxpolydegree = 5\n", + "X = np.zeros((n,Maxpolydegree-1))\n", + "\n", + "for degree in range(1,Maxpolydegree): #No intercept column\n", + " X[:,degree-1] = x**(degree)\n", + "\n", + "# We split the data in test and training data\n", + "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)\n", + "\n", + "# Decide which values of lambda to use\n", + "nlambdas = 500\n", + "MSERidgePredict = np.zeros(nlambdas)\n", + "lambdas = np.logspace(-4, 2, nlambdas)\n", + "for i in range(nlambdas):\n", + " lmb = lambdas[i]\n", + " RegRidge = linear_model.Ridge(lmb)\n", + " RegRidge.fit(X_train,y_train)\n", + " ypredictRidge = RegRidge.predict(X_test)\n", + " MSERidgePredict[i] = MSE(y_test,ypredictRidge)\n", + "\n", + "# Now plot the results\n", + "plt.figure()\n", + "plt.plot(np.log10(lambdas), MSERidgePredict, 'g--', label = 'MSE SL Ridge Test')\n", + "plt.xlabel('log10(lambda)')\n", + "plt.ylabel('MSE')\n", + "plt.legend()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "440bf579", + "metadata": {}, + "source": [ + "Here we have performed a rather data greedy calculation as function of the regularization parameter $\\lambda$. There is no resampling here. The latter can easily be added by employing the function **RidgeCV** instead of just calling the **Ridge** function. For **RidgeCV** we need to pass the array of $\\lambda$ values.\n", + "By inspecting the figure we can in turn determine which is the optimal regularization parameter.\n", + "This becomes however less functional in the long run." + ] + }, + { + "cell_type": "markdown", + "id": "683b1da2", + "metadata": {}, + "source": [ + "## Grid Search\n", + "\n", + "An alternative is to use the so-called grid search functionality\n", + "included with the library **Scikit-Learn**, as demonstrated for the same\n", + "example here." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "38be79e0", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from sklearn.model_selection import train_test_split\n", + "from sklearn.linear_model import Ridge\n", + "from sklearn.model_selection import GridSearchCV\n", + "\n", + "def R2(y_data, y_model):\n", + " return 1 - np.sum((y_data - y_model) ** 2) / np.sum((y_data - np.mean(y_data)) ** 2)\n", + "\n", + "def MSE(y_data,y_model):\n", + " n = np.size(y_model)\n", + " return np.sum((y_data-y_model)**2)/n\n", + "\n", + "# A seed just to ensure that the random numbers are the same for every run.\n", + "# Useful for eventual debugging.\n", + "np.random.seed(2021)\n", + "\n", + "n = 100\n", + "x = np.random.rand(n)\n", + "y = np.exp(-x**2) + 1.5 * np.exp(-(x-2)**2)+ np.random.randn(n)\n", + "\n", + "Maxpolydegree = 5\n", + "X = np.zeros((n,Maxpolydegree-1))\n", + "\n", + "for degree in range(1,Maxpolydegree): #No intercept column\n", + " X[:,degree-1] = x**(degree)\n", + "\n", + "# We split the data in test and training data\n", + "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)\n", + "\n", + "# Decide which values of lambda to use\n", + "nlambdas = 10\n", + "lambdas = np.logspace(-4, 2, nlambdas)\n", + "# create and fit a ridge regression model, testing each alpha\n", + "model = Ridge()\n", + "gridsearch = GridSearchCV(estimator=model, param_grid=dict(alpha=lambdas))\n", + "gridsearch.fit(X_train, y_train)\n", + "print(gridsearch)\n", + "ypredictRidge = gridsearch.predict(X_test)\n", + "# summarize the results of the grid search\n", + "print(f\"Best estimated lambda-value: {gridsearch.best_estimator_.alpha}\")\n", + "print(f\"MSE score: {MSE(y_test,ypredictRidge)}\")\n", + "print(f\"R2 score: {R2(y_test,ypredictRidge)}\")" + ] + }, + { + "cell_type": "markdown", + "id": "081fbe5c", + "metadata": {}, + "source": [ + "By default the grid search function includes cross validation with\n", + "five folds. The [Scikit-Learn\n", + "documentation](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html#sklearn.model_selection.GridSearchCV)\n", + "contains more information on how to set the different parameters.\n", + "\n", + "If we take out the random noise, running the above codes results in $\\lambda=0$ yielding the best fit." + ] + }, + { + "cell_type": "markdown", + "id": "a9798c07", + "metadata": {}, + "source": [ + "## Randomized Grid Search\n", + "\n", + "An alternative to the above manual grid set up, is to use a random\n", + "search where the parameters are tuned from a random distribution\n", + "(uniform below) for a fixed number of iterations. A model is\n", + "constructed and evaluated for each combination of chosen parameters.\n", + "We repeat the previous example but now with a random search. Note\n", + "that values of $\\lambda$ are now limited to be within $x\\in\n", + "[0,1]$. This domain may not be the most relevant one for the specific\n", + "case under study." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "0a7e4e2e", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from sklearn.model_selection import train_test_split\n", + "from sklearn.linear_model import Ridge\n", + "from sklearn.model_selection import GridSearchCV\n", + "from scipy.stats import uniform as randuniform\n", + "from sklearn.model_selection import RandomizedSearchCV\n", + "\n", + "\n", + "def R2(y_data, y_model):\n", + " return 1 - np.sum((y_data - y_model) ** 2) / np.sum((y_data - np.mean(y_data)) ** 2)\n", + "\n", + "def MSE(y_data,y_model):\n", + " n = np.size(y_model)\n", + " return np.sum((y_data-y_model)**2)/n\n", + "\n", + "# A seed just to ensure that the random numbers are the same for every run.\n", + "# Useful for eventual debugging.\n", + "np.random.seed(2021)\n", + "\n", + "n = 100\n", + "x = np.random.rand(n)\n", + "y = np.exp(-x**2) + 1.5 * np.exp(-(x-2)**2)+ np.random.randn(n)\n", + "\n", + "Maxpolydegree = 5\n", + "X = np.zeros((n,Maxpolydegree-1))\n", + "\n", + "for degree in range(1,Maxpolydegree): #No intercept column\n", + " X[:,degree-1] = x**(degree)\n", + "\n", + "# We split the data in test and training data\n", + "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)\n", + "\n", + "param_grid = {'alpha': randuniform()}\n", + "# create and fit a ridge regression model, testing each alpha\n", + "model = Ridge()\n", + "gridsearch = RandomizedSearchCV(estimator=model, param_distributions=param_grid, n_iter=100)\n", + "gridsearch.fit(X_train, y_train)\n", + "print(gridsearch)\n", + "ypredictRidge = gridsearch.predict(X_test)\n", + "# summarize the results of the grid search\n", + "print(f\"Best estimated lambda-value: {gridsearch.best_estimator_.alpha}\")\n", + "print(f\"MSE score: {MSE(y_test,ypredictRidge)}\")\n", + "print(f\"R2 score: {R2(y_test,ypredictRidge)}\")" + ] + }, + { + "cell_type": "markdown", + "id": "dcd07cb8", + "metadata": {}, + "source": [ + "## Wisconsin Cancer Data\n", + "\n", + "We show here how we can use a simple regression case on the breast\n", + "cancer data using Logistic regression as our algorithm for\n", + "classification." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "65061d95", + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "from sklearn.model_selection import train_test_split \n", + "from sklearn.datasets import load_breast_cancer\n", + "from sklearn.linear_model import LogisticRegression\n", + "\n", + "# Load the data\n", + "cancer = load_breast_cancer()\n", + "\n", + "X_train, X_test, y_train, y_test = train_test_split(cancer.data,cancer.target,random_state=0)\n", + "print(X_train.shape)\n", + "print(X_test.shape)\n", + "# Logistic Regression\n", + "logreg = LogisticRegression(solver='lbfgs')\n", + "logreg.fit(X_train, y_train)\n", + "print(\"Test set accuracy with Logistic Regression: {:.2f}\".format(logreg.score(X_test,y_test)))" + ] + }, + { + "cell_type": "markdown", + "id": "50492453", + "metadata": {}, + "source": [ + "## Using the correlation matrix\n", + "\n", + "In addition to the above scores, we could also study the covariance (and the correlation matrix).\n", + "We use **Pandas** to compute the correlation matrix." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "08a2ab17", + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "from sklearn.model_selection import train_test_split \n", + "from sklearn.datasets import load_breast_cancer\n", + "from sklearn.linear_model import LogisticRegression\n", + "cancer = load_breast_cancer()\n", + "import pandas as pd\n", + "# Making a data frame\n", + "cancerpd = pd.DataFrame(cancer.data, columns=cancer.feature_names)\n", + "\n", + "fig, axes = plt.subplots(15,2,figsize=(10,20))\n", + "malignant = cancer.data[cancer.target == 0]\n", + "benign = cancer.data[cancer.target == 1]\n", + "ax = axes.ravel()\n", + "\n", + "for i in range(30):\n", + " _, bins = np.histogram(cancer.data[:,i], bins =50)\n", + " ax[i].hist(malignant[:,i], bins = bins, alpha = 0.5)\n", + " ax[i].hist(benign[:,i], bins = bins, alpha = 0.5)\n", + " ax[i].set_title(cancer.feature_names[i])\n", + " ax[i].set_yticks(())\n", + "ax[0].set_xlabel(\"Feature magnitude\")\n", + "ax[0].set_ylabel(\"Frequency\")\n", + "ax[0].legend([\"Malignant\", \"Benign\"], loc =\"best\")\n", + "fig.tight_layout()\n", + "plt.show()\n", + "\n", + "import seaborn as sns\n", + "correlation_matrix = cancerpd.corr().round(1)\n", + "# use the heatmap function from seaborn to plot the correlation matrix\n", + "# annot = True to print the values inside the square\n", + "plt.figure(figsize=(15,8))\n", + "sns.heatmap(data=correlation_matrix, annot=True)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "5408b7dd", + "metadata": {}, + "source": [ + "## Discussing the correlation data\n", + "\n", + "In the above example we note two things. In the first plot we display\n", + "the overlap of benign and malignant tumors as functions of the various\n", + "features in the Wisconsing breast cancer data set. We see that for\n", + "some of the features we can distinguish clearly the benign and\n", + "malignant cases while for other features we cannot. This can point to\n", + "us which features may be of greater interest when we wish to classify\n", + "a benign or not benign tumour.\n", + "\n", + "In the second figure we have computed the so-called correlation\n", + "matrix, which in our case with thirty features becomes a $30\\times 30$\n", + "matrix.\n", + "\n", + "We constructed this matrix using **pandas** via the statements" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "76c3d259", + "metadata": {}, + "outputs": [], + "source": [ + "cancerpd = pd.DataFrame(cancer.data, columns=cancer.feature_names)" + ] + }, + { + "cell_type": "markdown", + "id": "83903231", + "metadata": {}, + "source": [ + "and then" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "58ccd6c3", + "metadata": {}, + "outputs": [], + "source": [ + "correlation_matrix = cancerpd.corr().round(1)" + ] + }, + { + "cell_type": "markdown", + "id": "adda54cb", + "metadata": {}, + "source": [ + "Diagonalizing this matrix we can in turn say something about which\n", + "features are of relevance and which are not. This leads us to\n", + "the classical Principal Component Analysis (PCA) theorem with\n", + "applications. This will be discussed later this semester ([week 43](https://compphysics.github.io/MachineLearning/doc/pub/week43/html/week43-bs.html))." + ] + }, + { + "cell_type": "markdown", + "id": "8799c034", + "metadata": {}, + "source": [ + "## Other ways of presenting a classification problem\n", + "\n", + "For a binary classifcation matrix, the so-called **confusion matrix**, is often used. It can also be extended to more catgeories/classes as well.\n", + "The following quantities are then used\n", + "1. positive condition number $P$, which represents the number of real positive cases in the data (output one/true etc)\n", + "\n", + "2. The condition negative number $N$ which is the number of negative cases (ouput zero/false etc)\n", + "\n", + "3. The true positive number $TP$ which represents whether a positive test result has been correctly classified (the application of our trained model on a test data set)\n", + "\n", + "4. The true negative $TN$ number which represents whether a negative test has been correctly classified\n", + "\n", + "5. The false positive $FP$ number, a so-called type I error which tells us about the fraction of positive test result which are wrongly classified\n", + "\n", + "6. A false negative $FN$ number, a so-called type II error which, should be pretty obvious, indicates if a negative test has been wrongly classified.\n", + "\n", + "It is is easy to think in terms of illness. You could think of the above as\n", + "1. True positive: Sick people correctly identified as sick\n", + "\n", + "2. False positive: Healthy people incorrectly identified as sick\n", + "\n", + "3. True negative: Healthy people correctly identified as healthy\n", + "\n", + "4. False negative: Sick people incorrectly identified as healthy" + ] + }, + { + "cell_type": "markdown", + "id": "dfbe0571", + "metadata": {}, + "source": [ + "## Combinations of classification results\n", + "\n", + "It is common in the literature to define various combinations the above numbers. The most commonly used are\n", + "\n", + "**Sensitivity, recall, hit rate, or true positive rate $TPR$. It is the probability of a positive test result, conditioned on the individual truly being positive.**" + ] + }, + { + "cell_type": "markdown", + "id": "65f7c63d", + "metadata": {}, + "source": [ + "$$\n", + "{\\displaystyle \\mathrm {TPR} ={\\frac {\\mathrm {TP} }{\\mathrm {P} }}={\\frac {\\mathrm {TP} }{\\mathrm {TP} +\\mathrm {FN} }}=1-\\mathrm {FNR} }\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "2e674d10", + "metadata": {}, + "source": [ + "The $TPR$ defines how many correct positive results occur among all positive samples available during the test\n", + "\n", + "**Miss rate or false negative rate $FNR$.**" + ] + }, + { + "cell_type": "markdown", + "id": "65577837", + "metadata": {}, + "source": [ + "$$\n", + "{\\displaystyle \\mathrm {FNR} ={\\frac {\\mathrm {FN} }{\\mathrm {P} }}={\\frac {\\mathrm {FN} }{\\mathrm {FN} +\\mathrm {TP} }} }\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "e5e8802d", + "metadata": {}, + "source": [ + "**Specificity, selectivity or true negative rate $TNR$. It is the probability of a negative test result, conditioned on the individual truly being negative.**" + ] + }, + { + "cell_type": "markdown", + "id": "07c61591", + "metadata": {}, + "source": [ + "$$\n", + "{\\displaystyle \\mathrm {TNR} ={\\frac {\\mathrm {TN} }{\\mathrm {N} }}={\\frac {\\mathrm {TN} }{\\mathrm {TN} +\\mathrm {FP} }}=1-\\mathrm {FPR} }\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "b3f61bb3", + "metadata": {}, + "source": [ + "with the fall-out false positive rate" + ] + }, + { + "cell_type": "markdown", + "id": "6544105e", + "metadata": {}, + "source": [ + "$$\n", + "{\\displaystyle \\mathrm {FPR} ={\\frac {\\mathrm {FP} }{\\mathrm {N} }}={\\frac {\\mathrm {FP} }{\\mathrm {FP} +\\mathrm {TN} }}=1-\\mathrm {TNR} }\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "0b571e85", + "metadata": {}, + "source": [ + "The $FPR$ defines how many incorrect positive results occur among\n", + "all negative samples available during the test." + ] + }, + { + "cell_type": "markdown", + "id": "17d6872a", + "metadata": {}, + "source": [ + "## Positive and negative prediction values\n", + "\n", + "The positive and negative predictive values \n", + "are the proportions of positive and negative results in statistics and\n", + "diagnostic tests that are true positive and true negative results,\n", + "respectively.[1] The PPV and NPV describe the performance of a\n", + "diagnostic test or other statistical measure. A high result can be\n", + "interpreted as indicating the accuracy of such a statistic.\n", + "\n", + "**Precision or positive predictive value $PPV$.**" + ] + }, + { + "cell_type": "markdown", + "id": "122f7e6c", + "metadata": {}, + "source": [ + "$$\n", + "{\\displaystyle \\mathrm {PPV} ={\\frac {\\mathrm {TP} }{\\mathrm {TP} +\\mathrm {FP} }}=1-\\mathrm {FDR} }\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "f44a5e78", + "metadata": {}, + "source": [ + "**Negative predictive value $NPV$.**" + ] + }, + { + "cell_type": "markdown", + "id": "86fa9670", + "metadata": {}, + "source": [ + "$$\n", + "{\\displaystyle \\mathrm {NPV} ={\\frac {\\mathrm {TN} }{\\mathrm {TN} +\\mathrm {FN} }}=1-\\mathrm {FOR} }\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "a30e358d", + "metadata": {}, + "source": [ + "## Other quantities\n", + "\n", + "**False discovery rate $FDR$.**" + ] + }, + { + "cell_type": "markdown", + "id": "3f0de6de", + "metadata": {}, + "source": [ + "$$\n", + "{\\displaystyle \\mathrm {FDR} ={\\frac {\\mathrm {FP} }{\\mathrm {FP} +\\mathrm {TP} }}=1-\\mathrm {PPV} }\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "0b4cc93f", + "metadata": {}, + "source": [ + "**False omission rate $FOR$.**" + ] + }, + { + "cell_type": "markdown", + "id": "4866ec0a", + "metadata": {}, + "source": [ + "$$\n", + "{\\displaystyle \\mathrm {FOR} ={\\frac {\\mathrm {FN} }{\\mathrm {FN} +\\mathrm {TN} }}=1-\\mathrm {NPV} }\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "9b1c8c45", + "metadata": {}, + "source": [ + "## $F_1$ score\n", + "\n", + "In statistical analysis of binary classification, the F-score or\n", + "F-measure is a measure of a test's accuracy. It is calculated from the\n", + "precision and recall of the test, where the precision is the number of\n", + "true positive results divided by the number of all positive results,\n", + "including those not identified correctly, and the recall is the number\n", + "of true positive results divided by the number of all samples that\n", + "should have been identified as positive. Precision is also known as\n", + "positive predictive value, and recall is also known as sensitivity in\n", + "diagnostic binary classification.\n", + "\n", + "The F1 score is the harmonic mean of the precision and recall. It thus\n", + "symmetrically represents both precision and recall in one metric. The\n", + "highest possible value of an F-score is 1.0, indicating perfect\n", + "precision and recall, and the lowest possible value is 0, if either\n", + "precision or recall are zero.\n", + "\n", + "It is defined as" + ] + }, + { + "cell_type": "markdown", + "id": "0e651a1f", + "metadata": {}, + "source": [ + "$$\n", + "{\\displaystyle \\mathrm {F} _{1}=2\\times {\\frac {\\mathrm {PPV} \\times \\mathrm {TPR} }{\\mathrm {PPV} +\\mathrm {TPR} }}={\\frac {2\\mathrm {TP} }{2\\mathrm {TP} +\\mathrm {FP} +\\mathrm {FN} }}}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "d83efe41", + "metadata": {}, + "source": [ + "## ROC curve\n", + "\n", + "A receiver operating characteristic curve, or ROC curve, is a\n", + "graphical plot that illustrates the performance of a binary classifier\n", + "model at varying threshold values.\n", + "\n", + "The ROC curve is the plot of the true positive rate (TPR) against the false positive rate (FPR) at each threshold setting.\n", + "\n", + "To draw a ROC curve, only the true positive rate (TPR) and false\n", + "positive rate (FPR) are needed (as functions of some classifier\n", + "parameter). The TPR defines how many correct positive results occur\n", + "among all positive samples available during the test. FPR, on the\n", + "other hand, defines how many incorrect positive results occur among\n", + "all negative samples available during the test.\n", + "\n", + "See for more discussions." + ] + }, + { + "cell_type": "markdown", + "id": "d088215b", + "metadata": {}, + "source": [ + "## Cumulative gain curve\n", + "\n", + "The cumulative gain curve is a performance evaluation used typically for binary classification problems.\n", + "It plots the $TPR$ True Positive Rate or Sensitivity (which represents the \n", + "fraction of examples correctly classified\n", + "against Predictive Positive Rate, which represents \n", + "the fraction of positively predicted examples.\n", + "\n", + "The examples below show the confusion matrix, the ROC curve and the cumulative gain for the Wisconsin cancer data." + ] + }, + { + "cell_type": "markdown", + "id": "5c0bcd1f", + "metadata": {}, + "source": [ + "## Other measures in classification studies: Cancer Data again" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "2a6f80df", + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "from sklearn.model_selection import train_test_split \n", + "from sklearn.datasets import load_breast_cancer\n", + "from sklearn.linear_model import LogisticRegression\n", + "\n", + "# Load the data\n", + "cancer = load_breast_cancer()\n", + "\n", + "X_train, X_test, y_train, y_test = train_test_split(cancer.data,cancer.target,random_state=0)\n", + "print(X_train.shape)\n", + "print(X_test.shape)\n", + "# Logistic Regression\n", + "logreg = LogisticRegression(solver='lbfgs')\n", + "logreg.fit(X_train, y_train)\n", + "\n", + "from sklearn.preprocessing import LabelEncoder\n", + "from sklearn.model_selection import cross_validate\n", + "#Cross validation\n", + "accuracy = cross_validate(logreg,X_test,y_test,cv=10)['test_score']\n", + "print(accuracy)\n", + "print(\"Test set accuracy with Logistic Regression: {:.2f}\".format(logreg.score(X_test,y_test)))\n", + "\n", + "import scikitplot as skplt\n", + "y_pred = logreg.predict(X_test)\n", + "skplt.metrics.plot_confusion_matrix(y_test, y_pred, normalize=True)\n", + "plt.show()\n", + "y_probas = logreg.predict_proba(X_test)\n", + "skplt.metrics.plot_roc(y_test, y_probas)\n", + "plt.show()\n", + "skplt.metrics.plot_cumulative_gain(y_test, y_probas)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "58e5b521", + "metadata": {}, + "source": [ + "## Material for Lecture Thursday November 9" + ] + }, + { + "cell_type": "markdown", + "id": "4ebe5a91", + "metadata": {}, + "source": [ + "## Recurrent neural networks (RNNs): Overarching view\n", + "\n", + "Till now our focus has been, including convolutional neural networks\n", + "as well, on feedforward neural networks. The output or the activations\n", + "flow only in one direction, from the input layer to the output layer.\n", + "\n", + "A recurrent neural network (RNN) looks very much like a feedforward\n", + "neural network, except that it also has connections pointing\n", + "backward. \n", + "\n", + "RNNs are used to analyze time series data such as stock prices, and\n", + "tell you when to buy or sell. In autonomous driving systems, they can\n", + "anticipate car trajectories and help avoid accidents. More generally,\n", + "they can work on sequences of arbitrary lengths, rather than on\n", + "fixed-sized inputs like all the nets we have discussed so far. For\n", + "example, they can take sentences, documents, or audio samples as\n", + "input, making them extremely useful for natural language processing\n", + "systems such as automatic translation and speech-to-text." + ] + }, + { + "cell_type": "markdown", + "id": "182f425e", + "metadata": {}, + "source": [ + "## A simple example" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "8b3ca785", + "metadata": {}, + "outputs": [], + "source": [ + "# Start importing packages\n", + "import pandas as pd\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import tensorflow as tf\n", + "from tensorflow.keras import datasets, layers, models\n", + "from tensorflow.keras.layers import Input\n", + "from tensorflow.keras.models import Model, Sequential \n", + "from tensorflow.keras.layers import Dense, SimpleRNN, LSTM, GRU\n", + "from tensorflow.keras import optimizers \n", + "from tensorflow.keras import regularizers \n", + "from tensorflow.keras.utils import to_categorical \n", + "\n", + "\n", + "\n", + "# convert into dataset matrix\n", + "def convertToMatrix(data, step):\n", + " X, Y =[], []\n", + " for i in range(len(data)-step):\n", + " d=i+step \n", + " X.append(data[i:d,])\n", + " Y.append(data[d,])\n", + " return np.array(X), np.array(Y)\n", + "\n", + "step = 4\n", + "N = 1000 \n", + "Tp = 800 \n", + "\n", + "t=np.arange(0,N)\n", + "x=np.sin(0.02*t)+2*np.random.rand(N)\n", + "df = pd.DataFrame(x)\n", + "df.head()\n", + "\n", + "values=df.values\n", + "train,test = values[0:Tp,:], values[Tp:N,:]\n", + "\n", + "# add step elements into train and test\n", + "test = np.append(test,np.repeat(test[-1,],step))\n", + "train = np.append(train,np.repeat(train[-1,],step))\n", + " \n", + "trainX,trainY =convertToMatrix(train,step)\n", + "testX,testY =convertToMatrix(test,step)\n", + "trainX = np.reshape(trainX, (trainX.shape[0], 1, trainX.shape[1]))\n", + "testX = np.reshape(testX, (testX.shape[0], 1, testX.shape[1]))\n", + "\n", + "model = Sequential()\n", + "model.add(SimpleRNN(units=32, input_shape=(1,step), activation=\"relu\"))\n", + "model.add(Dense(8, activation=\"relu\")) \n", + "model.add(Dense(1))\n", + "model.compile(loss='mean_squared_error', optimizer='rmsprop')\n", + "model.summary()\n", + "\n", + "model.fit(trainX,trainY, epochs=100, batch_size=16, verbose=2)\n", + "trainPredict = model.predict(trainX)\n", + "testPredict= model.predict(testX)\n", + "predicted=np.concatenate((trainPredict,testPredict),axis=0)\n", + "\n", + "trainScore = model.evaluate(trainX, trainY, verbose=0)\n", + "print(trainScore)\n", + "plt.plot(df)\n", + "plt.plot(predicted)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "b0c12b4c", + "metadata": {}, + "source": [ + "### RNNs\n", + "\n", + "RNNs are very powerful, because they\n", + "combine two properties:\n", + "1. Distributed hidden state that allows them to store a lot of information about the past efficiently.\n", + "\n", + "2. Non-linear dynamics that allows them to update their hidden state in complicated ways.\n", + "\n", + "With enough neurons and time, RNNs\n", + "can compute anything that can be\n", + "computed by your computer!" + ] + }, + { + "cell_type": "markdown", + "id": "d81020f6", + "metadata": {}, + "source": [ + "## Basic layout\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "2d7453c9", + "metadata": {}, + "source": [ + "### We need to specify the initial activity state of all the hidden and output units\n", + "\n", + "1. We could just fix these initial states to have some default value like 0.5.\n", + "\n", + "2. But it is better to treat the initial states as learned parameters.\n", + "\n", + "3. We learn them in the same way as we learn the weights.\n", + "\n", + "* Start off with an initial random guess for the initial states.\n", + "\n", + "a. At the end of each training sequence, backpropagate through time all the way to the initial states to get the gradient of the error function with respect to each initial state.\n", + "\n", + "b. Adjust the initial states by following the negative gradient." + ] + }, + { + "cell_type": "markdown", + "id": "fc4a082e", + "metadata": {}, + "source": [ + "### We can specify inputs in several ways\n", + "\n", + "1. Specify the initial states of all the units.\n", + "\n", + "2. Specify the initial states of a subset of the units.\n", + "\n", + "3. Specify the states of the same subset of the units at every time step.\n", + "\n", + "This is the natural way to model most sequential data." + ] + }, + { + "cell_type": "markdown", + "id": "c1106ad9", + "metadata": {}, + "source": [ + "### We can specify targets in several ways\n", + "\n", + "1. Specify desired final activities of all the units\n", + "\n", + "2. Specify desired activities of all units for the last few steps\n", + "\n", + "* Good for learning attractors\n", + "\n", + "* It is easy to add in extra error derivatives as we backpropagate.\n", + "\n", + " * Specify the desired activity of a subset of the units.\n", + "\n", + "* The other units are input or hidden units. \n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "b139ef7b", + "metadata": {}, + "source": [ + "### Backpropagation through time\n", + "\n", + "We can think of the recurrent net as a layered, feed-forward\n", + "net with shared weights and then train the feed-forward net\n", + "with weight constraints.\n", + "\n", + "We can also think of this training algorithm in the time domain:\n", + "1. The forward pass builds up a stack of the activities of all the units at each time step.\n", + "\n", + "2. The backward pass peels activities off the stack to compute the error derivatives at each time step.\n", + "\n", + "3. After the backward pass we add together the derivatives at all the different times for each weight." + ] + }, + { + "cell_type": "markdown", + "id": "70c95078", + "metadata": {}, + "source": [ + "### The backward pass is linear\n", + "\n", + "1. There is a big difference between the forward and backward passes.\n", + "\n", + "2. In the forward pass we use squashing functions (like the logistic) to prevent the activity vectors from exploding.\n", + "\n", + "3. The backward pass, is completely linear. If you double the error derivatives at the final layer, all the error derivatives will double.\n", + "\n", + "The forward pass determines the slope of the linear function used for\n", + "backpropagating through each neuron\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "2ca24031", + "metadata": {}, + "source": [ + "## The problem of exploding or vanishing gradients\n", + "* What happens to the magnitude of the gradients as we backpropagate through many layers?\n", + "\n", + "a. If the weights are small, the gradients shrink exponentially.\n", + "\n", + "b. If the weights are big the gradients grow exponentially.\n", + "\n", + "* Typical feed-forward neural nets can cope with these exponential effects because they only have a few hidden layers.\n", + "\n", + "* In an RNN trained on long sequences (e.g. 100 time steps) the gradients can easily explode or vanish.\n", + "\n", + "a. We can avoid this by initializing the weights very carefully.\n", + "\n", + "* Even with good initial weights, its very hard to detect that the current target output depends on an input from many time-steps ago.\n", + "\n", + "RNNs have difficulty dealing with long-range dependencies." + ] + }, + { + "cell_type": "markdown", + "id": "93648979", + "metadata": {}, + "source": [ + "## Four effective ways to learn an RNN\n", + "1. Long Short Term Memory Make the RNN out of little modules that are designed to remember values for a long time.\n", + "\n", + "2. Hessian Free Optimization: Deal with the vanishing gradients problem by using a fancy optimizer that can detect directions with a tiny gradient but even smaller curvature.\n", + "\n", + "3. Echo State Networks: Initialize the input a hidden and hidden-hidden and output-hidden connections very carefully so that the hidden state has a huge reservoir of weakly coupled oscillators which can be selectively driven by the input.\n", + "\n", + " * ESNs only need to learn the hidden-output connections.\n", + "\n", + "4. Good initialization with momentum Initialize like in Echo State Networks, but then learn all of the connections using momentum" + ] + }, + { + "cell_type": "markdown", + "id": "b8806dcd", + "metadata": {}, + "source": [ + "### Long Short Term Memory (LSTM)\n", + "\n", + "LSTM uses a memory cell for \n", + " modeling long-range dependencies and avoid vanishing gradient\n", + " problems.\n", + "\n", + "1. Introduced by Hochreiter and Schmidhuber (1997) who solved the problem of getting an RNN to remember things for a long time (like hundreds of time steps).\n", + "\n", + "2. They designed a memory cell using logistic and linear units with multiplicative interactions.\n", + "\n", + "3. Information gets into the cell whenever its “write” gate is on.\n", + "\n", + "4. The information stays in the cell so long as its **keep** gate is on.\n", + "\n", + "5. Information can be read from the cell by turning on its **read** gate." + ] + }, + { + "cell_type": "markdown", + "id": "b0edad40", + "metadata": {}, + "source": [ + "### Implementing a memory cell in a neural network\n", + "\n", + "To preserve information for a long time in\n", + "the activities of an RNN, we use a circuit\n", + "that implements an analog memory cell.\n", + "\n", + "1. A linear unit that has a self-link with a weight of 1 will maintain its state.\n", + "\n", + "2. Information is stored in the cell by activating its write gate.\n", + "\n", + "3. Information is retrieved by activating the read gate.\n", + "\n", + "4. We can backpropagate through this circuit because logistics are have nice derivatives. \n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "

Figure 1:

\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "58fd18f9", + "metadata": {}, + "source": [ + "## An extrapolation example\n", + "\n", + "The following code provides an example of how recurrent neural\n", + "networks can be used to extrapolate to unknown values of physics data\n", + "sets. Specifically, the data sets used in this program come from\n", + "a quantum mechanical many-body calculation of energies as functions of the number of particles." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "a604caa5", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "# For matrices and calculations\n", + "import numpy as np\n", + "# For machine learning (backend for keras)\n", + "import tensorflow as tf\n", + "# User-friendly machine learning library\n", + "# Front end for TensorFlow\n", + "import tensorflow.keras\n", + "# Different methods from Keras needed to create an RNN\n", + "# This is not necessary but it shortened function calls \n", + "# that need to be used in the code.\n", + "from tensorflow.keras import datasets, layers, models\n", + "from tensorflow.keras.layers import Input\n", + "from tensorflow.keras import regularizers\n", + "from tensorflow.keras.models import Model, Sequential\n", + "from tensorflow.keras.layers import Dense, SimpleRNN, LSTM, GRU\n", + "# For timing the code\n", + "from timeit import default_timer as timer\n", + "# For plotting\n", + "import matplotlib.pyplot as plt\n", + "\n", + "\n", + "# The data set\n", + "datatype='VaryDimension'\n", + "X_tot = np.arange(2, 42, 2)\n", + "y_tot = np.array([-0.03077640549, -0.08336233266, -0.1446729567, -0.2116753732, -0.2830637392, -0.3581341341, -0.436462435, -0.5177783846,\n", + "\t-0.6019067271, -0.6887363571, -0.7782028952, -0.8702784034, -0.9649652536, -1.062292565, -1.16231451, \n", + "\t-1.265109911, -1.370782966, -1.479465113, -1.591317992, -1.70653767])" + ] + }, + { + "cell_type": "markdown", + "id": "545336c9", + "metadata": {}, + "source": [ + "## Formatting the Data\n", + "\n", + "The way the recurrent neural networks are trained in this program\n", + "differs from how machine learning algorithms are usually trained.\n", + "Typically a machine learning algorithm is trained by learning the\n", + "relationship between the x data and the y data. In this program, the\n", + "recurrent neural network will be trained to recognize the relationship\n", + "in a sequence of y values. This is type of data formatting is\n", + "typically used time series forcasting, but it can also be used in any\n", + "extrapolation (time series forecasting is just a specific type of\n", + "extrapolation along the time axis). This method of data formatting\n", + "does not use the x data and assumes that the y data are evenly spaced.\n", + "\n", + "For a standard machine learning algorithm, the training data has the\n", + "form of (x,y) so the machine learning algorithm learns to assiciate a\n", + "y value with a given x value. This is useful when the test data has x\n", + "values within the same range as the training data. However, for this\n", + "application, the x values of the test data are outside of the x values\n", + "of the training data and the traditional method of training a machine\n", + "learning algorithm does not work as well. For this reason, the\n", + "recurrent neural network is trained on sequences of y values of the\n", + "form ((y1, y2), y3), so that the network is concerned with learning\n", + "the pattern of the y data and not the relation between the x and y\n", + "data. As long as the pattern of y data outside of the training region\n", + "stays relatively stable compared to what was inside the training\n", + "region, this method of training can produce accurate extrapolations to\n", + "y values far removed from the training data set.\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "3ef3ed13", + "metadata": {}, + "outputs": [], + "source": [ + "# FORMAT_DATA\n", + "def format_data(data, length_of_sequence = 2): \n", + " \"\"\"\n", + " Inputs:\n", + " data(a numpy array): the data that will be the inputs to the recurrent neural\n", + " network\n", + " length_of_sequence (an int): the number of elements in one iteration of the\n", + " sequence patter. For a function approximator use length_of_sequence = 2.\n", + " Returns:\n", + " rnn_input (a 3D numpy array): the input data for the recurrent neural network. Its\n", + " dimensions are length of data - length of sequence, length of sequence, \n", + " dimnsion of data\n", + " rnn_output (a numpy array): the training data for the neural network\n", + " Formats data to be used in a recurrent neural network.\n", + " \"\"\"\n", + "\n", + " X, Y = [], []\n", + " for i in range(len(data)-length_of_sequence):\n", + " # Get the next length_of_sequence elements\n", + " a = data[i:i+length_of_sequence]\n", + " # Get the element that immediately follows that\n", + " b = data[i+length_of_sequence]\n", + " # Reshape so that each data point is contained in its own array\n", + " a = np.reshape (a, (len(a), 1))\n", + " X.append(a)\n", + " Y.append(b)\n", + " rnn_input = np.array(X)\n", + " rnn_output = np.array(Y)\n", + "\n", + " return rnn_input, rnn_output\n", + "\n", + "\n", + "# ## Defining the Recurrent Neural Network Using Keras\n", + "# \n", + "# The following method defines a simple recurrent neural network in keras consisting of one input layer, one hidden layer, and one output layer.\n", + "\n", + "def rnn(length_of_sequences, batch_size = None, stateful = False):\n", + " \"\"\"\n", + " Inputs:\n", + " length_of_sequences (an int): the number of y values in \"x data\". This is determined\n", + " when the data is formatted\n", + " batch_size (an int): Default value is None. See Keras documentation of SimpleRNN.\n", + " stateful (a boolean): Default value is False. See Keras documentation of SimpleRNN.\n", + " Returns:\n", + " model (a Keras model): The recurrent neural network that is built and compiled by this\n", + " method\n", + " Builds and compiles a recurrent neural network with one hidden layer and returns the model.\n", + " \"\"\"\n", + " # Number of neurons in the input and output layers\n", + " in_out_neurons = 1\n", + " # Number of neurons in the hidden layer\n", + " hidden_neurons = 200\n", + " # Define the input layer\n", + " inp = Input(batch_shape=(batch_size, \n", + " length_of_sequences, \n", + " in_out_neurons)) \n", + " # Define the hidden layer as a simple RNN layer with a set number of neurons and add it to \n", + " # the network immediately after the input layer\n", + " rnn = SimpleRNN(hidden_neurons, \n", + " return_sequences=False,\n", + " stateful = stateful,\n", + " name=\"RNN\")(inp)\n", + " # Define the output layer as a dense neural network layer (standard neural network layer)\n", + " #and add it to the network immediately after the hidden layer.\n", + " dens = Dense(in_out_neurons,name=\"dense\")(rnn)\n", + " # Create the machine learning model starting with the input layer and ending with the \n", + " # output layer\n", + " model = Model(inputs=[inp],outputs=[dens])\n", + " # Compile the machine learning model using the mean squared error function as the loss \n", + " # function and an Adams optimizer.\n", + " model.compile(loss=\"mean_squared_error\", optimizer=\"adam\") \n", + " return model" + ] + }, + { + "cell_type": "markdown", + "id": "8a8b29b8", + "metadata": {}, + "source": [ + "## Predicting New Points With A Trained Recurrent Neural Network" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "d840beea", + "metadata": {}, + "outputs": [], + "source": [ + "def test_rnn (x1, y_test, plot_min, plot_max):\n", + " \"\"\"\n", + " Inputs:\n", + " x1 (a list or numpy array): The complete x component of the data set\n", + " y_test (a list or numpy array): The complete y component of the data set\n", + " plot_min (an int or float): the smallest x value used in the training data\n", + " plot_max (an int or float): the largest x valye used in the training data\n", + " Returns:\n", + " None.\n", + " Uses a trained recurrent neural network model to predict future points in the \n", + " series. Computes the MSE of the predicted data set from the true data set, saves\n", + " the predicted data set to a csv file, and plots the predicted and true data sets w\n", + " while also displaying the data range used for training.\n", + " \"\"\"\n", + " # Add the training data as the first dim points in the predicted data array as these\n", + " # are known values.\n", + " y_pred = y_test[:dim].tolist()\n", + " # Generate the first input to the trained recurrent neural network using the last two \n", + " # points of the training data. Based on how the network was trained this means that it\n", + " # will predict the first point in the data set after the training data. All of the \n", + " # brackets are necessary for Tensorflow.\n", + " next_input = np.array([[[y_test[dim-2]], [y_test[dim-1]]]])\n", + " # Save the very last point in the training data set. This will be used later.\n", + " last = [y_test[dim-1]]\n", + "\n", + " # Iterate until the complete data set is created.\n", + " for i in range (dim, len(y_test)):\n", + " # Predict the next point in the data set using the previous two points.\n", + " next = model.predict(next_input)\n", + " # Append just the number of the predicted data set\n", + " y_pred.append(next[0][0])\n", + " # Create the input that will be used to predict the next data point in the data set.\n", + " next_input = np.array([[last, next[0]]], dtype=np.float64)\n", + " last = next\n", + "\n", + " # Print the mean squared error between the known data set and the predicted data set.\n", + " print('MSE: ', np.square(np.subtract(y_test, y_pred)).mean())\n", + " # Save the predicted data set as a csv file for later use\n", + " name = datatype + 'Predicted'+str(dim)+'.csv'\n", + " np.savetxt(name, y_pred, delimiter=',')\n", + " # Plot the known data set and the predicted data set. The red box represents the region that was used\n", + " # for the training data.\n", + " fig, ax = plt.subplots()\n", + " ax.plot(x1, y_test, label=\"true\", linewidth=3)\n", + " ax.plot(x1, y_pred, 'g-.',label=\"predicted\", linewidth=4)\n", + " ax.legend()\n", + " # Created a red region to represent the points used in the training data.\n", + " ax.axvspan(plot_min, plot_max, alpha=0.25, color='red')\n", + " plt.show()\n", + "\n", + "# Check to make sure the data set is complete\n", + "assert len(X_tot) == len(y_tot)\n", + "\n", + "# This is the number of points that will be used in as the training data\n", + "dim=12\n", + "\n", + "# Separate the training data from the whole data set\n", + "X_train = X_tot[:dim]\n", + "y_train = y_tot[:dim]\n", + "\n", + "\n", + "# Generate the training data for the RNN, using a sequence of 2\n", + "rnn_input, rnn_training = format_data(y_train, 2)\n", + "\n", + "\n", + "# Create a recurrent neural network in Keras and produce a summary of the \n", + "# machine learning model\n", + "model = rnn(length_of_sequences = rnn_input.shape[1])\n", + "model.summary()\n", + "\n", + "# Start the timer. Want to time training+testing\n", + "start = timer()\n", + "# Fit the model using the training data genenerated above using 150 training iterations and a 5%\n", + "# validation split. Setting verbose to True prints information about each training iteration.\n", + "hist = model.fit(rnn_input, rnn_training, batch_size=None, epochs=150, \n", + " verbose=True,validation_split=0.05)\n", + "\n", + "for label in [\"loss\",\"val_loss\"]:\n", + " plt.plot(hist.history[label],label=label)\n", + "\n", + "plt.ylabel(\"loss\")\n", + "plt.xlabel(\"epoch\")\n", + "plt.title(\"The final validation loss: {}\".format(hist.history[\"val_loss\"][-1]))\n", + "plt.legend()\n", + "plt.show()\n", + "\n", + "# Use the trained neural network to predict more points of the data set\n", + "test_rnn(X_tot, y_tot, X_tot[0], X_tot[dim-1])\n", + "# Stop the timer and calculate the total time needed.\n", + "end = timer()\n", + "print('Time: ', end-start)" + ] + }, + { + "cell_type": "markdown", + "id": "2e5b339f", + "metadata": {}, + "source": [ + "## Other Things to Try\n", + "\n", + "Changing the size of the recurrent neural network and its parameters\n", + "can drastically change the results you get from the model. The below\n", + "code takes the simple recurrent neural network from above and adds a\n", + "second hidden layer, changes the number of neurons in the hidden\n", + "layer, and explicitly declares the activation function of the hidden\n", + "layers to be a sigmoid function. The loss function and optimizer can\n", + "also be changed but are kept the same as the above network. These\n", + "parameters can be tuned to provide the optimal result from the\n", + "network. For some ideas on how to improve the performance of a\n", + "[recurrent neural network](https://danijar.com/tips-for-training-recurrent-neural-networks)." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "370e799d", + "metadata": {}, + "outputs": [], + "source": [ + "def rnn_2layers(length_of_sequences, batch_size = None, stateful = False):\n", + " \"\"\"\n", + " Inputs:\n", + " length_of_sequences (an int): the number of y values in \"x data\". This is determined\n", + " when the data is formatted\n", + " batch_size (an int): Default value is None. See Keras documentation of SimpleRNN.\n", + " stateful (a boolean): Default value is False. See Keras documentation of SimpleRNN.\n", + " Returns:\n", + " model (a Keras model): The recurrent neural network that is built and compiled by this\n", + " method\n", + " Builds and compiles a recurrent neural network with two hidden layers and returns the model.\n", + " \"\"\"\n", + " # Number of neurons in the input and output layers\n", + " in_out_neurons = 1\n", + " # Number of neurons in the hidden layer, increased from the first network\n", + " hidden_neurons = 500\n", + " # Define the input layer\n", + " inp = Input(batch_shape=(batch_size, \n", + " length_of_sequences, \n", + " in_out_neurons)) \n", + " # Create two hidden layers instead of one hidden layer. Explicitly set the activation\n", + " # function to be the sigmoid function (the default value is hyperbolic tangent)\n", + " rnn1 = SimpleRNN(hidden_neurons, \n", + " return_sequences=True, # This needs to be True if another hidden layer is to follow\n", + " stateful = stateful, activation = 'sigmoid',\n", + " name=\"RNN1\")(inp)\n", + " rnn2 = SimpleRNN(hidden_neurons, \n", + " return_sequences=False, activation = 'sigmoid',\n", + " stateful = stateful,\n", + " name=\"RNN2\")(rnn1)\n", + " # Define the output layer as a dense neural network layer (standard neural network layer)\n", + " #and add it to the network immediately after the hidden layer.\n", + " dens = Dense(in_out_neurons,name=\"dense\")(rnn2)\n", + " # Create the machine learning model starting with the input layer and ending with the \n", + " # output layer\n", + " model = Model(inputs=[inp],outputs=[dens])\n", + " # Compile the machine learning model using the mean squared error function as the loss \n", + " # function and an Adams optimizer.\n", + " model.compile(loss=\"mean_squared_error\", optimizer=\"adam\") \n", + " return model\n", + "\n", + "# Check to make sure the data set is complete\n", + "assert len(X_tot) == len(y_tot)\n", + "\n", + "# This is the number of points that will be used in as the training data\n", + "dim=12\n", + "\n", + "# Separate the training data from the whole data set\n", + "X_train = X_tot[:dim]\n", + "y_train = y_tot[:dim]\n", + "\n", + "\n", + "# Generate the training data for the RNN, using a sequence of 2\n", + "rnn_input, rnn_training = format_data(y_train, 2)\n", + "\n", + "\n", + "# Create a recurrent neural network in Keras and produce a summary of the \n", + "# machine learning model\n", + "model = rnn_2layers(length_of_sequences = 2)\n", + "model.summary()\n", + "\n", + "# Start the timer. Want to time training+testing\n", + "start = timer()\n", + "# Fit the model using the training data genenerated above using 150 training iterations and a 5%\n", + "# validation split. Setting verbose to True prints information about each training iteration.\n", + "hist = model.fit(rnn_input, rnn_training, batch_size=None, epochs=150, \n", + " verbose=True,validation_split=0.05)\n", + "\n", + "\n", + "# This section plots the training loss and the validation loss as a function of training iteration.\n", + "# This is not required for analyzing the couple cluster data but can help determine if the network is\n", + "# being overtrained.\n", + "for label in [\"loss\",\"val_loss\"]:\n", + " plt.plot(hist.history[label],label=label)\n", + "\n", + "plt.ylabel(\"loss\")\n", + "plt.xlabel(\"epoch\")\n", + "plt.title(\"The final validation loss: {}\".format(hist.history[\"val_loss\"][-1]))\n", + "plt.legend()\n", + "plt.show()\n", + "\n", + "# Use the trained neural network to predict more points of the data set\n", + "test_rnn(X_tot, y_tot, X_tot[0], X_tot[dim-1])\n", + "# Stop the timer and calculate the total time needed.\n", + "end = timer()\n", + "print('Time: ', end-start)" + ] + }, + { + "cell_type": "markdown", + "id": "d8f62fc4", + "metadata": {}, + "source": [ + "## Other Types of Recurrent Neural Networks\n", + "\n", + "Besides a simple recurrent neural network layer, there are two other\n", + "commonly used types of recurrent neural network layers: Long Short\n", + "Term Memory (LSTM) and Gated Recurrent Unit (GRU). For a short\n", + "introduction to these layers see \n", + "and .\n", + "\n", + "The first network created below is similar to the previous network,\n", + "but it replaces the SimpleRNN layers with LSTM layers. The second\n", + "network below has two hidden layers made up of GRUs, which are\n", + "preceeded by two dense (feeddorward) neural network layers. These\n", + "dense layers \"preprocess\" the data before it reaches the recurrent\n", + "layers. This architecture has been shown to improve the performance\n", + "of recurrent neural networks (see the link above and also\n", + "." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "4ea36ea9", + "metadata": {}, + "outputs": [], + "source": [ + "def lstm_2layers(length_of_sequences, batch_size = None, stateful = False):\n", + " \"\"\"\n", + " Inputs:\n", + " length_of_sequences (an int): the number of y values in \"x data\". This is determined\n", + " when the data is formatted\n", + " batch_size (an int): Default value is None. See Keras documentation of SimpleRNN.\n", + " stateful (a boolean): Default value is False. See Keras documentation of SimpleRNN.\n", + " Returns:\n", + " model (a Keras model): The recurrent neural network that is built and compiled by this\n", + " method\n", + " Builds and compiles a recurrent neural network with two LSTM hidden layers and returns the model.\n", + " \"\"\"\n", + " # Number of neurons on the input/output layer and the number of neurons in the hidden layer\n", + " in_out_neurons = 1\n", + " hidden_neurons = 250\n", + " # Input Layer\n", + " inp = Input(batch_shape=(batch_size, \n", + " length_of_sequences, \n", + " in_out_neurons)) \n", + " # Hidden layers (in this case they are LSTM layers instead if SimpleRNN layers)\n", + " rnn= LSTM(hidden_neurons, \n", + " return_sequences=True,\n", + " stateful = stateful,\n", + " name=\"RNN\", use_bias=True, activation='tanh')(inp)\n", + " rnn1 = LSTM(hidden_neurons, \n", + " return_sequences=False,\n", + " stateful = stateful,\n", + " name=\"RNN1\", use_bias=True, activation='tanh')(rnn)\n", + " # Output layer\n", + " dens = Dense(in_out_neurons,name=\"dense\")(rnn1)\n", + " # Define the midel\n", + " model = Model(inputs=[inp],outputs=[dens])\n", + " # Compile the model\n", + " model.compile(loss='mean_squared_error', optimizer='adam') \n", + " # Return the model\n", + " return model\n", + "\n", + "def dnn2_gru2(length_of_sequences, batch_size = None, stateful = False):\n", + " \"\"\"\n", + " Inputs:\n", + " length_of_sequences (an int): the number of y values in \"x data\". This is determined\n", + " when the data is formatted\n", + " batch_size (an int): Default value is None. See Keras documentation of SimpleRNN.\n", + " stateful (a boolean): Default value is False. See Keras documentation of SimpleRNN.\n", + " Returns:\n", + " model (a Keras model): The recurrent neural network that is built and compiled by this\n", + " method\n", + " Builds and compiles a recurrent neural network with four hidden layers (two dense followed by\n", + " two GRU layers) and returns the model.\n", + " \"\"\" \n", + " # Number of neurons on the input/output layers and hidden layers\n", + " in_out_neurons = 1\n", + " hidden_neurons = 250\n", + " # Input layer\n", + " inp = Input(batch_shape=(batch_size, \n", + " length_of_sequences, \n", + " in_out_neurons)) \n", + " # Hidden Dense (feedforward) layers\n", + " dnn = Dense(hidden_neurons/2, activation='relu', name='dnn')(inp)\n", + " dnn1 = Dense(hidden_neurons/2, activation='relu', name='dnn1')(dnn)\n", + " # Hidden GRU layers\n", + " rnn1 = GRU(hidden_neurons, \n", + " return_sequences=True,\n", + " stateful = stateful,\n", + " name=\"RNN1\", use_bias=True)(dnn1)\n", + " rnn = GRU(hidden_neurons, \n", + " return_sequences=False,\n", + " stateful = stateful,\n", + " name=\"RNN\", use_bias=True)(rnn1)\n", + " # Output layer\n", + " dens = Dense(in_out_neurons,name=\"dense\")(rnn)\n", + " # Define the model\n", + " model = Model(inputs=[inp],outputs=[dens])\n", + " # Compile the mdoel\n", + " model.compile(loss='mean_squared_error', optimizer='adam') \n", + " # Return the model\n", + " return model\n", + "\n", + "# Check to make sure the data set is complete\n", + "assert len(X_tot) == len(y_tot)\n", + "\n", + "# This is the number of points that will be used in as the training data\n", + "dim=12\n", + "\n", + "# Separate the training data from the whole data set\n", + "X_train = X_tot[:dim]\n", + "y_train = y_tot[:dim]\n", + "\n", + "\n", + "# Generate the training data for the RNN, using a sequence of 2\n", + "rnn_input, rnn_training = format_data(y_train, 2)\n", + "\n", + "\n", + "# Create a recurrent neural network in Keras and produce a summary of the \n", + "# machine learning model\n", + "# Change the method name to reflect which network you want to use\n", + "model = dnn2_gru2(length_of_sequences = 2)\n", + "model.summary()\n", + "\n", + "# Start the timer. Want to time training+testing\n", + "start = timer()\n", + "# Fit the model using the training data genenerated above using 150 training iterations and a 5%\n", + "# validation split. Setting verbose to True prints information about each training iteration.\n", + "hist = model.fit(rnn_input, rnn_training, batch_size=None, epochs=150, \n", + " verbose=True,validation_split=0.05)\n", + "\n", + "\n", + "# This section plots the training loss and the validation loss as a function of training iteration.\n", + "# This is not required for analyzing the couple cluster data but can help determine if the network is\n", + "# being overtrained.\n", + "for label in [\"loss\",\"val_loss\"]:\n", + " plt.plot(hist.history[label],label=label)\n", + "\n", + "plt.ylabel(\"loss\")\n", + "plt.xlabel(\"epoch\")\n", + "plt.title(\"The final validation loss: {}\".format(hist.history[\"val_loss\"][-1]))\n", + "plt.legend()\n", + "plt.show()\n", + "\n", + "# Use the trained neural network to predict more points of the data set\n", + "test_rnn(X_tot, y_tot, X_tot[0], X_tot[dim-1])\n", + "# Stop the timer and calculate the total time needed.\n", + "end = timer()\n", + "print('Time: ', end-start)\n", + "\n", + "\n", + "# ### Training Recurrent Neural Networks in the Standard Way (i.e. learning the relationship between the X and Y data)\n", + "# \n", + "# Finally, comparing the performace of a recurrent neural network using the standard data formatting to the performance of the network with time sequence data formatting shows the benefit of this type of data formatting with extrapolation.\n", + "\n", + "# Check to make sure the data set is complete\n", + "assert len(X_tot) == len(y_tot)\n", + "\n", + "# This is the number of points that will be used in as the training data\n", + "dim=12\n", + "\n", + "# Separate the training data from the whole data set\n", + "X_train = X_tot[:dim]\n", + "y_train = y_tot[:dim]\n", + "\n", + "# Reshape the data for Keras specifications\n", + "X_train = X_train.reshape((dim, 1))\n", + "y_train = y_train.reshape((dim, 1))\n", + "\n", + "\n", + "# Create a recurrent neural network in Keras and produce a summary of the \n", + "# machine learning model\n", + "# Set the sequence length to 1 for regular data formatting \n", + "model = rnn(length_of_sequences = 1)\n", + "model.summary()\n", + "\n", + "# Start the timer. Want to time training+testing\n", + "start = timer()\n", + "# Fit the model using the training data genenerated above using 150 training iterations and a 5%\n", + "# validation split. Setting verbose to True prints information about each training iteration.\n", + "hist = model.fit(X_train, y_train, batch_size=None, epochs=150, \n", + " verbose=True,validation_split=0.05)\n", + "\n", + "\n", + "# This section plots the training loss and the validation loss as a function of training iteration.\n", + "# This is not required for analyzing the couple cluster data but can help determine if the network is\n", + "# being overtrained.\n", + "for label in [\"loss\",\"val_loss\"]:\n", + " plt.plot(hist.history[label],label=label)\n", + "\n", + "plt.ylabel(\"loss\")\n", + "plt.xlabel(\"epoch\")\n", + "plt.title(\"The final validation loss: {}\".format(hist.history[\"val_loss\"][-1]))\n", + "plt.legend()\n", + "plt.show()\n", + "\n", + "# Use the trained neural network to predict the remaining data points\n", + "X_pred = X_tot[dim:]\n", + "X_pred = X_pred.reshape((len(X_pred), 1))\n", + "y_model = model.predict(X_pred)\n", + "y_pred = np.concatenate((y_tot[:dim], y_model.flatten()))\n", + "\n", + "# Plot the known data set and the predicted data set. The red box represents the region that was used\n", + "# for the training data.\n", + "fig, ax = plt.subplots()\n", + "ax.plot(X_tot, y_tot, label=\"true\", linewidth=3)\n", + "ax.plot(X_tot, y_pred, 'g-.',label=\"predicted\", linewidth=4)\n", + "ax.legend()\n", + "# Created a red region to represent the points used in the training data.\n", + "ax.axvspan(X_tot[0], X_tot[dim], alpha=0.25, color='red')\n", + "plt.show()\n", + "\n", + "# Stop the timer and calculate the total time needed.\n", + "end = timer()\n", + "print('Time: ', end-start)" + ] + } + ], + "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.9.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/doc/LectureNotes/week45.ipynb b/doc/LectureNotes/week45.ipynb index 749491e98..5e57b02bb 100644 --- a/doc/LectureNotes/week45.ipynb +++ b/doc/LectureNotes/week45.ipynb @@ -3,9 +3,7 @@ { "cell_type": "markdown", "id": "31a10e2b", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "\n", @@ -15,9 +13,7 @@ { "cell_type": "markdown", "id": "019daa83", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "# Week 45, Recurrent Neural Networks\n", "**Morten Hjorth-Jensen**, Department of Physics, University of Oslo and Department of Physics and Astronomy and National Superconducting Cyclotron Laboratory, Michigan State University\n", @@ -28,9 +24,7 @@ { "cell_type": "markdown", "id": "6ecf1c2b", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Plan for week 45\n", "\n", @@ -68,9 +62,7 @@ { "cell_type": "markdown", "id": "d80a4db8", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Material for the lab sessions, additional ways to present classification results and other practicalities" ] @@ -78,9 +70,7 @@ { "cell_type": "markdown", "id": "1ded5c92", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Searching for Optimal Regularization Parameters $\\lambda$\n", "\n", @@ -97,10 +87,7 @@ "cell_type": "code", "execution_count": 1, "id": "6dea0513", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", @@ -154,9 +141,7 @@ { "cell_type": "markdown", "id": "440bf579", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "Here we have performed a rather data greedy calculation as function of the regularization parameter $\\lambda$. There is no resampling here. The latter can easily be added by employing the function **RidgeCV** instead of just calling the **Ridge** function. For **RidgeCV** we need to pass the array of $\\lambda$ values.\n", "By inspecting the figure we can in turn determine which is the optimal regularization parameter.\n", @@ -166,9 +151,7 @@ { "cell_type": "markdown", "id": "683b1da2", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Grid Search\n", "\n", @@ -181,10 +164,7 @@ "cell_type": "code", "execution_count": 2, "id": "38be79e0", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", @@ -234,9 +214,7 @@ { "cell_type": "markdown", "id": "081fbe5c", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "By default the grid search function includes cross validation with\n", "five folds. The [Scikit-Learn\n", @@ -249,9 +227,7 @@ { "cell_type": "markdown", "id": "a9798c07", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Randomized Grid Search\n", "\n", @@ -269,10 +245,7 @@ "cell_type": "code", "execution_count": 3, "id": "0a7e4e2e", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", @@ -323,9 +296,7 @@ { "cell_type": "markdown", "id": "dcd07cb8", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Wisconsin Cancer Data\n", "\n", @@ -338,10 +309,7 @@ "cell_type": "code", "execution_count": 4, "id": "65061d95", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", @@ -365,9 +333,7 @@ { "cell_type": "markdown", "id": "50492453", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Using the correlation matrix\n", "\n", @@ -379,10 +345,7 @@ "cell_type": "code", "execution_count": 5, "id": "08a2ab17", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", @@ -424,9 +387,7 @@ { "cell_type": "markdown", "id": "5408b7dd", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Discussing the correlation data\n", "\n", @@ -449,10 +410,7 @@ "cell_type": "code", "execution_count": 6, "id": "76c3d259", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "cancerpd = pd.DataFrame(cancer.data, columns=cancer.feature_names)" @@ -461,9 +419,7 @@ { "cell_type": "markdown", "id": "83903231", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "and then" ] @@ -472,10 +428,7 @@ "cell_type": "code", "execution_count": 7, "id": "58ccd6c3", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "correlation_matrix = cancerpd.corr().round(1)" @@ -484,9 +437,7 @@ { "cell_type": "markdown", "id": "adda54cb", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "Diagonalizing this matrix we can in turn say something about which\n", "features are of relevance and which are not. This leads us to\n", @@ -497,9 +448,7 @@ { "cell_type": "markdown", "id": "8799c034", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Other ways of presenting a classification problem\n", "\n", @@ -530,9 +479,7 @@ { "cell_type": "markdown", "id": "dfbe0571", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Combinations of classification results\n", "\n", @@ -544,9 +491,7 @@ { "cell_type": "markdown", "id": "65f7c63d", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "$$\n", "{\\displaystyle \\mathrm {TPR} ={\\frac {\\mathrm {TP} }{\\mathrm {P} }}={\\frac {\\mathrm {TP} }{\\mathrm {TP} +\\mathrm {FN} }}=1-\\mathrm {FNR} }\n", @@ -556,9 +501,7 @@ { "cell_type": "markdown", "id": "2e674d10", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "The $TPR$ defines how many correct positive results occur among all positive samples available during the test\n", "\n", @@ -568,9 +511,7 @@ { "cell_type": "markdown", "id": "65577837", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "$$\n", "{\\displaystyle \\mathrm {FNR} ={\\frac {\\mathrm {FN} }{\\mathrm {P} }}={\\frac {\\mathrm {FN} }{\\mathrm {FN} +\\mathrm {TP} }} }\n", @@ -580,9 +521,7 @@ { "cell_type": "markdown", "id": "e5e8802d", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "**Specificity, selectivity or true negative rate $TNR$. It is the probability of a negative test result, conditioned on the individual truly being negative.**" ] @@ -590,9 +529,7 @@ { "cell_type": "markdown", "id": "07c61591", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "$$\n", "{\\displaystyle \\mathrm {TNR} ={\\frac {\\mathrm {TN} }{\\mathrm {N} }}={\\frac {\\mathrm {TN} }{\\mathrm {TN} +\\mathrm {FP} }}=1-\\mathrm {FPR} }\n", @@ -602,9 +539,7 @@ { "cell_type": "markdown", "id": "b3f61bb3", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "with the fall-out false positive rate" ] @@ -612,9 +547,7 @@ { "cell_type": "markdown", "id": "6544105e", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "$$\n", "{\\displaystyle \\mathrm {FPR} ={\\frac {\\mathrm {FP} }{\\mathrm {N} }}={\\frac {\\mathrm {FP} }{\\mathrm {FP} +\\mathrm {TN} }}=1-\\mathrm {TNR} }\n", @@ -624,9 +557,7 @@ { "cell_type": "markdown", "id": "0b571e85", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "The $FPR$ defines how many incorrect positive results occur among\n", "all negative samples available during the test." @@ -635,9 +566,7 @@ { "cell_type": "markdown", "id": "17d6872a", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Positive and negative prediction values\n", "\n", @@ -654,9 +583,7 @@ { "cell_type": "markdown", "id": "122f7e6c", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "$$\n", "{\\displaystyle \\mathrm {PPV} ={\\frac {\\mathrm {TP} }{\\mathrm {TP} +\\mathrm {FP} }}=1-\\mathrm {FDR} }\n", @@ -666,9 +593,7 @@ { "cell_type": "markdown", "id": "f44a5e78", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "**Negative predictive value $NPV$.**" ] @@ -676,9 +601,7 @@ { "cell_type": "markdown", "id": "86fa9670", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "$$\n", "{\\displaystyle \\mathrm {NPV} ={\\frac {\\mathrm {TN} }{\\mathrm {TN} +\\mathrm {FN} }}=1-\\mathrm {FOR} }\n", @@ -688,9 +611,7 @@ { "cell_type": "markdown", "id": "a30e358d", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Other quantities\n", "\n", @@ -700,9 +621,7 @@ { "cell_type": "markdown", "id": "3f0de6de", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "$$\n", "{\\displaystyle \\mathrm {FDR} ={\\frac {\\mathrm {FP} }{\\mathrm {FP} +\\mathrm {TP} }}=1-\\mathrm {PPV} }\n", @@ -712,9 +631,7 @@ { "cell_type": "markdown", "id": "0b4cc93f", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "**False omission rate $FOR$.**" ] @@ -722,9 +639,7 @@ { "cell_type": "markdown", "id": "4866ec0a", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "$$\n", "{\\displaystyle \\mathrm {FOR} ={\\frac {\\mathrm {FN} }{\\mathrm {FN} +\\mathrm {TN} }}=1-\\mathrm {NPV} }\n", @@ -734,9 +649,7 @@ { "cell_type": "markdown", "id": "9b1c8c45", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## $F_1$ score\n", "\n", @@ -762,9 +675,7 @@ { "cell_type": "markdown", "id": "0e651a1f", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "$$\n", "{\\displaystyle \\mathrm {F} _{1}=2\\times {\\frac {\\mathrm {PPV} \\times \\mathrm {TPR} }{\\mathrm {PPV} +\\mathrm {TPR} }}={\\frac {2\\mathrm {TP} }{2\\mathrm {TP} +\\mathrm {FP} +\\mathrm {FN} }}}\n", @@ -774,9 +685,7 @@ { "cell_type": "markdown", "id": "d83efe41", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## ROC curve\n", "\n", @@ -799,9 +708,7 @@ { "cell_type": "markdown", "id": "d088215b", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Cumulative gain curve\n", "\n", @@ -811,28 +718,159 @@ "against Predictive Positive Rate, which represents \n", "the fraction of positively predicted examples.\n", "\n", - "The examples below show the confusion matrix, the ROC curve and the cumulative gain for the Wisconsin cancer data." + "The examples below show the confusion matrix (or error matrix), the ROC curve and the cumulative gain for the Wisconsin cancer data." ] }, { "cell_type": "markdown", "id": "5c0bcd1f", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Other measures in classification studies: Cancer Data again" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 1, "id": "2a6f80df", - "metadata": { - "collapsed": false, - "editable": true - }, - "outputs": [], + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(426, 30)\n", + "(143, 30)\n", + "[1. 0.86666667 1. 0.92857143 1. 0.85714286\n", + " 1. 0.92857143 0.92857143 1. ]\n", + "Test set accuracy with Logistic Regression: 0.94\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/mhjensen/miniforge3/envs/myenv/lib/python3.9/site-packages/sklearn/linear_model/_logistic.py:814: ConvergenceWarning: lbfgs failed to converge (status=1):\n", + "STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.\n", + "\n", + "Increase the number of iterations (max_iter) or scale the data as shown in:\n", + " https://scikit-learn.org/stable/modules/preprocessing.html\n", + "Please also refer to the documentation for alternative solver options:\n", + " https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression\n", + " n_iter_i = _check_optimize_result(\n", + "/Users/mhjensen/miniforge3/envs/myenv/lib/python3.9/site-packages/sklearn/linear_model/_logistic.py:814: ConvergenceWarning: lbfgs failed to converge (status=1):\n", + "STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.\n", + "\n", + "Increase the number of iterations (max_iter) or scale the data as shown in:\n", + " https://scikit-learn.org/stable/modules/preprocessing.html\n", + "Please also refer to the documentation for alternative solver options:\n", + " https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression\n", + " n_iter_i = _check_optimize_result(\n", + "/Users/mhjensen/miniforge3/envs/myenv/lib/python3.9/site-packages/sklearn/linear_model/_logistic.py:814: ConvergenceWarning: lbfgs failed to converge (status=1):\n", + "STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.\n", + "\n", + "Increase the number of iterations (max_iter) or scale the data as shown in:\n", + " https://scikit-learn.org/stable/modules/preprocessing.html\n", + "Please also refer to the documentation for alternative solver options:\n", + " https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression\n", + " n_iter_i = _check_optimize_result(\n", + "/Users/mhjensen/miniforge3/envs/myenv/lib/python3.9/site-packages/sklearn/linear_model/_logistic.py:814: ConvergenceWarning: lbfgs failed to converge (status=1):\n", + "STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.\n", + "\n", + "Increase the number of iterations (max_iter) or scale the data as shown in:\n", + " https://scikit-learn.org/stable/modules/preprocessing.html\n", + "Please also refer to the documentation for alternative solver options:\n", + " https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression\n", + " n_iter_i = _check_optimize_result(\n", + "/Users/mhjensen/miniforge3/envs/myenv/lib/python3.9/site-packages/sklearn/linear_model/_logistic.py:814: ConvergenceWarning: lbfgs failed to converge (status=1):\n", + "STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.\n", + "\n", + "Increase the number of iterations (max_iter) or scale the data as shown in:\n", + " https://scikit-learn.org/stable/modules/preprocessing.html\n", + "Please also refer to the documentation for alternative solver options:\n", + " https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression\n", + " n_iter_i = _check_optimize_result(\n", + "/Users/mhjensen/miniforge3/envs/myenv/lib/python3.9/site-packages/sklearn/linear_model/_logistic.py:814: ConvergenceWarning: lbfgs failed to converge (status=1):\n", + "STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.\n", + "\n", + "Increase the number of iterations (max_iter) or scale the data as shown in:\n", + " https://scikit-learn.org/stable/modules/preprocessing.html\n", + "Please also refer to the documentation for alternative solver options:\n", + " https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression\n", + " n_iter_i = _check_optimize_result(\n", + "/Users/mhjensen/miniforge3/envs/myenv/lib/python3.9/site-packages/sklearn/linear_model/_logistic.py:814: ConvergenceWarning: lbfgs failed to converge (status=1):\n", + "STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.\n", + "\n", + "Increase the number of iterations (max_iter) or scale the data as shown in:\n", + " https://scikit-learn.org/stable/modules/preprocessing.html\n", + "Please also refer to the documentation for alternative solver options:\n", + " https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression\n", + " n_iter_i = _check_optimize_result(\n", + "/Users/mhjensen/miniforge3/envs/myenv/lib/python3.9/site-packages/sklearn/linear_model/_logistic.py:814: ConvergenceWarning: lbfgs failed to converge (status=1):\n", + "STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.\n", + "\n", + "Increase the number of iterations (max_iter) or scale the data as shown in:\n", + " https://scikit-learn.org/stable/modules/preprocessing.html\n", + "Please also refer to the documentation for alternative solver options:\n", + " https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression\n", + " n_iter_i = _check_optimize_result(\n", + "/Users/mhjensen/miniforge3/envs/myenv/lib/python3.9/site-packages/sklearn/linear_model/_logistic.py:814: ConvergenceWarning: lbfgs failed to converge (status=1):\n", + "STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.\n", + "\n", + "Increase the number of iterations (max_iter) or scale the data as shown in:\n", + " https://scikit-learn.org/stable/modules/preprocessing.html\n", + "Please also refer to the documentation for alternative solver options:\n", + " https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression\n", + " n_iter_i = _check_optimize_result(\n", + "/Users/mhjensen/miniforge3/envs/myenv/lib/python3.9/site-packages/sklearn/linear_model/_logistic.py:814: ConvergenceWarning: lbfgs failed to converge (status=1):\n", + "STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.\n", + "\n", + "Increase the number of iterations (max_iter) or scale the data as shown in:\n", + " https://scikit-learn.org/stable/modules/preprocessing.html\n", + "Please also refer to the documentation for alternative solver options:\n", + " https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression\n", + " n_iter_i = _check_optimize_result(\n", + "/Users/mhjensen/miniforge3/envs/myenv/lib/python3.9/site-packages/sklearn/linear_model/_logistic.py:814: ConvergenceWarning: lbfgs failed to converge (status=1):\n", + "STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.\n", + "\n", + "Increase the number of iterations (max_iter) or scale the data as shown in:\n", + " https://scikit-learn.org/stable/modules/preprocessing.html\n", + "Please also refer to the documentation for alternative solver options:\n", + " https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression\n", + " n_iter_i = _check_optimize_result(\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAfYAAAHFCAYAAAAABdu/AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAA9hAAAPYQGoP6dpAABCWElEQVR4nO3deVxU9f7H8few4wIGCC4houa+pJCJZrmkZWZat7TsuqJlVmSuqaVpGtmiZoW5pFipVyu1zRauS1kuqVGWeuumKC7gnigmCJzfH17m1wjawMxIM+f19HEeD/nO95zzOTDwmc/3fM85FsMwDAEAAI/gVdYBAAAA5yGxAwDgQUjsAAB4EBI7AAAehMQOAIAHIbEDAOBBSOwAAHgQEjsAAB6ExA4AgAchsXuI5ORkWSwWBQQEaP/+/UVeb9eunRo3blwGkTlH//79VbNmTZu2mjVrqn///lc1jn379slisSg5Odmu/nv37tVjjz2munXrKjAwUOXKlVOjRo309NNP69ChQy6PtWvXrgoJCZHFYtGwYcOcvo+y+BlI0vr162WxWK74s+jQoYMsFkuR9429lixZopkzZ5ZonZK+PwBX8CnrAOBcOTk5evrpp/XOO++UdSgut3LlSgUFBZV1GJf1ySef6P7771dYWJgee+wxNW/eXBaLRT/99JMWLFigTz/9VKmpqS7b/5NPPqktW7ZowYIFqlKliqpWrer0fZT1z6BixYp66623iny4SEtL0/r16x2KbcmSJfr5559L9IGoatWq2rRpk2rXrl3q/QKOIrF7mNtvv11LlizRyJEj1axZM5ft548//lBgYKDLtm+P5s2bl+n+ryQtLU3333+/6tatq3Xr1ik4ONj6WocOHZSQkKCVK1e6NIaff/5ZLVu2VI8ePVy2j7L+GfTq1Uvz58/Xf//7X1133XXW9gULFqh69epq0qSJdu3a5fI48vPzlZeXJ39/f7Vq1crl+wOuhKF4DzN69GiFhoZqzJgxf9n3/PnzGjt2rKKjo+Xn56fq1avr0Ucf1e+//27Tr2bNmrrzzju1YsUKNW/eXAEBAZo0aZJ1OHTJkiUaM2aMqlatqgoVKqhbt246cuSIzpw5o4ceekhhYWEKCwvTgAEDdPbsWZttv/HGG7r55psVHh6u8uXLq0mTJnrxxRd14cKFv4z/0mHgdu3aWYdnL13+PDSamZmphx9+WNdee638/PwUHR2tSZMmKS8vz2b7hw8fVs+ePVWxYkUFBwerV69eyszM/Mu4JGn69OnKzs5WUlKSTVIvZLFYdM8999i0LViwQM2aNVNAQIBCQkJ09913a/fu3TZ9+vfvrwoVKui3337THXfcoQoVKigyMlIjRoxQTk6OpP8fpv7tt9/02WefWb8H+/bts56y2bdvn812C9dZv369tS01NVV33nmnwsPD5e/vr2rVqqlr1646ePCgtU9xQ/Hp6en65z//aV2vQYMGeuWVV1RQUGDtUzhk/fLLL2v69OmKjo5WhQoVFBcXp82bN9v1PZakTp06KTIyUgsWLLC2FRQUaNGiRerXr5+8vIr+ibPnPdeuXTt9+umn2r9/v8376M+xv/jii5oyZYqio6Pl7++vdevWFRmKP3/+vJo3b646dero9OnT1u1nZmaqSpUqateunfLz8+0+XsAeVOwepmLFinr66af1xBNPaO3aterQoUOx/QzDUI8ePbRmzRqNHTtWbdu21Y4dOzRx4kRt2rRJmzZtkr+/v7X/999/r927d+vpp59WdHS0ypcvr+zsbEnSuHHj1L59eyUnJ2vfvn0aOXKkHnjgAfn4+KhZs2ZaunSpUlNTNW7cOFWsWFGzZs2ybnfPnj3q3bu39cPFjz/+qKlTp+o///mPzR9reyQlJSkrK8um7ZlnntG6detUr149SRf/oLZs2VJeXl6aMGGCateurU2bNmnKlCnat2+fFi5cKOniiMStt96qw4cPKzExUXXr1tWnn36qXr162RXLl19+qYiICLurt8TERI0bN04PPPCAEhMTdeLECT377LOKi4vT1q1bbarRCxcu6K677lJ8fLxGjBihr7/+Ws8995yCg4M1YcIEtWjRQps2bdLdd9+t2rVr6+WXX5akEg3FZ2dnq1OnToqOjtYbb7yhiIgIZWZmat26dTpz5sxl1zt27Jhat26t3NxcPffcc6pZs6Y++eQTjRw5Unv27FFSUpJN/zfeeEP169e3nst+5plndMcddygtLa3YD0SX8vLyUv/+/fXWW29pypQp8vb21pdffqmDBw9qwIABeuKJJ4qsY897LikpSQ899JD27Nlz2ZGVWbNmqW7dunr55ZcVFBRk8zMqFBAQoOXLlysmJkYDBw7UBx98oIKCAj344IMyDENLly6Vt7f3Xx4nUCIG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F19o9uzZSkxMLNL/888/11dffaW9e/cqJCREklSzZs0S7ZOheACAKRTOindkKYnc3Fxt375dnTt3tmnv3LmzNm7cWOw6H330kWJjY/Xiiy+qevXqqlu3rkaOHKk//vjD7v1SsQMATMHLcnFxZH1JysrKsmn39/eXv79/kf7Hjx9Xfn6+IiIibNojIiKUmZlZ7D727t2rb775RgEBAVq5cqWOHz+uoUOH6uTJk3afZ6diBwCgBCIjIxUcHGxdihtS/7NLK33DMC5b/RcUFMhisWjx4sVq2bKl7rjjDk2fPl3Jycl2V+1U7AAAc7A4eJOZ/6164MABBQUFWZuLq9YlKSwsTN7e3kWq86NHjxap4gtVrVpV1atXV3BwsLWtQYMGMgxDBw8e1HXXXfeXYVKxAwBMoXDynCOLJAUFBdksl0vsfn5+iomJUUpKik17SkqKWrduXew6bdq00eHDh3X27Flr26+//iovLy9de+21dh0niR0AABcZPny45s+frwULFmj37t168sknlZ6eriFDhkiSxo4dq759+1r79+7dW6GhoRowYIB27dqlr7/+WqNGjdLAgQMVGBho1z4ZigcAmILlf/8cWb+kevXqpRMnTmjy5MnKyMhQ48aNtXr1akVFRUmSMjIylJ6ebu1foUIFpaSk6PHHH1dsbKxCQ0PVs2dPTZkyxe59ktgBAKbgrFnxJTV06FANHTq02NeSk5OLtNWvX7/I8H1JMBQPAIAHoWIHAJiCWR7baldinzVrlt0bTEhIKHUwAAC4SlncUrYs2JXYZ8yYYdfGLBYLiR0AgDJkV2JPS0tzdRwAALiUI49eLVzfHZR68lxubq5++eWXEj1KDgCAsuKsG9T83ZU4sZ87d07x8fEqV66cGjVqZL3+LiEhQS+88ILTAwQAwBmu9tPdykqJE/vYsWP1448/av369QoICLC233rrrVq2bJlTgwMAACVT4svdVq1apWXLlqlVq1Y2n14aNmyoPXv2ODU4AACchVnxl3Hs2DGFh4cXac/OznabYQoAgPkwee4ybrjhBn366afWrwuT+bx58xQXF+e8yAAAQImVuGJPTEzU7bffrl27dikvL0+vvvqqdu7cqU2bNumrr75yRYwAADjMIjnwCBjH1r2aSlyxt27dWt9++63OnTun2rVr68svv1RERIQ2bdqkmJgYV8QIAIDDzDIr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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkIAAAHFCAYAAAAe+pb9AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAA9hAAAPYQGoP6dpAACZO0lEQVR4nOzdeXhM9/fA8fdkX0hIQiQEsWuVEKW2orZaqq0lIWqndrWUVlXRarXVqqp9L0KCL6qlSu211K5a1C6WEBISIstk5v7+yM/UTYIkktyZzHk9j6edM/fOnORmOTn3s+gURVEQQgghhLBCNlonIIQQQgihFSmEhBBCCGG1pBASQgghhNWSQkgIIYQQVksKISGEEEJYLSmEhBBCCGG1pBASQgghhNWSQkgIIYQQVksKISGEEEJYLSmEhMghf/31Fz179sTf3x8nJycKFChAjRo1+Prrr4mJidE6vaeaMGECOp0uW+du2rSJCRMmZPhc6dKl6dGjR/YTew5Go5Hly5fTokULihYtir29PYUKFeKVV17hm2++4c6dO9l63R49elC6dOmcTTaTLPlrTAhzpZMtNoR4fvPnz2fgwIFUrFiRgQMH8sILL6DX6zl8+DDz58+nWrVqrFu3Tus0n2jChAlMnDiR7Pw4GDx4MDNnzszw3GPHjuHm5kbZsmVzIs1MS0hI4M033+T3338nODiYN998E19fX+Li4ti3bx8LFy6kQoUK7NmzJ8uvfeHCBeLi4qhevXouZP5klv41JoTZUoQQz2Xfvn2Kra2t8vrrryuJiYnpnk9KSlJ++uknDTLLvPHjxyvZ/XEwaNCgbJ+bW959910FUFasWJHh8/Hx8cq8efPyOKvsy8uvsYcPHypGozFHXksIS2BeP72EsEBt2rRR7OzslIiIiEwdDyjjx49PFy9VqpTSvXt30+PFixcrgLJt2zalT58+ioeHh1KwYEGla9euyoMHD5TIyEilY8eOiru7u1KsWDFl5MiRSnJysun8HTt2KICyY8cO1ftcunRJAZTFixebYhkVQmFhYUqzZs2UYsWKKU5OTkqlSpWUDz74QHnw4IHpmO7duytAun+XLl1K9zFFRUUp9vb2yscff5zuYz99+rQCKN9//70pFhkZqbz77rtK8eLFFXt7e6V06dLKhAkTFL1e/9TP740bNxQ7OzuldevWTz0urRkzZigNGjRQihQpori4uChVqlRRvvrqK9Xn9NHHXKpUKVUMUAYNGqQsXbpUqVSpkuLs7KxUrVpV+fnnn1XHRUVFKX379lVKlCihODg4KF5eXkrdunWVrVu3PjW33P4a++2335SePXsqXl5eCqCsXLlSAZTff/893WvMmjVLAZQTJ06YYocOHVLeeOMNpXDhwoqjo6MSEBCghIeHZypXIbRml7f9JyHyF4PBwPbt2wkMDMTPzy9X3qNPnz60a9eOsLAwjh07xkcffURKSgr//vsv7dq149133+X333/nq6++wtfXlxEjRuTI+547d45WrVoxbNgwXF1dOXPmDF999RUHDx5k+/btAIwbN474+HjWrFnD/v37Tef6+Pike70iRYrQpk0bfvzxRyZOnIiNzX9DFBcvXoyDgwNdunQB4ObNm9SqVQsbGxs++eQTypYty/79+5k0aRKXL19m8eLFT8x7x44dpKSk0LZt2yx9vBcuXCAkJAR/f38cHBw4ceIEn3/+OWfOnGHRokXPPH/jxo0cOnSITz/9lAIFCvD111/z9ttv8++//1KmTBkAunbtytGjR/n888+pUKEC9+7d4+jRo0RHRz/xdfPia6xXr160bt2aZcuWER8fT5s2bShatCiLFy+mSZMmqmOXLFlCjRo1qFq1KpD6+X799depXbs2c+bMwd3dnbCwMIKDg3n48KFmY8SEyDStKzEhLNnNmzcVQOnUqVOmzyGLf60PGTJEddxbb72lAMrUqVNV8YCAAKVGjRqmx8/bEXqc0WhU9Hq9smvXrnTdgKfdGkv7MW3YsEEBlC1btphiKSkpiq+vr9K+fXtTrF+/fkqBAgWUK1euqF7vm2++UQDln3/+eWKuX375pQIomzdvTvecXq9X/XsSg8Gg6PV6ZenSpYqtra0SExNjeu5JHSFvb28lLi7OFLt586ZiY2OjTJ482RQrUKCAMmzYsCe+b0by4musW7du6Y4dMWKE4uzsrNy7d88UO3XqlAIoP/zwgylWqVIlpXr16uk+n23atFF8fHwUg8GQ6byF0ILMGhPCzLVp00b1uHLlygC0bt06XfzKlSs59r4XL14kJCSEYsWKYWtri729PQ0bNgTg9OnT2XrNli1bUqxYMVVH57fffuPGjRv06tXLFPvll19o3Lgxvr6+pKSkmP61bNkSgF27dmX5vY8fP469vb3q3+Mz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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "import matplotlib.pyplot as plt\n", "import numpy as np\n", @@ -871,9 +909,7 @@ { "cell_type": "markdown", "id": "58e5b521", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Material for Lecture Thursday November 9" ] @@ -881,9 +917,7 @@ { "cell_type": "markdown", "id": "4ebe5a91", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Recurrent neural networks (RNNs): Overarching view\n", "\n", @@ -908,9 +942,7 @@ { "cell_type": "markdown", "id": "182f425e", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## A simple example" ] @@ -919,10 +951,7 @@ "cell_type": "code", "execution_count": 9, "id": "8b3ca785", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "# Start importing packages\n", @@ -992,9 +1021,7 @@ { "cell_type": "markdown", "id": "b0c12b4c", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "### RNNs\n", "\n", @@ -1012,9 +1039,7 @@ { "cell_type": "markdown", "id": "d81020f6", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Basic layout\n", "\n", @@ -1028,9 +1053,7 @@ { "cell_type": "markdown", "id": "2d7453c9", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "### We need to specify the initial activity state of all the hidden and output units\n", "\n", @@ -1050,9 +1073,7 @@ { "cell_type": "markdown", "id": "fc4a082e", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "### We can specify inputs in several ways\n", "\n", @@ -1068,9 +1089,7 @@ { "cell_type": "markdown", "id": "c1106ad9", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "### We can specify targets in several ways\n", "\n", @@ -1114,9 +1133,7 @@ { "cell_type": "markdown", "id": "b139ef7b", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "### Backpropagation through time\n", "\n", @@ -1135,9 +1152,7 @@ { "cell_type": "markdown", "id": "70c95078", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "### The backward pass is linear\n", "\n", @@ -1196,9 +1211,7 @@ { "cell_type": "markdown", "id": "2ca24031", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## The problem of exploding or vanishing gradients\n", "* What happens to the magnitude of the gradients as we backpropagate through many layers?\n", @@ -1221,9 +1234,7 @@ { "cell_type": "markdown", "id": "93648979", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Four effective ways to learn an RNN\n", "1. Long Short Term Memory Make the RNN out of little modules that are designed to remember values for a long time.\n", @@ -1240,9 +1251,7 @@ { "cell_type": "markdown", "id": "b8806dcd", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "### Long Short Term Memory (LSTM)\n", "\n", @@ -1264,9 +1273,7 @@ { "cell_type": "markdown", "id": "b0edad40", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "### Implementing a memory cell in a neural network\n", "\n", @@ -1346,9 +1353,7 @@ { "cell_type": "markdown", "id": "58fd18f9", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## An extrapolation example\n", "\n", @@ -1362,10 +1367,7 @@ "cell_type": "code", "execution_count": 10, "id": "a604caa5", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "\n", @@ -1401,9 +1403,7 @@ { "cell_type": "markdown", "id": "545336c9", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Formatting the Data\n", "\n", @@ -1445,10 +1445,7 @@ "cell_type": "code", "execution_count": 11, "id": "3ef3ed13", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "# FORMAT_DATA\n", @@ -1528,9 +1525,7 @@ { "cell_type": "markdown", "id": "8a8b29b8", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Predicting New Points With A Trained Recurrent Neural Network" ] @@ -1539,10 +1534,7 @@ "cell_type": "code", "execution_count": 12, "id": "d840beea", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "def test_rnn (x1, y_test, plot_min, plot_max):\n", @@ -1641,9 +1633,7 @@ { "cell_type": "markdown", "id": "2e5b339f", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Other Things to Try\n", "\n", @@ -1663,10 +1653,7 @@ "cell_type": "code", "execution_count": 13, "id": "370e799d", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "def rnn_2layers(length_of_sequences, batch_size = None, stateful = False):\n", @@ -1760,9 +1747,7 @@ { "cell_type": "markdown", "id": "d8f62fc4", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Other Types of Recurrent Neural Networks\n", "\n", @@ -1786,10 +1771,7 @@ "cell_type": "code", "execution_count": 14, "id": "4ea36ea9", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "def lstm_2layers(length_of_sequences, batch_size = None, stateful = False):\n", @@ -1985,7 +1967,25 @@ ] } ], - "metadata": {}, + "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.9.10" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/doc/pub/week45/ipynb/week45.ipynb b/doc/pub/week45/ipynb/week45.ipynb index 749491e98..ead5f8ff6 100644 --- a/doc/pub/week45/ipynb/week45.ipynb +++ b/doc/pub/week45/ipynb/week45.ipynb @@ -3,9 +3,7 @@ { "cell_type": "markdown", "id": "31a10e2b", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "\n", @@ -15,9 +13,7 @@ { "cell_type": "markdown", "id": "019daa83", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "# Week 45, Recurrent Neural Networks\n", "**Morten Hjorth-Jensen**, Department of Physics, University of Oslo and Department of Physics and Astronomy and National Superconducting Cyclotron Laboratory, Michigan State University\n", @@ -28,9 +24,7 @@ { "cell_type": "markdown", "id": "6ecf1c2b", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Plan for week 45\n", "\n", @@ -68,9 +62,7 @@ { "cell_type": "markdown", "id": "d80a4db8", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Material for the lab sessions, additional ways to present classification results and other practicalities" ] @@ -78,9 +70,7 @@ { "cell_type": "markdown", "id": "1ded5c92", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Searching for Optimal Regularization Parameters $\\lambda$\n", "\n", @@ -97,10 +87,7 @@ "cell_type": "code", "execution_count": 1, "id": "6dea0513", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", @@ -154,9 +141,7 @@ { "cell_type": "markdown", "id": "440bf579", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "Here we have performed a rather data greedy calculation as function of the regularization parameter $\\lambda$. There is no resampling here. The latter can easily be added by employing the function **RidgeCV** instead of just calling the **Ridge** function. For **RidgeCV** we need to pass the array of $\\lambda$ values.\n", "By inspecting the figure we can in turn determine which is the optimal regularization parameter.\n", @@ -166,9 +151,7 @@ { "cell_type": "markdown", "id": "683b1da2", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Grid Search\n", "\n", @@ -181,10 +164,7 @@ "cell_type": "code", "execution_count": 2, "id": "38be79e0", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", @@ -234,9 +214,7 @@ { "cell_type": "markdown", "id": "081fbe5c", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "By default the grid search function includes cross validation with\n", "five folds. The [Scikit-Learn\n", @@ -249,9 +227,7 @@ { "cell_type": "markdown", "id": "a9798c07", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Randomized Grid Search\n", "\n", @@ -269,10 +245,7 @@ "cell_type": "code", "execution_count": 3, "id": "0a7e4e2e", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", @@ -323,9 +296,7 @@ { "cell_type": "markdown", "id": "dcd07cb8", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Wisconsin Cancer Data\n", "\n", @@ -338,10 +309,7 @@ "cell_type": "code", "execution_count": 4, "id": "65061d95", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", @@ -365,9 +333,7 @@ { "cell_type": "markdown", "id": "50492453", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Using the correlation matrix\n", "\n", @@ -379,10 +345,7 @@ "cell_type": "code", "execution_count": 5, "id": "08a2ab17", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", @@ -424,9 +387,7 @@ { "cell_type": "markdown", "id": "5408b7dd", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Discussing the correlation data\n", "\n", @@ -449,10 +410,7 @@ "cell_type": "code", "execution_count": 6, "id": "76c3d259", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "cancerpd = pd.DataFrame(cancer.data, columns=cancer.feature_names)" @@ -461,9 +419,7 @@ { "cell_type": "markdown", "id": "83903231", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "and then" ] @@ -472,10 +428,7 @@ "cell_type": "code", "execution_count": 7, "id": "58ccd6c3", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "correlation_matrix = cancerpd.corr().round(1)" @@ -484,9 +437,7 @@ { "cell_type": "markdown", "id": "adda54cb", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "Diagonalizing this matrix we can in turn say something about which\n", "features are of relevance and which are not. This leads us to\n", @@ -497,9 +448,7 @@ { "cell_type": "markdown", "id": "8799c034", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Other ways of presenting a classification problem\n", "\n", @@ -530,9 +479,7 @@ { "cell_type": "markdown", "id": "dfbe0571", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Combinations of classification results\n", "\n", @@ -544,9 +491,7 @@ { "cell_type": "markdown", "id": "65f7c63d", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "$$\n", "{\\displaystyle \\mathrm {TPR} ={\\frac {\\mathrm {TP} }{\\mathrm {P} }}={\\frac {\\mathrm {TP} }{\\mathrm {TP} +\\mathrm {FN} }}=1-\\mathrm {FNR} }\n", @@ -556,9 +501,7 @@ { "cell_type": "markdown", "id": "2e674d10", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "The $TPR$ defines how many correct positive results occur among all positive samples available during the test\n", "\n", @@ -568,9 +511,7 @@ { "cell_type": "markdown", "id": "65577837", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "$$\n", "{\\displaystyle \\mathrm {FNR} ={\\frac {\\mathrm {FN} }{\\mathrm {P} }}={\\frac {\\mathrm {FN} }{\\mathrm {FN} +\\mathrm {TP} }} }\n", @@ -580,9 +521,7 @@ { "cell_type": "markdown", "id": "e5e8802d", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "**Specificity, selectivity or true negative rate $TNR$. It is the probability of a negative test result, conditioned on the individual truly being negative.**" ] @@ -590,9 +529,7 @@ { "cell_type": "markdown", "id": "07c61591", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "$$\n", "{\\displaystyle \\mathrm {TNR} ={\\frac {\\mathrm {TN} }{\\mathrm {N} }}={\\frac {\\mathrm {TN} }{\\mathrm {TN} +\\mathrm {FP} }}=1-\\mathrm {FPR} }\n", @@ -602,9 +539,7 @@ { "cell_type": "markdown", "id": "b3f61bb3", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "with the fall-out false positive rate" ] @@ -612,9 +547,7 @@ { "cell_type": "markdown", "id": "6544105e", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "$$\n", "{\\displaystyle \\mathrm {FPR} ={\\frac {\\mathrm {FP} }{\\mathrm {N} }}={\\frac {\\mathrm {FP} }{\\mathrm {FP} +\\mathrm {TN} }}=1-\\mathrm {TNR} }\n", @@ -624,9 +557,7 @@ { "cell_type": "markdown", "id": "0b571e85", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "The $FPR$ defines how many incorrect positive results occur among\n", "all negative samples available during the test." @@ -635,9 +566,7 @@ { "cell_type": "markdown", "id": "17d6872a", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Positive and negative prediction values\n", "\n", @@ -654,9 +583,7 @@ { "cell_type": "markdown", "id": "122f7e6c", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "$$\n", "{\\displaystyle \\mathrm {PPV} ={\\frac {\\mathrm {TP} }{\\mathrm {TP} +\\mathrm {FP} }}=1-\\mathrm {FDR} }\n", @@ -666,9 +593,7 @@ { "cell_type": "markdown", "id": "f44a5e78", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "**Negative predictive value $NPV$.**" ] @@ -676,9 +601,7 @@ { "cell_type": "markdown", "id": "86fa9670", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "$$\n", "{\\displaystyle \\mathrm {NPV} ={\\frac {\\mathrm {TN} }{\\mathrm {TN} +\\mathrm {FN} }}=1-\\mathrm {FOR} }\n", @@ -688,9 +611,7 @@ { "cell_type": "markdown", "id": "a30e358d", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Other quantities\n", "\n", @@ -700,9 +621,7 @@ { "cell_type": "markdown", "id": "3f0de6de", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "$$\n", "{\\displaystyle \\mathrm {FDR} ={\\frac {\\mathrm {FP} }{\\mathrm {FP} +\\mathrm {TP} }}=1-\\mathrm {PPV} }\n", @@ -712,9 +631,7 @@ { "cell_type": "markdown", "id": "0b4cc93f", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "**False omission rate $FOR$.**" ] @@ -722,9 +639,7 @@ { "cell_type": "markdown", "id": "4866ec0a", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "$$\n", "{\\displaystyle \\mathrm {FOR} ={\\frac {\\mathrm {FN} }{\\mathrm {FN} +\\mathrm {TN} }}=1-\\mathrm {NPV} }\n", @@ -734,9 +649,7 @@ { "cell_type": "markdown", "id": "9b1c8c45", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## $F_1$ score\n", "\n", @@ -762,9 +675,7 @@ { "cell_type": "markdown", "id": "0e651a1f", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "$$\n", "{\\displaystyle \\mathrm {F} _{1}=2\\times {\\frac {\\mathrm {PPV} \\times \\mathrm {TPR} }{\\mathrm {PPV} +\\mathrm {TPR} }}={\\frac {2\\mathrm {TP} }{2\\mathrm {TP} +\\mathrm {FP} +\\mathrm {FN} }}}\n", @@ -774,9 +685,7 @@ { "cell_type": "markdown", "id": "d83efe41", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## ROC curve\n", "\n", @@ -799,9 +708,7 @@ { "cell_type": "markdown", "id": "d088215b", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Cumulative gain curve\n", "\n", @@ -817,9 +724,7 @@ { "cell_type": "markdown", "id": "5c0bcd1f", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Other measures in classification studies: Cancer Data again" ] @@ -828,10 +733,7 @@ "cell_type": "code", "execution_count": 8, "id": "2a6f80df", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", @@ -871,9 +773,7 @@ { "cell_type": "markdown", "id": "58e5b521", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Material for Lecture Thursday November 9" ] @@ -881,9 +781,7 @@ { "cell_type": "markdown", "id": "4ebe5a91", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Recurrent neural networks (RNNs): Overarching view\n", "\n", @@ -908,9 +806,7 @@ { "cell_type": "markdown", "id": "182f425e", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## A simple example" ] @@ -919,10 +815,7 @@ "cell_type": "code", "execution_count": 9, "id": "8b3ca785", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "# Start importing packages\n", @@ -992,9 +885,7 @@ { "cell_type": "markdown", "id": "b0c12b4c", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "### RNNs\n", "\n", @@ -1012,9 +903,7 @@ { "cell_type": "markdown", "id": "d81020f6", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Basic layout\n", "\n", @@ -1028,9 +917,7 @@ { "cell_type": "markdown", "id": "2d7453c9", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "### We need to specify the initial activity state of all the hidden and output units\n", "\n", @@ -1050,9 +937,7 @@ { "cell_type": "markdown", "id": "fc4a082e", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "### We can specify inputs in several ways\n", "\n", @@ -1068,9 +953,7 @@ { "cell_type": "markdown", "id": "c1106ad9", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "### We can specify targets in several ways\n", "\n", @@ -1114,9 +997,7 @@ { "cell_type": "markdown", "id": "b139ef7b", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "### Backpropagation through time\n", "\n", @@ -1135,9 +1016,7 @@ { "cell_type": "markdown", "id": "70c95078", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "### The backward pass is linear\n", "\n", @@ -1196,9 +1075,7 @@ { "cell_type": "markdown", "id": "2ca24031", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## The problem of exploding or vanishing gradients\n", "* What happens to the magnitude of the gradients as we backpropagate through many layers?\n", @@ -1221,9 +1098,7 @@ { "cell_type": "markdown", "id": "93648979", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Four effective ways to learn an RNN\n", "1. Long Short Term Memory Make the RNN out of little modules that are designed to remember values for a long time.\n", @@ -1240,9 +1115,7 @@ { "cell_type": "markdown", "id": "b8806dcd", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "### Long Short Term Memory (LSTM)\n", "\n", @@ -1264,9 +1137,7 @@ { "cell_type": "markdown", "id": "b0edad40", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "### Implementing a memory cell in a neural network\n", "\n", @@ -1346,9 +1217,7 @@ { "cell_type": "markdown", "id": "58fd18f9", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## An extrapolation example\n", "\n", @@ -1362,10 +1231,7 @@ "cell_type": "code", "execution_count": 10, "id": "a604caa5", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "\n", @@ -1401,9 +1267,7 @@ { "cell_type": "markdown", "id": "545336c9", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Formatting the Data\n", "\n", @@ -1445,10 +1309,7 @@ "cell_type": "code", "execution_count": 11, "id": "3ef3ed13", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "# FORMAT_DATA\n", @@ -1528,9 +1389,7 @@ { "cell_type": "markdown", "id": "8a8b29b8", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Predicting New Points With A Trained Recurrent Neural Network" ] @@ -1539,10 +1398,7 @@ "cell_type": "code", "execution_count": 12, "id": "d840beea", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "def test_rnn (x1, y_test, plot_min, plot_max):\n", @@ -1641,9 +1497,7 @@ { "cell_type": "markdown", "id": "2e5b339f", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Other Things to Try\n", "\n", @@ -1663,10 +1517,7 @@ "cell_type": "code", "execution_count": 13, "id": "370e799d", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "def rnn_2layers(length_of_sequences, batch_size = None, stateful = False):\n", @@ -1760,9 +1611,7 @@ { "cell_type": "markdown", "id": "d8f62fc4", - "metadata": { - "editable": true - }, + "metadata": {}, "source": [ "## Other Types of Recurrent Neural Networks\n", "\n", @@ -1786,10 +1635,7 @@ "cell_type": "code", "execution_count": 14, "id": "4ea36ea9", - "metadata": { - "collapsed": false, - "editable": true - }, + "metadata": {}, "outputs": [], "source": [ "def lstm_2layers(length_of_sequences, batch_size = None, stateful = False):\n", @@ -1985,7 +1831,25 @@ ] } ], - "metadata": {}, + "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.9.18" + } + }, "nbformat": 4, "nbformat_minor": 5 }