Generieren von Einbettungen mit fester Position für Eingabesequenzen mithilfe sinusförmiger Einbettungen | von Pragyan Subedi | Juni 2023

0
25


Bei der Implementierung transformatorbasierter Modellarchitekturen für maschinelles Lernen sind in der Regel feste Positionseinbettungen erforderlich, um die Place von Eingabetokens in der Verarbeitung natürlicher Sprache zu erfassen.

Hier ist eine Schritt-für-Schritt-Methode zum Generieren fester Positionseinbettungen mithilfe sinusförmiger Einbettungen:

1. Berechnen Sie Umkehrfrequenzen

Wir wollen höherdimensionalen Positionen niedrigere Frequenzen und niedrigerdimensionalen Positionen höhere Frequenzen zuordnen. Die folgende Formel erfasst wirkungsvoll die Vorstellung, dass niederdimensionale Positionen langsamere Schwingungen in den sinusförmigen Einbettungen aufweisen sollten.

inv_freq = 1.0 / (10000 ** (torch.arange(0, dim, 2) / dim)) # the place dim is dimension of enter

Lassen Sie uns einige Werte übergeben und die Ausgabe sehen:

dim = 7

print(torch.arange(0, dim, 2) / dim)
print(10000 ** (torch.arange(0, dim, 2) / dim))
print(1.0 / (10000 ** (torch.arange(0, dim, 2) / dim)))

Output:

tensor([0.0000, 0.2857, 0.5714, 0.8571])
tensor([1.0000e+00, 1.3895e+01, 1.9307e+02, 2.6827e+03])
tensor([1.0000e+00, 7.1969e-02, 5.1795e-03, 3.7276e-04])

Darstellung der Umkehrfrequenzen für verschiedene Dimensionen,

dim = 10 # and 100
plt.plot(np.arange(0, dim, 2), 1.0 / (10000 ** (torch.arange(0, dim, 2) / dim)))
plt.title(f"dim:{dim}")
w

2. Erstellen Sie einen sinusförmigen Eingang

Als nächstes multiplizieren Sie die Umkehrfrequenzen mit einem Wertebereich von 0 bis zur Sequenzlänge (seq_len). Diese Multiplikation kombiniert die Positionsinformationen (0 bis seq_len) mit den variierenden Frequenzen, die durch die Umkehrfrequenzen bestimmt werden. Jeder Place entlang der Sequenz ist eine einzigartige Sinuswellenform zugeordnet.

# Matrix multiplication
sinusoid_inp = (
torch.einsum("i , j -> i j", torch.arange(seq_len), inv_freq)
.float()
)

Hier ist ein Beispiel:

dim = 10
seq_len = 5

inv_freq = 1.0 / (10000 ** (torch.arange(0, dim, 2) / dim))
sinusoid_inp = torch.einsum("i , j -> i j", torch.arange(seq_len), inv_freq).float()

print(sinusoid_inp)

# Output:
tensor([[0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00],
[1.0000e+00, 1.5849e-01, 2.5119e-02, 3.9811e-03, 6.3096e-04],
[2.0000e+00, 3.1698e-01, 5.0238e-02, 7.9621e-03, 1.2619e-03],
[3.0000e+00, 4.7547e-01, 7.5357e-02, 1.1943e-02, 1.8929e-03],
[4.0000e+00, 6.3396e-01, 1.0048e-01, 1.5924e-02, 2.5238e-03]])

3. Erstellen Sie Sinus- und Cosinus-Einbettungen

Bewerben Sie sich abschließend torch.sin Und torch.cos Funktionen für den Sinus-Eingangstensor zur Erzeugung separater Tensoren für die Sinus- und Kosinus-Einbettungen. Durch die Verwendung von Sinus und Cosinus des Sinuseingangs erhält die Funktion zwei komplementäre Wellenformen, die Positionsinformationen kontinuierlich und periodisch erfassen.

dim = 10
seq_len = 5

inv_freq = 1.0 / (10000 ** (torch.arange(0, dim, 2) / dim))
sinusoid_inp = torch.einsum("i , j -> i j", torch.arange(seq_len), inv_freq).float()
sin_emb = torch.sin(sinusoid_inp)
cos_emb = torch.cos(sinusoid_inp)

print(sin_emb, "nn", cos_emb)

#Output:

tensor([[ 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00],
[ 8.4147e-01, 1.5783e-01, 2.5116e-02, 3.9811e-03, 6.3096e-04],
[ 9.0930e-01, 3.1170e-01, 5.0217e-02, 7.9621e-03, 1.2619e-03],
[ 1.4112e-01, 4.5775e-01, 7.5285e-02, 1.1943e-02, 1.8929e-03],
[-7.5680e-01, 5.9234e-01, 1.0031e-01, 1.5924e-02, 2.5238e-03]])

tensor([[ 1.0000, 1.0000, 1.0000, 1.0000, 1.0000],
[ 0.5403, 0.9875, 0.9997, 1.0000, 1.0000],
[-0.4161, 0.9502, 0.9987, 1.0000, 1.0000],
[-0.9900, 0.8891, 0.9972, 0.9999, 1.0000],
[-0.6536, 0.8057, 0.9950, 0.9999, 1.0000]])

Bitte beachten Sie, dass die spezifischen Werte der Eingabesequenzen für die Generierung der festen Positionseinbettungen nicht wichtig sind. Das Einzige, was zählt, ist die Dimension und Länge der Eingabesequenzen.

Zeichnen von Meshgrids zur Visualisierung des oben Gesagten,

# Convert tensors to numpy arrays
sin_emb_np = sin_emb.numpy()
cos_emb_np = cos_emb.numpy()

# Create a grid of positions for the heatmap
x = np.arange(seq_len) # x-axis positions
y = np.arange(dim // 2) # y-axis positions

# Create a meshgrid from the positions
X, Y = np.meshgrid(x, y)

# Plot the sine embedding heatmap
plt.determine(figsize=(6, 4))
plt.title("Sine Embedding Heatmap")
plt.xlabel("Place")
plt.ylabel("Dimension")
plt.pcolormesh(X, Y, sin_emb_np, cmap='viridis')
plt.colorbar(label='Sine Worth')

# Plot the cosine embedding heatmap
plt.determine(figsize=(6, 4))
plt.title("Cosine Embedding Heatmap")
plt.xlabel("Place")
plt.ylabel("Dimension")
plt.pcolormesh(X, Y, cos_emb_np, cmap='viridis')
plt.colorbar(label='Cosine Worth')



Source link

HINTERLASSEN SIE EINE ANTWORT

Please enter your comment!
Please enter your name here