Transformatortoken en positie-inbedding met Keras PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

Transformatortoken en positie-inbedding met Keras

Introductie

Er zijn tal van handleidingen die uitleggen hoe transformatoren werken en voor het bouwen van een intuïtie op een belangrijk element ervan: token- en positie-inbedding.

Door tokens positioneel in te bedden, konden transformatoren niet-rigide relaties tussen tokens (meestal woorden) vertegenwoordigen, wat veel beter is in het modelleren van onze contextgestuurde spraak in taalmodellering. Hoewel het proces relatief eenvoudig is, is het vrij generiek, en de implementaties worden snel een standaardtekst.

In deze korte handleiding bekijken we hoe we KerasNLP, de officiële Keras-add-on, kunnen gebruiken om PositionEmbedding en TokenAndPositionEmbedding.

KerasNLP

KerasNLP is een horizontale toevoeging voor NLP. Op het moment van schrijven is het nog erg jong, met versie 0.3, en de documentatie is nog vrij summier, maar het pakket is al meer dan alleen bruikbaar.

Het biedt toegang tot Keras-lagen, zoals: TokenAndPositionEmbedding, TransformerEncoder en TransformerDecoder, wat het bouwen van aangepaste transformatoren eenvoudiger dan ooit maakt.

Om KerasNLP in ons project te gebruiken, kun je het installeren via pip:

$ pip install keras_nlp

Eenmaal geïmporteerd in het project, kunt u elke keras_nlp laag als een standaard Keras-laag.

tokenization

Computers werken met cijfers. We verwoorden onze gedachten in woorden. Om de computer ze te laten kraken, moeten we woorden in een of andere vorm aan getallen toewijzen.

Een veelgebruikte manier om dit te doen is om woorden eenvoudig toe te wijzen aan getallen waarbij elk geheel getal een woord vertegenwoordigt. Een corpus van woorden creëert een woordenschat en elk woord in de woordenschat krijgt een index. U kunt dus een reeks woorden omzetten in een reeks indices die bekend staat als penningen:

def tokenize(sequence):
    
    return tokenized_sequence

sequence = ['I', 'am', 'Wall-E']
sequence = tokenize(sequence)
print(sequence) 

Deze reeks tokens kan vervolgens worden ingebed in een dichte vector die de tokens in de latente ruimte definieert:

[[4], [26], [472]] -> [[0.5, 0.25], [0.73, 0.2], [0.1, -0.75]]

Dit wordt meestal gedaan met de Embedding laag in Keras. Transformers coderen niet alleen met behulp van een standaard Embedding laag. Zij treden op Embedding en PositionEmbedding, en ze bij elkaar optellen, waarbij de reguliere inbeddingen worden verplaatst door hun positie in de latente ruimte.

Met KerasNLP – optreden TokenAndPositionEmbedding combineert reguliere token-inbedding (Embedding) met positionele inbedding (PositionEmbedding).

PositieInbedding

Laten we eens kijken PositionEmbedding eerst. Het accepteert tensoren en rafelige tensoren en gaat ervan uit dat de laatste dimensie de kenmerken vertegenwoordigt, terwijl de voorlaatste dimensie de reeks vertegenwoordigt.

# Seq
(5, 10)
     # Features

De laag accepteert a sequence_length argument, dat aangeeft, nou ja, de lengte van de invoer- en uitvoerreeks. Laten we doorgaan en positioneel een willekeurige uniforme tensor insluiten:

seq_length = 5
input_data = tf.random.uniform(shape=[5, 10])

input_tensor = keras.Input(shape=[None, 5, 10])
output = keras_nlp.layers.PositionEmbedding(sequence_length=seq_length)(input_tensor)
model = keras.Model(inputs=input_tensor, outputs=output)
    
model(input_data)

Dit resulteert in:

<tf.Tensor: shape=(5, 10), dtype=float32, numpy=
array([[ 0.23758471, -0.16798696, -0.15070847,  0.208067  , -0.5123104 ,
        -0.36670157,  0.27487397,  0.14939266,  0.23843127, -0.23328197],
       [-0.51353353, -0.4293166 , -0.30189738, -0.140344  , -0.15444171,
        -0.27691704,  0.14078277, -0.22552207, -0.5952263 , -0.5982155 ],
       [-0.265581  , -0.12168896,  0.46075982,  0.61768025, -0.36352775,
        -0.14212841, -0.26831496, -0.34448475,  0.4418767 ,  0.05758983],
       [-0.46500492, -0.19256318, -0.23447984,  0.17891657, -0.01812166,
        -0.58293337, -0.36404118,  0.54269964,  0.3727749 ,  0.33238482],
       [-0.2965023 , -0.3390794 ,  0.4949159 ,  0.32005525,  0.02882379,
        -0.15913549,  0.27996767,  0.4387421 , -0.09119213,  0.1294356 ]],
      dtype=float32)>

TokenAndPositieInbedding

Het insluiten van tokens en posities komt neer op het gebruik van Embedding op de invoerreeks, PositionEmbedding op de ingesloten tokens, en vervolgens deze twee resultaten bij elkaar op te tellen, waardoor de token-inbeddingen in de ruimte effectief worden verplaatst om hun relatieve betekenisvolle relaties te coderen.

Dit kan technisch worden gedaan als:

seq_length = 10
vocab_size = 25
embed_dim = 10

input_data = tf.random.uniform(shape=[5, 10])

input_tensor = keras.Input(shape=[None, 5, 10])
embedding = keras.layers.Embedding(vocab_size, embed_dim)(input_tensor)
position = keras_nlp.layers.PositionEmbedding(seq_length)(embedding)
output = keras.layers.add([embedding, position])
model = keras.Model(inputs=input_tensor, outputs=output)
    
model(input_data).shape 

De ingangen worden ingebed en vervolgens positioneel ingebed, waarna ze bij elkaar worden opgeteld, waardoor een nieuwe positioneel ingebedde vorm ontstaat. Als alternatief kunt u gebruikmaken van de TokenAndPositionEmbedding laag, die dit onder de motorkap doet:

Bekijk onze praktische, praktische gids voor het leren van Git, met best-practices, door de industrie geaccepteerde normen en bijgevoegd spiekbriefje. Stop met Googlen op Git-commando's en eigenlijk leren het!

... 
def call(self, inputs):
        embedded_tokens = self.token_embedding(inputs)
        embedded_positions = self.position_embedding(embedded_tokens)
        outputs = embedded_tokens + embedded_positions
        return outputs

Dit maakt het veel schoner om te presteren TokenAndPositionEmbedding:

seq_length = 10
vocab_size = 25
embed_dim = 10

input_data = tf.random.uniform(shape=[5, 10])

input_tensor = keras.Input(shape=[None, 5, 10])
output = keras_nlp.layers.TokenAndPositionEmbedding(vocabulary_size=vocab_size, 
                                                     sequence_length=seq_length, 
                                                     embedding_dim=embed_dim)(input_tensor)
model = keras.Model(inputs=input_tensor, outputs=output)
    
model(input_data).shape 

De gegevens die we aan de laag hebben doorgegeven, zijn nu positioneel ingebed in een latente ruimte van 10 dimensies:

model(input_data)
<tf.Tensor: shape=(5, 10, 10), dtype=float32, numpy=
array([[[-0.01695484,  0.7656435 , -0.84340465,  0.50211895,
         -0.3162892 ,  0.16375223, -0.3774369 , -0.10028353,
         -0.00136751, -0.14690581],
        [-0.05646318,  0.00225556, -0.7745967 ,  0.5233861 ,
         -0.22601983,  0.07024342,  0.0905793 , -0.46133494,
         -0.30130145,  0.451248  ],
         ...

Verder gaan – Handmatig end-to-end project

Je leergierige karakter maakt dat je verder wilt gaan? We raden aan om onze Begeleid project: "Beeldbijschriften met CNN's en Transformers met Keras".

In dit begeleide project leer je hoe je een beeldondertitelingsmodel bouwt, dat een afbeelding als invoer accepteert en een tekstonderschrift als uitvoer produceert.

U leert hoe u:

  • Tekst voorbewerken
  • Eenvoudig tekstinvoer vectoriseren
  • Werk met de tf.data API en bouw performante datasets
  • Bouw Transformers helemaal opnieuw met TensorFlow/Keras en KerasNLP – de officiële horizontale toevoeging aan Keras voor het bouwen van state-of-the-art NLP-modellen
  • Bouw hybride architecturen waarbij de output van het ene netwerk wordt gecodeerd voor een ander

Hoe kadreren we beeldonderschriften? De meesten beschouwen het als een voorbeeld van generatief diep leren, omdat we een netwerk leren om beschrijvingen te genereren. Ik beschouw het echter graag als een voorbeeld van neurale machinevertaling - we vertalen de visuele kenmerken van een afbeelding in woorden. Door vertaling genereren we een nieuwe representatie van dat beeld, in plaats van alleen een nieuwe betekenis te genereren. Als je het als vertaling bekijkt, en alleen door het genereren van extensies, krijgt de taak een ander licht en wordt het een beetje intuïtiever.

Door het probleem in te lijsten als een van de vertalingen, wordt het gemakkelijker om erachter te komen welke architectuur we willen gebruiken. Encoder-only Transformers zijn geweldig in het begrijpen van tekst (sentimentanalyse, classificatie, enz.) omdat Encoders betekenisvolle representaties coderen. Modellen met alleen decoders zijn geweldig voor generatie (zoals GPT-3), omdat decoders zinvolle representaties kunnen afleiden in een andere reeks met dezelfde betekenis. Vertaling wordt meestal gedaan door een encoder-decoder-architectuur, waar encoders coderen voor een betekenisvolle representatie van een zin (of afbeelding, in ons geval) en decoders leren om deze reeks om te zetten in een andere betekenisvolle representatie die voor ons beter te interpreteren is (zoals een zin).

Conclusies

Transformers hebben sinds 2017 een grote golf gemaakt en veel geweldige handleidingen bieden inzicht in hoe ze werken, maar toch waren ze voor velen nog steeds ongrijpbaar vanwege de overhead van aangepaste implementaties. KerasNLP pakt dit probleem aan en biedt bouwstenen waarmee je flexibele, krachtige NLP-systemen kunt bouwen, in plaats van voorverpakte oplossingen te bieden.

In deze handleiding hebben we token- en positie-inbedding bekeken met Keras en KerasNLP.

Tijdstempel:

Meer van Stapelmisbruik