From 4a22ddc3b5052e3f2d1f3ec9d558ff08717b46ff Mon Sep 17 00:00:00 2001 From: judsonupchurch Date: Tue, 21 Jan 2025 03:11:37 +0000 Subject: [PATCH] Lecture 27, Adam optimizer --- lecture25_27/notes_25.ipynb | 256 ++++++++++++++++- lecture25_27/notes_25.pdf | Bin 0 -> 101985 bytes lecture25_27/notes_25.py | 555 ++++++++++++++++++++++++++++++++++++ 3 files changed, 810 insertions(+), 1 deletion(-) create mode 100644 lecture25_27/notes_25.pdf create mode 100644 lecture25_27/notes_25.py diff --git a/lecture25_27/notes_25.ipynb b/lecture25_27/notes_25.ipynb index d73463f..1f52de0 100644 --- a/lecture25_27/notes_25.ipynb +++ b/lecture25_27/notes_25.ipynb @@ -480,7 +480,9 @@ "metadata": {}, "source": [ "# RMSProp Optimizer\n", - "Root Meas Square Propagation optimizer. It is similar to AdaGrad in that you apply different learning rates to different weights. However, the way you change the learning rate focuses more on the past cache rather than the current gradient." + "Root Meas Square Propagation optimizer. It is similar to AdaGrad in that you apply different learning rates to different weights. However, the way you change the learning rate focuses more on the most recent cache than the sum of all of the last gradients.\n", + "\n", + "Notably, RMSProp does not use momentum. While it does have information of the past gradient in the cache, it uses this to scale the learning rate, not to correct for overshooting." ] }, { @@ -705,6 +707,258 @@ " optimizer.update_params(dense2)\n", " optimizer.post_update_params()\n" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Adam Optimizer\n", + "The Adam optimizer combines adaptive learning rate with momentum.\n", + "\n", + "$W_{i+1} = W_{i} - \\frac{\\alpha}{\\sqrt{\\frac{\\text{cache}}{1- \\beta_2^{i+1}}} + \\epsilon} * \\left(\\beta_{1} * \\frac{\\text{Momentum}_i}{ 1- \\beta_1^{i+1}} + \\left(1 - \\beta_2 \\right) * \\frac{\\delta L}{\\delta W}_i\\right)$\n", + "\n", + "From the equation, it is clear that the cache and momentum are \"corrected\" by dividing by some scalar that varies with the iteration value. This way, earlier iterations have larger corrected cache and momentum so local minima are harder to get stuck in." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "# Adam optimizer\n", + "class Optimizer_Adam():\n", + " def __init__(self, learning_rate=0.001, decay=0.0, epsilon=1e-7, beta_1=0.9, beta_2=0.999):\n", + " self.initial_learning_rate = learning_rate\n", + " self.current_learning_rate = learning_rate\n", + " self.decay = decay\n", + " self.iterations = 0\n", + " self.epsilon = epsilon\n", + " self.beta_1 = beta_1\n", + " self.beta_2 = beta_2\n", + "\n", + " def pre_update_params(self):\n", + " if self.decay:\n", + " self.current_learning_rate = self.initial_learning_rate * (1. / (1. + self.decay * self.iterations))\n", + "\n", + " def update_params(self, layer):\n", + " # If layer does not contain cache arrays, create them filled with zeros\n", + " if not hasattr(layer, 'weight_cache'):\n", + " layer.weight_momentums = np.zeros_like(layer.weights)\n", + " layer.weight_cache = np.zeros_like(layer.weights)\n", + " layer.bias_momentums = np.zeros_like(layer.biases)\n", + " layer.bias_cache = np.zeros_like(layer.biases)\n", + "\n", + " # Update momentum with current gradients\n", + " layer.weight_momentums = self.beta_1 * layer.weight_momentums + (1 - self.beta_1) * layer.dweights\n", + " layer.bias_momentums = self.beta_1 * layer.bias_momentums + (1 - self.beta_1) * layer.dbiases\n", + "\n", + " # Get corrected momentum\n", + " # use self.iteration + 1 because we start at iteration 0\n", + " weight_momentums_corrected = layer.weight_momentums / (1 - self.beta_1 ** (self.iterations + 1))\n", + " bias_momentums_corrected = layer.bias_momentums / (1 - self.beta_1 ** (self.iterations + 1))\n", + "\n", + " # Update cache with squared current gradients\n", + " layer.weight_cache = self.beta_2 * layer.weight_cache + (1 - self.beta_2) * layer.dweights**2\n", + " layer.bias_cache = self.beta_2 * layer.bias_cache + (1 - self.beta_2) * layer.dbiases**2\n", + "\n", + " # Get corrected cache\n", + " weight_cache_corrected = layer.weight_cache / (1 - self.beta_2 ** (self.iterations + 1))\n", + " bias_cache_corrected = layer.bias_cache / (1 - self.beta_2 ** (self.iterations + 1))\n", + "\n", + " # Vanilla SGD parameter update + normalization with square rooted cache\n", + " layer.weights += -self.current_learning_rate * weight_momentums_corrected / (np.sqrt(weight_cache_corrected) + self.epsilon)\n", + " layer.biases += -self.current_learning_rate * bias_momentums_corrected / (np.sqrt(bias_cache_corrected) + self.epsilon)\n", + "\n", + " # Call once after any parameter updates\n", + " def post_update_params(self):\n", + " self.iterations += 1\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Testing the Adam Optimizer" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "epoch: 0, acc: 0.327, loss: 1.099, lr: 0.02\n", + "epoch: 100, acc: 0.523, loss: 0.941, lr: 0.01998021958261321\n", + "epoch: 200, acc: 0.517, loss: 0.854, lr: 0.019960279044701046\n", + "epoch: 300, acc: 0.630, loss: 0.753, lr: 0.019940378268975763\n", + "epoch: 400, acc: 0.693, loss: 0.699, lr: 0.01992051713662487\n", + "epoch: 500, acc: 0.693, loss: 0.658, lr: 0.01990069552930875\n", + "epoch: 600, acc: 0.707, loss: 0.632, lr: 0.019880913329158343\n", + "epoch: 700, acc: 0.707, loss: 0.612, lr: 0.019861170418772778\n", + "epoch: 800, acc: 0.720, loss: 0.572, lr: 0.019841466681217078\n", + "epoch: 900, acc: 0.737, loss: 0.558, lr: 0.01982180200001982\n", + "epoch: 1000, acc: 0.730, loss: 0.548, lr: 0.019802176259170884\n", + "epoch: 1100, acc: 0.730, loss: 0.540, lr: 0.01978258934311912\n", + "epoch: 1200, acc: 0.733, loss: 0.529, lr: 0.01976304113677013\n", + "epoch: 1300, acc: 0.733, loss: 0.521, lr: 0.019743531525483964\n", + "epoch: 1400, acc: 0.750, loss: 0.517, lr: 0.01972406039507293\n", + "epoch: 1500, acc: 0.750, loss: 0.518, lr: 0.019704627631799327\n", + "epoch: 1600, acc: 0.743, loss: 0.508, lr: 0.019685233122373254\n", + "epoch: 1700, acc: 0.723, loss: 0.505, lr: 0.019665876753950384\n", + "epoch: 1800, acc: 0.740, loss: 0.502, lr: 0.01964655841412981\n", + "epoch: 1900, acc: 0.740, loss: 0.498, lr: 0.019627277990951823\n", + "epoch: 2000, acc: 0.730, loss: 0.493, lr: 0.019608035372895814\n", + "epoch: 2100, acc: 0.753, loss: 0.491, lr: 0.01958883044887805\n", + "epoch: 2200, acc: 0.760, loss: 0.488, lr: 0.019569663108249594\n", + "epoch: 2300, acc: 0.757, loss: 0.487, lr: 0.01955053324079414\n", + "epoch: 2400, acc: 0.743, loss: 0.482, lr: 0.019531440736725945\n", + "epoch: 2500, acc: 0.743, loss: 0.479, lr: 0.019512385486687673\n", + "epoch: 2600, acc: 0.760, loss: 0.479, lr: 0.019493367381748363\n", + "epoch: 2700, acc: 0.797, loss: 0.462, lr: 0.019474386313401298\n", + "epoch: 2800, acc: 0.787, loss: 0.439, lr: 0.019455442173562\n", + "epoch: 2900, acc: 0.790, loss: 0.436, lr: 0.019436534854566128\n", + "epoch: 3000, acc: 0.800, loss: 0.435, lr: 0.01941766424916747\n", + "epoch: 3100, acc: 0.787, loss: 0.433, lr: 0.019398830250535893\n", + "epoch: 3200, acc: 0.793, loss: 0.430, lr: 0.019380032752255354\n", + "epoch: 3300, acc: 0.800, loss: 0.429, lr: 0.01936127164832186\n", + "epoch: 3400, acc: 0.790, loss: 0.427, lr: 0.01934254683314152\n", + "epoch: 3500, acc: 0.790, loss: 0.426, lr: 0.019323858201528515\n", + "epoch: 3600, acc: 0.783, loss: 0.428, lr: 0.019305205648703173\n", + "epoch: 3700, acc: 0.790, loss: 0.424, lr: 0.01928658907028997\n", + "epoch: 3800, acc: 0.773, loss: 0.428, lr: 0.01926800836231563\n", + "epoch: 3900, acc: 0.787, loss: 0.420, lr: 0.019249463421207133\n", + "epoch: 4000, acc: 0.797, loss: 0.417, lr: 0.019230954143789846\n", + "epoch: 4100, acc: 0.797, loss: 0.415, lr: 0.019212480427285565\n", + "epoch: 4200, acc: 0.807, loss: 0.414, lr: 0.019194042169310647\n", + "epoch: 4300, acc: 0.810, loss: 0.412, lr: 0.019175639267874092\n", + "epoch: 4400, acc: 0.807, loss: 0.413, lr: 0.019157271621375684\n", + "epoch: 4500, acc: 0.793, loss: 0.411, lr: 0.0191389391286041\n", + "epoch: 4600, acc: 0.810, loss: 0.413, lr: 0.019120641688735073\n", + "epoch: 4700, acc: 0.810, loss: 0.409, lr: 0.019102379201329525\n", + "epoch: 4800, acc: 0.790, loss: 0.408, lr: 0.01908415156633174\n", + "epoch: 4900, acc: 0.810, loss: 0.408, lr: 0.01906595868406753\n", + "epoch: 5000, acc: 0.800, loss: 0.406, lr: 0.01904780045524243\n", + "epoch: 5100, acc: 0.793, loss: 0.407, lr: 0.019029676780939874\n", + "epoch: 5200, acc: 0.787, loss: 0.405, lr: 0.019011587562619416\n", + "epoch: 5300, acc: 0.793, loss: 0.405, lr: 0.01899353270211493\n", + "epoch: 5400, acc: 0.797, loss: 0.404, lr: 0.018975512101632844\n", + "epoch: 5500, acc: 0.810, loss: 0.405, lr: 0.018957525663750367\n", + "epoch: 5600, acc: 0.793, loss: 0.403, lr: 0.018939573291413745\n", + "epoch: 5700, acc: 0.790, loss: 0.403, lr: 0.018921654887936498\n", + "epoch: 5800, acc: 0.790, loss: 0.402, lr: 0.018903770356997706\n", + "epoch: 5900, acc: 0.793, loss: 0.401, lr: 0.018885919602640248\n", + "epoch: 6000, acc: 0.813, loss: 0.404, lr: 0.018868102529269144\n", + "epoch: 6100, acc: 0.807, loss: 0.401, lr: 0.018850319041649778\n", + "epoch: 6200, acc: 0.807, loss: 0.402, lr: 0.018832569044906263\n", + "epoch: 6300, acc: 0.810, loss: 0.401, lr: 0.018814852444519702\n", + "epoch: 6400, acc: 0.810, loss: 0.399, lr: 0.018797169146326564\n", + "epoch: 6500, acc: 0.793, loss: 0.401, lr: 0.01877951905651696\n", + "epoch: 6600, acc: 0.797, loss: 0.399, lr: 0.018761902081633034\n", + "epoch: 6700, acc: 0.807, loss: 0.398, lr: 0.018744318128567278\n", + "epoch: 6800, acc: 0.790, loss: 0.399, lr: 0.018726767104560903\n", + "epoch: 6900, acc: 0.810, loss: 0.398, lr: 0.018709248917202218\n", + "epoch: 7000, acc: 0.807, loss: 0.398, lr: 0.018691763474424996\n", + "epoch: 7100, acc: 0.807, loss: 0.399, lr: 0.018674310684506857\n", + "epoch: 7200, acc: 0.790, loss: 0.398, lr: 0.01865689045606769\n", + "epoch: 7300, acc: 0.790, loss: 0.398, lr: 0.01863950269806802\n", + "epoch: 7400, acc: 0.803, loss: 0.396, lr: 0.018622147319807447\n", + "epoch: 7500, acc: 0.790, loss: 0.399, lr: 0.018604824230923075\n", + "epoch: 7600, acc: 0.793, loss: 0.398, lr: 0.01858753334138793\n", + "epoch: 7700, acc: 0.810, loss: 0.396, lr: 0.018570274561509396\n", + "epoch: 7800, acc: 0.810, loss: 0.395, lr: 0.018553047801927663\n", + "epoch: 7900, acc: 0.803, loss: 0.395, lr: 0.018535852973614212\n", + "epoch: 8000, acc: 0.790, loss: 0.395, lr: 0.01851868998787026\n", + "epoch: 8100, acc: 0.813, loss: 0.395, lr: 0.018501558756325222\n", + "epoch: 8200, acc: 0.790, loss: 0.395, lr: 0.01848445919093522\n", + "epoch: 8300, acc: 0.793, loss: 0.395, lr: 0.018467391203981567\n", + "epoch: 8400, acc: 0.793, loss: 0.395, lr: 0.018450354708069265\n", + "epoch: 8500, acc: 0.813, loss: 0.394, lr: 0.018433349616125496\n", + "epoch: 8600, acc: 0.813, loss: 0.395, lr: 0.018416375841398172\n", + "epoch: 8700, acc: 0.793, loss: 0.394, lr: 0.01839943329745444\n", + "epoch: 8800, acc: 0.783, loss: 0.398, lr: 0.01838252189817921\n", + "epoch: 8900, acc: 0.793, loss: 0.393, lr: 0.018365641557773718\n", + "epoch: 9000, acc: 0.797, loss: 0.393, lr: 0.018348792190754044\n", + "epoch: 9100, acc: 0.813, loss: 0.394, lr: 0.0183319737119497\n", + "epoch: 9200, acc: 0.813, loss: 0.393, lr: 0.018315186036502167\n", + "epoch: 9300, acc: 0.810, loss: 0.393, lr: 0.018298429079863496\n", + "epoch: 9400, acc: 0.793, loss: 0.395, lr: 0.018281702757794862\n", + "epoch: 9500, acc: 0.800, loss: 0.392, lr: 0.018265006986365174\n", + "epoch: 9600, acc: 0.797, loss: 0.393, lr: 0.018248341681949654\n", + "epoch: 9700, acc: 0.807, loss: 0.392, lr: 0.018231706761228456\n", + "epoch: 9800, acc: 0.817, loss: 0.393, lr: 0.018215102141185255\n", + "epoch: 9900, acc: 0.817, loss: 0.395, lr: 0.018198527739105907\n", + "epoch: 10000, acc: 0.790, loss: 0.392, lr: 0.018181983472577025\n" + ] + } + ], + "source": [ + "# Create dataset\n", + "X, y = spiral_data(samples=100, classes=3)\n", + "\n", + "# Create Dense layer with 2 input features and 64 output values\n", + "dense1 = Layer_Dense(2, 64)\n", + "\n", + "# Create ReLU activation (to be used with Dense layer)\n", + "activation1 = Activation_ReLU()\n", + "\n", + "# Create second Dense layer with 64 input features (as we take output\n", + "# of previous layer here) and 3 output values (output values)\n", + "dense2 = Layer_Dense(64, 3)\n", + "\n", + "# Create Softmax classifier's combined loss and activation\n", + "loss_activation = Activation_Softmax_Loss_CategoricalCrossentropy()\n", + "\n", + "# Create optimizer\n", + "optimizer = Optimizer_Adam(learning_rate=0.02, decay=1e-5)\n", + "\n", + "# Train in loop\n", + "for epoch in range(10001):\n", + " # Perform a forward pass of our training data through this layer\n", + " dense1.forward(X)\n", + " \n", + " # Perform a forward pass through activation function\n", + " # takes the output of first dense layer here\n", + " activation1.forward(dense1.output)\n", + " \n", + " # Perform a forward pass through second Dense layer\n", + " # takes outputs of activation function of first layer as inputs\n", + " dense2.forward(activation1.output)\n", + " \n", + " # Perform a forward pass through the activation/loss function\n", + " # takes the output of second dense layer here and returns loss\n", + " loss = loss_activation.forward(dense2.output, y)\n", + " \n", + " # Calculate accuracy from output of activation2 and targets\n", + " # calculate values along first axis\n", + " predictions = np.argmax(loss_activation.output, axis=1)\n", + " if len(y.shape) == 2:\n", + " y = np.argmax(y, axis=1)\n", + " accuracy = np.mean(predictions == y)\n", + " \n", + " if not epoch % 100:\n", + " print(f'epoch: {epoch}, ' +\n", + " f'acc: {accuracy:.3f}, ' +\n", + " f'loss: {loss:.3f}, ' +\n", + " f'lr: {optimizer.current_learning_rate}')\n", + " \n", + " # Backward pass\n", + " loss_activation.backward(loss_activation.output, y)\n", + " dense2.backward(loss_activation.dinputs)\n", + " activation1.backward(dense2.dinputs)\n", + " dense1.backward(activation1.dinputs)\n", + " \n", + " # Update weights and biases\n", + " optimizer.pre_update_params()\n", + " optimizer.update_params(dense1)\n", + " optimizer.update_params(dense2)\n", + " optimizer.post_update_params()\n" + ] } ], "metadata": { diff --git a/lecture25_27/notes_25.pdf b/lecture25_27/notes_25.pdf new file mode 100644 index 0000000000000000000000000000000000000000..94c7f8fe7089cccc6f5d3723fc01e543eb87ade8 GIT binary patch literal 101985 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 Um_ji!FfuVSLy?k-%8Nn$Uoqev{Qv*} literal 0 HcmV?d00001 diff --git a/lecture25_27/notes_25.py b/lecture25_27/notes_25.py new file mode 100644 index 0000000..192820a --- /dev/null +++ b/lecture25_27/notes_25.py @@ -0,0 +1,555 @@ +# %% [markdown] +# # Previous Class Definitions + +# %% +# imports +import matplotlib.pyplot as plt +import numpy as np +import nnfs +from nnfs.datasets import spiral_data, vertical_data +nnfs.init() + +# %% +class Layer_Dense: + def __init__(self, n_inputs, n_neurons): + # Initialize the weights and biases + self.weights = 0.01 * np.random.randn(n_inputs, n_neurons) # Normal distribution of weights + self.biases = np.zeros((1, n_neurons)) + + def forward(self, inputs): + # Calculate the output values from inputs, weights, and biases + self.inputs = inputs + self.output = np.dot(inputs, self.weights) + self.biases # Weights are already transposed + + def backward(self, dvalues): + '''Calculated the gradient of the loss with respect to the weights and biases of this layer. + dvalues is equiavelent to a transposed dl_dZ. It is the gradient + of the loss with respect to the outputs of this layer.''' + self.dweights = np.dot(self.inputs.T, dvalues) + self.dbiases = np.sum(dvalues, axis=0, keepdims=0) + self.dinputs = np.dot(dvalues, self.weights.T) + +class Activation_ReLU: + def forward(self, inputs): + self.inputs = inputs + self.output = np.maximum(0, inputs) + + def backward(self, dvalues): + '''Calculated the gradient of the loss with respect to this layer's activation function + dvalues is equiavelent to a transposed dl_dZ. It is the gradient + of the loss with respect to the outputs of this layer.''' + self.dinputs = dvalues.copy() + self.dinputs[self.inputs <= 0] = 0 + +class Activation_Softmax: + def forward(self, inputs): + # Get the unnormalized probabilities + # Subtract max from the row to prevent larger numbers + exp_values = np.exp(inputs - np.max(inputs, axis=1, keepdims=True)) + + # Normalize the probabilities with element wise division + probabilities = exp_values / np.sum(exp_values, axis=1,keepdims=True) + self.output = probabilities + +# Base class for Loss functions +class Loss: + '''Calculates the data and regularization losses given + model output and ground truth values''' + def calculate(self, output, y): + sample_losses = self.forward(output, y) + data_loss = np.average(sample_losses) + return data_loss + +class Loss_CategoricalCrossEntropy(Loss): + def forward(self, y_pred, y_true): + '''y_pred is the neural network output + y_true is the ideal output of the neural network''' + samples = len(y_pred) + # Bound the predicted values + y_pred_clipped = np.clip(y_pred, 1e-7, 1-1e-7) + + if len(y_true.shape) == 1: # Categorically labeled + correct_confidences = y_pred_clipped[range(samples), y_true] + elif len(y_true.shape) == 2: # One hot encoded + correct_confidences = np.sum(y_pred_clipped*y_true, axis=1) + + # Calculate the losses + negative_log_likelihoods = -np.log(correct_confidences) + return negative_log_likelihoods + + def backward(self, dvalues, y_true): + samples = len(dvalues) + + # Number of lables in each sample + labels = len(dvalues[0]) + + # if the labels are sparse, turn them into a one-hot vector + if len(y_true.shape) == 1: + y_true = np.eye(labels)[y_true] + + # Calculate the gradient then normalize + self.dinputs = -y_true / dvalues + self.dinputs = self.dinputs / samples + +class Activation_Softmax_Loss_CategoricalCrossentropy(): + def __init__(self): + self.activation = Activation_Softmax() + self.loss = Loss_CategoricalCrossEntropy() + + def forward(self, inputs, y_true): + self.activation.forward(inputs) + self.output = self.activation.output + return self.loss.calculate(self.output, y_true) + + def backward(self, dvalues, y_true): + samples = len(dvalues) + + # if the samples are one-hot encoded, turn them into discrete values + if len(y_true.shape) == 2: + y_true = np.argmax(y_true, axis=1) + + # Copy so we can safely modify + self.dinputs = dvalues.copy() + + # Calculate and normalize gradient + self.dinputs[range(samples), y_true] -= 1 + self.dinputs = self.dinputs / samples + +class Optimizer_SGD(): + def __init__(self, learning_rate=0.5, decay=0.0, momentum=0.0): + self.initial_rate = learning_rate + self.current_learning_rate = self.initial_rate + self.decay = decay + self.iterations = 0 + self.momentum = momentum + + def pre_update_params(self): + # Update the current_learning_rate before updating params + if self.decay: + self.current_learning_rate = self.initial_rate / (1 + self.decay * self.iterations) + + def update_params(self, layer): + if self.momentum: + # For each layer, we need to use its last momentums + + # First check if the layer has a last momentum stored + if not hasattr(layer, 'weight_momentums'): + layer.weight_momentums = np.zeros_like(layer.weights) + layer.bias_momentums = np.zeros_like(layer.biases) + + weight_updates = self.momentum * layer.weight_momentums - \ + self.current_learning_rate * layer.dweights + layer.weight_momentums = weight_updates + + bias_updates = self.momentum * layer.bias_momentums - \ + self.current_learning_rate * layer.dbiases + layer.bias_momentums = bias_updates + + # Not using momentum + else: + weight_updates = -self.current_learning_rate * layer.dweights + bias_updates = -self.current_learning_rate * layer.dbiases + + layer.weights += weight_updates + layer.biases += bias_updates + + def post_update_params(self): + # Update the self.iterations for use with decay + self.iterations += 1 + +# %% [markdown] +# # Previous Notes and Notation +# The previous notation is clunky and long. From here forward, we will use the following notation for a layer with $n$ inputs and $i$ neurons. The neruon layer has is followed by an activation layer and then fed into a final value $y$ with a computed loss $l$. There can be $j$ batches of data. +# +# $\vec{X_j} = \begin{bmatrix} x_{1j} & x_{2j} & \cdots & x_{nj} \end{bmatrix}$ -> Row vector for the layer inputs for the $j$ batch of data. +# +# $\overline{\overline{W}} = \begin{bmatrix} \vec{w_{1}} \\ \vec{w_{2}} \\ \vdots \\ \vec{w_{i}} \end{bmatrix} = \begin{bmatrix} w_{11} & w_{12} & \cdots & w_{1n} \\ w_{21} & w_{22} & \cdots & w_{2n} \\ \vdots & \vdots & \ddots & \vdots \\ w_{i1} & w_{i2} & \cdots & w_{in}\end{bmatrix}$ -> Matrix of weight values. Each row is a neuron's weights and each column is the weights for a given input. +# +# $\vec{B} = \begin{bmatrix} b_1 & b_2 & \cdots & b_i \end{bmatrix}$ -> Row vector for the neuron biases +# +# $\vec{Z_j} = \begin{bmatrix} z_{1j} & z_{2j} & \cdots & z_{ij} \end{bmatrix}$ -> Row vector for the neuron outputs for the $j$ batch of data. +# +# $\vec{A_j} = \begin{bmatrix} a_{1j} & a_{2j} & \cdots & a_{ij} \end{bmatrix}$ -> Row vector for the activation later outputs for the $j$ batch of data. +# +# $y_j$ -> Final layer output for the $j$ batch of data if the layer is the final layer (could be summation, probability, etc). +# +# $l_j$ -> Loss for the $j$ batch of data. +# +# The $j$ is often dropped because we typically only need to think with 1 set of input data. +# +# ## Gradient Descent Using New Notation +# We will look at the weight that the $i$ neuron applies for the $n$ input. +# +# $\frac{\delta l}{\delta w_{in}} = \frac{\delta l}{\delta y} \frac{\delta y}{\delta a_i} \frac{\delta a_i}{\delta z_i} \frac{\delta z_i}{\delta w_{in}}$ +# +# Similarly, for the bias of the $i$ neuron, there is +# +# $\frac{\delta l}{\delta b_{i}} = \frac{\delta l}{\delta y} \frac{\delta y}{\delta a_i} \frac{\delta a_i}{\delta z_i} \frac{\delta z_i}{\delta b_{i}}$ +# +# For the system we are using, where $l = (y-0)^2$ and the activation layer is ReLU, we have +# +# $\frac{\delta l}{\delta y} = 2y$ +# +# $\frac{\delta y}{\delta a_i} = 1$ +# +# $\frac{\delta a_i}{\delta z_i} = 1$ if $z_i > 0$ else $0$ +# +# $\frac{\delta z_i}{\delta w_{in}} = x_n$ +# +# $\frac{\delta z_i}{\delta b_{i}} = 1$ +# +# ## Matrix Representation of Gradient Descent +# We can simplify by seeing that $\frac{\delta l}{\delta y} \frac{\delta y}{\delta a_i} \frac{\delta a_i}{\delta z_i} = \frac{\delta l}{\delta z_i}$ is a common term. +# +# We take $\frac{\delta l}{\delta z_i}$ and turn it into a 1 x $i$ vector that such that +# +# $\frac{\delta l}{\delta \vec{Z}} = \begin{bmatrix} \frac{\delta l}{\delta z_1} & \frac{\delta l}{\delta z_2} & \cdots & \frac{\delta l}{\delta z_i} \end{bmatrix}$ +# +# We than can get that the gradient matrix for all weights is a $i$ x $n$ matrix given by +# +# $\frac{\delta l}{\delta \overline{\overline{W}}} = \begin{bmatrix} \frac{\delta l}{\delta w_{11}} & \frac{\delta l}{\delta w_{12}} & \cdots & \frac{\delta l}{\delta w_{1n}} \\ \frac{\delta l}{\delta w_{21}} & w\frac{\delta l}{\delta w_{22}} & \cdots & \frac{\delta l}{\delta w_{2n}} \\ \vdots & \vdots & \ddots & \vdots \\ \frac{\delta l}{\delta w_{i1}} & \frac{\delta l}{\delta w_{i2}} & \cdots & \frac{\delta l}{\delta w_{in}} \end{bmatrix} = \begin{bmatrix} \frac{\delta l}{\delta z_1} \\ \frac{\delta l}{\delta z_2} \\ \vdots \\ \frac{\delta l}{\delta z_n} \end{bmatrix} \begin{bmatrix} \frac{\delta z_1}{\delta w_{i1}} & \frac{\delta z_1}{\delta w_{i1}} & \cdots & \frac{\delta z_1}{\delta w_{in}} \end{bmatrix} = \begin{bmatrix} \frac{\delta l}{\delta z_1} \\ \frac{\delta l}{\delta z_2} \\ \vdots \\ \frac{\delta l}{\delta z_n} \end{bmatrix} \begin{bmatrix} x_1 & x_2 & \cdots & x_n \end{bmatrix}$ +# +# Similarly, the gradient vector for the biases is given by +# $\frac{\delta l}{\delta \vec{B}} = \frac{\delta l}{\delta \vec{Z}} \frac{\delta \vec{Z}}{\delta \vec{B}} = \vec{1} \begin{bmatrix} \frac{\delta l}{\delta z_1} & \frac{\delta l}{\delta z_2} & \cdots & \frac{\delta l}{\delta z_i} \end{bmatrix}$ +# +# ## Gradients of the Loss with Respect to Inputs +# When chaining multiple layers together, we will need the partial derivatives of the loss with respect to the next layers input (ie, the output of the current layer). This involves extra summation because the output of 1 layer is fed into every neuron of the next layer, so the total loss must be found. +# +# The gradient of the loss with respect to the $n$ input fed into $i$ neurons is +# +# $\frac{\delta l}{\delta x_n} = \frac{\delta l}{\delta z_1} \frac{\delta z_1}{\delta x_n} + \frac{\delta l}{\delta z_2} \frac{\delta z_2}{\delta x_n} + ... + \frac{\delta l}{\delta z_i} \frac{\delta z_i}{\delta x_n}$ +# +# +# Noting that $\frac{\delta z_i}{\delta x_n} = w_{in}$ allows us to have +# +# $\frac{\delta l}{\delta \vec{X}} = \begin{bmatrix} \frac{\delta l}{\delta x_1} & \frac{\delta l}{\delta x_2} & \cdots & \frac{\delta l}{\delta x_n} \end{bmatrix} = \begin{bmatrix} \frac{\delta l}{\delta z_1} & \frac{\delta l}{\delta z_2} & \cdots & \frac{\delta l}{\delta z_n} \end{bmatrix} \begin{bmatrix} w_{11} & w_{12} & \cdots & w_{1n} \\ w_{21} & w_{22} & \cdots & w_{2n} \\ \vdots & \vdots & \ddots & \vdots \\ w_{i1} & w_{i2} & \cdots & w_{in} \end{bmatrix}$ +# +# ## Note With Layer_Dense class +# The Layer_Dense class has the weights stored in the transposed fashion for forward propagation. Therefore, the weight matrix must be transposed for the backpropagation. + +# %% [markdown] +# # AdaGrad Optimizer +# Different weights should have different learning rates. If one weight affects the loss much more strongly than the other, then consider using smaller learning rates with it. We can do this by maintaining a "cache" of the last gradients and normalizing based on this. +# +# A downside is that as the cache keeps accumulating, some neurons will have such a small learning rate that the neuron basically becomes fixed. + +# %% +class Optimizer_Adagrad(): + def __init__(self, learning_rate=0.5, decay=0.0, epsilon=1e-7): + self.initial_learning_rate = learning_rate + self.current_learning_rate = self.initial_learning_rate + self.decay = decay + self.iterations = 0 + self.epsilon = epsilon + + def pre_update_params(self): + if self.decay: + self.current_learning_rate = self.initial_learning_rate / (1 + self.decay * self.iterations) + + def update_params(self, layer): + if not hasattr(layer, 'weight_cache'): + layer.weight_cache = np.zeros_like(layer.weights) + layer.bias_cache = np.zeros_like(layer.biases) + + layer.weight_cache += layer.dweights**2 + layer.bias_cache += layer.dbiases**2 + + layer.weights += -self.current_learning_rate * layer.dweights / (np.sqrt(layer.weight_cache) + self.epsilon) + layer.biases += -self.current_learning_rate * layer.dbiases / (np.sqrt(layer.bias_cache) + self.epsilon) + + def post_update_params(self): + self.iterations += 1 + +# %% [markdown] +# ## Testing the AdagGrad Optimizer + +# %% +# Create dataset +X, y = spiral_data(samples=100, classes=3) + +# Create Dense layer with 2 input features and 64 output values +dense1 = Layer_Dense(2, 64) + +# Create ReLU activation (to be used with Dense layer) +activation1 = Activation_ReLU() + +# Create second Dense layer with 64 input features (as we take output +# of previous layer here) and 3 output values (output values) +dense2 = Layer_Dense(64, 3) + +# Create Softmax classifier's combined loss and activation +loss_activation = Activation_Softmax_Loss_CategoricalCrossentropy() + +# Create optimizer +optimizer = Optimizer_Adagrad(learning_rate=1.0, decay=1e-4) + +# Train in loop +for epoch in range(10001): + # Perform a forward pass of our training data through this layer + dense1.forward(X) + + # Perform a forward pass through activation function + # takes the output of first dense layer here + activation1.forward(dense1.output) + + # Perform a forward pass through second Dense layer + # takes outputs of activation function of first layer as inputs + dense2.forward(activation1.output) + + # Perform a forward pass through the activation/loss function + # takes the output of second dense layer here and returns loss + loss = loss_activation.forward(dense2.output, y) + + # Calculate accuracy from output of activation2 and targets + # calculate values along first axis + predictions = np.argmax(loss_activation.output, axis=1) + if len(y.shape) == 2: + y = np.argmax(y, axis=1) + accuracy = np.mean(predictions == y) + + if not epoch % 100: + print(f'epoch: {epoch}, ' + + f'acc: {accuracy:.3f}, ' + + f'loss: {loss:.3f}, ' + + f'lr: {optimizer.current_learning_rate}') + + # Backward pass + loss_activation.backward(loss_activation.output, y) + dense2.backward(loss_activation.dinputs) + activation1.backward(dense2.dinputs) + dense1.backward(activation1.dinputs) + + # Update weights and biases + optimizer.pre_update_params() + optimizer.update_params(dense1) + optimizer.update_params(dense2) + optimizer.post_update_params() + + +# %% [markdown] +# # RMSProp Optimizer +# Root Meas Square Propagation optimizer. It is similar to AdaGrad in that you apply different learning rates to different weights. However, the way you change the learning rate focuses more on the most recent cache than the sum of all of the last gradients. +# +# Notably, RMSProp does not use momentum. While it does have information of the past gradient in the cache, it uses this to scale the learning rate, not to correct for overshooting. + +# %% +class Optimizer_RMSProp(): + def __init__(self, learning_rate=1e-3, decay=0.0, epsilon=1e-7, rho=0.9): + self.initial_learning_rate = learning_rate + self.current_learning_rate = self.initial_learning_rate + self.decay = decay + self.iterations = 0 + self.epsilon = epsilon + self.rho = rho + + def pre_update_params(self): + if self.decay: + self.current_learning_rate = self.initial_learning_rate / (1 + self.decay * self.iterations) + + def update_params(self, layer): + if not hasattr(layer, 'weight_cache'): + layer.weight_cache = np.zeros_like(layer.weights) + layer.bias_cache = np.zeros_like(layer.biases) + + layer.weight_cache = self.rho * layer.weight_cache + (1 - self.rho) * layer.dweights**2 + layer.bias_cache = self.rho * layer.bias_cache + (1 - self.rho) * layer.dbiases**2 + + layer.weights += -self.current_learning_rate * layer.dweights / (np.sqrt(layer.weight_cache) + self.epsilon) + layer.biases += -self.current_learning_rate * layer.dbiases / (np.sqrt(layer.bias_cache) + self.epsilon) + + def post_update_params(self): + self.iterations += 1 + +# %% [markdown] +# ## Testing the RMSProp Optimizer + +# %% +# Create dataset +X, y = spiral_data(samples=100, classes=3) + +# Create Dense layer with 2 input features and 64 output values +dense1 = Layer_Dense(2, 64) + +# Create ReLU activation (to be used with Dense layer) +activation1 = Activation_ReLU() + +# Create second Dense layer with 64 input features (as we take output +# of previous layer here) and 3 output values (output values) +dense2 = Layer_Dense(64, 3) + +# Create Softmax classifier's combined loss and activation +loss_activation = Activation_Softmax_Loss_CategoricalCrossentropy() + +# Create optimizer +optimizer = Optimizer_RMSProp(learning_rate=0.02, decay=1e-5, rho=0.999) + +# Train in loop +for epoch in range(10001): + # Perform a forward pass of our training data through this layer + dense1.forward(X) + + # Perform a forward pass through activation function + # takes the output of first dense layer here + activation1.forward(dense1.output) + + # Perform a forward pass through second Dense layer + # takes outputs of activation function of first layer as inputs + dense2.forward(activation1.output) + + # Perform a forward pass through the activation/loss function + # takes the output of second dense layer here and returns loss + loss = loss_activation.forward(dense2.output, y) + + # Calculate accuracy from output of activation2 and targets + # calculate values along first axis + predictions = np.argmax(loss_activation.output, axis=1) + if len(y.shape) == 2: + y = np.argmax(y, axis=1) + accuracy = np.mean(predictions == y) + + if not epoch % 100: + print(f'epoch: {epoch}, ' + + f'acc: {accuracy:.3f}, ' + + f'loss: {loss:.3f}, ' + + f'lr: {optimizer.current_learning_rate}') + + # Backward pass + loss_activation.backward(loss_activation.output, y) + dense2.backward(loss_activation.dinputs) + activation1.backward(dense2.dinputs) + dense1.backward(activation1.dinputs) + + # Update weights and biases + optimizer.pre_update_params() + optimizer.update_params(dense1) + optimizer.update_params(dense2) + optimizer.post_update_params() + + +# %% [markdown] +# # Adam Optimizer +# The Adam optimizer combines adaptive learning rate with momentum. +# +# $W_{i+1} = W_{i} - \frac{\alpha}{\sqrt{\frac{\text{cache}}{1- \beta_2^{i+1}}} + \epsilon} * \left(\beta_{1} * \frac{\text{Momentum}_i}{ 1- \beta_1^{i+1}} + \left(1 - \beta_2 \right) * \frac{\delta L}{\delta W}_i\right)$ +# +# From the equation, it is clear that the cache and momentum are "corrected" by dividing by some scalar that varies with the iteration value. This way, earlier iterations have larger corrected cache and momentum so local minima are harder to get stuck in. + +# %% +import numpy as np + +# Adam optimizer +class Optimizer_Adam(): + def __init__(self, learning_rate=0.001, decay=0.0, epsilon=1e-7, beta_1=0.9, beta_2=0.999): + self.initial_learning_rate = learning_rate + self.current_learning_rate = learning_rate + self.decay = decay + self.iterations = 0 + self.epsilon = epsilon + self.beta_1 = beta_1 + self.beta_2 = beta_2 + + def pre_update_params(self): + if self.decay: + self.current_learning_rate = self.initial_learning_rate * (1. / (1. + self.decay * self.iterations)) + + def update_params(self, layer): + # If layer does not contain cache arrays, create them filled with zeros + if not hasattr(layer, 'weight_cache'): + layer.weight_momentums = np.zeros_like(layer.weights) + layer.weight_cache = np.zeros_like(layer.weights) + layer.bias_momentums = np.zeros_like(layer.biases) + layer.bias_cache = np.zeros_like(layer.biases) + + # Update momentum with current gradients + layer.weight_momentums = self.beta_1 * layer.weight_momentums + (1 - self.beta_1) * layer.dweights + layer.bias_momentums = self.beta_1 * layer.bias_momentums + (1 - self.beta_1) * layer.dbiases + + # Get corrected momentum + # use self.iteration + 1 because we start at iteration 0 + weight_momentums_corrected = layer.weight_momentums / (1 - self.beta_1 ** (self.iterations + 1)) + bias_momentums_corrected = layer.bias_momentums / (1 - self.beta_1 ** (self.iterations + 1)) + + # Update cache with squared current gradients + layer.weight_cache = self.beta_2 * layer.weight_cache + (1 - self.beta_2) * layer.dweights**2 + layer.bias_cache = self.beta_2 * layer.bias_cache + (1 - self.beta_2) * layer.dbiases**2 + + # Get corrected cache + weight_cache_corrected = layer.weight_cache / (1 - self.beta_2 ** (self.iterations + 1)) + bias_cache_corrected = layer.bias_cache / (1 - self.beta_2 ** (self.iterations + 1)) + + # Vanilla SGD parameter update + normalization with square rooted cache + layer.weights += -self.current_learning_rate * weight_momentums_corrected / (np.sqrt(weight_cache_corrected) + self.epsilon) + layer.biases += -self.current_learning_rate * bias_momentums_corrected / (np.sqrt(bias_cache_corrected) + self.epsilon) + + # Call once after any parameter updates + def post_update_params(self): + self.iterations += 1 + + +# %% [markdown] +# ## Testing the Adam Optimizer + +# %% +# Create dataset +X, y = spiral_data(samples=100, classes=3) + +# Create Dense layer with 2 input features and 64 output values +dense1 = Layer_Dense(2, 64) + +# Create ReLU activation (to be used with Dense layer) +activation1 = Activation_ReLU() + +# Create second Dense layer with 64 input features (as we take output +# of previous layer here) and 3 output values (output values) +dense2 = Layer_Dense(64, 3) + +# Create Softmax classifier's combined loss and activation +loss_activation = Activation_Softmax_Loss_CategoricalCrossentropy() + +# Create optimizer +optimizer = Optimizer_Adam(learning_rate=0.02, decay=1e-5) + +# Train in loop +for epoch in range(10001): + # Perform a forward pass of our training data through this layer + dense1.forward(X) + + # Perform a forward pass through activation function + # takes the output of first dense layer here + activation1.forward(dense1.output) + + # Perform a forward pass through second Dense layer + # takes outputs of activation function of first layer as inputs + dense2.forward(activation1.output) + + # Perform a forward pass through the activation/loss function + # takes the output of second dense layer here and returns loss + loss = loss_activation.forward(dense2.output, y) + + # Calculate accuracy from output of activation2 and targets + # calculate values along first axis + predictions = np.argmax(loss_activation.output, axis=1) + if len(y.shape) == 2: + y = np.argmax(y, axis=1) + accuracy = np.mean(predictions == y) + + if not epoch % 100: + print(f'epoch: {epoch}, ' + + f'acc: {accuracy:.3f}, ' + + f'loss: {loss:.3f}, ' + + f'lr: {optimizer.current_learning_rate}') + + # Backward pass + loss_activation.backward(loss_activation.output, y) + dense2.backward(loss_activation.dinputs) + activation1.backward(dense2.dinputs) + dense1.backward(activation1.dinputs) + + # Update weights and biases + optimizer.pre_update_params() + optimizer.update_params(dense1) + optimizer.update_params(dense2) + optimizer.post_update_params() + + +