From dc2cf45b108e905c15d9fb4e283dd6a89cd4c1f6 Mon Sep 17 00:00:00 2001 From: Gerardo Marx Date: Wed, 26 Mar 2025 13:45:37 -0600 Subject: [PATCH] model ok for lecture --- .gitignore | 1 + Readme.md | 248 ++++++++++++++++++++++ Readme_files/Readme_1_0.png | Bin 0 -> 18811 bytes Readme_files/Readme_5_1.png | Bin 0 -> 21780 bytes main.ipynb | 408 ++++++++++++++++++++++++++++++++++++ 5 files changed, 657 insertions(+) create mode 100644 .gitignore create mode 100644 Readme.md create mode 100644 Readme_files/Readme_1_0.png create mode 100644 Readme_files/Readme_5_1.png create mode 100644 main.ipynb diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..87620ac --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.ipynb_checkpoints/ diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..3493eb3 --- /dev/null +++ b/Readme.md @@ -0,0 +1,248 @@ +```python +#!pip3 install tensorflow +import tensorflow as tf +import numpy as np +import matplotlib.pyplot as plt +``` + + +```python +# data for training the ann mode +# option 1: +celsius = np.array([-40, -10, 0, 8, 15, 22, 38], dtype=float) +fahrenheit = np.array([-40, 14, 32, 46, 59, 72, 100], dtype=float) + +# option 2: (X°C x 9/5) + 32 = 41 °F +points = 100 +np.random.seed(99) +dataIn = np.linspace (-40,60, points) +target = dataIn*9/5 + 32 +4*np.random.randn(points) + +plt.plot(celsius, fahrenheit, 'or', label='data-set 1') +plt.plot(dataIn, target, '.b', alpha=0.3, label='data-set 2') +plt.legend() +plt.grid() +plt.show() +``` + + + +![png](Readme_files/Readme_1_0.png) + + + + +```python +from tensorflow.keras.models import Sequential # ANN type +from tensorflow.keras.layers import Dense, Input # All nodes connected + +# NN definition +hn=2 +model = Sequential() +model.add(Input(shape=(1,), name='input')) +model.add(Dense(hn, activation='linear', name='hidden')) +model.add(Dense(1, activation='linear', name='output')) +model.summary() +``` + + +
Model: "sequential_1"
+
+ + + + +
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
+┃ Layer (type)                     Output Shape                  Param # ┃
+┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
+│ hidden (Dense)                  │ (None, 2)              │             4 │
+├─────────────────────────────────┼────────────────────────┼───────────────┤
+│ output (Dense)                  │ (None, 1)              │             3 │
+└─────────────────────────────────┴────────────────────────┴───────────────┘
+
+ + + + +
 Total params: 7 (28.00 B)
+
+ + + + +
 Trainable params: 7 (28.00 B)
+
+ + + + +
 Non-trainable params: 0 (0.00 B)
+
+ + + + +```python +### veri important note implement a python code +# to show the ANN model connection using ascii +``` + + +```python +from tensorflow.keras.optimizers import Adam + +#hyper parameters +epoch = 500 +lr = 0.01 +hn = 2 # hidden nodes +tf.random.set_seed(42) # For TensorFlow + + +model.compile(optimizer=Adam(lr), loss='mean_squared_error') +print("Starting training ...") +historial = model.fit(dataIn, target, epochs=epoch, verbose=False,) +print("Model trainned!") +``` + + Starting training ... + Model trainned! + + + +```python +predict = model.predict(dataIn) +plt.plot(dataIn, predict, ':r', label='estimated') +plt.plot(dataIn,target, '.b', label='real', alpha=0.4) +plt.legend() +plt.grid() +plt.show() +``` + + 4/4 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step + + + + +![png](Readme_files/Readme_5_1.png) + + + + +```python +# Get weights +for layer in model.layers: + weights = layer.get_weights() + print(f"Layer: {layer.name}") + print(f" Weights (Kernel): {weights[0].shape} \n{weights[0]}") + print(f" Biases: {weights[1].shape} \n{weights[1]}") +``` + + Layer: hidden + Weights (Kernel): (1, 2) + [[-0.27738443 0.7908125 ]] + Biases: (2,) + [-8.219968 6.714554] + Layer: output + Weights (Kernel): (2, 1) + [[-1.9934888] + [ 1.5958738]] + Biases: (1,) + [5.1361823] + + +# Testing the model + + +```python +inTest = np.array([100]) +model.predict(inTest) +``` + + 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 87ms/step + + + + + + array([[213.73816]], dtype=float32) + + + + +```python +# Do the Maths: +inTest = np.array(inTest) +whi = np.array([[-0.27738443, 0.7908125 ]]) +bh = np.array([-8.219968, 6.714554]) +Oh = np.dot(inTest,whi)+bh +who = np.array([[-1.9934888],[ 1.5958738]]) +bo = np.array([5.1361823]) +Oo = np.dot(Oh,who)+bo +Oo +``` + + + + + array([213.73814765]) + + + + +```python +def generate_ascii_ann(model): + ascii_diagram = "\nArtificial Neural Network Architecture:\n" + + for i, layer in enumerate(model.layers): + weights = layer.get_weights() + + # Determine layer type and number of neurons + if isinstance(layer, Dense): + input_dim = weights[0].shape[0] # Number of inputs + output_dim = weights[0].shape[1] # Number of neurons + + ascii_diagram += f"\nLayer {i+1}: {layer.name} ({layer.__class__.__name__})\n" + ascii_diagram += f" Inputs: {input_dim}, Neurons: {output_dim}\n" + ascii_diagram += f" Weights Shape: {weights[0].shape}\n" + + if len(weights) > 1: # If bias exists + ascii_diagram += f" Biases Shape: {weights[1].shape}\n" + + # ASCII representation of neurons + ascii_diagram += " " + " o " * output_dim + " <- Output Neurons\n" + ascii_diagram += " | " * output_dim + "\n" + ascii_diagram += " " + " | " * input_dim + " <- Inputs\n" + + return ascii_diagram + +# Generate and print the ASCII diagram +ascii_ann = generate_ascii_ann(model) +print(ascii_ann) +``` + + + Artificial Neural Network Architecture: + + Layer 1: hidden (Dense) + Inputs: 1, Neurons: 2 + Weights Shape: (1, 2) + Biases Shape: (2,) + o o <- Output Neurons + | | + | <- Inputs + + Layer 2: output (Dense) + Inputs: 2, Neurons: 1 + Weights Shape: (2, 1) + Biases Shape: (1,) + o <- Output Neurons + | + | | <- Inputs + + + +```mermaid +graph LR +I1((I_1)) --> H1((H_1)) & H2((H_1)) +H1 & H2 --> O1((O_1)) & O2((O_2)) +``` diff --git a/Readme_files/Readme_1_0.png b/Readme_files/Readme_1_0.png new file mode 100644 index 0000000000000000000000000000000000000000..e52ea870aacf2000fe7d5c8b711d23666c38dc01 GIT binary patch literal 18811 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 ?=-00o--@tiuoTqhLdd`oi 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 E0Am)4YybcN literal 0 HcmV?d00001 diff --git a/Readme_files/Readme_5_1.png b/Readme_files/Readme_5_1.png new file mode 100644 index 0000000000000000000000000000000000000000..e79a3722a65f4b113dbb9119634953741980d943 GIT binary patch literal 21780 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 p@m*w!" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# data for training the ann mode\n", + "# option 1:\n", + "celsius = np.array([-40, -10, 0, 8, 15, 22, 38], dtype=float)\n", + "fahrenheit = np.array([-40, 14, 32, 46, 59, 72, 100], dtype=float)\n", + "\n", + "# option 2: (X°C x 9/5) + 32 = 41 °F\n", + "points = 100\n", + "np.random.seed(99)\n", + "dataIn = np.linspace (-40,60, points)\n", + "target = dataIn*9/5 + 32 +4*np.random.randn(points)\n", + "\n", + "plt.plot(celsius, fahrenheit, 'or', label='data-set 1')\n", + "plt.plot(dataIn, target, '.b', alpha=0.3, label='data-set 2')\n", + "plt.legend()\n", + "plt.grid()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Model: \"sequential_1\"\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1mModel: \"sequential_1\"\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
+       "┃ Layer (type)                     Output Shape                  Param # ┃\n",
+       "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
+       "│ hidden (Dense)                  │ (None, 2)              │             4 │\n",
+       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
+       "│ output (Dense)                  │ (None, 1)              │             3 │\n",
+       "└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
+       "
\n" + ], + "text/plain": [ + "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n", + "┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n", + "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n", + "│ hidden (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m2\u001b[0m) │ \u001b[38;5;34m4\u001b[0m │\n", + "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", + "│ output (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1\u001b[0m) │ \u001b[38;5;34m3\u001b[0m │\n", + "└─────────────────────────────────┴────────────────────────┴───────────────┘\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
 Total params: 7 (28.00 B)\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m7\u001b[0m (28.00 B)\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
 Trainable params: 7 (28.00 B)\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m7\u001b[0m (28.00 B)\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
 Non-trainable params: 0 (0.00 B)\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from tensorflow.keras.models import Sequential # ANN type\n", + "from tensorflow.keras.layers import Dense, Input # All nodes connected\n", + "\n", + "# NN definition\n", + "hn=2\n", + "model = Sequential()\n", + "model.add(Input(shape=(1,), name='input'))\n", + "model.add(Dense(hn, activation='linear', name='hidden'))\n", + "model.add(Dense(1, activation='linear', name='output'))\n", + "model.summary()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "### veri important note implement a python code \n", + "# to show the ANN model connection using ascii" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting training ...\n", + "Model trainned!\n" + ] + } + ], + "source": [ + "from tensorflow.keras.optimizers import Adam\n", + "\n", + "#hyper parameters\n", + "epoch = 500\n", + "lr = 0.01\n", + "hn = 2 # hidden nodes\n", + "tf.random.set_seed(42) # For TensorFlow\n", + "\n", + "\n", + "model.compile(optimizer=Adam(lr), loss='mean_squared_error')\n", + "print(\"Starting training ...\")\n", + "historial = model.fit(dataIn, target, epochs=epoch, verbose=False,)\n", + "print(\"Model trainned!\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1m4/4\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 4ms/step \n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "predict = model.predict(dataIn)\n", + "plt.plot(dataIn, predict, ':r', label='estimated')\n", + "plt.plot(dataIn,target, '.b', label='real', alpha=0.4)\n", + "plt.legend()\n", + "plt.grid()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Layer: hidden\n", + " Weights (Kernel): (1, 2) \n", + "[[-0.27738443 0.7908125 ]]\n", + " Biases: (2,) \n", + "[-8.219968 6.714554]\n", + "Layer: output\n", + " Weights (Kernel): (2, 1) \n", + "[[-1.9934888]\n", + " [ 1.5958738]]\n", + " Biases: (1,) \n", + "[5.1361823]\n" + ] + } + ], + "source": [ + "# Get weights\n", + "for layer in model.layers:\n", + " weights = layer.get_weights()\n", + " print(f\"Layer: {layer.name}\")\n", + " print(f\" Weights (Kernel): {weights[0].shape} \\n{weights[0]}\")\n", + " print(f\" Biases: {weights[1].shape} \\n{weights[1]}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Testing the model" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 87ms/step\n" + ] + }, + { + "data": { + "text/plain": [ + "array([[213.73816]], dtype=float32)" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "inTest = np.array([100])\n", + "model.predict(inTest)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([213.73814765])" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Do the Maths:\n", + "inTest = np.array(inTest)\n", + "whi = np.array([[-0.27738443, 0.7908125 ]])\n", + "bh = np.array([-8.219968, 6.714554])\n", + "Oh = np.dot(inTest,whi)+bh\n", + "who = np.array([[-1.9934888],[ 1.5958738]])\n", + "bo = np.array([5.1361823])\n", + "Oo = np.dot(Oh,who)+bo\n", + "Oo" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Artificial Neural Network Architecture:\n", + "\n", + "Layer 1: hidden (Dense)\n", + " Inputs: 1, Neurons: 2\n", + " Weights Shape: (1, 2)\n", + " Biases Shape: (2,)\n", + " o o <- Output Neurons\n", + " | | \n", + " | <- Inputs\n", + "\n", + "Layer 2: output (Dense)\n", + " Inputs: 2, Neurons: 1\n", + " Weights Shape: (2, 1)\n", + " Biases Shape: (1,)\n", + " o <- Output Neurons\n", + " | \n", + " | | <- Inputs\n", + "\n" + ] + } + ], + "source": [ + "def generate_ascii_ann(model):\n", + " ascii_diagram = \"\\nArtificial Neural Network Architecture:\\n\"\n", + " \n", + " for i, layer in enumerate(model.layers):\n", + " weights = layer.get_weights()\n", + " \n", + " # Determine layer type and number of neurons\n", + " if isinstance(layer, Dense):\n", + " input_dim = weights[0].shape[0] # Number of inputs\n", + " output_dim = weights[0].shape[1] # Number of neurons\n", + " \n", + " ascii_diagram += f\"\\nLayer {i+1}: {layer.name} ({layer.__class__.__name__})\\n\"\n", + " ascii_diagram += f\" Inputs: {input_dim}, Neurons: {output_dim}\\n\"\n", + " ascii_diagram += f\" Weights Shape: {weights[0].shape}\\n\"\n", + "\n", + " if len(weights) > 1: # If bias exists\n", + " ascii_diagram += f\" Biases Shape: {weights[1].shape}\\n\"\n", + "\n", + " # ASCII representation of neurons\n", + " ascii_diagram += \" \" + \" o \" * output_dim + \" <- Output Neurons\\n\"\n", + " ascii_diagram += \" | \" * output_dim + \"\\n\"\n", + " ascii_diagram += \" \" + \" | \" * input_dim + \" <- Inputs\\n\"\n", + "\n", + " return ascii_diagram\n", + "\n", + "# Generate and print the ASCII diagram\n", + "ascii_ann = generate_ascii_ann(model)\n", + "print(ascii_ann)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```mermaid\n", + "graph LR\n", + "I1((I_1)) --> H1((H_1)) & H2((H_1))\n", + "H1 & H2 --> O1((O_1)) & O2((O_2))\n", + "```" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "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.12.3" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}