-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy patheducational_examples.py
More file actions
222 lines (179 loc) · 7.61 KB
/
Copy patheducational_examples.py
File metadata and controls
222 lines (179 loc) · 7.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
"""
Educational Examples for Understanding Transformers
This script provides step-by-step examples to understand how transformer components work.
Run different functions to explore specific concepts interactively.
"""
import torch
import torch.nn as nn
import math
import matplotlib.pyplot as plt
from model import MultiHeadAttentionBlock, PositionalEncoding, LayerNormalization
def example_1_attention_mechanism():
"""
Example 1: Understanding the Attention Mechanism
This example shows how attention works with a simple sentence.
"""
print("="*60)
print("EXAMPLE 1: How Attention Works")
print("="*60)
# Simple example sentence: "The cat sat on the mat"
sentence = ["The", "cat", "sat", "on", "the", "mat"]
print(f"Sentence: {' '.join(sentence)}")
# Simplified attention scores (manually created for illustration)
# Each row shows how much each word attends to every word
attention_matrix = torch.tensor([
# The cat sat on the mat
[0.2, 0.1, 0.1, 0.1, 0.4, 0.1], # The
[0.1, 0.6, 0.2, 0.0, 0.0, 0.1], # cat
[0.1, 0.3, 0.4, 0.1, 0.0, 0.1], # sat
[0.1, 0.0, 0.2, 0.3, 0.1, 0.3], # on
[0.4, 0.1, 0.1, 0.1, 0.2, 0.1], # the
[0.1, 0.2, 0.1, 0.2, 0.1, 0.3], # mat
])
print("\nAttention Matrix (how much each word attends to others):")
print("Rows=Query words, Columns=Key words")
print(" ", end="")
for word in sentence:
print(f"{word:>6}", end="")
print()
for i, word in enumerate(sentence):
print(f"{word:>4}:", end="")
for j in range(len(sentence)):
print(f"{attention_matrix[i,j].item():6.2f}", end="")
print()
print("\nInterpretation:")
print("- 'cat' attends strongly to itself (0.60) - self-attention")
print("- 'sat' attends to 'cat' (0.30) - verb attending to subject")
print("- 'The' words attend to each other (0.40) - similar function words")
print("- 'on' attends to 'mat' (0.30) - preposition attending to object")
def example_2_positional_encoding():
"""
Example 2: Understanding Positional Encoding
Shows how transformers add position information to word embeddings.
"""
print("\n" + "="*60)
print("EXAMPLE 2: Positional Encoding")
print("="*60)
d_model = 8 # Small model dimension for illustration
seq_len = 6 # Length of our example sentence
# Create positional encoding
pos_encoding = PositionalEncoding(d_model, seq_len, dropout=0.0)
# Extract the positional encoding matrix
pe_matrix = pos_encoding.pe.squeeze(0) # Remove batch dimension
print(f"Positional encodings for {seq_len} positions with d_model={d_model}")
print("Each row represents the positional encoding for one position:")
print("Columns alternate between sin and cos functions")
for pos in range(seq_len):
print(f"Position {pos}: ", end="")
for dim in range(d_model):
print(f"{pe_matrix[pos, dim].item():6.3f}", end=" ")
print()
print("\nKey insights:")
print("- Each position gets a unique encoding pattern")
print("- Sin/cos functions create patterns the model can learn")
print("- Similar positions have similar (but not identical) encodings")
# Visualize if matplotlib is available
try:
plt.figure(figsize=(10, 6))
plt.imshow(pe_matrix.numpy(), cmap='RdBu', aspect='auto')
plt.title('Positional Encoding Visualization')
plt.xlabel('Model Dimension')
plt.ylabel('Position')
plt.colorbar()
plt.show()
print("- See the visualization above for the sin/cos patterns!")
except:
print("- Install matplotlib to see the visualization")
def example_3_multi_head_attention():
"""
Example 3: Multi-Head Attention in Action
Shows how multiple attention heads can focus on different relationships.
"""
print("\n" + "="*60)
print("EXAMPLE 3: Multi-Head Attention")
print("="*60)
d_model = 8
num_heads = 2
seq_len = 4
# Create a small multi-head attention block
mha = MultiHeadAttentionBlock(d_model, num_heads, dropout=0.0)
# Create dummy input (batch_size=1, seq_len=4, d_model=8)
x = torch.randn(1, seq_len, d_model)
print(f"Input shape: {x.shape}")
print(f"Model dimension: {d_model}")
print(f"Number of heads: {num_heads}")
print(f"Dimension per head: {d_model // num_heads}")
# Forward pass
with torch.no_grad():
output = mha(x, x, x, mask=None) # Self-attention (Q=K=V=x)
print(f"Output shape: {output.shape}")
# Access attention scores from the last forward pass
attention_scores = mha.attention_scores # Shape: (batch, heads, seq_len, seq_len)
print(f"Attention scores shape: {attention_scores.shape}")
print("\nAttention patterns for each head:")
for head in range(num_heads):
print(f"\nHead {head} attention matrix:")
head_attention = attention_scores[0, head] # Remove batch dimension
for i in range(seq_len):
print(f" Pos {i}: ", end="")
for j in range(seq_len):
print(f"{head_attention[i,j].item():6.3f}", end=" ")
print()
print("\nKey insights:")
print("- Each head learns different attention patterns")
print("- Multiple heads capture different types of relationships")
print("- Final output combines information from all heads")
def example_4_layer_normalization():
"""
Example 4: Layer Normalization
Shows how layer normalization stabilizes training.
"""
print("\n" + "="*60)
print("EXAMPLE 4: Layer Normalization")
print("="*60)
d_model = 4
layer_norm = LayerNormalization(d_model)
# Create input with different scales
x1 = torch.tensor([[1.0, 2.0, 3.0, 4.0]]) # Small values
x2 = torch.tensor([[100.0, 200.0, 300.0, 400.0]]) # Large values
x3 = torch.tensor([[1.0, 100.0, 2.0, 200.0]]) # Mixed values
print("Input examples:")
print(f"Small values: {x1}")
print(f"Large values: {x2}")
print(f"Mixed values: {x3}")
with torch.no_grad():
norm1 = layer_norm(x1)
norm2 = layer_norm(x2)
norm3 = layer_norm(x3)
print("\nAfter layer normalization:")
print(f"Small values: {norm1}")
print(f"Large values: {norm2}")
print(f"Mixed values: {norm3}")
print("\nKey insights:")
print("- All outputs have mean ≈ 0 and standard deviation ≈ 1")
print("- Relative relationships are preserved")
print("- This helps with training stability and gradient flow")
def run_all_examples():
"""Run all educational examples in sequence."""
print("🎓 TRANSFORMER EDUCATIONAL EXAMPLES")
print("🎓 Understanding Transformers Step by Step\n")
example_1_attention_mechanism()
example_2_positional_encoding()
example_3_multi_head_attention()
example_4_layer_normalization()
print("\n" + "="*60)
print("🎉 Congratulations! You've explored key transformer concepts!")
print("="*60)
print("\nNext steps:")
print("1. Run attention.py to see real attention patterns")
print("2. Train your own model with train.py")
print("3. Experiment with different architectures")
print("4. Read the 'Attention is All You Need' paper")
if __name__ == "__main__":
# You can run specific examples or all of them
run_all_examples()
# Or run individual examples:
# example_1_attention_mechanism()
# example_2_positional_encoding()
# example_3_multi_head_attention()
# example_4_layer_normalization()