{ "cells": [ { "cell_type": "markdown", "id": "ad2a9efe-ddf9-40b1-acdc-459a42d0d4c7", "metadata": {}, "source": [ "# PHASE 1: EXPLAIN & BREAKDOWN (LEARNING PHASE)\n", "\n", "## 1. Simple Explanation of Attention Mechanisms\n", "\n", "Attention mechanisms are a way for neural networks to focus on the most relevant parts of input data when making predictions. Think of it like reading a paragraph and highlighting the most important words that help you understand the meaning. Instead of processing all information equally, attention allows the model to assign different importance weights to different parts of the input. For example, when translating \"The cat sat on the mat\" to French, the model might pay more attention to \"cat\" when generating \"chat\" and to \"mat\" when generating \"tapis.\" This selective focus dramatically improves performance in tasks like machine translation, text summarization, and image captioning by helping models understand relationships between different parts of the input.\n", "\n", "## 2. Detailed Roadmap to Master Attention Mechanisms\n", "\n", "**Step 1: Foundation Concepts**\n", "- Understanding sequence-to-sequence models and their limitations\n", "- The alignment problem in neural machine translation\n", "- Basic concept of \"paying attention\" to relevant information\n", "\n", "**Step 2: Core Attention Components**\n", "- Query, Key, and Value vectors\n", "- Attention scores and attention weights\n", "- Softmax normalization for probability distribution\n", "\n", "**Step 3: Attention Variants**\n", "- Additive (Bahdanau) attention\n", "- Multiplicative (Luong) attention\n", "- Scaled dot-product attention\n", "\n", "**Step 4: Self-Attention**\n", "- Difference between cross-attention and self-attention\n", "- Multi-head attention mechanisms\n", "- Position encodings and their importance\n", "\n", "**Step 5: Advanced Applications**\n", "- Transformer architecture\n", "- BERT and GPT models\n", "- Vision transformers for image processing\n", "\n", "**Step 6: Implementation Practice**\n", "- Building attention from scratch\n", "- Using attention in real projects\n", "- Debugging attention visualizations\n", "\n", "## 3. Key Formulas with Detailed Explanations\n", "\n", "**Basic Attention Score:**\n", "$$e_{ij} = a(s_{i-1}, h_j)$$\n", "- $e_{ij}$: Raw attention score between decoder state $i$ and encoder state $j$\n", "- $s_{i-1}$: Previous decoder hidden state\n", "- $h_j$: Encoder hidden state at position $j$\n", "- $a()$: Alignment function (neural network)\n", "\n", "**Attention Weights (Softmax Normalization):**\n", "$$\\alpha_{ij} = \\frac{\\exp(e_{ij})}{\\sum_{k=1}^{T_x} \\exp(e_{ik})}$$\n", "- $\\alpha_{ij}$: Normalized attention weight (probability)\n", "- $T_x$: Length of input sequence\n", "- Ensures all weights sum to 1\n", "\n", "**Context Vector:**\n", "$$c_i = \\sum_{j=1}^{T_x} \\alpha_{ij} h_j$$\n", "- $c_i$: Context vector for decoder step $i$\n", "- Weighted sum of all encoder hidden states\n", "- Captures relevant information from entire input sequence\n", "\n", "**Scaled Dot-Product Attention:**\n", "$$\\text{Attention}(Q, K, V) = \\text{softmax}\\left(\\frac{QK^T}{\\sqrt{d_k}}\\right)V$$\n", "- $Q$: Query matrix (what we're looking for)\n", "- $K$: Key matrix (what we're comparing against)\n", "- $V$: Value matrix (actual information to retrieve)\n", "- $d_k$: Dimension of key vectors (for scaling)\n", "- $\\sqrt{d_k}$: Scaling factor to prevent vanishing gradients\n", "\n", "## 4. Step-by-Step Numerical Example\n", "\n", "Let's work through a simple attention calculation with concrete numbers:\n", "\n", "**Given:**\n", "- Query: $Q = [1, 2]$\n", "- Keys: $K = [[1, 0], [0, 1], [1, 1]]$\n", "- Values: $V = [[0.5, 0.3], [0.8, 0.2], [0.1, 0.9]]$\n", "- $d_k = 2$ (dimension of keys)\n", "\n", "**Step 1: Calculate Raw Scores**\n", "$QK^T = [1, 2] \\times [[1, 0, 1], [0, 1, 1]] = [1 \\times 1 + 2 \\times 0, 1 \\times 0 + 2 \\times 1, 1 \\times 1 + 2 \\times 1] = [1, 2, 3]$\n", "\n", "**Step 2: Scale by $\\sqrt{d_k}$**\n", "$\\text{Scaled scores} = \\frac{[1, 2, 3]}{\\sqrt{2}} = [0.707, 1.414, 2.121]$\n", "\n", "**Step 3: Apply Softmax**\n", "$\\text{Attention weights} = \\text{softmax}([0.707, 1.414, 2.121])$\n", "- $\\exp(0.707) = 2.028$\n", "- $\\exp(1.414) = 4.110$\n", "- $\\exp(2.121) = 8.340$\n", "- Sum = 14.478\n", "- Weights = $[0.140, 0.284, 0.576]$\n", "\n", "**Step 4: Weighted Sum of Values**\n", "$\\text{Output} = 0.140 \\times [0.5, 0.3] + 0.284 \\times [0.8, 0.2] + 0.576 \\times [0.1, 0.9]$\n", "$= [0.070, 0.042] + [0.227, 0.057] + [0.058, 0.518] = [0.355, 0.617]$\n", "\n", "## 5. Complete Background Calculation Example\n", "\n", "Let me walk you through a complete real-world example of attention in neural machine translation:\n", "\n", "**Scenario:** Translating \"I love cats\" to Spanish \"Yo amo gatos\"\n", "\n", "**Step 1: Input Representation**\n", "- English words: [\"I\", \"love\", \"cats\"]\n", "- Encoder hidden states (simplified 2D vectors):\n", " - $h_1 = [0.8, 0.3]$ (for \"I\")\n", " - $h_2 = [0.4, 0.9]$ (for \"love\")\n", " - $h_3 = [0.6, 0.7]$ (for \"cats\")\n", "\n", "**Step 2: Decoder State**\n", "- We're generating the Spanish word \"amo\" (love)\n", "- Current decoder state: $s_1 = [0.5, 0.8]$\n", "\n", "**Step 3: Calculate Attention Scores**\n", "Using dot product attention (simplified):\n", "- $e_{11} = s_1 \\cdot h_1 = [0.5, 0.8] \\cdot [0.8, 0.3] = 0.5 \\times 0.8 + 0.8 \\times 0.3 = 0.4 + 0.24 = 0.64$\n", "- $e_{12} = s_1 \\cdot h_2 = [0.5, 0.8] \\cdot [0.4, 0.9] = 0.5 \\times 0.4 + 0.8 \\times 0.9 = 0.2 + 0.72 = 0.92$\n", "- $e_{13} = s_1 \\cdot h_3 = [0.5, 0.8] \\cdot [0.6, 0.7] = 0.5 \\times 0.6 + 0.8 \\times 0.7 = 0.3 + 0.56 = 0.86$\n", "\n", "**Step 4: Apply Softmax to Get Attention Weights**\n", "Raw scores: $[0.64, 0.92, 0.86]$\n", "- $\\exp(0.64) = 1.896$\n", "- $\\exp(0.92) = 2.509$\n", "- $\\exp(0.86) = 2.363$\n", "- Sum = $1.896 + 2.509 + 2.363 = 6.768$\n", "\n", "Attention weights:\n", "- $\\alpha_{11} = \\frac{1.896}{6.768} = 0.280$ (attention to \"I\")\n", "- $\\alpha_{12} = \\frac{2.509}{6.768} = 0.371$ (attention to \"love\")\n", "- $\\alpha_{13} = \\frac{2.363}{6.768} = 0.349$ (attention to \"cats\")\n", "\n", "**Step 5: Calculate Context Vector**\n", "$c_1 = \\alpha_{11} \\times h_1 + \\alpha_{12} \\times h_2 + \\alpha_{13} \\times h_3$\n", "$c_1 = 0.280 \\times [0.8, 0.3] + 0.371 \\times [0.4, 0.9] + 0.349 \\times [0.6, 0.7]$\n", "$c_1 = [0.224, 0.084] + [0.148, 0.334] + [0.209, 0.244]$\n", "$c_1 = [0.581, 0.662]$\n", "\n", "**Step 6: Interpretation**\n", "- The model pays highest attention (0.371) to \"love\" when generating \"amo\"\n", "- This makes sense because \"amo\" is the Spanish translation of \"love\"\n", "- The attention weights show the model correctly learned the alignment between source and target words\n", "\n", "**Why This Works:**\n", "- The context vector $c_1 = [0.581, 0.662]$ contains information from all input words, but weighted most heavily toward \"love\"\n", "- This context vector is then used alongside the decoder state to generate the next Spanish word\n", "- The attention mechanism solved the \"bottleneck\" problem where all information had to be compressed into a single vector\n", "\n", "## 6. Real-World AI Use Case\n", "\n", "**Google Translate with Attention:**\n", "When translating \"The quick brown fox jumps over the lazy dog\" to Spanish, attention mechanisms help the model focus on the right words at each step:\n", "\n", "- When generating \"El\" (The), attention focuses on \"The\"\n", "- When generating \"zorro\" (fox), attention focuses on \"fox\" and \"brown\" \n", "- When generating \"salta\" (jumps), attention focuses on \"jumps\" and \"over\"\n", "- When generating \"perezoso\" (lazy), attention focuses on \"lazy\" and \"dog\"\n", "\n", "This allows the model to handle word reordering and long-distance dependencies that occur in translation. Without attention, the model would struggle with longer sentences as it tries to compress all information into a single context vector.\n", "\n", "## 7. Tips for Mastering Attention Mechanisms\n", "\n", "**Practice Sources:**\n", "- Implement attention from scratch using NumPy first\n", "- Use PyTorch tutorials on attention and transformers\n", "- Work through the \"Attention Is All You Need\" paper step-by-step\n", "- Practice on sequence-to-sequence tasks like machine translation\n", "\n", "**Recommended Resources:**\n", "- \"Deep Learning\" by Ian Goodfellow (Chapter 12)\n", "- \"Natural Language Processing with PyTorch\" by Delip Rao\n", "- Stanford CS224N lecture notes on attention\n", "- The Illustrated Transformer blog post by Jay Alammar\n", "\n", "**Key Problems to Practice:**\n", "- Implement basic attention for neural machine translation\n", "- Build multi-head attention from scratch\n", "- Create attention visualizations to understand what the model learns\n", "- Fine-tune pre-trained transformer models (BERT, GPT)\n", "- Experiment with different attention variants (additive vs multiplicative)\n", "\n", "**Mathematical Prerequisites to Review:**\n", "- Matrix multiplication and transpose operations\n", "- Softmax function and its properties\n", "- Gradient computation for backpropagation\n", "- Basic probability and normalization concepts\n", "\n", "Ready to move to Phase 2? Just say \"Understood\" and I'll provide the complete Python implementation with logging!" ] }, { "cell_type": "code", "execution_count": 2, "id": "5bb50813-2c17-4391-ba09-1062c0002563", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Collecting seaborn\n", " Downloading seaborn-0.13.2-py3-none-any.whl.metadata (5.4 kB)\n", "Requirement already satisfied: numpy!=1.24.0,>=1.20 in /Users/karthik/Desktop/importants/venv/lib/python3.13/site-packages (from seaborn) (2.3.1)\n", "Requirement already satisfied: pandas>=1.2 in /Users/karthik/Desktop/importants/venv/lib/python3.13/site-packages (from seaborn) (2.3.1)\n", "Requirement already satisfied: matplotlib!=3.6.1,>=3.4 in /Users/karthik/Desktop/importants/venv/lib/python3.13/site-packages (from seaborn) (3.10.3)\n", "Requirement already satisfied: contourpy>=1.0.1 in /Users/karthik/Desktop/importants/venv/lib/python3.13/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (1.3.2)\n", "Requirement already satisfied: cycler>=0.10 in /Users/karthik/Desktop/importants/venv/lib/python3.13/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (0.12.1)\n", "Requirement already satisfied: fonttools>=4.22.0 in /Users/karthik/Desktop/importants/venv/lib/python3.13/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (4.58.5)\n", "Requirement already satisfied: kiwisolver>=1.3.1 in /Users/karthik/Desktop/importants/venv/lib/python3.13/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (1.4.8)\n", "Requirement already satisfied: packaging>=20.0 in /Users/karthik/Desktop/importants/venv/lib/python3.13/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (25.0)\n", "Requirement already satisfied: pillow>=8 in /Users/karthik/Desktop/importants/venv/lib/python3.13/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (11.3.0)\n", "Requirement already satisfied: pyparsing>=2.3.1 in /Users/karthik/Desktop/importants/venv/lib/python3.13/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (3.2.3)\n", "Requirement already satisfied: python-dateutil>=2.7 in /Users/karthik/Desktop/importants/venv/lib/python3.13/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (2.9.0.post0)\n", "Requirement already satisfied: pytz>=2020.1 in /Users/karthik/Desktop/importants/venv/lib/python3.13/site-packages (from pandas>=1.2->seaborn) (2025.2)\n", "Requirement already satisfied: tzdata>=2022.7 in /Users/karthik/Desktop/importants/venv/lib/python3.13/site-packages (from pandas>=1.2->seaborn) (2025.2)\n", "Requirement already satisfied: six>=1.5 in /Users/karthik/Desktop/importants/venv/lib/python3.13/site-packages (from python-dateutil>=2.7->matplotlib!=3.6.1,>=3.4->seaborn) (1.17.0)\n", "Downloading seaborn-0.13.2-py3-none-any.whl (294 kB)\n", "Installing collected packages: seaborn\n", "Successfully installed seaborn-0.13.2\n", "Note: you may need to restart the kernel to use updated packages.\n" ] } ], "source": [ "pip install seaborn" ] }, { "cell_type": "code", "execution_count": 4, "id": "f259185a-f28a-4f1b-884e-c6f259718b33", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using device: mps\n", "🚀 Starting Attention Mechanism Implementation...\n", "Loading and preprocessing Iris dataset...\n", "Original dataset shape: X=(150, 4), y=(150,)\n", "Class distribution: [50 50 50]\n", "Train set: (90, 4), Val set: (30, 4), Test set: (30, 4)\n", "Creating sequence dataset with seq_len=10\n", "Original data shape: X=(90, 4), y=(90,)\n", "✓ Created sequence dataset shape: (90, 10, 4)\n", "Creating sequence dataset with seq_len=10\n", "Original data shape: X=(30, 4), y=(30,)\n", "✓ Created sequence dataset shape: (30, 10, 4)\n", "Creating sequence dataset with seq_len=10\n", "Original data shape: X=(30, 4), y=(30,)\n", "✓ Created sequence dataset shape: (30, 10, 4)\n", "✓ DataLoaders created successfully\n", "✓ PositionalEncoding initialized: d_model=64, max_len=128\n", "✓ MultiHeadAttention initialized: d_model=64, n_heads=4, d_k=16\n", "✓ TransformerBlock initialized: d_model=64, n_heads=4, d_ff=256\n", "✓ MultiHeadAttention initialized: d_model=64, n_heads=4, d_k=16\n", "✓ TransformerBlock initialized: d_model=64, n_heads=4, d_ff=256\n", "✓ AttentionClassifier initialized: input_dim=4, d_model=64, n_heads=4, n_layers=2, n_classes=3\n", "✓ Model created with 102,467 trainable parameters\n", "Starting training for 50 epochs...\n", "First batch shapes - data: torch.Size([16, 10, 4]), target: torch.Size([16])\n", "Epoch [10/50] - Train Loss: 0.0519, Train Acc: 98.89% - Val Loss: 0.0735, Val Acc: 96.67%\n", "Epoch [20/50] - Train Loss: 0.0368, Train Acc: 98.89% - Val Loss: 0.1678, Val Acc: 93.33%\n", "Early stopping at epoch 22\n", "✓ Training completed! Best validation accuracy: 100.00%\n", "✓ Best model weights loaded\n", "Evaluating model on test set...\n", "✓ Test Accuracy: 0.9333\n", "Testing sample predictions...\n", "\n", "Sample Predictions:\n", "Sample 1: True=versicolor, Pred=versicolor, Conf=0.9417\n", "Sample 2: True=setosa, Pred=setosa, Conf=0.9827\n", "Sample 3: True=versicolor, Pred=versicolor, Conf=0.9270\n", "Creating visualizations...\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAABcEAAAHqCAYAAADMCYafAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAA9IBJREFUeJzs3Qd8U2X7xvEr3RQoe++N7KEiispSBFTAPf7uvbevuHCjuHiduNfrXjhQFBHEgYggW/besy2zhbb/z/2kKS100rQZ/X39HJOepMmTtPTk3Oc+1+PJyMjIEAAAAAAAAAAAYSgi0AMAAAAAAAAAAKCkUAQHAAAAAAAAAIQtiuAAAAAAAAAAgLBFERwAAAAAAAAAELYoggMAAAAAAAAAwhZFcAAAAAAAAABA2KIIDgAAAAAAAAAIWxTBAQAAAAAAAABhiyI4AAAAAAAAACBsUQRH2Lv44ovVuHHjQ/reBx54QB6PR+Fs+fLl7jW+/fbbpf7c9rz2HvvYGGydjakg9jO1n22w/K4AANjmFoRt7n5scwEAixYt0oknnqhKlSq5bdLo0aPDZrsbrHr27OkWoCyiCI6AsY1RYZaJEycGeqhl3o033uh+FosXL87zPvfcc4+7z6xZsxTM1q5d64oAM2bMULDwfTh76qmnAj0UAGGKbW7oYJtbev7991/3PsbFxSkxMTHQwwGAgFiyZImuuuoqNW3a1P09TEhI0DHHHKP//ve/2r17d4k+90UXXaTZs2fr0Ucf1XvvvafDDz9c4cIO9to2xt7P3N5HOwDg+/x1KPuBwb6NBYJRVKAHgLLLNnLZvfvuuxo3btxB6w877LBiPc9rr72m9PT0Q/ree++9V3fddZfKuvPPP1/PP/+8PvjgA91///253ufDDz9U+/bt1aFDh0N+ngsuuEDnnHOOYmNjVVLsw8KDDz7ous86derkt98VAAhmbHNDB9vc0vO///1PtWvX1rZt2/TZZ5/p8ssvD+h4AKC0jRkzRmeeeabbFlx44YVq166dUlNT9dtvv+mOO+7Q3Llz9eqrr5bIc1thePLkye7A7vXXX18iz9GoUSP3PNHR0QqEqKgo7dq1S998843OOuusHLe9//777qDDnj17/L6Nzc+PP/54SM8HhAOK4AiY//u//8vx9Z9//ul2yA9cfyDbiMTHxxf6eYqzwbONli1lXbdu3dS8eXO3053bDrl9eFm2bJkef/zxYj1PZGSkWwIlUB+OAKCksc0NHWxzS0dGRoY70HDeeee599OKEcFaBN+5c6fKly8f6GEACDP2t88Ohlqh+Oeff1adOnWybrvuuuvcGUlWJC8pmzZtcpeVK1cusefwne0TKHZwwbrqbZt+YBHctkEDBw7U559/Xipj8X2mi4mJKZXnA4IRcSgIapZVZUejp02bpuOOO8790b777rvdbV999ZXbaNStW9dtXJo1a6aHH35YaWlp+WZOZo+esKPa9n32/UcccYSmTp1aYD6pfW1Hqi2vzMZm39u2bVuNHTv2oPHbaeV2SpdteO15XnnllUJnnv7666/uqHzDhg3dczRo0EC33HLLQadS2eurUKGC1qxZo8GDB7vrNWrU0O23337Qe2Gn+tr9LXPNPmzY6WeFPf3XOtPmz5+v6dOnH3SbbcDtNZ177rmuc8B22rt27eqex3bajj32WE2YMKHA58gtn9R2Uh955BHVr1/f/fx79erlOhIOtHXrVvearTPO3gM77ax///6aOXNmjp+H/ZzNJZdcknX6mS8jLrd8UtvxvO2229z7bz+HVq1aud8dG9eh/l4cqo0bN+qyyy5TrVq13O9Ux44d9c477xx0v48++si9/xUrVnTvg70ndjqjz969e13XQIsWLdzjVKtWTT169HAFMQBlF9tctrllaZv7+++/u9duBSBbJk2apNWrVx90P+tWt22ovVb73bKf90knnaS///77oK7yI4880r1vVapUcf+GsnfbHZjJnlfeuu/n8ssvv+jaa69VzZo13c/DrFixwq2z96VcuXJu+22/t7nlutvvmv0O2+Pb+2OPYV2emzdv1o4dO9zvyk033XTQ99l7YAdHhg8fXuj3EkBoGjFihPt78MYbb+QogPvYAdnsfyf27dvntv2+bbn9fbHPCSkpKTm+z9affPLJrpvc/i7a306LWrGz0Hzs76EV3411nNvfPd82Ia85I3Lbptv+i+3H2HbWtkf299H32SW/THAr+tv20v4W2vcOGjTIRWTl9nx2MMDGZPezba1t06ygXFh2sPX777/P8RnAPgNZHIrdVhLb2Pw+0x2YCW6fT+xndODr79evn9ueWcc5EC5ot0HQ27Jli/ujbzso1rFmBUBjf+Bto3Drrbe6S9uQ2Y5gcnKynnzyyQIf13Yit2/f7vLP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sK5B6+g6kL3fV155pevmttPep02b5j6YWJeAdavZh1Ff15x9iLUPhHYqvHV1WceE7SDbhz1f14b9LHr27KmuXbu6zra///7bPdb111/v19cDIDywzS06trnBuc21gyTWHXjg5JvZT1fv16+fKzZYHqqNx4rEdt26H0866SRX6P7111/dbbbdtIPINmYrbNhkaXagwh5n6tSpLmrA3k/f9tkK71agtlP1rUhtXeYHvrf5sffd/u1ZXIn9jO1gh3XPW/E6O5vrw7brlu1tc4PY9t4+G1hUmv0s7L3N3plohTArLtm/HTsQAqBssL+rtn2xCBHbT7CzoWy7aQe6//jjD/e30PY9jP3dsM8BdvDOF5P2119/uaKpbafsb6K/WJe0FWVt22Z/ry2qyg4q23xG2SeGtO2QHVy07Z91eFuUhx00tn0gO5snL08++aQ74Gfd75dddpmbb8H2l+xvq32eKCl2wNTONipISWxj82MTddr7ZmeRWUSmeeutt9z+op1JbF3hQNjIAILEddddZ3vTOdYdf/zxGW3bts31/r///nvGUUcdlVGuXLmMunXrZtx5550ZP/zwg3uMCRMmZN3voosuymjUqFHW18uWLXP3efLJJw96TFs/bNiwrK/t+oFjsq9trAey57Dnym78+PEZnTt3zoiJiclo1qxZxuuvv55x2223ZcTFxRX4fsybNy+jb9++GRUqVMioXr16xhVXXJExc+ZM9/xvvfVWjtdXvnz5g74/t7Fv2bIl44ILLshISEjIqFSpkrv+zz//HPSYBRkzZoz7njp16mSkpaXluC09PT3jsccec+9HbGyse/3ffvvtQT+H3N5vG4Ots5+Rjz3+gw8+6J7LftY9e/bMmDNnzkHv9549e9x767vfMccckzF58mT3O2RLdl999VVGmzZtMqKionK89tzGuH379oxbbrnF/Y5FR0dntGjRwv3u2Os81N+LA/l+J/Na3nvvPXe/DRs2ZFxyySXu98F+p9q3b3/Qz+2zzz7LOPHEEzNq1qzp7tOwYcOMq666KmPdunVZ93nkkUcyjjzyyIzKlSu796p169YZjz76aEZqamq+4wQQPtjm5sQ2t2xsc59++mn3vfa7kpe3337b3cfGbfbt2+fGYNtK+92qUaNGRv/+/TOmTZuW4/vefPNN9/7bz6FKlSrufRg3blyO9/Y///mP+/2K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7vbbb89RsNy3b1+hHrdGjRpZkzii7Nq5c6fb7r744ou53j5ixAg999xzGjVqlKZMmaLy5cu7bfOePXuy7mMF8Llz57pt+LfffusK68U9wAIAAAAA8ANP+GeCB3RU1h1oxZgDl7ffftvdbpcTJ0486Hv++ecfpaSkaMmSJbr44osDNHoACK45E3xLpUqVXLeu72s7c6ZixYr6/vvv1bVrVzdPwm+//eb+hg4aNEi1atVShQoVdMQRR+inn37KNw7FHtcOPg4ZMsQVx1u0aKGvv/66WGP//PPP1bZtWzcuez47wJmdnfVjzxMXF+fGesYZZ2Td9tlnn6l9+/au+7hatWquA9kKtvCv/v3765FHHnE/9wPZdtt+R+699173+9ShQwe9++67Wrt2bVbH+L///quxY8e6351u3bqpR48eev755/XRRx+5+wEAAAAAAsgT/nEoITUxZrBZm7hbs1Ynqmr5WB3ZpGqghwOghFiRb/fetIA8d7noSFd49oe77rpLTz31lJo2baoqVapo1apVGjBggB599FFXgLbCpUVeLFiwQA0bNszzcR588EHX+fvkk0+6QqZ1+K5YsUJVqxb97+C0adN01llnubiWs88+W3/88YeuvfZaV9C2g5x2xtCNN96o9957T0cffbSL1Pj111/d91qH+7nnnuvGYsXZ7du3u9vs54XSY1Fm69evdwcgfOxAjBW7J0+erHPOOcddWgTK4YcfnnUfu39ERITrHM+tuA7kyv59L5sk7d6moBIZIzXrJUXnPlE7AP9JT8/Qn8u2KHHXXr895lFNq6lq+Ri/PR4AAAg+FMGLYcysdXr0u391Sse6FMGBMGYF8Db3/xCQ5573UD/Fx/jnT/VDDz2kE044IetrK1pbxIXPww8/rC+//NJ1dl9//fV5Po4Vp634bB577DEXg/HXX3/ppJNOKvKYnnnmGfXp00f33Xef+7ply5aaN2+eK7Db81gklkVrnHzyya6bvVGjRlkRWlYEt1iX0047za031hWO0mUFcGNd+tnZ177b7LJmzZo5bo+KinK/g7775MbO+rLFJzk52c+jR8iZ+rr03f54p6DSdoh0pvdsRgAlU/weO3e9/vvTIi3YsN2vj/3Z1d1VtTz7cwCAMswTnBEm/kQRvBgaVfPm5C7fzKn3AIJf9i5cY5MSWge2zbXgKyjv3r07x1wMubG4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uvfee939OnTooHfffVdr16513epBG4liLBIls6O9UEXwrcu8l1WalPwYAQAAAMBPcSgePy7BiEzwYCiCW+5ovkVwbyf4NDrBAQBB6Oijj9arr76qhQsXqmXLlpo5c6aLX3nmmWfc7cuWLdP69etdBIpPpUqV1K1bNzdR5znnnJPr46akpLjFJzk5WaWm5UmZkShLvZEodToocZe3CF45njgUAEBgff3114W+76mnnlqiYwEAIBRQBA+WyTHX5j05ZqeGld2cXKu27tam7SmqUTG29MYHAEAB7rrrLlegbt26tcsbt4zwRx99VOeff7673QrgplatWjm+z7723Zab4cOH68EHH1RAxFaQWpwg/fuNtxu8ToesTvCEQsWh0AkOACg5gwcPLtT9rBvPtssAAOQnSJu3/Yo4lECr23n/TvPOLbneJSEuWi1rVnTXyQUHAASbTz75RO+//74++OADTZ8+Xe+8846eeuopd1kcQ4cOVVJSUtayatUqBSQSxXLBMzIKjkPZu0favtZ7nU5wAEAJSk9PL9RCARwAUBieMhCHQhE80MpVlqq1KLAbvEsjcsEBAIVn2dwPPfSQVq5cWeLPdccdd7hucIs1ad++vS644ALdcsstrpPb1K5d211u2LAhx/fZ177bchMbG6uEhIQcS6lq0S9bJMqsgovgiSu8lzEVpfiqpThQAAAAAEB+KIIH1eSY0wvMBacTHABQGDfffLO++OILNW3aVCeccII++uijHPna/rRr1y5FROT8SGGxKNaBZpo0aeKK3ePHj8+63eJTpkyZou7duytouUiUE73X536p5IKK4L4olKqNy8b5hACAoLFz50599913GjVqlJ577rkcCwAABYnw+HcJRmSCB4N6XaVZH+c/OWYjbxF85uokpe5LV0wUxy8AAPkXwW2xeJK3335bN9xwg6699lqdd955uvTSS9WlS+YBWD845ZRTXAZ4w4YN1bZtW/3zzz9uUkx7HmOnw9lYHnnkEbVo0cIVxe+77z7VrVu30JmmAdN2sPTv19Lc0UqKP6lwRXCiUAAApci2uwMGDHAHpa0YXrVqVW3evFnx8fGqWbOmbrzxxkAPEQAQ5DxloImHSmqwFMF9cSgZGbnepWn18qocH+0K4PPWJZfu+AAAIcuK3dYFtnbtWg0bNkyvv/66jjjiCHXq1ElvvvmmMvLY7hTF888/rzPOOMMV2Q877DDdfvvtuuqqq/Twww9n3efOO+90hfgrr7zSPf+OHTs0duxYxcXFKai5SJRy0rZlqr5jvltFERwAEEwsgswOSG/btk3lypXTn3/+qRUrVqhr165ujg4AAEARPDjUaidFREs7N0mbF+Z5RCYrEoVccABAIe3du9dNXHnqqafqtttu0+GHH+4K4aeffrruvvtunX/++cV+jooVK2rkyJFuh3v37t1asmSJ6/qOiYnJsR2zjPL169drz549+umnn9SyZctiP3epRKK09EaiHL5zkrukCA4ACCYzZsxw23iLJrM4Mos/a9CggUaMGOG29QAAFMTj5yVsiuCrVq3S6tWrs77+66+/3GnOr776qj/HVnZEx0nNenuvz/k8z7t1aeidHHMaueAAgAJYDIp1XtepU0fXX3+9iymZM2eOfvvtN11yySUujsQK0V9++WWghxr82ngjW47f95ukjLyL4FuXeS+rNCnFwQEAyrro6OisuTks/sQ3KXalSpXcvjsAAAWJ8Hj8uoRNEdzyRCdMmOCuW0eXTbhlhfB77rnHdXnhELQ/w3s5+7M8I1F8ueD/0AkOACiARY4sWrRIL7/8stasWeNOh27dunWO+1g29znnnBOwMYaMlv2UEVVODbRBbT3LVSk+lyK4bbvpBAcABEDnzp01depUd/3444/X/fffr/fff981qrVr1y7QwwMAIHSL4NZJduSRR7rrdoq1bVj/+OMPt6G1ybdwCFoN8GaObl0irZuR61061q/sZlhdm7RH65J2l/oQAQChY+nSpS5z+8wzz3QdYrkpX7683nrrrVIfW8iJKa99zU5wV0+O/DP3TvAdG6V9uyVPhFSpQemPEQBQZj322GPuzC9jE1VXqVJF11xzjTZt2sTZ2gCAQvF4/LuETRHc8kVjY2PddTuV2nJGjXWYrVu3zr8jLCtc5mi/fCNRysdGqXXtBHd9+orE0hwdACDEbNy4UVOmTDlova37+++/AzKmUJbY5GR3OTByimIjc/n45OsCT6gvRe3PQgcAoKTZfB+9evXKikOxg+DJycmaNm2aOnbsGOjhAQAQukVwyxUdNWqUfv31V40bN04nnXSSW7927VpVq1bN32Mse5Eoc76Q0tNzvUvXzEiU6eSCAwDycd111+WaA2rRKHYbimZDreO0OyNGDT0bcz9ja1tmHnhVolAAAAAAhBaPx+PXJRhFHco3PfHEExoyZIiefPJJXXTRRVlHl7/++uusmBQcguYnSLEJUvIaadWfUqOjD7pLl0aV9d6fKzSNXHAAQD7mzZunLl265JobarehaBL3RWt8emedHDlFmvulVLdzzjuQBw4ACBCb4yO/goNFpAEAkJ8grVsHvgjes2dPbd682Z1iZXljPldeeaXi4+P9Ob6yJTpOOuwUacb73gkycyuCN/S+33PXJmnP3jTFRUcGYKAAgGBnsWUbNmxQ06ZNc6y32LKoqEPa/JdpSbv36ru0bplF8NFS3wdzflKkCA4ACBCbAPPA+NJ//vnHxaLccccdARtXWfHRB+/rnbfe0ObNm9SyVWvddfd9at+hQ6CHhTwc06WZbrmwr7q0aag6NSrprFte1TcTZ+W4z33XDNQlQ45W5YrlNHnmUt342MdasnJTwMaMwuPfI/weh7J7926lpKRkFcBXrFihkSNHasGCBS6DDMXQ7nTv5bzRUtreg25uWDVe1SvEaG9ahiuEAwCQmxNPPFFDhw5VUtL+bUViYqLuvvtunXCCd5JHFK0IPiG9k1I8cVLiCmntPznvQBEcABAgN910U47l9ttv1/vvv6+HHnrI7aOj5Iz9/js9NWK4rrr2On306Zdq1aq1rrnqMm3ZsiXQQ0MeypeL1eyFa3Tz8I9zvf22i/vq2nOP142PfaTjLnxKO3en6psXr1NsDE0kwY5/j8UT4fH4dQmbIvigQYP07rvvZu1Qd+vWTU8//bQGDx6sl19+2d9jLFuaHC/FV5d2bZGW/XLQzXaaW+fMbnAiUQAAeXnqqadcJnijRo3cZFm22OnS69evd9tsFL0Ivltxmlex+/6D1dltzcwEpwgOAAgS/fv31+effx7oYYS19955S6edcZYGDzldzZo3173DHlRcXJxGf8H7Hqx+/H2eHnzpW309IWf3t8915/XSE6/9oG8nztacRWt1+X3vuo7xU3sxyWyw499j8Xg8/l3Cpgg+ffp0HXvsse76Z599plq1arlucCuMP/fcc/4eY9kSGSW1Hey9Pvvz/CfHXJFYmiMDAISQevXqadasWRoxYoTatGmjrl276r///a9mz56tBg0aBHp4IVkEN4uq9/GusFzwjAzv9dRd0o713utVmgRqiAAA5GD76lWrVg30MMLW3tRU/Ttvro7qvj/GNCIiQkcddbRmzTzgjDGEhMb1qrmC989T5metS96xR1PnLFe3DjQ6BDP+PaIwDul8jl27dqlixYru+o8//qjTTjst85frKFcMRzG1O0Oa+ro0/1tp77PerPBccsGnrdymjIyMoJ11FQAQWOXLl3fzdaD4knanustNtXpKq+KlxJXeSJR6XbzXTWwlqdz+uVIAACgNNul19n1C20e0M782bdqkl156ya/PZWeZDRs2TG+++abKum2J25SWlqZq1arlWG9fL1vGZKShqHb1BHe5cev2HOs3btmuWtW8tyE48e+x+DxloLZ4SEXw5s2ba/To0RoyZIh++OEH3XLLLW79xo0blZDAH4Zia9BNSqgvJa+WFv0otTk1x80d6ldSVIRHm7anaPW23WpQlclIAQC5mzdvnlauXKnUVG8R1+fUU3NuW1C4TvDyFSpILft5O8FtsSJ4Vh54o+A99w8AELYsrjR78cIa1GrUqKGePXuqdevWfn2urVu36p133sm3CG7zh9mSXUZkrJu0GwCAkCqC33///TrvvPNc8bt3797q3r17Vle4HYVGMUVESO1Ok/54Tprz2UFF8LjoSLWtm6CZq5M0feU2iuAAgIMsXbrUHay2+BPbMbauMOPbSbZOCRS9CF4pPlpqOySzCD5aOuEhaRt54ACAwHnggQf89lhff/11gZ8vCjJ8+HA9+OCDOdbdc98w3Xu//8YZDKpUrqLIyMiDJt2zr6tXrx6wceHQrd+c7C5rVq2Ydd19Xa2iZi1YHcCRoSD8ewxQXnZZKIKfccYZ6tGjh9atW6eOHfdPDtCnTx+3ww0/aHe6twi+8AcpZbsU642f8bHJMV0RfMU2DepUL2DDBAAEp5tuuslNhDl+/Hh3+ddff7kPgbfddpubNBOHWAQvFy01PUGKjpeSLBJl+v5O8KrkgQMASp8VfmzfvGbNmjnW23bf1hXlwPfgwYNzHDw/lFPmhw4dqltvvfWgTvBwEx0To8PatNWUPyerd5++bl16erqmTJmsc879v0APD4dg+ZotWrcpSb26tdKshWvcuorl43REu8Z67dPfAj085IN/j8XnKQNntB5yob927dqu63vt2rVavdp7ROzII4/0++lWZVadjlK15tK+PdL87w66uYtvcsyVTI4JADjY5MmT9dBDD7nOBzst2hY7gG3dWTfeeGOghxfaRfCYeKnlSd4b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61Z1a+I9xf2L6auVkUEkCgCUVTExMfr444+1YMECvf/++/riiy+0ZMkSvfnmm+42FA6d4AAAAADCXQSd4Ah67TO7wWd/5i7OPbKBYqIiNH1lov5atjWwYwMABFyLFi105pln6uSTT3aTYqJoKIIDAAAAQOijCB4ukSjLfpF2bFTNhDid0bW+W/XyL0sCOzYAQMCcfvrpeuKJJw5aP2LECFcUR+FQBAcAAAAQ7jwej1+XYBQURfAXX3xRjRs3VlxcnMsv/euvvwr1fR999JF7YwcPHqwyq2pTqV5XKSNdmjvarbry2Kbu1IOJCzZp3trkQI8QABAAkyZN0oABAw5a379/f3cbCociOAAAAIBwF0EcSsmzvNJbb71Vw4YN0/Tp09WxY0f169dPGzduzPf7li9frttvv13HHntsqY01aLU7w3s553N30bh6eQ1oX8ddpxscAMqmHTt25Jr9HR0dreRkDpAWVuIubxE8gSI4AAAAAISsgBfBn3nmGV1xxRW65JJL1KZNG40aNUrx8fFu4q68pKWl6fzzz9eDDz6opk2blup4g1LbIXbigrTqTylxlVt1Tc9m7nLMrLVasWVngAcIACht7du3dweaczuLyra3KJzkzE7wyvEUwQEAAACEJ4/Hv0swigrkk6empmratGkaOnRo1rqIiAj17dtXkydPzvP7HnroIdWsWVOXXXaZfv3113yfIyUlxS0+Ydn9llBHatxDWv6rtxu8x81qW7eSjm9ZQ78s3KRXJy3Vo0PaB3qUAIBSdN999+m0007TkiVL1Lt3b7du/Pjx+vDDD/Xpp58GenghIS09Q9tT9rnrxKEAAAAACFcRwVq5DpdO8M2bN7uu7lq1auVYb1+vX78+1+/57bff9MYbb+i1114r1HMMHz5clSpVyloaNGigsJ4gc85nWat83eCfTlutjdv3BGpkAIAAOOWUUzR69GgtXrxY1157rW677TatXr1aP/30U9meS+MQusANRXAAAAAAKHmPP/64mwPy5ptvDq84lKLYvn27LrjgAlcAr169eqG+x7rMk5KSspZVq7xxIWGnzSApIkpaP1vatNCt6takqro0rKzUfel687flgR4hAKCUDRw4UL///rt27tzpDjz//PPPOv744zVnzpxADy2kJsWMj4lUdGRIfWQCAAAAgJCbGHPq1Kl65ZVX1KFDB/lbQPfo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Kzc3N/Tq1Qv79u3DunXr8Nprr+GFF15AYGCguo18XU0mIJGJRORFya5duzBhwgTdfl4iIiJbwWM4ERERMo9rhQoVQrt27dTEmCdOnMD69evx+uuv48yZM+o2gwcPxmeffYZly5bh0KFDePXVVxEbG5vrNuXDYDlOvvjii+o+pm3+/PPP6vrixYurb0BJ25aLFy+qKnD5EHnYsGFqMszZs2erViym46dcFq+88oo6rr711luqBdncuXPVhJ1EZBkMwYns1MqVK9Un4lmXxx9/PPP6Dz/8EPPnz1c9P2WGa5kZWz7dFh4eHli1apWaVbt27dp49tlnVe/Qb7/9NvP+8qJh3LhxmDRpEipXroynn35aHfCJiIjo0fAYTkREhMzj2t9//62qxjt27Kiqrfv27at6gst8FeLNN99UH/bK8U16cEtg3aFDh7tuV9qxyDFSAvMKFSqgf//+md+iknYncqx999131QfIpg+aP/74Y4wYMQJjx45V42jdurVqj1KyZEl1vYxx8eLFKliX+TmmTJmCTz/9NM/3ERFpDDI75s3zRESKfKq9dOlStG/fXu+hEBER0QPgMZyIiIiI6E6sBCciIiIiIiIiIiIim8UQnIiIiIiIiIiIiIhsFtuhEBEREREREREREZHNYiU4EREREREREREREdkshuBEREREREREREREZLMYghMRERERERERERGRzWIITkREREREREREREQ2iyE4EREREREREREREdkshuBEREREREREREREZLMYghMRERERERERERGRzWIITkREREREREREREQ2iyE4EREREREREREREcFW/T+B5ls3tcmowAAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Visualizing attention weights for 2 samples...\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAApEAAAIjCAYAAABbKUC1AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAVstJREFUeJzt3Ql8U2X28PHTFtpSoOxQlrIzQgHZQXBGVBBQRFFGQHFYdNBRWaQzjKACjoiIsqkg4AKuCK6AjjJi3UBRZFMQBQSUtSzDUmihhTbv5zzzJv+kpJDbJE2T+/v6udJ7c3PzZD85z/OcG+VwOBwCAAAAWBBtZWcAAABAEUQCAADAMoJIAAAAWEYQCQAAAMsIIgEAAGAZQSQAAAAsI4gEAACAZQSRAAAAsIwgEgAAAJYRRKLYi4qKkkceeUQi1ZVXXmmWwl63WbNmAW8T/s9vv/1mXoMvv/xyqJsCN3Xr1pXrr78+oMeM9M8aINAIIiPcc889Zz4YO3To4PXyLVu2mA9N/aL0dt2i+uL86KOPitWH95NPPmketw0bNnhs17OEVqhQwVy2a9cuj8vOnDkjcXFxctttt0lxs3//fvP4bty4MWRtWLVqlVx77bVSs2ZNiY+Pl9q1a0uvXr1k4cKFYjeLFy+W22+/XRo1amReS4X9EaH0ParHuNiiQVdxCManTp0qkejUqVMyYcIE6dGjh1SsWJEfHrCFEqFuAILrjTfeMF8ea9askV9//VUaNmx4XhD5r3/9y3yJ5f+S0SCycuXKMnjw4CIJImfPnu01kDx9+rSUKFG0L9U//vGPrsCnVatWru0//fSTHD9+3LTn66+/lnr16rku+/777yUnJ8d1XV998sknUhRBpD7P+hy3bNlSitrbb78t/fr1M7c9cuRIE4hrEP7VV1/JCy+8UCwD72CaM2eOrFu3Ttq1ayf//e9//TrWFVdcIa+99prHtr/+9a/Svn17ueuuu1zbypQp49ft4MKOHDkijz76qPlx1KJFC/niiy9C3SQg6AgiI5h+SX/zzTfy3nvvyd13320CSv2lHG40a1XU2rZta25Xg8jhw4e7tmvgWKlSJXO5XqbZJCddV1aDyNjYWIl0+uMgJSVFvv322/Pu76FDh8RuNOjTjGx0dLTfwxHq169vFnd/+9vfzDb312d+586dk7y8PFu8/opC9erV5cCBA5KUlCRr1641PxCASEd3dgTToFEzPj179pQ///nPZt2ddrXccsst5u+rrrrK1e2lv6A1Y6VZty+//NK13b3LTbNx999/vyQnJ5suXM1wTpkyxXwpeeu+ev7556VBgwZmX/1w1aydk2Y6NQup3LvfLjROSbuZtWs0MTHRZFi6dOliApT890+vq4FfamqqVKlSRUqXLi033XSTHD58+IKPnX6xajv1uu50vWPHjnL55Zd7vax8+fKuoEAfi5kzZ0rTpk1NQFqtWjUTzB87duyiYyJ///13ueGGG0x7q1atKqNGjZL//Oc/rucnP80o63OYkJBgghPtjnfS/Z1faEOGDHE9vs6utu3bt0ufPn3Ml5+2s1atWtK/f385ceKEBMqOHTtMG7wFLHr/3OnrpVOnTiZYL1WqlLRp00beeeed866n92HYsGEmy6kBqu6rz82mTZvM5fPmzTOvS71P+vjmH7LhHE+qGUG9Pb2+Zpbnzp3r03365ZdfzPtKuy71NvSHxbJly3y6rr5vNIAsKu7vRX1NOt+L+rpxvk/yPz76uvH2evvuu+9Ml225cuXM661z587nvRf8sWDBArn66qvN60LbqM+tZm4vlMnXDLc+B7qv/mjOz5fPqws9z7t3777ofnpcfQ8BdkImMoJp0HjzzTebL+5bb73VfBBr8OYMKLQbbMSIEfLMM8/Igw8+KE2aNDHb9V/9otEMnAZoDz30kNmuQZDKysoyXxz79u0zQZF232jGc+zYseaXuF7XnY55O3nypNlXv5Q0wNF27dy5U0qWLGm2a3frihUrzuuW80aD2z/96U8mgPznP/9pjqEBgwYFGvTmH/+p90ODac3C6heltk+DDx2XdiGaUVy5cqW5jrOrX78snV2Fejz9ctLAUcdK6mOgQYwzOND7pV/QGrjp46yZ4VmzZpkAWI+j7fYmMzPTfInqY6ldv/rFpI/h559/7nV/DUr1S10f0759+5qA64EHHpDmzZubQFufT+1mGz9+vOne1MdOaeCk3e/du3eX7Oxs8zjpbenz+uGHH5r7poFCINSpU0fS0tJk7969Jki9kKefftoE0AMGDDDtW7Rokfmxo23SH0Tu9PnRwO2+++4z65MnTzaTLfR1ocMx7r33XvP46GvujjvukM8+++y8x+66664zj5u+R9566y255557zHtG97/Qa1B/SGjAPmbMGBPs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KuXaftNNN5kJNwAAAIh8ljORK1eulG+++UZiY2M9ttetW1f27dsXyLYBAAAEBbOzQ5CJ1NMZ5ubmnrd97969plsbAAAAvps9e7ZJxsXHx0uHDh1kzZo1Be77008/mSo5un9UVJTMnDmzUMfUk8do7e9KlSpJmTJlzDEPHjwY3CCyW7duHg3WO6ATaiZMmCDXXXed1cMBAAAUuagg/WfV4sWLJTU11cRR69evlxYtWkj37t3l0KFDXvfPysqS+vXryxNPPCFJSUmFPuaoUaPkgw8+kLffflu+/PJLM0H65ptvDm4QOW3aNPn6668lJSXFRLG33XabqytbJ9cAAACES3d2oBeVkZHhsejE44JMnz5dhg4dKkOGDDGxlU5QTkhIkPnz53vdv127dvLUU09J//79JS4urlDHPHHihLz00ktmv6uvvlratGljSjjqcMVvv/1WghZE1qpVS3744Qd58MEHTRTbqlUrEw1v2LBBqlatavVwAAAAESU5OVnKlSvnWiZPnux1v5ycHFm3bp107drVtS06Otqsr169ulC37csx9fKzZ8967NO4cWOpXbu2pdu1PLHGXKlECbn99tsLc1UAAICInlizZ88eSUxMdG0vKGN45MgRM8+kWrVqHtt1/ZdffilUG3w5Znp6upkgrWchzL+PXha0IPLVV1+94OUDBw60ekgAAICIkZiY6BFERqoShakT6U7ToTrIUyNa7W8niAQAAMWdTgzWJdDHtKJy5coSExNz3qxoXS9o0kwgjqn/arf38ePHPbKRVm/X8phILTLuvujM7K1bt8of//hHefPNN60eDgAAwJZiY2PNpBb3k7VoKUVd79ixY9COqZeXLFnSYx+N5fRshFZut1BjIvNr1KiRmVyj4yQL24cPAABgt2LjqampMmjQIHM2wPbt25syipmZmWZmtdIe3po1a7om52gGccuWLa6/tTrOxo0bTa3Hhg0b+nRMnexz5513mv0qVqxout6HDx9uAsjLLrusaINIc6ASJUyNIQAAAPimX79+cvjwYRk/fryZ1NKyZUtZvny5a2KMZgd1drWTxlpaGcdp6tSpZuncubN88cUXPh1TzZgxwxxXi4xrCSKtI/ncc8+JFZaDyGXLlnmsOxwOOXDggMyaNUsuv/xyq4cDAAAocjp8McBDIqWwxxs2bJhZvHEGhk5am1tjL3+OqfRMNnpWG10Ky3IQ2bt37/MGkVapUsUUq9RC5AAAAMVddFSUWQJ9TDuxHETq4EwAAADYW6HHRGoxS50BZIc6SAAAILIUl4k14cxSiR+tJ3TfffeZGkQ6OLNChQqmntDYsWNNrUgAAADYg8+ZyKNHj5qp3zqVfMCAAdKkSROzXaeZP/vss7JixQpZtWqV/Pjjj+bk3SNGjAhmuwEAAAovCBNrxGaZSJ+DyEcffdR0X+/YseO88zHqZd26dZO//OUv8sknn8gzzzwTjLYCAAAg3ILIJUuWyLx5884LIJV2aT/55JNy3XXXyYQJE0yBSwAAgOIqWqLMEuhj2onPQaTWgmzatGmBlzdr1swUrdQgsqgdOH5aTuWWlHC25XCGhLsdR09LJGhXo5xEgpgIKDVRp3y8RII/NKgokeDoiQQJd79k50gkaFazrISzM5mhbgGKdGKNTqb57bffCrx8165dUrVq1YA0CgAAoCiKjQd6sROfg0g9Hc5DDz1kztOYn54uZ9y4cdKjR49Atw8AACBoJX4CvdiJpYk1eiLvRo0amTI/jRs3Nqfd+fnnn825FjWQfPXVV4PbWgAAAIRXEFmrVi1ZvXq13HvvvaYupPO8jXraw2uuucacO7t27drBbCsAAEBAcNrDIj5jTb169eTjjz+WY8eOyfbt2822hg0bSsWKkTFoHAAAAEE87aGeqaZ9+/aFuSoAAEDIBWMiTJS9EpHWTnsIAAAAFDoTCQAAEPbFxgM9JlLslYokEwkAAADLyEQCAADbYUyk/wgiAQCA7UQHoTs2WuzFbvcXAAAAAUAmEgAA2I6eLEWXQB/TTshEAgAAwDIykQAAwHY0ZxjovGGU2AuZSAAAAFhGJhIAANiOFhoPeLHxKHvlIslEAgAAIPyCyH379sntt98ulSpVklKlSknz5s1l7dq1oW4WAACwybjIQC12E9Lu7GPHjsnll18uV111lXz88cdSpUoV2b59u1SoUCGUzQIAABGOM9aEeRA5ZcoUSU5OlgULFri21atXL5RNAgAAQHHvzl62bJm0bdtWbrnlFqlataq0atVKXnjhhQL3z87OloyMDI8FAACgsMXGA73YSUiDyJ07d8qcOXOkUaNG8p///EfuueceGTFihLzyyite9588ebKUK1fOtWgWEwAAADYLIvPy8qR169by+OOPmyzkXXfdJUOHDpW5c+d63X/s2LFy4sQJ17Jnz54ibzMAAIiMACgYi52E9P5Wr15dUlJSPLY1adJEdu/e7XX/uLg4SUxM9FgAAABgs4k1OjN769atHtu2bdsmderUCVmbAABA5AvGGMYoxkQWnVGjRsm3335rurN//fVXWbhwoTz//PNy3333hbJZAAAAKM5BZLt27eT999+XN998U5o1ayYTJ06UmTNnyoABA0LZLAAAEOECXWg8yoYFx0N+7uzrr7/eLAAAAAgfIQ8iAQAAihpjIv1HEAkAAGwnGCV5osVe7HZ/AQAAEABkIgEAgO3Qne0/MpEAAACwjCASAADYTnEq8TN79mypW7euxMfHS4cOHWTNmjUX3P/tt9+Wxo0bm/2bN28uH330kcflBw8elMGDB0uNGjUkISFBevToIdu3b/fYJz09Xf7yl79IUlKSlC5d2pyG+t1337XUboJIAACAEFm8eLGkpqbKhAkTZP369dKiRQvp3r27HDp0yOv+33zzjdx6661y5513yoYNG6R3795m2bx5s7nc4XCY9Z07d8rSpUvNPnomwK5du0pmZqbrOAMHDjRnDVy2bJls2rRJbr75Zunbt6/Z31cEkQAAwHZ0+GIwFqumT58uQ4cOlSFDhkhKSorMnTvXZA/nz5/vdf+nn37aZBZHjx4tTZo0MSdq0SzirFmzzOWacdSzAc6ZM8ec1OWSSy4xf58+fdqc3MU9GB0+fLi0b99e6tevLw8//LCUL19e1q1b53PbCSIBAAACKCMjw2PJzs72ul9OTo4J2jRL6BQdHW3WV69e7fU6ut19f6WZS+f+ztvSrm73Y8bFxcmqVatc2zp16mSyoEePHpW8vDxZtGiRnDlzRq688kqf7ydBJAAAsJ1oiQrKopKTk6VcuXKuZfLkyV7bcOTIEcnNzZVq1ap5bNd1HbPojW6/0P46VrJ27doyduxYOXbsmAlUp0yZInv37pUDBw64rvPWW2/J2bNnpVKlSibAvPvuu82pqBs2bOjzY0iJHwAAYDuF7X6+2DHVnj17JDExUZw0SCsqJUuWlPfee8+MmaxYsaLExMSYzOW1115rxks6jRs3To4fPy6ffvqpVK5cWZYsWWLGRK5cudJM1vEFQSQAAEAAJSYmegSRBdHgTYM8nU3tTtd11rQ3uv1i+7dp00Y2btwoJ06cMJnIKlWqmFnfbdu2NZfv2LHDjKHUyThNmzY123RCjwaQOlNcx2X6gu5sAABgO1FB+s+K2NhYE/ClpaW5tun4RF3v2LGj1+vodvf91YoVK7zur13pGkDqZJu1a9fKjTfeaLZnZWW5xkq604BWb99XZCIBAABCJDU1VQYNGmSyhDpTeubMmaYUj87WdpbiqVmzpmtc5ciRI6Vz584ybdo06dmzp5kQowHi888/71FHUoNHHRup5Xv0Olr2p1u3bq5xkzr2UcdBTp061YyL1O5sDUY//PBDn9tOEAkAAGwnmGMirejXr58cPnxYxo8fbybHtGzZUpYvX+6aPLN7926PjKHOql64cKEpyfPggw9Ko0aNTADYrFkz1z46gUaDU+3mrl69uglEdQyk+7hJLVA+ZswY6dWrl5w6dcoEla+88opcd911Prc9yuE+yjLM6LR5TdVu3JEuZctefOxBcbZu3zEJdzuOnpZI0K5GOYkEMRFwDtf0rDMSCV5fs08iwdET4f98/LJ5r0SC1IHtJZydyTwpk3q3NmP2fBk7GIzY4e1vf5WEMmUDeuysUyfllssahuR+hUJEZCJLlYyRUrExEs7Kx5WUcFcp4axEgrjo8H4tOZ1z+D6upbg6lxe2v3E9nD0X/s+FOn36nIS7s9mR8Tm197j3uoPhIicrJ9RNMOMXnSV5AnlMO2FiDQAAAOyZiQQAAAjHMZHhjCASAADYDkGk/+jOBgAAgGVkIgEAgO0Upji4L8e0EzKRAAAAsIxMJAAAsJ3oqP8tgT6mnZCJBAAAgGVkIgEAgO0wJtJ/ZCIBAABgGZlIAABgO9SJ9B9BJAAAsB2N9wLfnW0vdGcDAADAMjKRAADAdijx4z8ykQAAALCMTCQAALAdSvz4j0wkAAAALCMTCQAAbIcSP/4jEwkAAADLyEQCAACb1okM/DHthCASAADYTrRESXSA+5+jbRZG0p0NAAAAy8hEAgAA26E7239kIgEAAGAZmUgAAGA/pCL9RiYSAAAAlpGJBAAAtsNpD/1HJhIAAACWkYkEAAD2E4TTHoq9EpEEkQAAwH6YV+M/urMBAABgGZlIAABgP6Qi/UYmEgAAAJaRiQQAALZDiR//kYkEAACAZWQiAQCA7UQFocRPlL0SkWQiAQAAYB2ZSAAAYDtMzvYfQSQAALAfoki/0Z0NAAAAy8hEAgAA26HEj//IRAIAAITQ7NmzpW7duhIfHy8dOnSQNWvWXHD/t99+Wxo3bmz2b968uXz00Ucelx88eFAGDx4sNWrUkISEBOnRo4ds3779vOOsXr1arr76aildurQkJibKFVdcIadPn/a53QSRAADAtiV+Ar1YtXjxYklNTZUJEybI+vXrpUWLFtK9e3c5dOiQ1/2/+eYbufXWW+XOO++UDRs2SO/evc2yefNmc7nD4TDrO3fulKVLl5p96tSpI127dpXMzEyPAFKDy27dupmg9fvvv5dhw4ZJdLTvoWGUQ28tTGVkZEi5cuVk6+7DUjYxUcLZ5v0nJNz9diJLIkGTiuH9WnI658iTcLf3lO+/iIuz177dK5Hg0JHwf4//umWPRIIBt7SVcJaTdUoWDLpMTpw4YTJgoYgdVm7eK2XKBva2T53MkD81q2XpfmnmsV27djJr1iyznpeXJ8nJyTJ8+HAZM2bMefv369fPBIMffviha9tll10mLVu2lLlz58q2bdvkkksuMUFl06ZNXcdMSkqSxx9/XP7617+6rnPNNdfIxIkTC31/yUQCAADbTs4O9OIMVN2X7Oxs8SYnJ0fWrVtnsoROmgnUdc0UeqPb3fdXmrl07u+8Le3qdj9mXFycrFq1yqxrlvO7776TqlWrSqdOnaRatWrSuXNn1+W2mljzWNqvEptQRsLZ0ZPeX2DhpHJinESCpNL/98YLZ3nh28ngcjYv/LOpqk7V8P58cmpSq5yEu47NkiQS3NOhtoQzzdgtkMiVnJzssa5d1Y888sh5+x05ckRyc3NNEOdO13/55Revx05PT/e6v25XOlaydu3aMnbsWJk3b54Z7zhjxgzZu3evHDhwwOyjXd1K2zR16lSTxXz11VelS5cuJoPZqFEj+wSRAAAAxaVO5J49ezy6szULWFRKliwp7733nhkzWbFiRYmJiTGZy2uvvdaMl3R2b6u7775bhgwZYv5u1aqVpKWlyfz582Xy5Mk+3RZBJAAAsJ1glvhJTEz0aUxk5cqVTZCns6nd6bqOYfRGt19s/zZt2sjGjRvN2EztMq9SpYoZe9m27f/G0lavXt38m5KS4nGcJk2ayO7du32+v4yJBAAACIHY2FgT8GkG0EmzhLresWNHr9fR7e77qxUrVnjdXycQaQCp5X3Wrl0rN954o9mu5YS0/M/WrVs99tdJOTqT21dkIgEAgO0UtiTPxY5plZb3GTRokMkStm/fXmbOnGlmXzu7mQcOHCg1a9Z0dTGPHDnSTIKZNm2a9OzZUxYtWmQCxOeff96jjqQGjzo2ctOmTeY6WvZHy/moqKgoGT16tBmrqSWFdEzkK6+8YsZhvvPOOz63nSASAAAgRPr16yeHDx+W8ePHm8kxGtAtX77cNXlGu5fdazfqbOqFCxfKww8/LA8++KCZBLNkyRJp1qyZax+dQKPBqXZza9e1BqLjxo3zuN37779fzpw5I6NGjZKjR4+aYFIzmg0aNLBXnci/LFjN7OxiIFJmZ/dqXEUiQSTMzj6anSORYPVvGRIJEmJjJNzlnAv/90WkzM7ulFIzpHUiV2/ZF5Q6kR1DdL9CgTGRAAAAsIzubAAAYD9BLPFjF2QiAQAAYBmZSAAAYDvBrBNpF2QiAQAAYBmZSAAAYDvFpU5kOCOIBAAAtsO8Gv/RnQ0AAADLyEQCAAD7IRXpNzKRAAAAsIxMJAAAsB1K/PiPTCQAAAAsIxMJAABshxI/YZ6JzM3NlXHjxkm9evWkVKlS0qBBA5k4caI4HI5QNgsAAADFORM5ZcoUmTNnjrzyyivStGlTWbt2rQwZMkTKlSsnI0aMCGXTAABABGNydpgHkd98843ceOON0rNnT7Net25defPNN2XNmjVe98/OzjaLU0ZGRpG1FQAARBCiyPDuzu7UqZOkpaXJtm3bzPoPP/wgq1atkmuvvdbr/pMnTzZZSueSnJxcxC0GAABAyDORY8aMMdnExo0bS0xMjBkjOWnSJBkwYIDX/ceOHSupqamudb0ugSQAALCKEj9hHkS+9dZb8sYbb8jChQvNmMiNGzfK/fffLzVq1JBBgwadt39cXJxZAAAAYOMgcvTo0SYb2b9/f7PevHlz+f333023tbcgEgAAICCCUOJH7JWIDO2YyKysLImO9myCdmvn5eWFrE0AAAAo5pnIXr16mTGQtWvXNt3ZGzZskOnTp8sdd9wRymYBAIAIx+TsMA8in332WVNs/N5775VDhw6ZsZB33323jB8/PpTNAgAAQHEOIsuWLSszZ840CwAAQJEhFek3zp0NAABshxI/YT6xBgAAAOGJTCQAALCdqCCU+ImyVyKSTCQAAACsIxMJAABsh3k1/iMTCQAAAMvIRAIAAPshFek3MpEAAACwjEwkAACwHepE+o8gEgAA2LM3O9AlfsRe6M4GAACAZWQiAQCA7TCvxn9kIgEAAGAZmUgAAGA7nPbQf2QiAQAAYBmZSAAAYEOMivRXRASRb02fL1ExsRLOohq0lnDXpEU9iQTlS5WUSFClTPi/vetXSJBIMLhlTYkEVRLjQt0Ev5WMiYwOuMplw/s7LyPuXKibgAAI/28ZAAAAixgT6b/I+EkGAABQiM7sQC+FMXv2bKlbt67Ex8dLhw4dZM2aNRfc/+2335bGjRub/Zs3by4fffSRx+UHDx6UwYMHS40aNSQhIUF69Ogh27dv93osh8Mh1157rURFRcmSJUsstZsgEgAAIEQWL14sqampMmHCBFm/fr20aNFCunfvLocOHfK6/zfffCO33nqr3HnnnbJhwwbp3bu3WTZv3uwKCnV9586dsnTpUrNPnTp1pGvXrpKZmXne8WbOnGkCyMIgiAQAALbtzg70YtX06dNl6NChMmTIEElJSZG5c+ea7OH8+fO97v/000+bzOLo0aOlSZMmMnHiRGndurXMmjXLXK4Zx2+//VbmzJkj7dq1k0suucT8ffr0aXnzzTc9jrVx40aZNm1agbd1MQSRAAAAAZSRkeGxZGdne90vJydH1q1bZ7KETtHR0WZ99erVXq+j2933V5q5dO7vvC3t6nY/ZlxcnKxatcq1LSsrS2677TbTlZ6UlFSo+0kQCQAAbCcqSP+p5ORkKVeunGuZPHmyeHPkyBHJzc2VatWqeWzX9fT0dK/X0e0X2l/HStauXVvGjh0rx44dM4HqlClTZO/evXLgwAHXdUaNGiWdOnWSG2+8UQqL2dkAAAABtGfPHklMTHStaxawqJQsWVLee+89M2ayYsWKEhMTYzKXOnlGx0uqZcuWyWeffWbGS/qDIBIAANhPEGuNJyYmegSRBalcubIJ8nQ2tTtdL6iLWbdfbP82bdqY8Y4nTpwwmcgqVaqYWd9t27Y1l2sAuWPHDilfvrzHcfr06SN/+tOf5IsvvvDp7tKdDQAAEAKxsbEm4EtLS3Nty8vLM+sdO3b0eh3d7r6/WrFihdf9tStdA0idbLN27VpX1/WYMWPkxx9/NIGmc1EzZsyQBQsW+Nx+MpEAAMB2istJD1NTU2XQoEEmS9i+fXtTckdL8ehsbTVw4ECpWbOma1zlyJEjpXPnzmZWdc+ePWXRokUmQHz++ec96khq8KhjIzdt2mSuo2V/unXrZi7XrKW3TKfuX6+e72efI4gEAAC2U1zOWNOvXz85fPiwjB8/3kyOadmypSxfvtw1eWb37t1mdrWTToZZuHChPPzww/Lggw9Ko0aNTJHwZs2aufbRCTQanGo3d/Xq1U0gOm7cOAm0KIdzlGUY0mnzmqqNaz6Uc2cXA5Fy7uwurWpIJODc2cVH9YT/K7URzjh3dvER9ufOzsiQmlUrmDF7vowdDEbs8OveI1I2wLd9MiNDGtaqHJL7FQrh/y0DAABgkXtJnkAe004i4ycZAAAAihSZSAAAYD/FZWZNGCMTCQAAAMvIRAIAANshEek/MpEAAACwjEwkAACwneJSJzKcEUQCAAAbCnyJH7FZhzbd2QAAALCMTCQAALAdurP9RyYSAAAAlhFEAgAAwDKCSAAAAFjGmEgAAGA7jIn0H5lIAAAAWEYmEgAA2LRKZGBTh1E2qxNJEAkAAGyH7mz/0Z0NAAAAy8hEAgAA29GkISc99A+ZSAAAAFhGJhIAANgPqUi/kYkEAACAZWQiAQCA7VDix39kIgEAAGAZmUgAAGA71In0H5lIAAAAWEYmEgAA2A6Ts/1HEAkAAOyHKNJvdGcDAADAMjKRAADAdijx4z8ykQAAALCMTCQAALAdSvzYPIh0OBz/+zc3R8Le2dMS7nLPZEokyM46JZHgTFSMhLuskrkSCTLzIuAzSkRKRcVJuCsRExkdcLGOWAlnJ09meHyPh0JGRkZYHLM4i3KE8hn00969eyU5OTnUzQAAAIWwZ88eqVWrVpHe5pkzZ6RevXqSnp4elOMnJSXJrl27JD4+XiJdWAeReXl5sn//filbtqxEBSmHrL8qNFDVF3piYmJQbgO+4bkoPnguiheej+KD58I3GnqcPHlSatSoIdHRRZ8d1kAyJyc4PQSxsbG2CCDDvjtbX3hF9QtGPwz4QCgeeC6KD56L4oXno/jgubi4cuXKhey2NcizS6AXTJExOAQAAABFiiASAAAAlhFEXkRcXJxMmDDB/IvQ4rkoPnguiheej+KD5wJ2EtYTawAAABAaZCIBAABgGUEkAAAALCOIBAAAgGUEkQAAALCMIPICZs+eLXXr1jUFSTt06CBr1qwJdZNsafLkydKuXTtzZqKqVatK7969ZevWraFuFkTkiSeeMGeLuv/++0PdFFvat2+f3H777VKpUiUpVaqUNG/eXNauXRvqZtlObm6ujBs3zpxKT5+HBg0ayMSJE0N6XmigKBBEFmDx4sWSmppqSjWsX79eWrRoId27d5dDhw6Fumm28+WXX8p9990n3377raxYsULOnj0r3bp1k8zMzFA3zda+//57mTdvnlx66aWhbootHTt2TC6//HIpWbKkfPzxx7JlyxaZNm2aVKhQIdRNs50pU6bInDlzZNasWfLzzz+b9SeffFKeffbZUDcNCCpK/BRAM4+a/dIPBed5uvV8qMOHD5cxY8aEunm2dvjwYZOR1ODyiiuuCHVzbOnUqVPSunVree655+Sxxx6Tli1bysyZM0PdLFvRz6Gvv/5aVq5cGeqm2N71118v1apVk5deesm1rU+fPiYr+frrr4e0bUAwkYn0Qk/Kvm7dOunatavHebp1ffXq1SFtG0ROnDhh/q1YsWKom2Jbmhnu2bOnx3sERWvZsmXStm1bueWWW8yPqlatWskLL7wQ6mbZUqdOnSQtLU22bdtm1n/44QdZtWqVXHvttaFuGhBUJYJ7+PB05MgRM8ZFf1m60/VffvklZO3C/zLCOv5Ou/GaNWsW6ubY0qJFi8wQD+3ORujs3LnTdKHqsJsHH3zQPB8jRoyQ2NhYGTRoUKibZ7uscEZGhjRu3FhiYmLM98ekSZNkwIABoW4aEFQEkQi7DNjmzZvNr3wUvT179sjIkSPN2FSdcIbQ/qDSTOTjjz9u1jUTqe+NuXPnEkQWsbfeekveeOMNWbhwoTRt2lQ2btxofuzWqFGD5wIRjSDSi8qVK5tfkwcPHvTYrutJSUkha5fdDRs2TD788EP56quvpFatWqFuji3pMA+dXKbjIZ0066LPiY4fzs7ONu8dBF/16tUlJSXFY1uTJk3k3XffDVmb7Gr06NEmG9m/f3+zrrPkf//9d1NZgiASkYwxkV5od1CbNm3MGBf3X/263rFjx5C2zY507pcGkO+//7589tlnpowGQqNLly6yadMmk2lxLpoN0247/ZsAsujokI78pa50TF6dOnVC1ia7ysrKMuPm3el7Qb83gEhGJrIAOs5If0HqF2T79u3NzFMtKTNkyJBQN82WXdjaTbR06VJTKzI9Pd1sL1eunJn9iKKjj3/+sailS5c2dQoZo1q0Ro0aZSZ0aHd23759TR3b559/3iwoWr169TJjIGvXrm26szds2CDTp0+XO+64I9RNA4KKEj8XoN1zTz31lAlatITJM888Y0r/oGhpMWtvFixYIIMHDy7y9sDTlVdeSYmfENHhHWPHjpXt27ebDL3++B06dGiom2U7J0+eNMXGtbdEh3voWMhbb71Vxo8fb3q2gEhFEAkAAADLGBMJAAAAywgiAQAAYBlBJAAAACwjiAQAAIBlBJEAAACwjCASAAAAlhFEAgAAwDKCSAAAAFhGEAkgYtStW/eiZ8555JFHzBl2AAD+IYgEbEpPGdm7d2+Pbe+8847Ex8fLtGnTgnKbX3zxhTmNpXOpVq2a9OnTR3bu3BmQ43///fdy1113udb1NpYsWeKxzz/+8Q9JS0sLyO0BgJ0RRAIwXnzxRRkwYIDMmTNH/v73vwf1trZu3Sr79++Xt99+W3766Sfp1auX5Obm+n3cKlWqSEJCwgX3KVOmjFSqVMnv2wIAuyOIBCBPPvmkDB8+XBYtWiRDhgxxbV+6dKm0bt3aZCfr168v//rXv+TcuXPmsjvuuEOuv/56j+OcPXtWqlatKi+99NIFb0/3qV69ulxxxRUyfvx42bJli/z666/mMg1iGzRoILGxsXLJJZfIa6+95rqew+Ew3dG1a9eWuLg4qVGjhowYMcJrd7b+rW666SaTkXSu5+/OzsvLk0cffVRq1apljqmXLV++3HX5b7/9Zq7/3nvvyVVXXWWC1BYtWsjq1asL+WgDQGQgiARs7oEHHpCJEyfKhx9+aAIup5UrV8rAgQNl5MiRJsibN2+evPzyyzJp0iRz+V//+lcTbB04cMB1HT1GVlaW9OvXz+fbL1WqlPk3JydH3n//fXN7mgndvHmz3H333Sao/fzzz80+7777rsyYMcO0Zfv27aarunnz5gV2basFCxaYNjrX83v66adN9/3UqVPlxx9/lO7du8sNN9xgju/uoYceMl3hGzdulD/84Q9y6623ugJqALAlBwBbGjRokCM2NtahHwNpaWnnXd6lSxfH448/7rHttddec1SvXt21npKS4pgyZYprvVevXo7BgwcXeJuff/65ub1jx46Z9f379zs6derkqFmzpiM7O9v8PXToUI/r3HLLLY7rrrvO/D1t2jTHH/7wB0dOTo7X49epU8cxY8YM17re1vvvv++xz4QJExwtWrRwrdeoUcMxadIkj33atWvnuPfee83fu3btMsd58cUXXZf/9NNPZtvPP/9c4H0FgEhHJhKwsUsvvdR0806YMEFOnTrlcdkPP/xgunl1DKFzGTp0qMnqabbRmY3UTJ86ePCgfPzxx6ab+2K067h06dKmOzozM9NkGLX7+ueff5bLL7/cY19d1+3qlltukdOnT5uudW2LZi79yQZmZGSYsZkXuk33x8pJu+LVoUOHCn3bABDuCCIBG6tZs6aZMb1v3z7p0aOHnDx50nWZBpU6BlK7b53Lpk2bTDevjpFU2t2tM6t1fODrr78u9erVkz/96U8XvV3tKteuYw3i9LgdOnTwqb3JyclmUs5zzz1nusHvvfdeM65Sx2IGW8mSJV1/6xhJ53hKALArgkjA5urUqSNffvmlpKenewSSOqFGA7aGDRuet0RH/++jQ2c5a5kgzUbqeEn3STkXosGmTp4pW7asx/YmTZrI119/7bFN11NSUlzrGjzqbO5nnnnGBMAawGpwW1Dgd6FZ34mJiSYberHbBACcr4SXbQBsRjN8GpDp7GOdWKITZnTWtM6+1pnQf/7zn03gqF3cOuHlsccec11Xu7R1Pw3WBg0a5Fc7Ro8eLX379pVWrVpJ165d5YMPPjCzoj/99FNzuQaqejuaudRZ0pr91KBSA2FvtKtea0Jq97TOvK5QoYLX29TufA1qdWa2BsSaHX3jjTf8ui8AEOnIRAJwjVPUQPLIkSMmkOzYsaOZbf3JJ59Iu3bt5LLLLjMzo/MHbBrs6RhBvY5m9fyhWU2dLa0zpZs2bWpmYWtQd+WVV5rLy5cvLy+88IIJCnWMogaXGmgWVPdRZ12vWLHCBMkamHqjJYJSU1PNjHCd6a0B9LJly6RRo0Z+3RcAiHRROrsm1I0AEL507KSOrdRg7+abbw51cwAARYTubACFopNKNGup2T7NEGptRQCAfRBEAiiU3bt3mwky2g2uYxVLlODjBADshO5sAAAAWMbEGgAAAFhGEAkAAADLCCIBAABgGUEkAAAALCOIBAAAgGUEkQAAALCMIBIAAACWEUQCAABArPp/4F3kdlg7MHQAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAApEAAAIjCAYAAABbKUC1AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAVKRJREFUeJzt3Qd8VFX2wPGTBBICIfROILSVXqQJ7AIKAoooyiooLgFd3FWkZdeCCqioFGkq1YIVBF0FLCuKWcEGizQVUARBQVpASoBIEpL5f851Z/4zyQTyMjOZzLzf18+TvDcv790pmTlz7r3nRTgcDocAAAAAFkRa2RkAAABQBJEAAACwjCASAAAAlhFEAgAAwDKCSAAAAFhGEAkAAADLCCIBAABgGUEkAAAALCOIBAAAgGUEkSj2IiIi5OGHH5Zw1b17d7MU9nebN2/u9zbh//3000/mNfjSSy8Fuylwk5iYKNdcc41fjxnu7zWAvxFEhrl58+aZN8aOHTt6vX3Hjh3mTVM/KL39blF9cP773/8uVm/e06ZNM4/bli1bPLbrVUIrVKhgbtu7d6/HbefOnZOYmBi55ZZbpLg5ePCgeXy3bt0atDZ8/vnnctVVV0mtWrWkVKlSUqdOHenXr58sWbJE7OTXX3+VJ598Urp27SpVqlSR8uXLy2WXXSbLli0r1PH0b1RfjxdbNOgqDsH49OnTJVxlZGTIfffdJzVr1pTY2Fjzvrt69epgNwsImBKBOzSKg8WLF5sPjw0bNsju3bulYcOGeYLIRx55xGS0cn/IaBBZuXJlGTp0aJEEkXPnzvUaSP72229SokTRvlT/+Mc/ugKfNm3auLZv375dTp48adrzxRdfSL169Vy3ffXVV5KZmen63YL66KOPpCiCSH2e9Tlu3bq1FLU333xTBg4caM49evRoE4hrEP7pp5/Kc889VywD70BZt26dPPjgg3L11VfLQw89ZF5Lb731lgwaNMj192iFBqOvvvqqx7a//vWv0qFDB7njjjtc2+Li4vx2H+Cdvlf+61//kjFjxkijRo1MgK/P8yeffGL5fQEIBQSRYUw/pL/88kt5++235W9/+5sJKCdOnCihRrNWRa1du3bmvBpEjhw50rVdA8dKlSqZ2/W2W2+91XWbriurHxbR0dES7vTLQdOmTWX9+vV57m9qaqrYSbNmzWTXrl1St25d17a77rpLevbsKVOnTpV7771XypQpU+Dj1a9f3yzu/v73v5tt7q/P3M6fPy85OTm2eP0VBf2ivnTpUpNl/uc//2m2DRkyxAw30edU34uBcEN3dhjToFEzPn379pU///nPZt2dfku+8cYbzc+XX365q9trzZo1JmOlWbe1a9e6truP29NsnH7bTkhIMF24muHUD0D9UPLWffXss89KgwYNzL7t27c3WTv3b++ahVTu3W8XGqek3czaNRofH28yLD169DABSu77p7+rgV9ycrLpOtQP5+uvv16OHj16wcdOP1i1nfq77nS9U6dO0qVLF6+3adekc4yiPhazZ882QYMGpNWqVTPB/IkTJy46JvLnn3+Wa6+91rS3atWqMnbsWPnwww9dz09umsHS57B06dKmu1i74510f70vatiwYa7H1zlUQQOaAQMGSPXq1U07a9eubbJip06dEn/58ccfTRu8BSx6/9zp66Vz584mWNcuwbZt25rsTm56H+6++26T5dQAVffV5+bbb781ty9cuNC8LvU+6eObe8iGczzppk2bzPn09zWzvGDBggLdp++//978XVWsWNGcQ79YvPPOOxf9PT2HewDpvC/9+/c33aF79uwRf3P/W9TXpPNvUV83zr+T3I+Pvm68vd7++9//Sp8+faRcuXLm9datW7c8fwu+ePHFF+WKK64wrwttoz638+fPv2AmXzPc+hzovvqlObeCvF9d6Hnet2/fRffT12hUVJRH9lfbdPvtt5vs8/79+y96DCDUkIkMYxo03nDDDeaD++abbzZvxBq8OQMK7QYbNWqUPP300/LAAw9IkyZNzHb9Vz9oNAOnAZp2vSkNglR6err54Dhw4IAJinRsm37LHjdunBw6dMj8rjsd83b69Gmzr34oaYCj7dIPy5IlS5rt2t2qY4dyd8t5o8Htn/70JxNA6jd8PYYGDBoUaNCbe/yn3g8NpjULqx+U2j4NPi42Bk0zip999pn5HWdXv35YOrsK9Xj64aSBo46V1MdAg5jIyN+/m+n90g9oDdz0cdbM8Jw5c0wArMfRdntz9uxZ8yGqj6V2/Wpwp4+hdol5o0GpfqjrY3rTTTeZDzMdl9WiRQsTaOvz+eijj8qECRPMB5w+dkoDJ+1+7927twle9HHSc+nz+t5775n7poGCP2jQlJKSIr/88osJUi/kqaeeMgH04MGD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uFBeeuklefzxx83tf/3rX02wdejQIdfv6DHS09Nl4MCBBT5/bGys+TczM1OWL19uzqeZ0G3btsnf/vY3E9R+8sknZp+33npLZs2aZdqya9cu01XdokWLfLu21Ysvvmja6FzP7amnnjLd99OnT5dvvvlGevfuLddee605vrsHH3zQdIVv3bpV/vCHP8jNN9/sCqgBwJYcAGwpKSnJER0d7dC3gZSUlDy39+jRw/HEE094bHv11VcdNWrUcK03bdrUMXXqVNd6v379HEOHDs33nJ988ok534kTJ8z6wYMHHZ07d3bUqlXLkZGRYX4ePny4x+/ceOONjquvvtr8PGPGDMcf/vAHR2Zmptfj161b1zFr1izXup5r+fLlHvtMnDjR0apVK9d6zZo1HY8//rjHPu3bt3fcdddd5ue9e/ea4zz//POu27dv3262fffdd/neVwAId2QiARtr2bKl6eadOHGinDlzxuO2r7/+2nTz6hhC5zJ8+HCT1dNsozMbqZk+deTIEfnggw9MN/fFaNdxmTJlTHf02bNnTYZRu6+/++476dKli8e+uq7b1Y033ii//fab6VrXtmjm0pdsYFpamhmbeaFzuj9WTtoVr1JTUwt9bgAIdQSRgI3VqlXLzJg+cOCA9OnTR06fPu26TYNKHQOp3bfO5dtvvzXdvDpGUml3t86s1vGBr732mtSrV0/+9Kc/XfS82lWuXccaxOlxO3bsWKD2JiQkmEk58+bNM93gd911lxlXqWMxA61kyZKun3WMpHM8JQDYFUEkYHN169aVtWvXyuHDhz0CSZ1QowFbw4YN8yyRkb+/degsZy0TpNlIHS/pPinnQjTY1MkzZcuW9djepEkT+eKLLzy26XrTpk1d6xo86mzup59+2gTAGsBqcJtf4HehWd/x8fEmG3qxcwIA8irhZRsAm9EMnwZkOvtYJ5bohBmdNa2zr3Um9J///GcTOGoXt054eeyxx1y/q13aup8Ga0lJST6145577pGbbrpJ2rRpIz179pR3333XzIr++OOPze0aqOp5NHOps6Q1+6lBpQbC3mhXvdaE1O5pnXldoUIFr+fU7nwNanVmtgbEmh1dvHixT/cFAMIdmUgArnGKGkgeO3bMBJKdOnUys60/+ugjad++vVx22WVmZnTugE2DPR0jqL+jWT1faFZTZ0vrTOlmzZqZWdga1HXv3t3cXr58eXnuuedMUKhjFDW41EAzv7qPOut69erVJkjWwNQbLRGUnJxsZoTrTG8NoN955x1p1KiRT/cFAMJdhM6uCXYjAIQuHTupYys12LvhhhuC3RwAQBGhOxtAoeikEs1aarZPM4RaWxEAYB8EkQAKZd++fWaCjHaD61jFEiV4OwEAO6E7GwAAAJYxsQYAAACWEUQCAADAMoJIAAAAWEYQCQAAAMsIIgEAAGAZQSQAAAAsI4gEAACAZQSRAAAAEKv+DyozGQvk5zErAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "🎉 Implementation completed successfully!\n" ] } ], "source": [ "import torch\n", "import torch.nn as nn\n", "import torch.optim as optim\n", "import torch.nn.functional as F\n", "from torch.utils.data import DataLoader, TensorDataset\n", "import numpy as np\n", "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "from sklearn.datasets import load_iris\n", "from sklearn.model_selection import train_test_split\n", "from sklearn.preprocessing import StandardScaler\n", "from sklearn.metrics import accuracy_score, classification_report, confusion_matrix\n", "import math\n", "import warnings\n", "warnings.filterwarnings('ignore')\n", "\n", "device = torch.device('mps' if torch.backends.mps.is_available() else 'cuda' if torch.cuda.is_available() else 'cpu')\n", "print(f\"Using device: {device}\")\n", "\n", "class MultiHeadAttention(nn.Module):\n", " def __init__(self, d_model, n_heads):\n", " super(MultiHeadAttention, self).__init__()\n", " self.d_model = d_model\n", " self.n_heads = n_heads\n", " self.d_k = d_model // n_heads\n", " \n", " assert d_model % n_heads == 0, \"d_model must be divisible by n_heads\"\n", " \n", " self.W_q = nn.Linear(d_model, d_model)\n", " self.W_k = nn.Linear(d_model, d_model)\n", " self.W_v = nn.Linear(d_model, d_model)\n", " self.W_o = nn.Linear(d_model, d_model)\n", " \n", " self.dropout = nn.Dropout(0.1)\n", " \n", " print(f\"✓ MultiHeadAttention initialized: d_model={d_model}, n_heads={n_heads}, d_k={self.d_k}\")\n", " \n", " def scaled_dot_product_attention(self, Q, K, V, mask=None):\n", " d_k = Q.size(-1)\n", " scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(d_k)\n", " \n", " if mask is not None:\n", " scores = scores.masked_fill(mask == 0, -1e9)\n", " \n", " attention_weights = F.softmax(scores, dim=-1)\n", " attention_weights = self.dropout(attention_weights)\n", " \n", " context = torch.matmul(attention_weights, V)\n", " return context, attention_weights\n", " \n", " def forward(self, query, key, value, mask=None):\n", " batch_size, seq_len, d_model = query.size()\n", " \n", " Q = self.W_q(query).view(batch_size, seq_len, self.n_heads, self.d_k).transpose(1, 2)\n", " K = self.W_k(key).view(batch_size, seq_len, self.n_heads, self.d_k).transpose(1, 2)\n", " V = self.W_v(value).view(batch_size, seq_len, self.n_heads, self.d_k).transpose(1, 2)\n", " \n", " attention_output, attention_weights = self.scaled_dot_product_attention(Q, K, V, mask)\n", " \n", " attention_output = attention_output.transpose(1, 2).contiguous().view(\n", " batch_size, seq_len, d_model\n", " )\n", " \n", " output = self.W_o(attention_output)\n", " return output, attention_weights\n", "\n", "class PositionalEncoding(nn.Module):\n", " def __init__(self, d_model, max_len=5000):\n", " super(PositionalEncoding, self).__init__()\n", " \n", " pe = torch.zeros(max_len, d_model)\n", " position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)\n", " div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))\n", " \n", " pe[:, 0::2] = torch.sin(position * div_term)\n", " pe[:, 1::2] = torch.cos(position * div_term)\n", " pe = pe.unsqueeze(0).transpose(0, 1)\n", " \n", " self.register_buffer('pe', pe)\n", " print(f\"✓ PositionalEncoding initialized: d_model={d_model}, max_len={max_len}\")\n", " \n", " def forward(self, x):\n", " seq_len = x.size(1)\n", " return x + self.pe[:seq_len, :].transpose(0, 1)\n", "\n", "class TransformerBlock(nn.Module):\n", " def __init__(self, d_model, n_heads, d_ff, dropout=0.1):\n", " super(TransformerBlock, self).__init__()\n", " self.attention = MultiHeadAttention(d_model, n_heads)\n", " self.norm1 = nn.LayerNorm(d_model)\n", " self.norm2 = nn.LayerNorm(d_model)\n", " \n", " self.feed_forward = nn.Sequential(\n", " nn.Linear(d_model, d_ff),\n", " nn.ReLU(),\n", " nn.Dropout(dropout),\n", " nn.Linear(d_ff, d_model)\n", " )\n", " \n", " self.dropout = nn.Dropout(dropout)\n", " print(f\"✓ TransformerBlock initialized: d_model={d_model}, n_heads={n_heads}, d_ff={d_ff}\")\n", " \n", " def forward(self, x, mask=None):\n", " attn_output, attn_weights = self.attention(x, x, x, mask)\n", " x = self.norm1(x + self.dropout(attn_output))\n", " \n", " ff_output = self.feed_forward(x)\n", " x = self.norm2(x + self.dropout(ff_output))\n", " \n", " return x, attn_weights\n", "\n", "class AttentionClassifier(nn.Module):\n", " def __init__(self, input_dim, d_model, n_heads, n_layers, n_classes, max_len=128):\n", " super(AttentionClassifier, self).__init__()\n", " self.d_model = d_model\n", " self.input_projection = nn.Linear(input_dim, d_model)\n", " self.pos_encoding = PositionalEncoding(d_model, max_len)\n", " \n", " self.transformer_blocks = nn.ModuleList([\n", " TransformerBlock(d_model, n_heads, d_model * 4)\n", " for _ in range(n_layers)\n", " ])\n", " \n", " self.classifier = nn.Sequential(\n", " nn.Linear(d_model, d_model // 2),\n", " nn.ReLU(),\n", " nn.Dropout(0.1),\n", " nn.Linear(d_model // 2, n_classes)\n", " )\n", " \n", " print(f\"✓ AttentionClassifier initialized: input_dim={input_dim}, d_model={d_model}, n_heads={n_heads}, n_layers={n_layers}, n_classes={n_classes}\")\n", " \n", " def forward(self, x):\n", " x = self.input_projection(x)\n", " x = self.pos_encoding(x)\n", " \n", " attention_weights = []\n", " for transformer_block in self.transformer_blocks:\n", " x, attn_weights = transformer_block(x)\n", " attention_weights.append(attn_weights)\n", " \n", " x = torch.mean(x, dim=1)\n", " output = self.classifier(x)\n", " \n", " return output, attention_weights\n", "\n", "def create_sequence_dataset(X, y, seq_len=10):\n", " print(f\"Creating sequence dataset with seq_len={seq_len}\")\n", " print(f\"Original data shape: X={X.shape}, y={y.shape}\")\n", " \n", " n_samples = X.shape[0]\n", " n_features = X.shape[1]\n", " \n", " X_seq = np.zeros((n_samples, seq_len, n_features))\n", " \n", " for i in range(n_samples):\n", " base_sample = X[i]\n", " for j in range(seq_len):\n", " noise_factor = 0.1 * np.random.randn(n_features)\n", " X_seq[i, j] = base_sample + noise_factor\n", " \n", " print(f\"✓ Created sequence dataset shape: {X_seq.shape}\")\n", " return X_seq, y\n", "\n", "def load_and_preprocess_data():\n", " print(\"Loading and preprocessing Iris dataset...\")\n", " iris = load_iris()\n", " X, y = iris.data, iris.target\n", " \n", " print(f\"Original dataset shape: X={X.shape}, y={y.shape}\")\n", " print(f\"Class distribution: {np.bincount(y)}\")\n", " \n", " scaler = StandardScaler()\n", " X_scaled = scaler.fit_transform(X)\n", " \n", " X_train, X_temp, y_train, y_temp = train_test_split(\n", " X_scaled, y, test_size=0.4, random_state=42, stratify=y\n", " )\n", " X_val, X_test, y_val, y_test = train_test_split(\n", " X_temp, y_temp, test_size=0.5, random_state=42, stratify=y_temp\n", " )\n", " \n", " print(f\"Train set: {X_train.shape}, Val set: {X_val.shape}, Test set: {X_test.shape}\")\n", " \n", " X_train_seq, y_train_seq = create_sequence_dataset(X_train, y_train)\n", " X_val_seq, y_val_seq = create_sequence_dataset(X_val, y_val)\n", " X_test_seq, y_test_seq = create_sequence_dataset(X_test, y_test)\n", " \n", " train_dataset = TensorDataset(torch.FloatTensor(X_train_seq), torch.LongTensor(y_train_seq))\n", " val_dataset = TensorDataset(torch.FloatTensor(X_val_seq), torch.LongTensor(y_val_seq))\n", " test_dataset = TensorDataset(torch.FloatTensor(X_test_seq), torch.LongTensor(y_test_seq))\n", " \n", " train_loader = DataLoader(train_dataset, batch_size=16, shuffle=True)\n", " val_loader = DataLoader(val_dataset, batch_size=16, shuffle=False)\n", " test_loader = DataLoader(test_dataset, batch_size=16, shuffle=False)\n", " \n", " print(\"✓ DataLoaders created successfully\")\n", " return train_loader, val_loader, test_loader\n", "\n", "def train_model(model, train_loader, val_loader, epochs=50):\n", " print(f\"Starting training for {epochs} epochs...\")\n", " \n", " criterion = nn.CrossEntropyLoss()\n", " optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4)\n", " scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=20, gamma=0.5)\n", " \n", " train_losses = []\n", " val_losses = []\n", " train_accuracies = []\n", " val_accuracies = []\n", " \n", " best_val_acc = 0.0\n", " patience = 15\n", " patience_counter = 0\n", " \n", " for epoch in range(epochs):\n", " model.train()\n", " train_loss = 0.0\n", " train_correct = 0\n", " train_total = 0\n", " \n", " for batch_idx, (data, target) in enumerate(train_loader):\n", " data, target = data.to(device), target.to(device)\n", " \n", " if epoch == 0 and batch_idx == 0:\n", " print(f\"First batch shapes - data: {data.shape}, target: {target.shape}\")\n", " \n", " optimizer.zero_grad()\n", " \n", " output, attention_weights = model(data)\n", " loss = criterion(output, target)\n", " \n", " torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)\n", " \n", " loss.backward()\n", " optimizer.step()\n", " \n", " train_loss += loss.item()\n", " _, predicted = torch.max(output.data, 1)\n", " train_total += target.size(0)\n", " train_correct += (predicted == target).sum().item()\n", " \n", " model.eval()\n", " val_loss = 0.0\n", " val_correct = 0\n", " val_total = 0\n", " \n", " with torch.no_grad():\n", " for data, target in val_loader:\n", " data, target = data.to(device), target.to(device)\n", " \n", " output, _ = model(data)\n", " loss = criterion(output, target)\n", " \n", " val_loss += loss.item()\n", " _, predicted = torch.max(output.data, 1)\n", " val_total += target.size(0)\n", " val_correct += (predicted == target).sum().item()\n", " \n", " train_acc = 100. * train_correct / train_total\n", " val_acc = 100. * val_correct / val_total\n", " \n", " train_losses.append(train_loss / len(train_loader))\n", " val_losses.append(val_loss / len(val_loader))\n", " train_accuracies.append(train_acc)\n", " val_accuracies.append(val_acc)\n", " \n", " scheduler.step()\n", " \n", " if (epoch + 1) % 10 == 0:\n", " print(f'Epoch [{epoch+1}/{epochs}] - Train Loss: {train_losses[-1]:.4f}, Train Acc: {train_acc:.2f}% - Val Loss: {val_losses[-1]:.4f}, Val Acc: {val_acc:.2f}%')\n", " \n", " if val_acc > best_val_acc:\n", " best_val_acc = val_acc\n", " patience_counter = 0\n", " torch.save(model.state_dict(), 'best_attention_model.pth')\n", " else:\n", " patience_counter += 1\n", " if patience_counter >= patience:\n", " print(f\"Early stopping at epoch {epoch+1}\")\n", " break\n", " \n", " print(f\"✓ Training completed! Best validation accuracy: {best_val_acc:.2f}%\")\n", " return train_losses, val_losses, train_accuracies, val_accuracies\n", "\n", "def evaluate_model(model, test_loader):\n", " print(\"Evaluating model on test set...\")\n", " \n", " model.eval()\n", " all_predictions = []\n", " all_targets = []\n", " all_attention_weights = []\n", " \n", " with torch.no_grad():\n", " for data, target in test_loader:\n", " data, target = data.to(device), target.to(device)\n", " \n", " output, attention_weights = model(data)\n", " _, predicted = torch.max(output, 1)\n", " \n", " all_predictions.extend(predicted.cpu().numpy())\n", " all_targets.extend(target.cpu().numpy())\n", " all_attention_weights.append(attention_weights)\n", " \n", " accuracy = accuracy_score(all_targets, all_predictions)\n", " print(f\"✓ Test Accuracy: {accuracy:.4f}\")\n", " \n", " return accuracy, all_predictions, all_targets, all_attention_weights\n", "\n", "def test_sample_predictions(model, test_loader):\n", " print(\"Testing sample predictions...\")\n", " \n", " model.eval()\n", " iris = load_iris()\n", " class_names = iris.target_names\n", " \n", " with torch.no_grad():\n", " for data, target in test_loader:\n", " data, target = data.to(device), target.to(device)\n", " \n", " output, attention_weights = model(data)\n", " probabilities = F.softmax(output, dim=1)\n", " _, predicted = torch.max(output, 1)\n", " \n", " print(\"\\nSample Predictions:\")\n", " for i in range(min(3, data.size(0))):\n", " true_label = target[i].item()\n", " pred_label = predicted[i].item()\n", " confidence = probabilities[i].max().item()\n", " \n", " print(f\"Sample {i+1}: True={class_names[true_label]}, Pred={class_names[pred_label]}, Conf={confidence:.4f}\")\n", " \n", " break\n", "\n", "def visualize_attention(model, test_loader, num_samples=2):\n", " print(f\"Visualizing attention weights for {num_samples} samples...\")\n", " \n", " model.eval()\n", " sample_count = 0\n", " \n", " with torch.no_grad():\n", " for data, target in test_loader:\n", " data, target = data.to(device), target.to(device)\n", " \n", " output, attention_weights = model(data)\n", " \n", " for i in range(min(num_samples - sample_count, data.size(0))):\n", " attn_weights = attention_weights[0][i, 0].cpu().numpy()\n", " \n", " plt.figure(figsize=(8, 6))\n", " plt.imshow(attn_weights, cmap='Blues', aspect='auto')\n", " plt.colorbar()\n", " plt.title(f'Attention Weights - Sample {sample_count + 1}, True Label: {target[i].item()}')\n", " plt.xlabel('Key Position')\n", " plt.ylabel('Query Position')\n", " plt.show()\n", " \n", " sample_count += 1\n", " if sample_count >= num_samples:\n", " break\n", " \n", " if sample_count >= num_samples:\n", " break\n", "\n", "def main():\n", " print(\"🚀 Starting Attention Mechanism Implementation...\")\n", " \n", " train_loader, val_loader, test_loader = load_and_preprocess_data()\n", " \n", " model = AttentionClassifier(\n", " input_dim=4,\n", " d_model=64,\n", " n_heads=4,\n", " n_layers=2,\n", " n_classes=3,\n", " max_len=128\n", " ).to(device)\n", " \n", " total_params = sum(p.numel() for p in model.parameters() if p.requires_grad)\n", " print(f\"✓ Model created with {total_params:,} trainable parameters\")\n", " \n", " train_losses, val_losses, train_accuracies, val_accuracies = train_model(\n", " model, train_loader, val_loader, epochs=50\n", " )\n", " \n", " model.load_state_dict(torch.load('best_attention_model.pth'))\n", " print(\"✓ Best model weights loaded\")\n", " \n", " accuracy, predictions, targets, attention_weights = evaluate_model(model, test_loader)\n", " \n", " test_sample_predictions(model, test_loader)\n", " \n", " print(\"Creating visualizations...\")\n", " plt.figure(figsize=(15, 5))\n", " \n", " plt.subplot(1, 3, 1)\n", " plt.plot(train_losses, label='Train Loss')\n", " plt.plot(val_losses, label='Validation Loss')\n", " plt.title('Training and Validation Loss')\n", " plt.xlabel('Epoch')\n", " plt.ylabel('Loss')\n", " plt.legend()\n", " \n", " plt.subplot(1, 3, 2)\n", " plt.plot(train_accuracies, label='Train Accuracy')\n", " plt.plot(val_accuracies, label='Validation Accuracy')\n", " plt.title('Training and Validation Accuracy')\n", " plt.xlabel('Epoch')\n", " plt.ylabel('Accuracy (%)')\n", " plt.legend()\n", " \n", " plt.subplot(1, 3, 3)\n", " cm = confusion_matrix(targets, predictions)\n", " sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')\n", " plt.title('Confusion Matrix')\n", " plt.xlabel('Predicted')\n", " plt.ylabel('Actual')\n", " \n", " plt.tight_layout()\n", " plt.show()\n", " \n", " visualize_attention(model, test_loader)\n", " \n", " print(\"🎉 Implementation completed successfully!\")\n", "\n", "if __name__ == \"__main__\":\n", " main()" ] }, { "cell_type": "code", "execution_count": null, "id": "0c9d6ed2-db0f-4cde-a33e-2859adf3408a", "metadata": {}, "outputs": [], "source": [ "import torch\n", "import torch.nn as nn\n", "import torch.optim as optim\n", "import torch.nn.functional as F\n", "from torch.utils.data import DataLoader, TensorDataset\n", "import numpy as np\n", "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "from sklearn.datasets import load_iris\n", "from sklearn.model_selection import train_test_split\n", "from sklearn.preprocessing import StandardScaler\n", "from sklearn.metrics import accuracy_score, classification_report, confusion_matrix\n", "import math\n", "import warnings\n", "warnings.filterwarnings('ignore')\n", "\n", "# Automatically detect the best available device (Apple Silicon MPS, CUDA, or CPU)\n", "# MPS (Metal Performance Shaders) provides GPU acceleration on Apple Silicon Macs\n", "device = torch.device('mps' if torch.backends.mps.is_available() else 'cuda' if torch.cuda.is_available() else 'cpu')\n", "print(f\"Using device: {device}\")\n", "\n", "class MultiHeadAttention(nn.Module):\n", " \"\"\"\n", " Multi-Head Attention mechanism implementation.\n", " \n", " This is the core component that allows the model to focus on different parts\n", " of the input sequence simultaneously through multiple attention heads.\n", " \n", " Args:\n", " d_model: Dimensionality of the model (embedding size)\n", " n_heads: Number of attention heads to use in parallel\n", " \"\"\"\n", " \n", " def __init__(self, d_model, n_heads):\n", " super(MultiHeadAttention, self).__init__()\n", " self.d_model = d_model # Total embedding dimension\n", " self.n_heads = n_heads # Number of parallel attention heads\n", " self.d_k = d_model // n_heads # Dimension of each attention head\n", " \n", " # Ensure d_model is evenly divisible by n_heads for proper splitting\n", " assert d_model % n_heads == 0, \"d_model must be divisible by n_heads\"\n", " \n", " # Linear transformations for Query, Key, Value, and Output projections\n", " # These learn different representations for the attention mechanism\n", " self.W_q = nn.Linear(d_model, d_model) # Query projection\n", " self.W_k = nn.Linear(d_model, d_model) # Key projection \n", " self.W_v = nn.Linear(d_model, d_model) # Value projection\n", " self.W_o = nn.Linear(d_model, d_model) # Output projection\n", " \n", " # Dropout for regularization to prevent overfitting\n", " self.dropout = nn.Dropout(0.1)\n", " \n", " print(f\"✓ MultiHeadAttention initialized: d_model={d_model}, n_heads={n_heads}, d_k={self.d_k}\")\n", " \n", " def scaled_dot_product_attention(self, Q, K, V, mask=None):\n", " \"\"\"\n", " Compute scaled dot-product attention.\n", " \n", " Formula: Attention(Q,K,V) = softmax(QK^T / sqrt(d_k))V\n", " \n", " Args:\n", " Q: Query tensor [batch_size, n_heads, seq_len, d_k]\n", " K: Key tensor [batch_size, n_heads, seq_len, d_k] \n", " V: Value tensor [batch_size, n_heads, seq_len, d_k]\n", " mask: Optional mask to ignore certain positions\n", " \n", " Returns:\n", " context: Attention-weighted values\n", " attention_weights: Attention probability distributions\n", " \"\"\"\n", " d_k = Q.size(-1) # Get the key dimension for scaling\n", " \n", " # Compute attention scores: Q * K^T\n", " # Shape: [batch_size, n_heads, seq_len, seq_len]\n", " scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(d_k)\n", " \n", " # Apply mask if provided (e.g., for padding tokens)\n", " if mask is not None:\n", " scores = scores.masked_fill(mask == 0, -1e9) # Large negative value for masked positions\n", " \n", " # Apply softmax to get attention weights (probabilities)\n", " # Each row sums to 1, representing attention distribution\n", " attention_weights = F.softmax(scores, dim=-1)\n", " attention_weights = self.dropout(attention_weights) # Apply dropout for regularization\n", " \n", " # Compute weighted sum of values using attention weights\n", " # Shape: [batch_size, n_heads, seq_len, d_k]\n", " context = torch.matmul(attention_weights, V)\n", " \n", " return context, attention_weights\n", " \n", " def forward(self, query, key, value, mask=None):\n", " \"\"\"\n", " Forward pass for multi-head attention.\n", " \n", " Args:\n", " query: Query tensor [batch_size, seq_len, d_model]\n", " key: Key tensor [batch_size, seq_len, d_model]\n", " value: Value tensor [batch_size, seq_len, d_model]\n", " mask: Optional attention mask\n", " \n", " Returns:\n", " output: Attention output [batch_size, seq_len, d_model]\n", " attention_weights: Attention weights for visualization\n", " \"\"\"\n", " batch_size, seq_len, d_model = query.size()\n", " \n", " # Apply linear transformations and reshape for multi-head attention\n", " # Transform to [batch_size, n_heads, seq_len, d_k] for parallel processing\n", " Q = self.W_q(query).view(batch_size, seq_len, self.n_heads, self.d_k).transpose(1, 2)\n", " K = self.W_k(key).view(batch_size, seq_len, self.n_heads, self.d_k).transpose(1, 2)\n", " V = self.W_v(value).view(batch_size, seq_len, self.n_heads, self.d_k).transpose(1, 2)\n", " \n", " # Apply scaled dot-product attention to all heads simultaneously\n", " attention_output, attention_weights = self.scaled_dot_product_attention(Q, K, V, mask)\n", " \n", " # Concatenate all attention heads back together\n", " # Reshape from [batch_size, n_heads, seq_len, d_k] to [batch_size, seq_len, d_model]\n", " attention_output = attention_output.transpose(1, 2).contiguous().view(\n", " batch_size, seq_len, d_model\n", " )\n", " \n", " # Apply final linear transformation to get output\n", " output = self.W_o(attention_output)\n", " \n", " return output, attention_weights\n", "\n", "class PositionalEncoding(nn.Module):\n", " \"\"\"\n", " Positional encoding to give the model information about token positions.\n", " \n", " Since attention mechanisms are permutation-invariant, we need to inject\n", " positional information so the model knows the order of elements.\n", " \n", " Uses sinusoidal functions: PE(pos, 2i) = sin(pos/10000^(2i/d_model))\n", " PE(pos, 2i+1) = cos(pos/10000^(2i/d_model))\n", " \"\"\"\n", " \n", " def __init__(self, d_model, max_len=5000):\n", " super(PositionalEncoding, self).__init__()\n", " \n", " # Create positional encoding matrix\n", " pe = torch.zeros(max_len, d_model) # [max_len, d_model]\n", " position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1) # [max_len, 1]\n", " \n", " # Create division term for sinusoidal pattern\n", " # This creates different frequencies for different dimensions\n", " div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))\n", " \n", " # Apply sine to even indices (2i)\n", " pe[:, 0::2] = torch.sin(position * div_term)\n", " # Apply cosine to odd indices (2i+1) \n", " pe[:, 1::2] = torch.cos(position * div_term)\n", " \n", " # Reshape and register as buffer (not a parameter, but part of model state)\n", " pe = pe.unsqueeze(0).transpose(0, 1) # [max_len, 1, d_model]\n", " self.register_buffer('pe', pe)\n", " \n", " print(f\"✓ PositionalEncoding initialized: d_model={d_model}, max_len={max_len}\")\n", " \n", " def forward(self, x):\n", " \"\"\"\n", " Add positional encoding to input embeddings.\n", " \n", " Args:\n", " x: Input tensor [batch_size, seq_len, d_model]\n", " \n", " Returns:\n", " x + positional encoding: Enhanced input with position information\n", " \"\"\"\n", " seq_len = x.size(1)\n", " # Add positional encoding up to sequence length\n", " # The [:seq_len, :] ensures we only use the needed positions\n", " return x + self.pe[:seq_len, :].transpose(0, 1)\n", "\n", "class TransformerBlock(nn.Module):\n", " \"\"\"\n", " A complete Transformer block containing:\n", " 1. Multi-head self-attention\n", " 2. Feed-forward network\n", " 3. Residual connections\n", " 4. Layer normalization\n", " \n", " This follows the \"Attention Is All You Need\" architecture.\n", " \"\"\"\n", " \n", " def __init__(self, d_model, n_heads, d_ff, dropout=0.1):\n", " super(TransformerBlock, self).__init__()\n", " \n", " # Multi-head attention layer\n", " self.attention = MultiHeadAttention(d_model, n_heads)\n", " \n", " # Layer normalization layers (applied after residual connections)\n", " self.norm1 = nn.LayerNorm(d_model) # After attention\n", " self.norm2 = nn.LayerNorm(d_model) # After feed-forward\n", " \n", " # Position-wise feed-forward network\n", " # Expands to d_ff dimensions, then back to d_model\n", " self.feed_forward = nn.Sequential(\n", " nn.Linear(d_model, d_ff), # Expansion layer\n", " nn.ReLU(), # Non-linear activation\n", " nn.Dropout(dropout), # Regularization\n", " nn.Linear(d_ff, d_model) # Compression back to d_model\n", " )\n", " \n", " # Dropout for residual connections\n", " self.dropout = nn.Dropout(dropout)\n", " \n", " print(f\"✓ TransformerBlock initialized: d_model={d_model}, n_heads={n_heads}, d_ff={d_ff}\")\n", " \n", " def forward(self, x, mask=None):\n", " \"\"\"\n", " Forward pass with residual connections and layer normalization.\n", " \n", " Args:\n", " x: Input tensor [batch_size, seq_len, d_model]\n", " mask: Optional attention mask\n", " \n", " Returns:\n", " x: Transformed tensor [batch_size, seq_len, d_model]\n", " attn_weights: Attention weights for analysis\n", " \"\"\"\n", " # Self-attention with residual connection and layer norm\n", " # Pattern: LayerNorm(x + Sublayer(x))\n", " attn_output, attn_weights = self.attention(x, x, x, mask) # Self-attention (Q=K=V=x)\n", " x = self.norm1(x + self.dropout(attn_output)) # Add & Norm\n", " \n", " # Feed-forward with residual connection and layer norm\n", " ff_output = self.feed_forward(x)\n", " x = self.norm2(x + self.dropout(ff_output)) # Add & Norm\n", " \n", " return x, attn_weights\n", "\n", "class AttentionClassifier(nn.Module):\n", " \"\"\"\n", " Complete attention-based classifier for sequence data.\n", " \n", " Architecture:\n", " 1. Input projection to d_model dimensions\n", " 2. Positional encoding\n", " 3. Stack of Transformer blocks\n", " 4. Global average pooling\n", " 5. Classification head\n", " \"\"\"\n", " \n", " def __init__(self, input_dim, d_model, n_heads, n_layers, n_classes, max_len=128):\n", " super(AttentionClassifier, self).__init__()\n", " self.d_model = d_model\n", " \n", " # Project input features to model dimension\n", " # This is necessary because attention expects fixed d_model size\n", " self.input_projection = nn.Linear(input_dim, d_model)\n", " \n", " # Add positional information to embeddings\n", " self.pos_encoding = PositionalEncoding(d_model, max_len)\n", " \n", " # Stack of Transformer blocks for deep feature learning\n", " # Each block can capture different levels of abstraction\n", " self.transformer_blocks = nn.ModuleList([\n", " TransformerBlock(d_model, n_heads, d_model * 4) # d_ff = 4 * d_model (common practice)\n", " for _ in range(n_layers)\n", " ])\n", " \n", " # Classification head with dropout for regularization\n", " self.classifier = nn.Sequential(\n", " nn.Linear(d_model, d_model // 2), # Reduce dimensions\n", " nn.ReLU(), # Non-linear activation\n", " nn.Dropout(0.1), # Prevent overfitting\n", " nn.Linear(d_model // 2, n_classes) # Final classification layer\n", " )\n", " \n", " print(f\"✓ AttentionClassifier initialized: input_dim={input_dim}, d_model={d_model}, n_heads={n_heads}, n_layers={n_layers}, n_classes={n_classes}\")\n", " \n", " def forward(self, x):\n", " \"\"\"\n", " Forward pass through the entire model.\n", " \n", " Args:\n", " x: Input tensor [batch_size, seq_len, input_dim]\n", " \n", " Returns:\n", " output: Classification logits [batch_size, n_classes]\n", " attention_weights: List of attention weights from each layer\n", " \"\"\"\n", " # Project input to model dimension\n", " # [batch_size, seq_len, input_dim] -> [batch_size, seq_len, d_model]\n", " x = self.input_projection(x)\n", " \n", " # Add positional encoding to give sequence order information\n", " x = self.pos_encoding(x)\n", " \n", " # Pass through all Transformer blocks, collecting attention weights\n", " attention_weights = []\n", " for transformer_block in self.transformer_blocks:\n", " x, attn_weights = transformer_block(x)\n", " attention_weights.append(attn_weights) # Store for visualization\n", " \n", " # Global average pooling to convert sequence to single vector\n", " # [batch_size, seq_len, d_model] -> [batch_size, d_model]\n", " x = torch.mean(x, dim=1)\n", " \n", " # Apply classification head to get final predictions\n", " # [batch_size, d_model] -> [batch_size, n_classes]\n", " output = self.classifier(x)\n", " \n", " return output, attention_weights\n", "\n", "def create_sequence_dataset(X, y, seq_len=10):\n", " \"\"\"\n", " Convert tabular data into sequence format for attention models.\n", " \n", " This creates artificial sequences by adding noise to the original features,\n", " simulating a scenario where we have temporal or sequential data.\n", " \n", " Args:\n", " X: Feature matrix [n_samples, n_features]\n", " y: Target labels [n_samples]\n", " seq_len: Length of sequences to create\n", " \n", " Returns:\n", " X_seq: Sequence data [n_samples, seq_len, n_features]\n", " y: Original labels (unchanged)\n", " \"\"\"\n", " print(f\"Creating sequence dataset with seq_len={seq_len}\")\n", " print(f\"Original data shape: X={X.shape}, y={y.shape}\")\n", " \n", " n_samples = X.shape[0]\n", " n_features = X.shape[1]\n", " \n", " # Initialize sequence array\n", " X_seq = np.zeros((n_samples, seq_len, n_features))\n", " \n", " # For each sample, create a sequence by adding controlled noise\n", " for i in range(n_samples):\n", " base_sample = X[i] # Original feature vector\n", " for j in range(seq_len):\n", " # Add small random noise to create sequence variation\n", " # This simulates natural variation in sequential data\n", " noise_factor = 0.1 * np.random.randn(n_features)\n", " X_seq[i, j] = base_sample + noise_factor\n", " \n", " print(f\"✓ Created sequence dataset shape: {X_seq.shape}\")\n", " return X_seq, y\n", "\n", "def load_and_preprocess_data():\n", " \"\"\"\n", " Load and preprocess the Iris dataset for attention-based classification.\n", " \n", " Steps:\n", " 1. Load Iris dataset\n", " 2. Standardize features\n", " 3. Create train/validation/test splits with stratification\n", " 4. Convert to sequence format\n", " 5. Create PyTorch DataLoaders\n", " \n", " Returns:\n", " train_loader, val_loader, test_loader: PyTorch DataLoaders\n", " \"\"\"\n", " print(\"Loading and preprocessing Iris dataset...\")\n", " \n", " # Load the classic Iris dataset (150 samples, 4 features, 3 classes)\n", " iris = load_iris()\n", " X, y = iris.data, iris.target\n", " \n", " print(f\"Original dataset shape: X={X.shape}, y={y.shape}\")\n", " print(f\"Class distribution: {np.bincount(y)}\") # Should be [50, 50, 50] for balanced dataset\n", " \n", " # Standardize features to have zero mean and unit variance\n", " # This is crucial for neural networks to train effectively\n", " scaler = StandardScaler()\n", " X_scaled = scaler.fit_transform(X)\n", " \n", " # Create stratified train/validation/test splits\n", " # Stratification ensures each split has the same class distribution\n", " X_train, X_temp, y_train, y_temp = train_test_split(\n", " X_scaled, y, test_size=0.4, random_state=42, stratify=y\n", " )\n", " X_val, X_test, y_val, y_test = train_test_split(\n", " X_temp, y_temp, test_size=0.5, random_state=42, stratify=y_temp\n", " )\n", " \n", " print(f\"Train set: {X_train.shape}, Val set: {X_val.shape}, Test set: {X_test.shape}\")\n", " \n", " # Convert tabular data to sequence format for attention processing\n", " X_train_seq, y_train_seq = create_sequence_dataset(X_train, y_train)\n", " X_val_seq, y_val_seq = create_sequence_dataset(X_val, y_val)\n", " X_test_seq, y_test_seq = create_sequence_dataset(X_test, y_test)\n", " \n", " # Create PyTorch datasets and dataloaders\n", " # TensorDataset combines features and labels into a single dataset\n", " train_dataset = TensorDataset(torch.FloatTensor(X_train_seq), torch.LongTensor(y_train_seq))\n", " val_dataset = TensorDataset(torch.FloatTensor(X_val_seq), torch.LongTensor(y_val_seq))\n", " test_dataset = TensorDataset(torch.FloatTensor(X_test_seq), torch.LongTensor(y_test_seq))\n", " \n", " # DataLoaders handle batching and shuffling\n", " # Batch size of 16 works well for this small dataset\n", " train_loader = DataLoader(train_dataset, batch_size=16, shuffle=True) # Shuffle for training\n", " val_loader = DataLoader(val_dataset, batch_size=16, shuffle=False) # No shuffle for validation\n", " test_loader = DataLoader(test_dataset, batch_size=16, shuffle=False) # No shuffle for testing\n", " \n", " print(\"✓ DataLoaders created successfully\")\n", " return train_loader, val_loader, test_loader\n", "\n", "def train_model(model, train_loader, val_loader, epochs=50):\n", " \"\"\"\n", " Train the attention model with proper optimization and regularization.\n", " \n", " Features:\n", " - Adam optimizer with weight decay\n", " - Learning rate scheduling\n", " - Gradient clipping\n", " - Early stopping\n", " - Comprehensive logging\n", " \n", " Args:\n", " model: The attention model to train\n", " train_loader: Training data loader\n", " val_loader: Validation data loader\n", " epochs: Maximum number of epochs\n", " \n", " Returns:\n", " Training history (losses and accuracies)\n", " \"\"\"\n", " print(f\"Starting training for {epochs} epochs...\")\n", " \n", " # CrossEntropyLoss is standard for multi-class classification\n", " # It combines LogSoftmax and NLLLoss for numerical stability\n", " criterion = nn.CrossEntropyLoss()\n", " \n", " # Adam optimizer with weight decay for regularization\n", " # lr=0.001 is a good starting point, weight_decay prevents overfitting\n", " optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4)\n", " \n", " # Learning rate scheduler reduces lr when learning plateaus\n", " # StepLR reduces lr by gamma every step_size epochs\n", " scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=20, gamma=0.5)\n", " \n", " # Track training history for analysis\n", " train_losses = []\n", " val_losses = []\n", " train_accuracies = []\n", " val_accuracies = []\n", " \n", " # Early stopping parameters to prevent overfitting\n", " best_val_acc = 0.0 # Best validation accuracy seen so far\n", " patience = 15 # Number of epochs to wait without improvement\n", " patience_counter = 0 # Current count of epochs without improvement\n", " \n", " for epoch in range(epochs):\n", " # Training phase\n", " model.train() # Set model to training mode (enables dropout, batch norm updates)\n", " train_loss = 0.0\n", " train_correct = 0\n", " train_total = 0\n", " \n", " for batch_idx, (data, target) in enumerate(train_loader):\n", " # Move data to the appropriate device (CPU/GPU/MPS)\n", " data, target = data.to(device), target.to(device)\n", " \n", " # Log tensor shapes for the first batch to verify correctness\n", " if epoch == 0 and batch_idx == 0:\n", " print(f\"First batch shapes - data: {data.shape}, target: {target.shape}\")\n", " \n", " # Zero gradients from previous iteration\n", " optimizer.zero_grad()\n", " \n", " # Forward pass through the model\n", " output, attention_weights = model(data)\n", " \n", " # Calculate loss between predictions and true labels\n", " loss = criterion(output, target)\n", " \n", " # Clip gradients to prevent exploding gradient problem\n", " # This is especially important for attention models\n", " torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)\n", " \n", " # Backward pass to compute gradients\n", " loss.backward()\n", " \n", " # Update model parameters\n", " optimizer.step()\n", " \n", " # Accumulate training statistics\n", " train_loss += loss.item()\n", " _, predicted = torch.max(output.data, 1) # Get predicted class\n", " train_total += target.size(0)\n", " train_correct += (predicted == target).sum().item()\n", " \n", " # Validation phase\n", " model.eval() # Set model to evaluation mode (disables dropout, batch norm updates)\n", " val_loss = 0.0\n", " val_correct = 0\n", " val_total = 0\n", " \n", " # Disable gradient computation for efficiency and memory\n", " with torch.no_grad():\n", " for data, target in val_loader:\n", " data, target = data.to(device), target.to(device)\n", " \n", " # Forward pass only (no backward pass in validation)\n", " output, _ = model(data)\n", " loss = criterion(output, target)\n", " \n", " # Accumulate validation statistics\n", " val_loss += loss.item()\n", " _, predicted = torch.max(output.data, 1)\n", " val_total += target.size(0)\n", " val_correct += (predicted == target).sum().item()\n", " \n", " # Calculate accuracies as percentages\n", " train_acc = 100. * train_correct / train_total\n", " val_acc = 100. * val_correct / val_total\n", " \n", " # Store metrics for plotting\n", " train_losses.append(train_loss / len(train_loader))\n", " val_losses.append(val_loss / len(val_loader))\n", " train_accuracies.append(train_acc)\n", " val_accuracies.append(val_acc)\n", " \n", " # Update learning rate according to schedule\n", " scheduler.step()\n", " \n", " # Print progress every 10 epochs\n", " if (epoch + 1) % 10 == 0:\n", " print(f'Epoch [{epoch+1}/{epochs}] - Train Loss: {train_losses[-1]:.4f}, Train Acc: {train_acc:.2f}% - Val Loss: {val_losses[-1]:.4f}, Val Acc: {val_acc:.2f}%')\n", " \n", " # Early stopping logic\n", " if val_acc > best_val_acc:\n", " best_val_acc = val_acc\n", " patience_counter = 0\n", " # Save the best model weights\n", " torch.save(model.state_dict(), 'best_attention_model.pth')\n", " else:\n", " patience_counter += 1\n", " if patience_counter >= patience:\n", " print(f\"Early stopping at epoch {epoch+1}\")\n", " break\n", " \n", " print(f\"✓ Training completed! Best validation accuracy: {best_val_acc:.2f}%\")\n", " return train_losses, val_losses, train_accuracies, val_accuracies\n", "\n", "def evaluate_model(model, test_loader):\n", " \"\"\"\n", " Evaluate the trained model on the test set.\n", " \n", " Args:\n", " model: Trained model\n", " test_loader: Test data loader\n", " \n", " Returns:\n", " accuracy: Test accuracy\n", " predictions: Model predictions\n", " targets: True labels\n", " attention_weights: Attention weights for analysis\n", " \"\"\"\n", " print(\"Evaluating model on test set...\")\n", " \n", " model.eval() # Set to evaluation mode\n", " all_predictions = []\n", " all_targets = []\n", " all_attention_weights = []\n", " \n", " # No gradient computation needed for evaluation\n", " with torch.no_grad():\n", " for data, target in test_loader:\n", " data, target = data.to(device), target.to(device)\n", " \n", " # Get model predictions and attention weights\n", " output, attention_weights = model(data)\n", " _, predicted = torch.max(output, 1) # Get class with highest probability\n", " \n", " # Collect results for analysis\n", " all_predictions.extend(predicted.cpu().numpy())\n", " all_targets.extend(target.cpu().numpy())\n", " all_attention_weights.append(attention_weights)\n", " \n", " # Calculate overall test accuracy\n", " accuracy = accuracy_score(all_targets, all_predictions)\n", " print(f\"✓ Test Accuracy: {accuracy:.4f}\")\n", " \n", " return accuracy, all_predictions, all_targets, all_attention_weights\n", "\n", "def test_sample_predictions(model, test_loader):\n", " \"\"\"\n", " Test the model on individual samples and show predictions with confidence.\n", " \n", " This helps understand how confident the model is in its predictions\n", " and provides insight into potential failure cases.\n", " \"\"\"\n", " print(\"Testing sample predictions...\")\n", " \n", " model.eval()\n", " iris = load_iris()\n", " class_names = iris.target_names # ['setosa', 'versicolor', 'virginica']\n", " \n", " with torch.no_grad():\n", " for data, target in test_loader:\n", " data, target = data.to(device), target.to(device)\n", " \n", " # Get model output and convert to probabilities\n", " output, attention_weights = model(data)\n", " probabilities = F.softmax(output, dim=1) # Convert logits to probabilities\n", " _, predicted = torch.max(output, 1)\n", " \n", " print(\"\\nSample Predictions:\")\n", " # Show first 3 samples from the batch\n", " for i in range(min(3, data.size(0))):\n", " true_label = target[i].item()\n", " pred_label = predicted[i].item()\n", " confidence = probabilities[i].max().item() # Highest probability\n", " \n", " print(f\"Sample {i+1}: True={class_names[true_label]}, Pred={class_names[pred_label]}, Conf={confidence:.4f}\")\n", " \n", " break # Only show first batch\n", "\n", "def visualize_attention(model, test_loader, num_samples=2):\n", " \"\"\"\n", " Visualize attention weights to understand what the model focuses on.\n", " \n", " Attention visualization helps interpret the model's decision-making process\n", " by showing which parts of the input sequence receive the most attention.\n", " \n", " Args:\n", " model: Trained model\n", " test_loader: Test data loader\n", " num_samples: Number of samples to visualize\n", " \"\"\"\n", " print(f\"Visualizing attention weights for {num_samples} samples...\")\n", " \n", " model.eval()\n", " sample_count = 0\n", " \n", " with torch.no_grad():\n", " for data, target in test_loader:\n", " data, target = data.to(device), target.to(device)\n", " \n", " # Get attention weights from the model\n", " output, attention_weights = model(data)\n", " \n", " # Visualize attention for each sample\n", " for i in range(min(num_samples - sample_count, data.size(0))):\n", " # Extract attention weights from first layer, first head\n", " # Shape: [seq_len, seq_len] showing attention between all position pairs\n", " attn_weights = attention_weights[0][i, 0].cpu().numpy()\n", " \n", " # Create heatmap visualization\n", " plt.figure(figsize=(8, 6))\n", " plt.imshow(attn_weights, cmap='Blues', aspect='auto')\n", " plt.colorbar(label='Attention Weight')\n", " plt.title(f'Attention Weights - Sample {sample_count + 1}, True Label: {target[i].item()}')\n", " plt.xlabel('Key Position')\n", " plt.ylabel('Query Position')\n", " plt.show()\n", " \n", " sample_count += 1\n", " if sample_count >= num_samples:\n", " break\n", " \n", " if sample_count >= num_samples:\n", " break\n", "\n", "def main():\n", " \"\"\"\n", " Main function that orchestrates the entire training and evaluation pipeline.\n", " \n", " This function demonstrates a complete machine learning workflow:\n", " 1. Data loading and preprocessing\n", " 2. Model initialization\n", " 3. Training with validation\n", " 4. Evaluation on test set\n", " 5. Visualization and analysis\n", " \"\"\"\n", " print(\"🚀 Starting Attention Mechanism Implementation...\")\n", " \n", " # Step 1: Load and preprocess data\n", " train_loader, val_loader, test_loader = load_and_preprocess_data()\n", " \n", " # Step 2: Initialize the attention model\n", " model = AttentionClassifier(\n", " input_dim=4, # 4 features in Iris dataset\n", " d_model=64, # Model dimension (embedding size)\n", " n_heads=4, # Number of attention heads\n", " n_layers=2, # Number of transformer blocks\n", " n_classes=3, # 3 classes in Iris dataset\n", " max_len=128 # Maximum sequence length\n", " ).to(device)\n", " \n", " # Count total trainable parameters\n", " total_params = sum(p.numel() for p in model.parameters() if p.requires_grad)\n", " print(f\"✓ Model created with {total_params:,} trainable parameters\")\n", " \n", " # Step 3: Train the model\n", " train_losses, val_losses, train_accuracies, val_accuracies = train_model(\n", " model, train_loader, val_loader, epochs=50\n", " )\n", " \n", " # Step 4: Load best model weights and evaluate\n", " model.load_state_dict(torch.load('best_attention_model.pth'))\n", " print(\"✓ Best model weights loaded\")\n", " \n", " accuracy, predictions, targets, attention_weights = evaluate_model(model, test_loader)\n", " \n", " # Step 5: Test individual predictions\n", " test_sample_predictions(model, test_loader)\n", " \n", " # Step 6: Create comprehensive visualizations\n", " print(\"Creating visualizations...\")\n", " plt.figure(figsize=(15, 5))\n", " \n", " # Plot 1: Training and validation loss\n", " plt.subplot(1, 3, 1)\n", " plt.plot(train_losses, label='Train Loss', color='blue')\n", " plt.plot(val_losses, label='Validation Loss', color='red')\n", " plt.title('Training and Validation Loss')\n", " plt.xlabel('Epoch')\n", " plt.ylabel('Loss')\n", " plt.legend()\n", " plt.grid(True, alpha=0.3)\n", "\n", " # Plot 2: Training and validation accuracy\n", " plt.subplot(1, 3, 2)\n", " plt.plot(train_accuracies, label='Train Accuracy', color='blue')\n", " plt.plot(val_accuracies, label='Validation Accuracy', color='red')\n", " plt.title('Training and Validation Accuracy')\n", " plt.xlabel('Epoch')\n", " plt.ylabel('Accuracy (%)')\n", " plt.legend()\n", " plt.grid(True, alpha=0.3)\n", " \n", " # Plot 3: Confusion matrix for test set\n", " plt.subplot(1, 3, 3)\n", " cm = confusion_matrix(targets, predictions)\n", " sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', \n", " xticklabels=['Setosa', 'Versicolor', 'Virginica'],\n", " yticklabels=['Setosa', 'Versicolor', 'Virginica'])\n", " plt.title('Confusion Matrix')\n", " plt.xlabel('Predicted')\n", " plt.ylabel('Actual')\n", " \n", " plt.tight_layout()\n", " plt.show()\n", " \n", " # Step 7: Visualize attention patterns\n", " visualize_attention(model, test_loader)\n", " \n", " print(\"🎉 Implementation completed successfully!\")\n", "\n", "# Execute the main function when script is run directly\n", "if __name__ == \"__main__\":\n", " main()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.13.5" } }, "nbformat": 4, "nbformat_minor": 5 }