Code: Select all | Expand
FUNCTION Main()
LOCAL aEmbeddings, aWq, aWk, aWv, aBq, aBk, aBv
LOCAL aQ, aK, aV
LOCAL aAttentionScores, aOutput
// Simulamos embeddings y matrices de peso (normalmente serían cargados o generados)
aEmbeddings := GenerateRandomMatrix(3, 4) // [batch_size, seq_len, d_model]
aWq := GenerateRandomMatrix(4, 2) // [d_model, d_k]
aWk := GenerateRandomMatrix(4, 2)
aWv := GenerateRandomMatrix(4, 2)
aBq := GenerateRandomVector(2) // [d_k]
aBk := GenerateRandomVector(2)
aBv := GenerateRandomVector(2)
? aEmbeddings
// Realizamos las transformaciones lineales
aQ := LinearTransformation(aEmbeddings, aWq, aBq)
aK := LinearTransformation(aEmbeddings, aWk, aBk)
aV := LinearTransformation(aEmbeddings, aWv, aBv)
// Calculamos las puntuaciones de atención
aAttentionScores := CalculateAttentionScores(aQ, aK)
// Aplicamos las puntuaciones de atención a los valores
aOutput := ApplyAttention(aAttentionScores, aV)
// Imprimimos los resultados
? "Query:", aQ
? "Key:", aK
? "Value:", aV
? "Attention Scores:", aAttentionScores
? "Output:", aOutput
RETURN NIL
FUNCTION LinearTransformation(aX, aW, aB)
LOCAL aResult, i, j, k, nSum
LOCAL nRows := Len(aX), nCols := Len(aW[1]), nInner := Len(aW)
aResult := Array(nRows)
FOR i := 1 TO nRows
aResult[i] := Array(nCols)
FOR j := 1 TO nCols
nSum := 0
FOR k := 1 TO nInner
nSum += aX[i][k] * aW[k][j]
NEXT
aResult[i][j] := nSum + aB[j]
NEXT
NEXT
RETURN aResult
FUNCTION GenerateRandomMatrix(nRows, nCols)
LOCAL aMatrix := Array(nRows, nCols), i, j
FOR i := 1 TO nRows
FOR j := 1 TO nCols
aMatrix[i,j] := hb_Random(-1, 1)
NEXT
NEXT
RETURN aMatrix
FUNCTION GenerateRandomVector(nSize)
LOCAL aVector := Array(nSize), i
FOR i := 1 TO nSize
aVector[i] := hb_Random(-1, 1)
NEXT
RETURN aVector
FUNCTION CalculateAttentionScores(aQ, aK)
LOCAL aScores, i, j, k, nSum, nExpSum
LOCAL nRowsQ := Len(aQ), nColsQ := Len(aQ[1])
LOCAL nRowsK := Len(aK), nColsK := Len(aK[1])
// aQ y aK deben tener el mismo número de columnas (d_k)
IF nColsQ <> nColsK
? "Error: Las dimensiones de aQ y aK no coinciden"
RETURN NIL
ENDIF
aScores := Array(nRowsQ, nRowsK)
FOR i := 1 TO nRowsQ
FOR j := 1 TO nRowsK
nSum := 0
FOR k := 1 TO nColsQ
nSum += aQ[i][k] * aK[j][k]
NEXT
aScores[i][j] := nSum / Sqrt(nColsQ) // Escalado de las puntuaciones de atención
NEXT
NEXT
// Aplicamos la normalización softmax
FOR i := 1 TO nRowsQ
nExpSum := 0
FOR j := 1 TO nRowsK
aScores[i][j] := Exp(aScores[i][j])
nExpSum += aScores[i][j]
NEXT
FOR j := 1 TO nRowsK
aScores[i][j] /= nExpSum
NEXT
NEXT
RETURN aScores
FUNCTION ApplyAttention(aScores, aV)
LOCAL aOutput, i, j, k, nSum
LOCAL nRows := Len(aScores), nCols := Len(aV[1]), nInner := Len(aV)
aOutput := Array(nRows, nCols)
FOR i := 1 TO nRows
FOR j := 1 TO nCols
nSum := 0
FOR k := 1 TO nInner
nSum += aScores[i][k] * aV[k][j]
NEXT
aOutput[i][j] := nSum
NEXT
NEXT
RETURN aOutput
{{-0.20, -0.33, -0.13, 0.75}, {0.56, 0.31, 0.19, -0.09}, {-0.26, 0.48, 0.73, -0.32}}
Query: {{0.6859, -0.0584}, {1.3492, 0.9291}, {1.0082, 1.1412}}
Key: {{0.3594, 1.1780}, {1.0069, 1.3886}, {0.8579, 0.6985}}
Value: {{-0.2781, -0.6665}, {-1.0988, 0.3276}, {-0.3004, 0.3100}}
Attention Scores: {{0.27, 0.37, 0.36}, {0.23, 0.49, 0.27}, {0.26, 0.49, 0.25}}
Output: {{-0.590643, 0.049439}, {-0.690302, 0.091827}, {-0.684619, 0.064918}}