課題:3.3章(P58):簡単なSelf-Attention機構を使って、コンテキストベクトルを作る章を理解する
取り組み:LLM本の説明を正しく理解しているか検証のため、ライブラリを使わず、素でn次元配列を演算して、コンテキストベクトルを生成する
結論:LLM本の実行例の通りには計算できた
詳細:
LLM本ではコンテキストベクトルを作るための演算が図解されている。理解があってるのかを確かめるため、ライブラリを使わず素でコンテキストベクトルを生成する。試作コードは以下
#!/usr/bin/python3
#
# self Attention functions (simple version)
# (LLM from Scratch ... Section 3.3; self attentino P.64 - P.67 )
#
import math
def get_context_vector(token, attention_vector):
context_vector = [None] * len(token)
for nth_context in range(len(token)):
context_vector[nth_context] = [0] * len(token[nth_context])
for nth_token in range(len(token)):
for nth_vector in range(len(token[nth_token])):
context_vector[nth_context][nth_vector] += token[nth_token][nth_vector] * attention_vector[nth_context][nth_token]
return context_vector
def get_attention_vector(vector):
attention_vector = []
for i in range(len(vector)):
attention_vector.append(get_attention_score(vector, i))
return attention_vector
def get_attention_score(vector, n):
attention = []
for i in range(len(vector)):
attention.append(inner_product(vector[n], vector[i]))
attention = soft_max(attention)
return attention
def inner_product(x, y):
value = 0
if len(x) != len(y):
print('Error! not same dimension')
return None
else:
for i in range(len(x)):
value += x[i] * y[i]
return value
def soft_max(ary):
exp_values = [math.exp(x) for x in ary]
sum_value = sum(exp_values)
smax_values = [x/sum_value for x in exp_values]
return smax_values上記を実行してみる
#!/usr/bin/python3 from lib.attention import * token_vector = ( (0.43, 0.15, 0.89), (0.55, 0.87, 0.66), (0.57, 0.85, 0.64), (0.22, 0.58, 0.33), (0.77, 0.25, 0.10), (0.05, 0.80, 0.55), ) attention_v = get_attention_vector(token_vector) context_v = get_context_vector(token_vector, attention_v) print(context_v) # # $ python3 test_att.py # [[0.44205939860215243, 0.5930985621414954, 0.5789890706688827], # [0.4418657478512921, 0.651481978030222, 0.5683088877257294], # [0.4431275119837131, 0.6495945789684161, 0.56707305766733], # [0.4303897327932225, 0.6298280620566503, 0.5510270600472974], # [0.46710172950836115, 0.5909927255410325, 0.5265965239654562], # [0.4177244739388295, 0.6503232057064708, 0.5645352170639022] # ]
上記コンテキストベクトルは、LLM本のP66の結果と一致するのでまぁ計算方法は合っているだろうと判断
ただ、、やっつけ実装なので、、次元が変わった時でも正しく計算できるのかは不明。なお、これはSimpleな実装のため学習できないらしく、3.4章で学習可能なSelf-Attentionが説明される。例の、クエリ、キー、値で定義?されるAttentionの仕組み。正月休み中にはまとまった時間が取れるので、学習可能なSelf-AttentionとMulti-Headまでは終えたい。
■補足
バックプロパゲーションも手で書けるかとClaudeに相談したら、「基礎的な数学の知識で実装できます」と言ってきたので、ライブラリを使わず、できるところまで素で実装してみる。