TensorFlow/Keras ile Python'da 5 Satırlı GPT Tarzı Metin Oluşturma

Transformers, 2017'de piyasaya sürülmesine rağmen, yalnızca son birkaç yılda önemli bir çekiş kazanmaya başladı. HuggingFace, NLP ve benzeri platformlar aracılığıyla teknolojinin yaygınlaşmasıyla Büyük Dil Modelleri (LLM'ler) zamankinden daha erişilebilir hale geldi.

Yine de - etraflarındaki tüm yutturmaca ve çok teori odaklı kılavuzlar, çevrimiçi olarak pek çok özel uygulama yoktur ve kaynaklar, daha uzun süredir var olan diğer bazı ağ türlerinde olduğu kadar hazır değildir. HuggingFace'ten önceden oluşturulmuş bir Transformer (başka bir kılavuzun konusu) kullanarak çalışma döngünüzü basitleştirebilirken, hissetmek bir kütüphane aracılığıyla soyutlamadan önce kendiniz bir tane oluşturarak nasıl çalıştığını. Burada teori ve optimizasyondan ziyade inşa etmeye odaklanacağız.

Bu kılavuzda, bir Otoregresif Dil Modeli için metin oluştur. Veri yüklemenin, bölmenin, vektörleştirmenin, bir model oluşturmanın, özel bir geri arama yazmanın ve eğitim/çıkarımın pratik ve minimalist/özlü yönlerine odaklanacağız. Bu görevlerin her biri daha ayrıntılı kılavuzlara dönüştürülebilir, bu nedenle uygulamayı genel bir görev olarak tutacağız ve kendi veri kümenize bağlı olarak özelleştirme ve optimizasyon için yer bırakacağız.

LLM türleri ve GPT-Fyodor

Kategorizasyon çok daha karmaşık hale gelebilirken, geniş Transformer tabanlı dil modellerini üç kategoriye ayırın:

  • Enkoder Tabanlı Modeller – ALBERT, BERT, DistilBERT, RoBERTa
  • Kod Çözücü Tabanlı – GPT, GPT-2, GPT-3, TransformerXL
  • Seq2Seq Modelleri – BART, mBART, T5

Enkoder tabanlı modeller, mimarilerinde yalnızca bir Transformer kodlayıcı kullanır (tipik olarak, yığılmış) ve cümleleri anlamak için mükemmeldir (sınıflandırma, adlandırılmış varlık tanıma, soru yanıtlama).

kod çözücü tabanlı modeller, mimarilerinde yalnızca bir Transformer kod çözücü kullanır (ayrıca tipik olarak yığılır) ve gelecekteki tahminler için mükemmeldir, bu da onları metin oluşturmaya uygun hale getirir.

Sıra2Seq modeller hem kodlayıcıları hem de kod çözücüleri birleştirir ve metin oluşturma, özetleme ve en önemlisi çeviride mükemmeldir.

Son birkaç yılda çok fazla ilgi çeken GPT model ailesi, kod çözücü tabanlı transformatör modelleridir ve insan benzeri metinler üretmede, büyük veri toplulukları üzerinde eğitilmede ve yeni bir komut istemi olarak verilmesinde mükemmeldir. nesil için tohum başlangıç. Örneğin:

generate_text('the truth ultimately is')

Kaputun altında, bu istemi GPT benzeri bir modele besler ve şunları üretir:

'the truth ultimately is really a joy in history, this state of life through which is almost invisible, superfluous  teleological...'

Bu aslında kılavuzun sonundan küçük bir spoiler! Başka bir küçük spoiler, bu metni üreten mimaridir:

inputs = layers.Input(shape=(maxlen,))
embedding_layer = keras_nlp.layers.TokenAndPositionEmbedding(vocab_size, maxlen, embed_dim)(inputs)
transformer_block = keras_nlp.layers.TransformerDecoder(embed_dim, num_heads)(embedding_layer)
outputs = layers.Dense(vocab_size, activation='softmax')(transformer_block)
    
model = keras.Model(inputs=inputs, outputs=outputs)

Küçük bir GPT'yi simüle eden yalnızca kod çözücü bir transformatör modeli oluşturmak için 5 satır yeterlidir. Modeli Fyodor Dostoyevski'nin romanları (Wikipedia'dan Reddit yorumlarına kadar başka herhangi bir şeyle değiştirebilirsiniz) üzerine eğiteceğimiz için, geçici olarak modeli arayacağız GPT-Fyodor.

KerasNLP

5 satırlı bir GPT-Fyodor'un hilesi, KerasNLPResmi Keras ekibi tarafından geliştirilen ve gerçek Keras tarzında endüstri gücündeki NLP'yi yeni katmanlarla (kodlayıcılar, kod çözücüler, belirteç yerleştirmeler, konum yerleştirmeler, ölçümler, belirteçler vb.).

KerasNLP bir model hayvanat bahçesi değil. Ana paketle genel derin öğrenme gelişimine giriş engelini azalttığı gibi, NLP model geliştirmeye giriş engelini de azaltan Keras'ın bir parçasıdır (ayrı bir paket olarak).

Not: Yazım itibariyle KerasNLP hala üretiliyor ve erken aşamalarda. Gelecekteki sürümlerde küçük farklılıklar olabilir. Yazma sürümü kullanıyor 0.3.0.

KerasNLP'yi kullanabilmek için, aracılığıyla yüklemeniz gerekir. pip:

$ pip install keras_nlp

Ve sürümü şu şekilde doğrulayabilirsiniz:

keras_nlp.__version__

Keras ile GPT Tarzı Bir Model Uygulamak

Kullanacağımız kitaplıkları içe aktararak başlayalım – TensorFlow, Keras, KerasNLP ve NumPy:

import tensorflow as tf
from tensorflow import keras
import keras_nlp
import numpy as np

Veri yükleniyor

Dostoyevski'nin romanlarından birkaçını yükleyelim - ilk aşamalardan itibaren biraz fazla uydurma olmadan, bir modelin sığması için çok kısa olurdu. Ham metin dosyalarını incelikle kullanacağız. Project Gutenberg, bu tür verilerle çalışmanın basitliği nedeniyle:

crime_and_punishment_url = 'https://www.gutenberg.org/files/2554/2554-0.txt'
brothers_of_karamazov_url = 'https://www.gutenberg.org/files/28054/28054-0.txt'
the_idiot_url = 'https://www.gutenberg.org/files/2638/2638-0.txt'
the_possessed_url = 'https://www.gutenberg.org/files/8117/8117-0.txt'

paths = [crime_and_punishment_url, brothers_of_karamazov_url, the_idiot_url, the_possessed_url]
names = ['Crime and Punishment', 'Brothers of Karamazov', 'The Idiot', 'The Possessed']
texts = ''
for index, path in enumerate(paths):
    filepath = keras.utils.get_file(f'{names[index]}.txt', origin=path)
    text = ''
    with open(filepath, encoding='utf-8') as f:
        text = f.read()
        
        
        
        texts += text[10000:]

Tüm dosyaları indirdik, inceledik ve üst üste birleştirdik. Bu, Fyodor'u belirgin bir şekilde korurken, kullanılan dilde biraz çeşitlilik içerir! Her dosya için, önsözün ve Gutenberg girişinin ortalama uzunluğu civarında olan ilk 10k karakteri atladık, bu yüzden her yineleme için büyük ölçüde sağlam bir kitap gövdesiyle kaldık. Dizideki rastgele 500 karaktere bir göz atalım. texts şimdi dize:


texts[25000:25500]
'nd that was whynI addressed you at once. For in unfolding to you the story of my life, Indo not wish to make myself a laughing-stock before these idle listeners,nwho indeed know all about it already, but I am looking for a mannof feeling and education. Know then that my wife was educated in anhigh-class school for the daughters of noblemen, and on leaving shendanced the shawl dance before the governor and other personages fornwhich she was presented with a gold medal and a certificate of merit.n'

Başka bir işlem yapmadan önce dizeyi cümlelere ayıralım:

text_list = texts.split('.')
len(text_list) 

69 bin cümlemiz var. değiştirdiğinizde n boşluklu karakterler ve kelimeleri sayın:

len(texts.replace('n', ' ').split(' ')) 

Not: Genellikle bir veri setinde en az bir milyon kelimeye ve ideal olarak bundan çok daha fazlasına sahip olmak isteyeceksiniz. Dil modelleri daha yaygın olarak onlarca gigabaytlık metin üzerinde eğitilirken, birkaç megabayt veriyle (~5MB) çalışıyoruz. Bu, doğal olarak, metin girdisini fazla uydurmayı gerçekten kolaylaştıracak ve genelleştirmeyi zorlaştıracaktır (fazla uydurma olmadan yüksek kafa karışıklığı veya çok fazla uydurma ile düşük kafa karışıklığı). Sonuçları bir tuz tanesi ile alın.

Yine de, bunları bir bölüme ayıralım Eğitim, test ve onaylama Ayarlamak. Önce boş dizeleri çıkaralım ve cümleleri karıştıralım:


text_list = list(filter(None, text_list))

import random
random.shuffle(text_list)

Ardından, 70/15/15'lik bir bölme yapacağız:

length = len(text_list)
text_train = text_list[:int(0.7*length)]
text_test = text_list[int(0.7*length):int(0.85*length)]
text_valid = text_list[int(0.85*length):]

Bu, bir tren-test-doğrulama ayrımı gerçekleştirmenin basit ama etkili bir yoludur. bir göz atalım text_train:

[' It was a dull morning, but the snow had ceased',
 'nn"Pierre, you who know so much of what goes on here, can you really havenknown nothing of this business and have heard nothing about it?"nn"What? What a set! So it's not enough to be a child in your old age,nyou must be a spiteful child too! Varvara Petrovna, did you hear what hensaid?"nnThere was a general outcry; but then suddenly an incident took placenwhich no one could have anticipated', ...

Standardizasyon ve vektörleştirme zamanı!

Metin Vektörleştirme

Ağlar kelimeleri anlamaz – sayıları anlarlar. Şu kelimeleri belirtmek isteyeceğiz:

...
sequence = ['I', 'am', 'Wall-E']
sequence = tokenize(sequence)
print(sequence) # [4, 26, 472]
...

Ayrıca, cümlelerin uzunlukları farklılık gösterdiğinden, beslenen cümleler arasında aynı şekli sağlamak için dolgu genellikle sola veya sağa eklenir. En uzun cümlemizin 5 kelime (belirteç) uzunluğunda olduğunu varsayalım. Bu durumda, Wall-E cümlesi iki sıfırla doldurulur, böylece aynı giriş şeklini sağlarız:

sequence = pad_sequence(sequence)
print(sequence) # [4, 26, 472, 0, 0]

Geleneksel olarak, bu bir TensorFlow kullanılarak yapıldı. Tokenizer ve Keras' pad_sequences() yöntemler – ancak, çok daha kullanışlı bir katman, TextVectorization, kullanılabilir, hangi belirteç ve girdilerinizi doldurur, kelime dağarcığını önceden bilmeden kelime dağarcığını ve boyutunu çıkarmanıza izin verir!

En iyi uygulamalar, endüstri tarafından kabul edilen standartlar ve dahil edilen hile sayfası ile Git'i öğrenmek için uygulamalı, pratik kılavuzumuza göz atın. Googling Git komutlarını durdurun ve aslında öğrenmek o!

Uyum sağlayalım ve bir TextVectorization katman:

from tensorflow.keras.layers import TextVectorization

def custom_standardization(input_string):
    sentence = tf.strings.lower(input_string)
    sentence = tf.strings.regex_replace(sentence, "n", " ")
    return sentence

maxlen = 50



vectorize_layer = TextVectorization(
    standardize = custom_standardization,
    output_mode="int",
    output_sequence_length=maxlen + 1,
)

vectorize_layer.adapt(text_list)
vocab = vectorize_layer.get_vocabulary()

The custom_standardization() yöntem bundan çok daha uzun sürebilir. Tüm girdileri küçük harfe dönüştürdük ve değiştirdik n ile " ". Burası, metin için ön işlemenizin çoğunu gerçekten koyabileceğiniz ve isteğe bağlı olarak vektörleştirme katmanına sağlayabileceğiniz yerdir. standardize argüman. bir kez sen adapt() metin katmanı (NumPy dizisi veya metin listesi) - oradan kelime bilgisini ve boyutunu alabilirsiniz:

vocab_size = len(vocab)
vocab_size 

Son olarak, kelimeleri de-tokenize etmek için bir index_lookup sözlük:

index_lookup = dict(zip(range(len(vocab)), vocab))    
index_lookup[5] 

Tüm belirteçleri eşler ([1, 2, 3, 4, ...]) kelime dağarcığındaki kelimelere (['a', 'the', 'i', ...]). Bir anahtar (belirteç dizini) girerek sözcüğü kolayca geri alabiliriz. şimdi çalıştırabilirsiniz vectorize_layer() herhangi bir girdide ve vectorized cümleleri gözlemleyin:

vectorize_layer(['hello world!'])

Hangi sonuç:

<tf.Tensor: shape=(1, 51), dtype=int64, numpy=
array([[   1, 7509,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0]], dtype=int64)>

Merhaba indeksi var 1 dünya endeksine sahipken 7509! Geri kalanı için dolgu maxlen hesapladık.

Metni vektörleştirmek için araçlara sahibiz – şimdi veri kümeleri oluşturalım text_train, text_test ve text_validGPT-Fyodor'a beslenebilen kelimeler ve vektörler arasında bir dönüştürme ortamı olarak vektörleştirme katmanımızı kullanarak.

Veri Kümesi Oluşturma

bir oluşturacağız tf.data.Dataset setlerimizin her biri için from_tensor_slices() ve tensör dilimlerinin (cümlelerin) bir listesini sağlamak:

batch_size = 64

train_dataset = tf.data.Dataset.from_tensor_slices(text_train)
train_dataset = train_dataset.shuffle(buffer_size=256)
train_dataset = train_dataset.batch(batch_size)

test_dataset = tf.data.Dataset.from_tensor_slices(text_test)
test_dataset = test_dataset.shuffle(buffer_size=256)
test_dataset = test_dataset.batch(batch_size)

valid_dataset = tf.data.Dataset.from_tensor_slices(text_valid)
valid_dataset = valid_dataset.shuffle(buffer_size=256)
valid_dataset = valid_dataset.batch(batch_size)

Bir kez oluşturulduktan ve karıştırıldıktan sonra (yine iyi bir önlem için) - bir ön işleme (vektörleştirme ve dizi bölme) işlevi uygulayabiliriz:

def preprocess_text(text):
    text = tf.expand_dims(text, -1)
    tokenized_sentences = vectorize_layer(text)
    x = tokenized_sentences[:, :-1]
    y = tokenized_sentences[:, 1:]
    return x, y


train_dataset = train_dataset.map(preprocess_text)
train_dataset = train_dataset.prefetch(tf.data.AUTOTUNE)

test_dataset = test_dataset.map(preprocess_text)
test_dataset = test_dataset.prefetch(tf.data.AUTOTUNE)

valid_dataset = valid_dataset.map(preprocess_text)
valid_dataset = valid_dataset.prefetch(tf.data.AUTOTUNE)

The preprocess_text() fonksiyon basitçe son boyuta göre genişler, metni bizim kullanarak vektörleştirir. vectorize_layer ve tek bir belirteçle dengelenen girdileri ve hedefleri oluşturur. Modelin kullanacağı [0..n] anlaması için n+1, her kelime için bir tahmin vererek, ondan önceki tüm kelimeleri hesaba katar. Veri kümelerinden herhangi birinde tek bir girişe bakalım:

for entry in train_dataset.take(1):
    print(entry)

Döndürülen girdileri ve hedefleri 64'lük gruplar halinde (her biri 30 uzunluğunda) inceleyerek, bunların nasıl birer birer dengelendiğini açıkça görebiliriz:

(<tf.Tensor: shape=(64, 50), dtype=int64, numpy=
array([[17018,   851,     2, ...,     0,     0,     0],
       [  330,    74,     4, ...,     0,     0,     0],
       [   68,   752, 30273, ...,     0,     0,     0],
       ...,
       [    7,    73,  2004, ...,     0,     0,     0],
       [   44,    42,    67, ...,     0,     0,     0],
       [  195,   252,   102, ...,     0,     0,     0]], dtype=int64)>, <tf.Tensor: shape=(64, 50), dtype=int64, numpy=
array([[  851,     2,  8289, ...,     0,     0,     0],
       [   74,     4,    34, ...,     0,     0,     0],
       [  752, 30273,  7514, ...,     0,     0,     0],
       ...,
       [   73,  2004,    31, ...,     0,     0,     0],
       [   42,    67,    76, ...,     0,     0,     0],
       [  252,   102,  8596, ...,     0,     0,     0]], dtype=int64)>)

Son olarak – modeli inşa etme zamanı!

Model Tanımı

Burada KerasNLP katmanlarından faydalanacağız. sonra Input, girişi bir aracılığıyla kodlayacağız TokenAndPositionEmbedding katmanımızda geçen vocab_size, maxlen ve embed_dim. Aynısı embed_dim bu katmanın çıktısını ve girdisini TransformerDecoder olacak Dekoderde tutulur. Yazma anında, Kod Çözücü girdi boyutunu otomatik olarak korur ve farklı bir çıktıya yansıtmanıza izin vermez, ancak gizli boyutları tanımlamanıza izin verir. intermediate_dim argüman.

Gizli gösterim için gömme boyutlarını iki ile çarpacağız, ancak onu aynı tutabilir veya gömme karartmalarından ayrılmış bir sayı kullanabilirsiniz:

embed_dim = 128
num_heads = 4

def create_model():
    inputs = keras.layers.Input(shape=(maxlen,), dtype=tf.int32)
    embedding_layer = keras_nlp.layers.TokenAndPositionEmbedding(vocab_size, maxlen, embed_dim)(inputs)
    decoder = keras_nlp.layers.TransformerDecoder(intermediate_dim=embed_dim, 
                                                            num_heads=num_heads, 
                                                            dropout=0.5)(embedding_layer)
    
    outputs = keras.layers.Dense(vocab_size, activation='softmax')(decoder)
    
    model = keras.Model(inputs=inputs, outputs=outputs)
    
    model.compile(
        optimizer="adam", 
        loss='sparse_categorical_crossentropy',
        metrics=[keras_nlp.metrics.Perplexity(), 'accuracy']
    )
    return model

model = create_model()
model.summary()

Kod çözücünün üzerinde bir Dense ile sıradaki bir sonraki kelimeyi seçmek için katman softmax aktivasyon (her bir sonraki belirteç için olasılık dağılımını üretir). Modelin özetine bir göz atalım:

Model: "model_5"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 input_6 (InputLayer)        [(None, 30)]              0         
                                                                 
 token_and_position_embeddin  (None, 30, 128)          6365824   
 g_5 (TokenAndPositionEmbedd                                     
 ing)                                                            
                                                                 
 transformer_decoder_5 (Tran  (None, 30, 128)          132480    
 sformerDecoder)                                                 
                                                                 
 dense_5 (Dense)             (None, 30, 49703)         6411687   
                                                                 
=================================================================
Total params: 13,234,315
Trainable params: 13,234,315
Non-trainable params: 0
_________________________________________________________________

GPT-2 birçok kod çözücüyü yığınlar – GPT-2 Small 12 yığın kod çözücüye (117M param) sahipken GPT-2 Ekstra Büyük 48 yığın kod çözücüye (1.5B param) sahiptir. Mütevazı bir 13M parametresine sahip tek kod çözücü modelimiz, eğitim amaçlı olarak yeterince iyi çalışmalıdır. LLM'ler ile - ölçek büyütmenin son derece iyi bir strateji olduğu kanıtlanmıştır ve Transformers, iyi ölçeklendirmeye izin vererek son derece büyük modelleri eğitmeyi mümkün kılar.

GPT-3'ün bir "yetersiz" 175B parametreleri. Google Brain'in ekibi, hesaplamayı çok daha küçük modellerle aynı düzeyde tutarken seyreklik araştırması yapmak için 1.6T parametre modelini eğitti.

Nitekim dekoder sayısını 1'den 3'e çıkarırsak:

def create_model():
    inputs = keras.layers.Input(shape=(maxlen,), dtype=tf.int32)
    x = keras_nlp.layers.TokenAndPositionEmbedding(vocab_size, maxlen, embed_dim)(inputs)
    for i in range(4):
        x = keras_nlp.layers.TransformerDecoder(intermediate_dim=embed_dim*2, num_heads=num_heads,                                                             dropout=0.5)(x)
    do = keras.layers.Dropout(0.4)(x)
    outputs = keras.layers.Dense(vocab_size, activation='softmax')(do)
    
    model = keras.Model(inputs=inputs, outputs=outputs)

Parametre sayımız 400k artacaktı:

Total params: 13,631,755
Trainable params: 13,631,755
Non-trainable params: 0

Ağımızdaki parametrelerin çoğu, TokenAndPositionEmbedding ve Dense katmanlar!

Kod çözücünün farklı derinliklerini deneyin – 1'den makinenizin işleyebileceği tüm yollara kadar ve sonuçları not edin. Her durumda – modeli eğitmeye neredeyse hazırız! Her çağda bir metin örneği üretecek özel bir geri arama oluşturalım, böylece modelin eğitim yoluyla cümleler oluşturmayı nasıl öğrendiğini görebiliriz.

Özel Geri Arama

class TextSampler(keras.callbacks.Callback):
    def __init__(self, start_prompt, max_tokens):
        self.start_prompt = start_prompt
        self.max_tokens = max_tokens
        
    
    
    def sample_token(self, logits):
        logits, indices = tf.math.top_k(logits, k=5, sorted=True)
        indices = np.asarray(indices).astype("int32")
        preds = keras.activations.softmax(tf.expand_dims(logits, 0))[0]
        preds = np.asarray(preds).astype("float32")
        return np.random.choice(indices, p=preds)

    def on_epoch_end(self, epoch, logs=None):
        decoded_sample = self.start_prompt
        
        for i in range(self.max_tokens-1):
            tokenized_prompt = vectorize_layer([decoded_sample])[:, :-1]
            predictions = self.model.predict([tokenized_prompt], verbose=0)
            
            
            
            
            sample_index = len(decoded_sample.strip().split())-1
            
            sampled_token = self.sample_token(predictions[0][sample_index])
            sampled_token = index_lookup[sampled_token]
            decoded_sample += " " + sampled_token
            
        print(f"nSample text:n{decoded_sample}...n")


random_sentence = ' '.join(random.choice(text_valid).replace('n', ' ').split(' ')[:4])
sampler = TextSampler(random_sentence, 30)
reducelr = keras.callbacks.ReduceLROnPlateau(patience=10, monitor='val_loss')

Modeli Eğitmek

Sonunda, antrenman zamanı! hadi içimize atalım train_dataset ve validation_dataset geri aramalar yerindeyken:

model = create_model()
history = model.fit(train_dataset, 
                    validation_data=valid_dataset,
                    epochs=10, 
                    callbacks=[sampler, reducelr])

Örnekleyici, son alıntıyla başlayan ve alıntıya başlayan talihsiz bir cümle seçti, ancak eğitim sırasında yine de ilginç sonuçlar veriyor:

# Epoch training
Epoch 1/10
658/658 [==============================] - ETA: 0s - loss: 2.7480 - perplexity: 15.6119 - accuracy: 0.6711
# on_epoch_end() sample generation
Sample text:
”  “What do you had not been i had been the same man was not be the same eyes to been a whole man and he did a whole man to the own...
# Validation
658/658 [==============================] - 158s 236ms/step - loss: 2.7480 - perplexity: 15.6119 - accuracy: 0.6711 - val_loss: 2.2130 - val_perplexity: 9.1434 - val_accuracy: 0.6864 - lr: 0.0010
...
Sample text:
”  “What do you know it is it all this very much as i should not have a great impression  in the room to be  able of it in my heart...

658/658 [==============================] - 149s 227ms/step - loss: 1.7753 - perplexity: 5.9019 - accuracy: 0.7183 - val_loss: 2.0039 - val_perplexity: 7.4178 - val_accuracy: 0.7057 - lr: 0.0010

Şununla başlar:

“Sen ne değildin, ben aynıydım”…

Ki bu pek mantıklı değil. On kısa dönemin sonunda, şu çizgide bir şeyler üretir:

“Bir erkeğin en sıradan adamı ne demek tabii ki”…

İkinci cümle hala çok anlamlı olmasa da - ilkinden çok daha mantıklı. Daha fazla veri üzerinde daha uzun eğitim (daha karmaşık ön işleme adımları ile) daha iyi sonuçlar verir. Küçük veri kümesi boyutuyla mücadele etmek için yalnızca yüksek bırakmalı 10 çağda eğittik. Çok daha uzun süre eğitime bırakılırsa, Fyodor benzeri metinler üretecekti, çünkü büyük parçalarını ezberleyecekti.

Not: Çıktı oldukça ayrıntılı olduğundan, ince ayar yapabilirsiniz. verbose Ekrandaki metin miktarını azaltmak için modeli uydururken argüman.

Model Çıkarımı

Çıkarım yapmak için, arayüzün arayüzünü kopyalamak isteyeceğiz. TextSampler – bir tohum ve bir response_length (max_tokens). Örnekleyicidekiyle aynı yöntemleri kullanacağız:

def sample_token(logits):
        logits, indices = tf.math.top_k(logits, k=5, sorted=True)
        indices = np.asarray(indices).astype("int32")
        preds = keras.activations.softmax(tf.expand_dims(logits, 0))[0]
        preds = np.asarray(preds).astype("float32")
        return np.random.choice(indices, p=preds)

def generate_text(prompt, response_length=20):
    decoded_sample = prompt
    for i in range(response_length-1):
        tokenized_prompt = vectorize_layer([decoded_sample])[:, :-1]
        predictions = model.predict([tokenized_prompt], verbose=0)
        sample_index = len(decoded_sample.strip().split())-1

        sampled_token = sample_token(predictions[0][sample_index])
        sampled_token = index_lookup[sampled_token]
        decoded_sample += " " + sampled_token
    return decoded_sample

Artık yöntemi yeni örnekler üzerinde çalıştırabilirsiniz:

generate_text('the truth ultimately is')


generate_text('the truth ultimately is')

Sonuçları İyileştirme?

Peki, sonuçları nasıl iyileştirebilirsiniz? Yapabileceğiniz bazı oldukça uygulanabilir şeyler var:

  • Veri temizleme (giriş verilerini daha titizlikle temizleyin, başlangıçtan itibaren yaklaşık bir sayıyı kısalttık ve yeni satır karakterlerini kaldırdık)
  • Daha fazla veri alın (sadece birkaç megabayt metin verisiyle çalıştık)
  • Modeli verilerle birlikte ölçeklendirin (kod çözücüleri yığınlamak zor değil!)

Sonuç

Ön işleme hattı minimalist ve geliştirilebilir olsa da – bu kılavuzda ana hatları verilen boru hattı, Keras'ı kullanarak özel bir yalnızca kod çözücü transformatörü oluşturmak için yalnızca 5 satır kod gerektiren iyi bir GPT tarzı model üretti!

Transformatörler popülerdir ve genel dizi modelleme için yaygın olarak uygulanabilir (ve birçok şey diziler olarak ifade edilebilir). Şimdiye kadar, girişin önündeki ana engel, hantal bir uygulamaydı, ancak KerasNLP ile - derin öğrenme uygulayıcıları, modelleri hızlı ve kolay bir şekilde oluşturmak için uygulamalardan yararlanabilir.

Zaman Damgası:

Den fazla Yığın kötüye kullanımı