{ "nbformat": 4, "nbformat_minor": 0, "metadata": { "colab": { "provenance": [], "toc_visible": true }, "kernelspec": { "name": "python3", "display_name": "Python 3" }, "language_info": { "name": "python" } }, "cells": [ { "cell_type": "markdown", "source": [ "## Source\n", "\n", "- The source code comes from [here](https://www.tensorflow.org/api_docs/python/tf/keras/layers/Attention).\n", "\n", "- More detailed explanation can be read from [here](https://machinelearningmastery.com/the-luong-attention-mechanism/)." ], "metadata": { "id": "Exu3AGMEkCjL" } }, { "cell_type": "markdown", "source": [ "## Data\n", "\n", "The code snippet is responsible for generating synthetic data to train a neural network model. The `batch_size` variable defines how many examples will be processed at once during training, which is set to 32. The `max_sequence_length` is a hyperparameter that specifies the length of the input sequences, and it's set to 10; this value can be adjusted based on the specific requirements of the dataset or the model architecture. `num_samples` is the total number of training examples to be generated, here equal to 1000. Using NumPy's `random.randint` function, two datasets `fake_query_data` and `fake_value_data` are created, each consisting of 1000 samples where each sample is a sequence of 10 integers (representing tokens), and each integer can range from 0 to 999. Similarly, `fake_labels` is created as a binary target variable for each sample, suitable for a binary classification task.\n" ], "metadata": { "id": "0DRCdMW8j3y7" } }, { "cell_type": "code", "source": [ "from tqdm import tqdm" ], "metadata": { "id": "opBhRqAjnUfK" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "# Generate fake data\n", "batch_size = 32\n", "max_sequence_length = 64 # You can set the sequence length to what makes sense for your problem\n", "num_samples = 1000 # Number of samples in fake data\n", "\n", "# Create fake data with the correct dimensions\n", "fake_query_data = np.random.randint(1000, size=(num_samples, max_sequence_length))\n", "fake_value_data = np.random.randint(1000, size=(num_samples, max_sequence_length))\n", "# fake_labels = np.random.randint(2, size=(num_samples, 1))\n", "module_1 = (fake_query_data[:, 0] + fake_query_data[:, 1]) % 2\n", "module_2 = (fake_query_data[:, 2] + fake_query_data[:, 3]) % 2\n", "\n", "fake_labels = []\n", "for i in tqdm(range(num_samples)):\n", " if np.random.randint(0, 2):\n", " fake_labels.append(module_1[i])\n", " else:\n", " fake_labels.append(module_2[i])" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "UMIRmUt8jaVO", "outputId": "8c794a82-3bd4-4b08-f4f8-4e191adf35f4" }, "execution_count": null, "outputs": [ { "output_type": "stream", "name": "stderr", "text": [ "100%|██████████| 1000/1000 [00:00<00:00, 158875.15it/s]\n" ] } ] }, { "cell_type": "code", "source": [ "fake_labels = np.array(fake_labels)\n", "fake_labels[:20]" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "dmgj_GRAm7w_", "outputId": "9c96b323-e0fa-4ec3-85e2-31c926b18d3a" }, "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "array([0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0])" ] }, "metadata": {}, "execution_count": 56 } ] }, { "cell_type": "code", "source": [ "print(fake_query_data.shape)\n", "print(fake_value_data.shape)\n", "print(fake_labels.shape)" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "rZkdP7Fsjh4a", "outputId": "de71e383-0729-40d9-8958-e232c94c78d0" }, "execution_count": null, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "(1000, 64)\n", "(1000, 64)\n", "(1000,)\n" ] } ] }, { "cell_type": "markdown", "source": [ "## Model Architecture Explanation\n", "\n", "The given code defines a neural network model using TensorFlow, particularly with its high-level API, Keras. The model is designed to process sequences of integers, which could represent words or tokens in a natural language processing context.\n", "\n", "First, the code imports the required TensorFlow and NumPy libraries. It then defines two input layers: `query_input` and `value_input`. Both are expected to receive sequences of integers of variable length, as denoted by `shape=(None,)`, and the data type specified is `int32`.\n", "\n", "An embedding layer, `token_embedding`, is then declared, which is capable of mapping each integer in the sequences to a 64-dimensional vector space. The input dimension is set to 1000, meaning the layer can handle 1000 unique tokens. The `query_embeddings` and `value_embeddings` are generated by passing `query_input` and `value_input` through this embedding layer, effectively converting the token sequences into dense vectors that capture semantic information.\n", "\n", "Following the embeddings, a 1D convolutional neural network (CNN) layer is applied to both sets of embeddings. This `cnn_layer` uses 100 filters and a kernel size of 4, with 'same' padding to ensure the output length is equal to the input length. The result of this operation is two sets of encoded sequences, `query_seq_encoding` and `value_seq_encoding`.\n", "\n", "The code then employs an attention mechanism, specifically using the `Attention` layer, to compare the query and value encodings and generate a sequence that represents the weighted importance of the values with respect to the query.\n", "\n", "Global average pooling is applied to both the query encoding and the combined query-value attention sequence. This operation reduces the sequence dimension, averaging out the features across the time steps, resulting in two fixed-size vectors.\n", "\n", "These vectors are then concatenated to form a single input layer, `input_layer`, which serves as the combined representation of both the query and value information.\n", "\n", "Next, the code defines a dense neural network layer with 64 units and a ReLU activation function to introduce non-linearity into the model. This is followed by the output layer, which is a single neuron with a sigmoid activation function, indicating the model is designed for binary classification.\n", "\n", "Finally, the `model` is constructed by specifying the inputs and output layer. This model can now be compiled and trained on suitable data for tasks such as document retrieval, question answering, or any other scenario where the relationship between two sequences needs to be modeled.\n" ], "metadata": { "id": "wXVBH7hxkeKT" } }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "DO_DwbcijQij" }, "outputs": [], "source": [ "import tensorflow as tf\n", "import numpy as np\n", "\n", "# Define the inputs\n", "query_input = tf.keras.Input(shape=(None,), dtype='int32')\n", "value_input = tf.keras.Input(shape=(None,), dtype='int32')\n", "\n", "# Embedding lookup\n", "token_embedding = tf.keras.layers.Embedding(input_dim=1000, output_dim=64)\n", "# Query and value embeddings\n", "query_embeddings = token_embedding(query_input)\n", "value_embeddings = token_embedding(value_input)\n", "\n", "# CNN layer\n", "cnn_layer = tf.keras.layers.Conv1D(filters=100, kernel_size=4, padding='same')\n", "# Encoded sequences\n", "query_seq_encoding = cnn_layer(query_embeddings)\n", "value_seq_encoding = cnn_layer(value_embeddings)\n", "\n", "# Attention layer\n", "query_value_attention_seq = tf.keras.layers.Attention()([query_seq_encoding, value_seq_encoding])\n", "\n", "# Global Average Pooling\n", "query_encoding = tf.keras.layers.GlobalAveragePooling1D()(query_seq_encoding)\n", "query_value_attention = tf.keras.layers.GlobalAveragePooling1D()(query_value_attention_seq)\n", "\n", "# Concatenate layer\n", "input_layer = tf.keras.layers.Concatenate()([query_encoding, query_value_attention])\n", "\n", "# Add DNN layers\n", "dense_layer = tf.keras.layers.Dense(64, activation='relu')(input_layer)\n", "output_layer = tf.keras.layers.Dense(1, activation='sigmoid')(dense_layer)\n", "\n", "# Create the model\n", "model = tf.keras.Model(inputs=[query_input, value_input], outputs=output_layer)" ] }, { "cell_type": "code", "source": [ "tf.keras.utils.plot_model(model)" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 607 }, "id": "SqMVuadensV9", "outputId": "6baa0d27-4465-47cc-d48d-e182a96400f1" }, "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "image/png": "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AsBwUXwBg1DI4hsVFTVhwoT79+8nJyc3b968YsWK+uO9evXS97PnPhw1apRWq42Ojn7w4MHo0aONjIwOHDggSdKYMWOEENu2bUtJSblz507r1q0tLCyysrKeHSEpKSl/aRs/frxGo/n9998fPnx47NixJk2avPHGG7du3Sp4zBe5dOmSEKJRo0be3t4ODg5ardbd3X3WrFm5ubkFz0aRiu+VK1fs7e2zs7MlSfr999+FEE9V7TI9h3pKLr6SJO3ataty5cr169e/cOGC3FkAGCiWOgBliZ+f31dffWVra2tnZ+fr65ucnHz37t2C3/L48eOIiIgePXr06tXLxsZm7NixJiYmCxcuzHuBl5eXlZWVvb19UFBQenr61atXCx4wMzPzhx9+6NmzZ79+/aytrevXr//zzz/fu3dv7ty5rzam/kNs9vb2U6ZMSUxMvH37dvfu3T/55JNly5a9fEYKbdmyZe+++66xsbEQwtfXV6vVRkVFZWZmFua9hj+HEEK0bt364MGDpqamnp6emzdvljsOAENE8QXKKhMTEyFETk5OwS87c+ZMRkZG3gfFzMzMHBwcTp8+/ewr9b+a1+l0BQ+YmJiYlpbm4eGRd8TT01Oj0SQkJLzamFqtVghRt25dLy8vOzs7a2vriRMnWltb52+Br2/ZsmU9e/bU/28rK6uOHTumpqYW8hNRhj+H0HN0dNy1a5evr2+XLl2mTZsmsZMGgP9F8QXKkj///NPb29ve3l6r1X755ZeFeUt6eroQYuzYsar/uHLlSkZGxitnePjwoRDC0tIy/0EbG5tHjx692oBVqlQRQty7dy/viEajcXFxuXDhwiuHfMqJEyeOHz/erVu3vEnQ76f77N4Oz2X4c4g8pqamCxcujIiIGDduXJ8+fV7n/yYA5Q/FFygzrl692qNHDwcHh4SEhJSUlGnTphXmXfb29kKI8PDw/Iuc4uLiXjmGjY2NEOKpivbw4UNHR8dXG9DS0rJGjRonT57MfzA7O9va2vqVQz5l6dKlvXv3zj8D9+/fNzMz27x5861bt176dsOfQzxlyJAhW7Zs2b59u5eXl34ROQAIii9Qhhw/flyn03388ceurq6mpqYqlaow79JvRPD3338XV4x69epZWloePHgw70hCQkJWVtZbb731ymMGBgYeOXLk4sWL+ocZGRlXrlwprt3NJElasWLF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\n", "text/plain": [ "" ] }, "metadata": {}, "execution_count": 61 } ] }, { "cell_type": "markdown", "source": [ "### Model Compilation Explanation\n", "\n", "The code snippet is a crucial step in preparing the neural network model for training. The `compile` method is used to configure the model with the necessary settings for the training process.\n", "\n", "The `optimizer` parameter is set to 'adam', which refers to the Adam optimization algorithm. Adam is an adaptive learning rate optimization algorithm designed to handle sparse gradients on noisy problems. It's a popular choice due to its efficiency and minimal memory requirement.\n", "\n", "The `loss` parameter is set to 'binary_crossentropy', which is the loss function used for binary classification problems. Crossentropy loss measures the performance of a classification model whose output is a probability value between 0 and 1. Binary crossentropy loss is used when there are only two label classes (labels are supposed to be 0 and 1).\n", "\n", "Lastly, the `metrics` parameter includes 'accuracy' as a metric to be evaluated by the model during training and testing. Accuracy calculates how often predictions equal labels, providing a measure of how many instances were correctly classified.\n", "\n", "By compiling the model with these parameters, we are essentially setting up the model for the backpropagation process: the optimizer will minimize the loss function, improving the model's accuracy over iterations of training." ], "metadata": { "id": "jG9T9W98koQb" } }, { "cell_type": "code", "source": [ "# Compile the model\n", "model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])" ], "metadata": { "id": "u6H_Fuo7jY4L" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "source": [ "### Model Training Explanation\n", "\n", "The code snippet provided is used to train the neural network model with synthetic data. The `fit` method of the `model` object is used to feed the data into the model and to perform the training process.\n", "\n", "- The first argument to `model.fit` is a list containing `fake_query_data` and `fake_value_data`, which are the input features for the model. These should be numpy arrays or tensors containing the input data. In this context, it appears that these arrays represent encoded sequences of data that the model will learn from.\n", "\n", "- The second argument, `fake_labels`, represents the target outputs that the model should learn to predict. These labels are associated with the input data and in binary classification tasks, such as the one implied by the preceding code, they would typically consist of 0s and 1s indicating the class of each sample.\n", "\n", "- `batch_size=batch_size` tells the `fit` method how many samples to process before updating the model's weights. `batch_size` is a hyperparameter that defines the number of samples to work through before updating the internal model parameters. Here, it is set to the variable `batch_size` which was defined earlier in the code (not shown in this snippet but typically would be an integer value).\n", "\n", "- `epochs=10` specifies the number of epochs to run the training for, which is the number of complete passes through the entire training dataset. An epoch is one complete presentation of the data set to be learned to a learning machine. Running for 10 epochs means that the entire dataset will be passed through the neural network a total of 10 times.\n", "\n", "By executing this `fit` method, the model will start the training process, adjusting its weights on the synthetic data for 10 iterations over the dataset, optimizing the loss function specified during the compilation step, and trying to improve the accuracy metric that was also set previously." ], "metadata": { "id": "_ocYyJQclAkl" } }, { "cell_type": "code", "source": [ "# Fit the model with fake data\n", "model.fit(\n", " [fake_query_data, fake_value_data],\n", " fake_labels,\n", " batch_size=batch_size,\n", " epochs=10)" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "G7W5L67GjcJG", "outputId": "bd05899d-0dd3-47c9-f38b-30333d7bbd36" }, "execution_count": null, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Epoch 1/10\n", "32/32 [==============================] - 1s 17ms/step - loss: 0.6938 - accuracy: 0.4830\n", "Epoch 2/10\n", "32/32 [==============================] - 1s 17ms/step - loss: 0.6853 - accuracy: 0.6190\n", "Epoch 3/10\n", "32/32 [==============================] - 1s 28ms/step - loss: 0.5792 - accuracy: 0.7670\n", "Epoch 4/10\n", "32/32 [==============================] - 1s 24ms/step - loss: 0.3071 - accuracy: 0.9020\n", "Epoch 5/10\n", "32/32 [==============================] - 1s 21ms/step - loss: 0.1207 - accuracy: 0.9710\n", "Epoch 6/10\n", "32/32 [==============================] - 1s 32ms/step - loss: 0.0593 - accuracy: 0.9900\n", "Epoch 7/10\n", "32/32 [==============================] - 1s 24ms/step - loss: 0.0207 - accuracy: 0.9980\n", "Epoch 8/10\n", "32/32 [==============================] - 1s 25ms/step - loss: 0.0079 - accuracy: 1.0000\n", "Epoch 9/10\n", "32/32 [==============================] - 1s 31ms/step - loss: 0.0034 - accuracy: 1.0000\n", "Epoch 10/10\n", "32/32 [==============================] - 1s 17ms/step - loss: 0.0021 - accuracy: 1.0000\n" ] }, { "output_type": "execute_result", "data": { "text/plain": [ "" ] }, "metadata": {}, "execution_count": 60 } ] }, { "cell_type": "code", "source": [], "metadata": { "id": "WDsYAb1_jff8" }, "execution_count": null, "outputs": [] } ] }