Das positionsbezogene Feed-Ahead-Netzwerk bietet gegenüber den üblichen Positionseinbettungen in Transformatoren die folgenden Vorteile:
- Modellierung langer Sequenzen: Das positionsbezogene Feed-Ahead-Netzwerk ermöglicht es dem Modell, Positionsinformationen effektiv zu erfassen, indem es eine lernbare Zuordnung vom Positionsindex zu einer kontinuierlichen Darstellung bereitstellt. Dies ist entscheidend für die Modellierung langfristiger Abhängigkeiten in der Sequenz.
- Verallgemeinerung auf unsichtbare Positionen: Positionsbezogene Feed-Ahead-Netzwerke ermöglichen eine gute Verallgemeinerung des Modells auf unbekannte Positionen. Das Modell kann während des Trainings die Muster und Beziehungen zwischen verschiedenen Positionen lernen und dieses Wissen kann auf Positionen angewendet werden, die während des Trainings nicht angetroffen wurden. Diese Flexibilität ist wichtig, wenn Sequenzen unterschiedlicher Länge verarbeitet werden oder wenn Daten außerhalb der Domäne verarbeitet werden.
- Parametereffizienz: Positionsbezogene Feed-Ahead-Netzwerke erfordern im Vergleich zu rotierenden Positionseinbettungen weniger Parameter. In einem positionsbezogenen Feed-Ahead-Netzwerk werden die Parameter von allen Positionen gemeinsam genutzt, wohingegen rotierende Positionseinbettungen separate Parameter für jede Place erfordern. Diese gemeinsame Nutzung von Parametern reduziert den Speicherbedarf des Modells und verbessert die Recheneffizienz.
- Kompatibilität mit Pre-Coaching: Positionsbezogene Feed-Ahead-Netzwerke werden häufiger in Szenarien vor dem Coaching verwendet, beispielsweise bei der Sprachmodellierung. Dadurch können Modelle wie Transformer XL an vorhandenen Techniken und Modellen vor dem Coaching ausgerichtet werden, was eine einfachere Integration und Transferlernen erleichtert.
Die Einbettung kann mit dem folgenden Code implementiert werden, wie er hier beschrieben ist Repository:
class PositionwiseFF(nn.Module):
def __init__(self, d_model, d_inner, dropout, pre_lnorm=False):
tremendous(PositionwiseFF, self).__init__()self.d_model = d_model
self.d_inner = d_inner
self.dropout = dropout
self.CoreNet = nn.Sequential(
nn.Linear(d_model, d_inner), nn.ReLU(inplace=True),
nn.Dropout(dropout),
nn.Linear(d_inner, d_model),
nn.Dropout(dropout),
)
self.layer_norm = nn.LayerNorm(d_model)
self.pre_lnorm = pre_lnorm
def ahead(self, inp):
if self.pre_lnorm:
# layer normalization + positionwise feed-forward
core_out = self.CoreNet(self.layer_norm(inp))
# residual connection
output = core_out + inp
else:
# positionwise feed-forward
core_out = self.CoreNet(inp)
# residual connection + layer normalization
output = self.layer_norm(inp + core_out)
return output