Neural-Networks-From-Scratch/lecture03_06/notes_03.ipynb

610 lines
57 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Layer of Neurons and Batch of Data Using Numpy\n",
"From lecture 1, 1 layer of 3 neurons"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 4.8 1.21 2.385]\n",
" [ 8.9 -1.81 0.2 ]\n",
" [ 1.41 1.051 0.026]]\n"
]
}
],
"source": [
"import numpy as np\n",
"\n",
"inputs = [ # Batch of inputs\n",
" [1.0, 2.0, 3.0, 2.5], \n",
" [2.0, 5.0, -1.0, 2.0], \n",
" [-1.5, 2.7, 3.3, -0.8]\n",
"]\n",
"weights = np.array([\n",
" [0.2, 0.8, -0.5, 1],\n",
" [0.5, -0.91, 0.26, -0.5],\n",
" [-0.26, -0.27, 0.17, 0.87]\n",
"])\n",
"biases = [2.0, 3.0, 0.5]\n",
"\n",
"outputs = np.dot(inputs, weights.T) + biases\n",
"# For every row of inputs, compute the dot of input set and weights\n",
"print(outputs)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 2 Layers and Batch of Data Using Numpy\n",
"2 layers. Layer 1 and layer 2 have 3 neurons. Therefore, there are 3 final outputs.\n",
"\n",
"There are 3 batches of input data to generate 3 total output arrays."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 0.5031 -1.04185 -2.03875]\n",
" [ 0.2434 -2.7332 -5.7633 ]\n",
" [-0.99314 1.41254 -0.35655]]\n"
]
}
],
"source": [
"import numpy as np\n",
"\n",
"inputs = [[1, 2, 3, 2.5],\n",
" [2., 5., -1., 2],\n",
" [-1.5, 2.7, 3.3, -0.8]]\n",
"\n",
"weights = [[0.2, 0.8, -0.5, 1],\n",
" [0.5, -0.91, 0.26, -0.5],\n",
" [-0.26, -0.27, 0.17, 0.87]]\n",
"\n",
"biases = [2, 3, 0.5]\n",
"\n",
"weights2 = [[0.1, -0.14, 0.5],\n",
" [-0.5, 0.12, -0.33],\n",
" [-0.44, 0.73, -0.13]]\n",
"\n",
"biases2 = [-1, 2, -0.5]\n",
"\n",
"# Make the lists np.arrays so we can transpose them\n",
"inputs_array = np.array(inputs)\n",
"weights_array = np.array(weights)\n",
"biases_array = np.array(biases)\n",
"weights2_array = np.array(weights2)\n",
"biases2_array = np.array(biases2)\n",
"\n",
"# Get the output of the first layer\n",
"layer1_outputs = np.dot(inputs_array, weights_array.T) + biases_array\n",
"\n",
"# Feed the output of the first layer into the second layer with their own weights\n",
"layer2_outputs = np.dot(layer1_outputs, weights2_array.T) + biases2_array\n",
"\n",
"print(layer2_outputs)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 4 Layers and Batch of Data Using Numpy\n",
"Cascading neural network with 4 layers. Layer 1 has 4 neurons, layer 2 has 3, layer 3 has 2 and layer 4 has a single output."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[0.47467235]\n",
" [0.7219189 ]\n",
" [0.0541053 ]]\n"
]
}
],
"source": [
"import numpy as np\n",
"\n",
"# Batch of inputs\n",
"inputs = [\n",
" [1, 2, 3, 2.5],\n",
" [2., 5., -1., 2],\n",
" [-1.5, 2.7, 3.3, -0.8]\n",
"]\n",
"\n",
"# Weights are stored in a list of np.array\n",
"# index 0 = layer 1 weights and so on\n",
"weights = [\n",
" np.array([ # Layer 1\n",
" [0.2, 0.8, -0.5, 1], # Neuron 1.1\n",
" [0.5, -0.91, 0.26, -0.5], # Neuron 1.2\n",
" [-0.26, -0.27, 0.17, 0.87], # Neuron 1.3\n",
" [-0.27, 0.87, 0.2, 0.8], # Neuron 1.4\n",
" ]),\n",
" np.array([ # Layer 2\n",
" [0.1, 0.65, -0.24, 1.2], # Neuron 2.1\n",
" [0.51, -0.21, 0.206, -0.05], # Neuron 2.2\n",
" [-0.46, -0.67, 0.14, 0.37], # Neuron 2.3\n",
" ]),\n",
" np.array([ # Layer 3\n",
" [0.25, 0.4, -0.2], # Neuron 3.1\n",
" [0.58, -0.25, 0.26], # Neuron 3.2\n",
" ]),\n",
" np.array([ # Layer 4\n",
" [0.3, 0.1], # Neuron 4.1\n",
" ])\n",
"]\n",
"biases = [\n",
" [0.5, 2, 1, -2], # Layer 1\n",
" [0.2, -0.6, 1.3,], # Layer 2\n",
" [-1, 0.5,], # Layer 3\n",
" [0.28], # Layer 4\n",
"]\n",
"\n",
"# Iterate through each layer, get the output of the layer, use it as the input for the next layer\n",
"layer_inputs = inputs\n",
"layer_outputs = np.array([])\n",
"for layer in range(len(weights)):\n",
" layer_weights = weights[layer]\n",
" layer_biases = biases[layer]\n",
" layer_outputs = np.dot(layer_inputs, layer_weights.T) + layer_biases\n",
" \n",
" # Update the inputs for the next layer based on the outputs of this layer\n",
" layer_inputs = layer_outputs\n",
"# layer_outputs is left holding the final outputs of the network\n",
"\n",
"print(layer_outputs)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Generating Non Linear Training Data\n",
"Generate 2D training data, x and y"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"from nnfs.datasets import spiral_data\n",
"import numpy as np\n",
"import nnfs\n",
"nnfs.init()\n",
"import matplotlib.pyplot as plt\n",
"X, y = spiral_data(samples=100, classes=3)\n",
"plt.scatter(X[:, 0], X[:, 1], c=y, cmap='brg')\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Dense Layer Class\n",
"Given number of neurons and inputs in the layer, predict the output by assigning weights and biases."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 0.0000000e+00 0.0000000e+00 0.0000000e+00]\n",
" [-1.0475188e-04 1.1395361e-04 -4.7983500e-05]\n",
" [-2.7414842e-04 3.1729150e-04 -8.6921798e-05]\n",
" [-4.2188365e-04 5.2666257e-04 -5.5912682e-05]\n",
" [-5.7707680e-04 7.1401405e-04 -8.9430439e-05]]\n"
]
}
],
"source": [
"import numpy as np\n",
"import nnfs\n",
"from nnfs.datasets import spiral_data\n",
"nnfs.init()\n",
"\n",
"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",
"# Create a dataset\n",
"X, y = spiral_data(samples=100, classes=3)\n",
"# Create a dense layer with 2 inputs and 3 output values\n",
"dense1 = Layer_Dense(2, 3)\n",
"# Perform a forward pass of the dataset through the dense layer\n",
"dense1.forward(X)\n",
"\n",
"# Print just the first few outputs\n",
"print(dense1.output[:5])\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Python Array Summation"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"45\n",
"[12 15 18]\n",
"[ 6 15 24]\n",
"[[12 15 18]]\n",
"[[ 6]\n",
" [15]\n",
" [24]]\n"
]
}
],
"source": [
"import numpy as np\n",
"\n",
"A = [\n",
" [1, 2, 3],\n",
" [4, 5, 6],\n",
" [7, 8, 9]\n",
"]\n",
"\n",
"# Sum the elements in the array resulting in a scalar\n",
"print(np.sum(A))\n",
"\n",
"# Sum the rows resulting in a row vector\n",
"'''\n",
" [1, 2, 3]\n",
"+ [4, 5, 6]\n",
"+ [7, 8, 9]\n",
"= [12, 15, 18]\n",
"'''\n",
"print(np.sum(A, axis=0))\n",
"\n",
"# Sum the columns resulting in a column vector\n",
"'''\n",
"1 + 2 + 3 = 6\n",
"4 + 5 + 6 = 15\n",
"7 + 8 + 9 = 24\n",
"'''\n",
"print(np.sum(A, axis=1))\n",
"\n",
"# keepdims will keep the dimension of A\n",
"print(np.sum(A, axis=0, keepdims=True))\n",
"print(np.sum(A, axis=1, keepdims=True))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Python Array Broadcasting Rules\n",
"Check if arrays are broadcastable by scanning right to left for their dimensions. If they share the sime size in that dimension, either of them is size 1, or one size does not exist, continue left.\n",
"\n",
"Given A is 3x3 and B is 3x3, check if it is broadcastable.\n",
"\n",
"3 x 3\n",
"\n",
"3 x 1\n",
"\n",
"Start by comparing 3 and 1. This is fine because B has size 1.\n",
"\n",
"Move to 3 and 3. This is fine because they are equal. The arrays are broadcastable.\n",
"\n",
"Once the arrays are deemed broadcastable, Python will maniupulate one or the other to perform the operation."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 2 3 4]\n",
" [ 6 7 8]\n",
" [10 11 12]]\n",
"[[ 2 3 4]\n",
" [ 6 7 8]\n",
" [10 11 12]]\n",
"[[-2 -1 0]\n",
" [-2 -1 0]\n",
" [-2 -1 0]]\n"
]
}
],
"source": [
"import numpy as np\n",
"\n",
"A = np.array([\n",
" [1, 2, 3],\n",
" [4, 5, 6],\n",
" [7, 8, 9]\n",
"]) # 3 x 3\n",
"\n",
"B = np.array([\n",
" [1],\n",
" [2],\n",
" [3]\n",
"]) # 3 x 1\n",
"\n",
"print(A+B)\n",
"\n",
"# Adding the arrays will broadcast B into a 3x3 in order to add them.\n",
"B_broadcast = np.array([\n",
" [1, 1, 1],\n",
" [2, 2, 2],\n",
" [3, 3, 3]\n",
"]) # 3 x 1\n",
"\n",
"print(A+B_broadcast)\n",
"\n",
"# Example\n",
"# Take each row and subtract the maximum value from the row\n",
"A = np.array([\n",
" [1, 2, 3],\n",
" [4, 5, 6],\n",
" [7, 8, 9]\n",
"]) # 3 x 3\n",
"\n",
"# Gets the max value in each row by comparing columns (axis1). Use keepdims so it is a column vector\n",
"result = A - np.max(A, axis=1, keepdims=True)\n",
"print(result)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Activation Function: ReLU\n",
"Rectified Linear Unit. Only passes through positive values.\n",
"\n",
"y = max(0, x)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"class Activation_ReLU:\n",
" def forward(self, inputs):\n",
" self.output = np.maximum(0, inputs)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[0. 0. 0. ]\n",
" [0. 0.00011395 0. ]\n",
" [0. 0.00031729 0. ]\n",
" [0. 0.00052666 0. ]\n",
" [0. 0.00071401 0. ]]\n"
]
}
],
"source": [
"import numpy as np\n",
"import nnfs\n",
"from nnfs.datasets import spiral_data\n",
"nnfs.init()\n",
"\n",
"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",
"# Create a dataset\n",
"X, y = spiral_data(samples=100, classes=3)\n",
"\n",
"# Create a dense layer with 2 inputs and 3 output values\n",
"dense1 = Layer_Dense(2, 3)\n",
"\n",
"# Create ReLU activation\n",
"activation1 = Activation_ReLU()\n",
"\n",
"# Perform a forward pass of the dataset through the dense layer\n",
"dense1.forward(X)\n",
"\n",
"# Pass the output from the layer through the ReLU activation function\n",
"activation1.forward(dense1.output)\n",
"\n",
"# Print just the first few outputs from ReLU\n",
"print(activation1.output[:5])\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Activation Function: Softmax\n",
"Output falls between (0, 1) and relates the output as a probability.\n",
"\n",
"Given 3 outputs o1, o2, o3, oi = e^{oi} / (e^{o1} + e^{o2} + e^{o3})\n",
"\n",
"Sum of the outputs is 1.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"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\n",
" probabilities = exp_values / np.sum(exp_values, axis=1,keepdims=True)\n",
" self.output = probabilities"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[0.33333334 0.33333334 0.33333334]\n",
" [0.33333316 0.3333332 0.33333364]\n",
" [0.33333287 0.3333329 0.33333418]\n",
" [0.3333326 0.33333263 0.33333477]\n",
" [0.33333233 0.3333324 0.33333528]]\n"
]
}
],
"source": [
"import numpy as np\n",
"import nnfs\n",
"from nnfs.datasets import spiral_data\n",
"nnfs.init()\n",
"\n",
"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",
"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",
"# Create dataset\n",
"X, y = spiral_data(samples=100, classes=3)\n",
"\n",
"dense1 = Layer_Dense(2, 3)\n",
"activation1 = Activation_ReLU()\n",
"dense2 = Layer_Dense(3, 3)\n",
"activation2 = Activation_Softmax()\n",
"\n",
"# Make a forward pass of our training data through this layer\n",
"dense1.forward(X)\n",
"\n",
"# Make a forward pass through activation function\n",
"activation1.forward(dense1.output)\n",
"# Make a forward pass through second Dense layer\n",
"dense2.forward(activation1.output)\n",
"# Make a forward pass through activation function\n",
"activation2.forward(dense2.output)\n",
"# Let's see output of the first few samples:\n",
"print(activation2.output[:5])"
]
}
],
"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
}