From d4f2566363b47fecfb20e18f4f95c62f36b4f62a Mon Sep 17 00:00:00 2001 From: judsonupchurch Date: Wed, 1 Jan 2025 23:51:37 +0000 Subject: [PATCH] Gradient of Loss wrt Inputs --- lecture13_17/notes_13.ipynb | 23 ++- lecture13_17/notes_13.pdf | Bin 0 -> 83081 bytes lecture13_17/notes_13.py | 346 ++++++++++++++++++++++++++++++++++++ lecture18/notes_18.ipynb | 180 +++++++++++++++++++ 4 files changed, 544 insertions(+), 5 deletions(-) create mode 100644 lecture13_17/notes_13.pdf create mode 100644 lecture13_17/notes_13.py create mode 100644 lecture18/notes_18.ipynb diff --git a/lecture13_17/notes_13.ipynb b/lecture13_17/notes_13.ipynb index 5422a26..50fef66 100644 --- a/lecture13_17/notes_13.ipynb +++ b/lecture13_17/notes_13.ipynb @@ -537,7 +537,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -630,11 +630,24 @@ ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], - "source": [] + "source": [ + "# Gradients of the Loss with Respect to Inputs\n", + "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.\n", + "\n", + "The gradient of the loss with respect to the $n$ input fed into $i$ neurons is\n", + "\n", + "$\\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}$\n", + "\n", + "\n", + "Noting that $\\frac{\\delta z_i}{\\delta x_n} = w_{in}$ allows us to have\n", + "\n", + "$\\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}$\n", + "\n", + "## Note With Layer_Dense class\n", + "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." + ] } ], "metadata": { diff --git a/lecture13_17/notes_13.pdf b/lecture13_17/notes_13.pdf new file mode 100644 index 0000000000000000000000000000000000000000..97c3a8e222b0db306e3cdd1ee86c77885b76e430 GIT binary patch literal 83081 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

TL1saN47QUt> z9Si0uahzDW=4KTP-x}t~Z)I;k!rF=)ymS@Cn8+bK$xFOfuGuD``e-aONy7tIJ9K3# zB_(6lbcZpDFL@CpcLceW;6#MzTyzRzU!t{ZMjK}r3t}(07N-Gped{&?&Iyy=J(K4I zkVEV3;4i2t2{SNkQd(7n9Hk6^sUg;GM=`|vP`j*vryw}E1VN5jK437XdtAtJii^h5HIWkrMA<&?Ij$AOhT1j|90!UT? znAY40D3;abd7ZMo_uTk^oHCtr{19!t2}CO}K6&(RdKNO7`rQj6sMP-P4mR@{0-+PS zmI;JC-Y7woYs8l1PIfY@F7mPa%ySNO2$$cANI$@3A*(a!ycF2;EJj8R(=93LlY zMg8*Y?r3doqM~L-N0-KS1bXiseQoN?t22Ku1%Jie#k0LtXPE2Rq8mlfz9ku>GqmO+^&}YYW%!{R!o&`;;(I9Y?~%)kHCuAZ>Xc zS}lrI-p!-|W`yROtdS(S52dD70{*06Jr^fTl z6iwD^krtzLbt`Y{e37qhd#QH&>et!*#Ms>$yRH88#gV~Vqt%_J)!e7Nl>o1LgNVf1 zFd9~Z5-pE$1Y%_kfb=Iz7W9S;+6#cXAh~+`tYjM!me!mBe6>^QP6m}p3YCp-`RDD# z+uD+{wKU)XGJ}ZiN{fasVsT(RC7(}y&s1XfYzPi^Wo~Dg81XlPCD%VGv4V`C>g|$Q z>y>VHQ;l=29)8nk8DBnMZzU|pLl^8NJ6T@dY}2OD9+-6+ zop>iVIdpd+N_cv71#sq&qo+C8{SUHQOXhOUOmo4chPNGgRJn)R%?P@#fukjfzmgkP`lGp2C>Gym#LwMcr@ehQ&{JS_pzg}^2_Nl%6h&cjnZ=1x+kZ2piYqpz; z6ZLHeS}BQlQb0Nl!oTlG5ig|bZn{bIyUL6fQ*hm;lvJ)KWIAoiKTjs;I`zX}UhA>3 z?`Wgbu)sfAF*BsL8oCSh8q9AK=sjfxkY=1PHzlFRoFU*v>rkuT`zD(r$y1Qm96K@X)$a?HBT35Qqq_bIe z-K3+^dB$W6wRhft_7o6*5;jE;N<3DYy!o>#KOu9MM^3nD+=|$ E09d*H6aWAK literal 0 HcmV?d00001 diff --git a/lecture13_17/notes_13.py b/lecture13_17/notes_13.py new file mode 100644 index 0000000..0873ed1 --- /dev/null +++ b/lecture13_17/notes_13.py @@ -0,0 +1,346 @@ +# %% [markdown] +# # Previous Class Definitions +# The previously defined Layer_Dense, Activation_ReLU, Activation_Softmax, Loss, and Loss_CategoricalCrossEntropy classes. + +# %% +# 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.output = np.dot(inputs, self.weights) + self.biases # Weights are already transposed + +class Activation_ReLU: + def forward(self, inputs): + self.output = np.maximum(0, inputs) + +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 + +# %% [markdown] +# # Backpropagation of a Single Neuron +# Backpropagation helps us find the gradient of the neural network with respect to each of the parameters (weights and biases) of each neuron. +# +# Imagine a layer that has 3 inputs and 1 neuron. There are 3 inputs (x0, x1, x2), three weights (w0, w1, w2), 1 bias (b0), and 1 output (z). There is a ReLU activation layer after the neuron output going into a square loss function (loss = z^2). +# +# Loss = (ReLU(sum(mul(x0, w0), mul(x1, w1), mul(x2, w2(, b0)))))^2 +# +# $\frac{\delta Loss()}{\delta w0} = \frac{\delta Loss()}{\delta ReLU()} * \frac{\delta ReLU()}{\delta sum()} * \frac{\delta sum()}{\delta mul(x0, w0)} * \frac{\delta mul(x0, w0)}{\delta w0}$ +# +# $\frac{\delta Loss()}{\delta ReLU()} = 2 * ReLU(sum(...))$ +# +# $\frac{\delta ReLU()}{\delta sum()}$ = 0 if sum(...) is less than 0 and 1 if sum(...) is greater than 0 +# +# $\frac{\delta sum()}{\delta mul(x0, w0)} = 1$ +# +# $\frac{\delta mul(x0, w0)}{\delta w0} = x0$ +# +# This is repeated for w0, w1, w2, b0. +# +# We then use numerical differentiation to approximate the gradient. Then, we update the parameters using small step sizes, such that $w0[i+1] = w0[i] - step*\frac{\delta Loss()}{\delta w0}$ +# + +# %% +import numpy as np + +# Initial parameters +weights = np.array([-3.0, -1.0, 2.0]) +bias = 1.0 +inputs = np.array([1.0, -2.0, 3.0]) +target_output = 0.0 +learning_rate = 0.001 + +def relu(x): + return np.maximum(0, x) + +def relu_derivative(x): + return np.where(x > 0, 1.0, 0.0) + +for iteration in range(200): + # Forward pass + linear_output = np.dot(weights, inputs) + bias + output = relu(linear_output) + loss = (output - target_output) ** 2 + + # Backward pass to calculate gradient + dloss_doutput = 2 * (output - target_output) + doutput_dlinear = relu_derivative(linear_output) + dlinear_dweights = inputs + dlinear_dbias = 1.0 + + dloss_dlinear = dloss_doutput * doutput_dlinear + dloss_dweights = dloss_dlinear * dlinear_dweights + dloss_dbias = dloss_dlinear * dlinear_dbias + + # Update weights and bias + weights -= learning_rate * dloss_dweights + bias -= learning_rate * dloss_dbias + + # Print the loss for this iteration + print(f"Iteration {iteration + 1}, Loss: {loss}") + +print("Final weights:", weights) +print("Final bias:", bias) + + +# %% [markdown] +# # Backpropagation of a Layer +# Same thing as a single neuron, but now using matrices to keep track of each neuron in the layer. +# +# If there are multiple input arrays (batches), one can take the summation of the loss from each batch as a total loss, and therefore the gradient of the total loss with respect to a weight or bias is the summation of the gradients of each batch's loss with respect to the weight or bias given that batch's input. +# +# In general, the partial derivative of the loss with respect to a specific weight or bias remains the same across all neurons of that layer for that batch. ie, the weight gradient matrix has the same column vector for N number of neurons. The bias gradient matrix is similar but is a single row of N elements for the same value. + +# %% +import numpy as np + +# Initial inputs +inputs = np.array([1, 2, 3, 4]) + +# Initial weights and biases +weights = np.array([ + [0.1, 0.2, 0.3, 0.4], + [0.5, 0.6, 0.7, 0.8], + [0.9, 1.0, 1.1, 1.2] +]) + +biases = np.array([0.1, 0.2, 0.3]) + +learning_rate = 0.001 + +# Add the derivative function to the ReLU class +class Activation_ReLU: + def forward(self, inputs): + return np.maximum(0, inputs) + + def derivative(self, inputs): + return np.where(inputs > 0, 1, 0) + +relu = Activation_ReLU() + +num_iterations = 200 + +# Training loop +# A single layer of 3 neurons, each with 4 inputs +# The neuron layer is then fed into a ReLU activation layer +for iteration in range(num_iterations): + # Forward pass + neuron_outputs = np.dot(weights, inputs) + biases + relu_outputs = relu.forward(neuron_outputs) + + # Calculate the squared loss assuming the desired output is a sum of 0. Trivial but just an example + final_output = np.sum(relu_outputs) + loss = final_output**2 + + # Backward pass + dL_dfinal_output = 2 * final_output + dfinal_output_drelu_output = np.ones_like(relu_outputs) + drelu_output_dneuron_output = relu.derivative(neuron_outputs) + + dL_dneuron_output = dL_dfinal_output * dfinal_output_drelu_output * drelu_output_dneuron_output + + # Get the gradient of the Loss with respect to the weights and biases + # dL_dW = np.outer(dL_dneuron_output, inputs) + dL_dW = inputs.reshape(-1, 1) @ dL_dneuron_output.reshape(1, -1) + dL_db = dL_dneuron_output + + # Update the weights and biases + # Remove the .T if using dL_dW = np.outer(dL_dneuron_output, inputs) + weights -= learning_rate * dL_dW.T + biases -= learning_rate * dL_db + + # Print the loss every 20 iterations + if iteration % 20 == 0: + print(f"Iteration {iteration}, Loss: {loss}") + +# Final weights and biases +print("Final weights:\n", weights) +print("Final biases:\n", biases) + + +# %% + + +# %% [markdown] +# ## Change of 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}$ +# + +# %% +# Code changed to match new notation +import numpy as np + +# Initial inputs +X = np.array([1, 2, 3, 4]) + +# Initial weights and biases +W = np.array([ + [0.1, 0.2, 0.3, 0.4], + [0.5, 0.6, 0.7, 0.8], + [0.9, 1.0, 1.1, 1.2] +]) + +B = np.array([0.1, 0.2, 0.3]) + +learning_rate = 0.001 + +# Add the derivative function to the ReLU class +class Activation_ReLU: + def forward(self, inputs): + return np.maximum(0, inputs) + + def derivative(self, inputs): + return np.where(inputs > 0, 1, 0) + +relu = Activation_ReLU() + +num_iterations = 200 + +# Training loop +# A single layer of 3 neurons, each with 4 inputs +# The neuron layer is then fed into a ReLU activation layer +for iteration in range(num_iterations): + # Forward pass + Z = np.dot(W, X) + B + A = relu.forward(Z) + + # Calculate the squared loss assuming the desired output is a sum of 0. Trivial but just an example + y = np.sum(A) + l = y**2 + + # Backward pass + dL_dy = 2 * y + dy_dA = np.ones_like(A) + dA_dZ = relu.derivative(Z) + + dl_dZ = dL_dy * dy_dA * dA_dZ + + # Get the gradient of the Loss with respect to the weights and biases + dL_dW = np.outer(X.T, dl_dZ) + dL_dB = dl_dZ + + # Update the weights and biases + W -= learning_rate * dL_dW.T + B -= learning_rate * dL_dB + + # Print the loss every 20 iterations + if iteration % 20 == 0: + print(f"Iteration {iteration}, Loss: {l}") + +# Final weights and biases +print("Final weights:\n", W) +print("Final biases:\n", B) + + +# %% [markdown] +# # 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. + + diff --git a/lecture18/notes_18.ipynb b/lecture18/notes_18.ipynb new file mode 100644 index 0000000..b0ade36 --- /dev/null +++ b/lecture18/notes_18.ipynb @@ -0,0 +1,180 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Previous Class Definitions" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# imports\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import nnfs\n", + "from nnfs.datasets import spiral_data, vertical_data\n", + "nnfs.init()" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "class Layer_Dense:\n", + " def __init__(self, n_inputs, n_neurons):\n", + " # Initialize the weights and biases\n", + " self.weights = 0.01 * np.random.randn(n_inputs, n_neurons) # Normal distribution of weights\n", + " self.biases = np.zeros((1, n_neurons))\n", + "\n", + " def forward(self, inputs):\n", + " # Calculate the output values from inputs, weights, and biases\n", + " self.output = np.dot(inputs, self.weights) + self.biases # Weights are already transposed\n", + "\n", + "class Activation_ReLU:\n", + " def forward(self, inputs):\n", + " self.output = np.maximum(0, inputs)\n", + " \n", + " def derivative(self, inputs):\n", + " return np.where(inputs > 0, 1, 0)\n", + " \n", + "class Activation_Softmax:\n", + " def forward(self, inputs):\n", + " # Get the unnormalized probabilities\n", + " # Subtract max from the row to prevent larger numbers\n", + " exp_values = np.exp(inputs - np.max(inputs, axis=1, keepdims=True))\n", + "\n", + " # Normalize the probabilities with element wise division\n", + " probabilities = exp_values / np.sum(exp_values, axis=1,keepdims=True)\n", + " self.output = probabilities\n", + "\n", + "# Base class for Loss functions\n", + "class Loss:\n", + " '''Calculates the data and regularization losses given\n", + " model output and ground truth values'''\n", + " def calculate(self, output, y):\n", + " sample_losses = self.forward(output, y)\n", + " data_loss = np.average(sample_losses)\n", + " return data_loss\n", + "\n", + "class Loss_CategoricalCrossEntropy(Loss):\n", + " def forward(self, y_pred, y_true):\n", + " '''y_pred is the neural network output\n", + " y_true is the ideal output of the neural network'''\n", + " samples = len(y_pred)\n", + " # Bound the predicted values \n", + " y_pred_clipped = np.clip(y_pred, 1e-7, 1-1e-7)\n", + " \n", + " if len(y_true.shape) == 1: # Categorically labeled\n", + " correct_confidences = y_pred_clipped[range(samples), y_true]\n", + " elif len(y_true.shape) == 2: # One hot encoded\n", + " correct_confidences = np.sum(y_pred_clipped*y_true, axis=1)\n", + "\n", + " # Calculate the losses\n", + " negative_log_likelihoods = -np.log(correct_confidences)\n", + " return negative_log_likelihoods" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Previous Notes and Notation\n", + "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.\n", + "\n", + "$\\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.\n", + "\n", + "$\\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.\n", + "\n", + "$\\vec{B} = \\begin{bmatrix} b_1 & b_2 & \\cdots & b_i \\end{bmatrix}$ -> Row vector for the neuron biases\n", + "\n", + "$\\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.\n", + "\n", + "$\\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.\n", + "\n", + "$y_j$ -> Final layer output for the $j$ batch of data if the layer is the final layer (could be summation, probability, etc).\n", + "\n", + "$l_j$ -> Loss for the $j$ batch of data.\n", + "\n", + "The $j$ is often dropped because we typically only need to think with 1 set of input data.\n", + "\n", + "## Gradient Descent Using New Notation\n", + "We will look at the weight that the $i$ neuron applies for the $n$ input.\n", + "\n", + "$\\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}}$\n", + "\n", + "Similarly, for the bias of the $i$ neuron, there is\n", + "\n", + "$\\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}}$\n", + "\n", + "For the system we are using, where $l = (y-0)^2$ and the activation layer is ReLU, we have\n", + "\n", + "$\\frac{\\delta l}{\\delta y} = 2y$\n", + "\n", + "$\\frac{\\delta y}{\\delta a_i} = 1$\n", + "\n", + "$\\frac{\\delta a_i}{\\delta z_i} = 1$ if $z_i > 0$ else $0$\n", + "\n", + "$\\frac{\\delta z_i}{\\delta w_{in}} = x_n$\n", + "\n", + "$\\frac{\\delta z_i}{\\delta b_{i}} = 1$\n", + "\n", + "## Matrix Representation of Gradient Descent\n", + "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.\n", + "\n", + "We take $\\frac{\\delta l}{\\delta z_i}$ and turn it into a 1 x $i$ vector that such that \n", + "\n", + "$\\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}$\n", + "\n", + "We than can get that the gradient matrix for all weights is a $i$ x $n$ matrix given by \n", + "\n", + "$\\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}$\n", + "\n", + "Similarly, the gradient vector for the biases is given by\n", + "$\\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}$\n", + "\n", + "## Gradients of the Loss with Respect to Inputs\n", + "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.\n", + "\n", + "The gradient of the loss with respect to the $n$ input fed into $i$ neurons is\n", + "\n", + "$\\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}$\n", + "\n", + "\n", + "Noting that $\\frac{\\delta z_i}{\\delta x_n} = w_{in}$ allows us to have\n", + "\n", + "$\\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}$\n", + "\n", + "## Note With Layer_Dense class\n", + "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." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.12" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}