497 lines
28 KiB
Plaintext
497 lines
28 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Üretici Ağlar\n",
|
||
"\n",
|
||
"Tekrarlayan Sinir Ağları (RNN'ler) ve Uzun Kısa Süreli Bellek Hücreleri (LSTM'ler) ile Gated Recurrent Units (GRU'lar) gibi kapılı hücre varyantları, dil modelleme için bir mekanizma sağladı, yani kelime sıralamasını öğrenebilir ve bir dizideki bir sonraki kelime için tahminlerde bulunabilirler. Bu, RNN'leri **üretici görevler** için kullanmamıza olanak tanır, örneğin sıradan metin üretimi, makine çevirisi ve hatta görüntü açıklaması.\n",
|
||
"\n",
|
||
"Önceki birimde tartıştığımız RNN mimarisinde, her RNN birimi bir sonraki gizli durumu çıktı olarak üretiyordu. Ancak, her tekrarlayan birime başka bir çıktı da ekleyebiliriz, bu da bize bir **dizi** (orijinal diziyle aynı uzunlukta) üretme imkanı sağlar. Dahası, her adımda bir girdi kabul etmeyen ve sadece bir başlangıç durum vektörü alarak bir çıktı dizisi üreten RNN birimlerini de kullanabiliriz.\n",
|
||
"\n",
|
||
"Bu not defterinde, metin üretmemize yardımcı olan basit üretici modeller üzerine odaklanacağız. Basitlik adına, harf harf metin üreten bir **karakter düzeyinde ağ** oluşturalım. Eğitim sırasında, bir metin korpusunu alıp harf dizilerine bölmemiz gerekecek.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import tensorflow as tf\n",
|
||
"from tensorflow import keras\n",
|
||
"import tensorflow_datasets as tfds\n",
|
||
"import numpy as np\n",
|
||
"\n",
|
||
"ds_train, ds_test = tfds.load('ag_news_subset').values()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Karakter Kelime Dağarcığı Oluşturma\n",
|
||
"\n",
|
||
"Karakter seviyesinde bir üretici ağ oluşturmak için metni kelimeler yerine bireysel karakterlere ayırmamız gerekiyor. Daha önce kullandığımız `TextVectorization` katmanı bunu yapamaz, bu yüzden iki seçeneğimiz var:\n",
|
||
"\n",
|
||
"* Metni manuel olarak yükleyip, [bu resmi Keras örneğinde](https://keras.io/examples/generative/lstm_character_level_text_generation/) olduğu gibi 'elle' tokenizasyon yapmak.\n",
|
||
"* Karakter seviyesinde tokenizasyon için `Tokenizer` sınıfını kullanmak.\n",
|
||
"\n",
|
||
"Biz ikinci seçeneği tercih edeceğiz. `Tokenizer`, kelimelere tokenizasyon yapmak için de kullanılabilir, bu nedenle karakter seviyesinden kelime seviyesine tokenizasyona geçiş oldukça kolay olmalıdır.\n",
|
||
"\n",
|
||
"Karakter seviyesinde tokenizasyon yapmak için `char_level=True` parametresini geçmemiz gerekiyor:\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 2,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def extract_text(x):\n",
|
||
" return x['title']+' '+x['description']\n",
|
||
"\n",
|
||
"def tupelize(x):\n",
|
||
" return (extract_text(x),x['label'])\n",
|
||
"\n",
|
||
"tokenizer = keras.preprocessing.text.Tokenizer(char_level=True,lower=False)\n",
|
||
"tokenizer.fit_on_texts([x['title'].numpy().decode('utf-8') for x in ds_train])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Dizinin **sonunu** belirtmek için `<eos>` olarak adlandıracağımız özel bir token kullanmak istiyoruz. Hadi bunu kelime dağarcığına manuel olarak ekleyelim:\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 3,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"eos_token = len(tokenizer.word_index)+1\n",
|
||
"tokenizer.word_index['<eos>'] = eos_token\n",
|
||
"\n",
|
||
"vocab_size = eos_token + 1"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Şimdi, metni sayı dizilerine dönüştürmek için şunları kullanabiliriz:\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 4,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[[48, 2, 10, 10, 5, 44, 1, 25, 5, 8, 10, 13, 78]]"
|
||
]
|
||
},
|
||
"execution_count": 4,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"tokenizer.texts_to_sequences(['Hello, world!'])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Başlıklar Üretmek için Bir Generative RNN Eğitmek\n",
|
||
"\n",
|
||
"RNN'i haber başlıkları üretmek için şu şekilde eğiteceğiz. Her adımda bir başlık alacağız, bu başlık bir RNN'e verilecek ve her bir giriş karakteri için ağdan bir sonraki çıkış karakterini üretmesini isteyeceğiz:\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"Dizimizin son karakteri için ağdan `<eos>` tokenini üretmesini isteyeceğiz.\n",
|
||
"\n",
|
||
"Burada kullandığımız generative RNN'in temel farkı, RNN'in her adımından bir çıktı alacak olmamızdır, sadece son hücreden değil. Bu, RNN hücresine `return_sequences` parametresini belirterek gerçekleştirilebilir.\n",
|
||
"\n",
|
||
"Bu nedenle, eğitim sırasında, ağa bir giriş olarak belirli bir uzunlukta kodlanmış karakter dizisi verilecek ve bir çıkış olarak aynı uzunlukta, ancak bir eleman kaydırılmış ve `<eos>` ile sonlandırılmış bir dizi alınacaktır. Minibatch, bu tür birkaç diziden oluşacak ve tüm dizileri hizalamak için **padding** kullanmamız gerekecek.\n",
|
||
"\n",
|
||
"Şimdi, veri setini bizim için dönüştürecek fonksiyonlar oluşturalım. Dizileri minibatch seviyesinde doldurmak istediğimiz için, önce `.batch()` çağrısı yaparak veri setini gruplandıracağız ve ardından dönüşüm yapmak için `map` kullanacağız. Bu nedenle, dönüşüm fonksiyonu bir minibatch'in tamamını parametre olarak alacak:\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def title_batch(x):\n",
|
||
" x = [t.numpy().decode('utf-8') for t in x]\n",
|
||
" z = tokenizer.texts_to_sequences(x)\n",
|
||
" z = tf.keras.preprocessing.sequence.pad_sequences(z)\n",
|
||
" return tf.one_hot(z,vocab_size), tf.one_hot(tf.concat([z[:,1:],tf.constant(eos_token,shape=(len(z),1))],axis=1),vocab_size)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Burada yaptığımız birkaç önemli şey:\n",
|
||
"* Öncelikle, string tensöründen gerçek metni çıkarıyoruz\n",
|
||
"* `text_to_sequences`, string listesini bir tamsayı tensörleri listesine dönüştürür\n",
|
||
"* `pad_sequences`, bu tensörleri maksimum uzunluklarına kadar doldurur\n",
|
||
"* Son olarak, tüm karakterleri one-hot encode ediyoruz, ayrıca kaydırma ve `<eos>` ekleme işlemini yapıyoruz. Karakterleri neden one-hot encode ettiğimizi yakında göreceğiz\n",
|
||
"\n",
|
||
"Ancak, bu fonksiyon **Pythonic** bir yapıya sahiptir, yani Tensorflow hesaplama grafiğine otomatik olarak çevrilemez. Bu fonksiyonu doğrudan `Dataset.map` fonksiyonunda kullanmaya çalışırsak hata alırız. Bu Pythonic çağrıyı `py_function` sarmalayıcısını kullanarak çevrelememiz gerekiyor:\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 6,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def title_batch_fn(x):\n",
|
||
" x = x['title']\n",
|
||
" a,b = tf.py_function(title_batch,inp=[x],Tout=(tf.float32,tf.float32))\n",
|
||
" return a,b"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"> **Not**: Pythonic ve Tensorflow dönüşüm fonksiyonları arasındaki farkı anlamak biraz karmaşık görünebilir ve neden veri setini `fit` fonksiyonuna geçmeden önce standart Python fonksiyonlarıyla dönüştürmediğimizi sorguluyor olabilirsiniz. Bu kesinlikle yapılabilir, ancak `Dataset.map` kullanmanın büyük bir avantajı vardır: veri dönüşüm hattı Tensorflow hesaplama grafiği kullanılarak yürütülür, bu da GPU hesaplamalarından faydalanır ve CPU/GPU arasında veri geçişi ihtiyacını en aza indirir.\n",
|
||
"\n",
|
||
"Şimdi jeneratör ağımızı oluşturabilir ve eğitime başlayabiliriz. Bu ağ, önceki birimde tartıştığımız herhangi bir tekrarlayan hücreye (basit, LSTM veya GRU) dayanabilir. Örneğimizde LSTM kullanacağız.\n",
|
||
"\n",
|
||
"Ağ karakterleri girdi olarak aldığı ve kelime dağarcığı boyutu oldukça küçük olduğu için, gömme katmanına ihtiyacımız yoktur; tekil kodlanmış girdi doğrudan LSTM hücresine gidebilir. Çıkış katmanı, LSTM çıktısını tekil kodlanmış token numaralarına dönüştürecek bir `Dense` sınıflandırıcı olacaktır.\n",
|
||
"\n",
|
||
"Ek olarak, değişken uzunlukta dizilerle çalıştığımız için, dizinin doldurulmuş kısmını görmezden gelecek bir maske oluşturmak için `Masking` katmanını kullanabiliriz. Bu kesinlikle gerekli değildir, çünkü `<eos>` token'ını aşan her şeyle çok fazla ilgilenmiyoruz, ancak bu katman türüyle biraz deneyim kazanmak adına kullanacağız. `input_shape` `(None, vocab_size)` olacaktır, burada `None` değişken uzunlukta diziyi belirtir ve çıkış şekli de `(None, vocab_size)` olacaktır, `summary` çıktısından da görebileceğiniz gibi:\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 7,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Model: \"sequential\"\n",
|
||
"_________________________________________________________________\n",
|
||
"Layer (type) Output Shape Param # \n",
|
||
"=================================================================\n",
|
||
"masking (Masking) (None, None, 84) 0 \n",
|
||
"_________________________________________________________________\n",
|
||
"lstm (LSTM) (None, None, 128) 109056 \n",
|
||
"_________________________________________________________________\n",
|
||
"dense (Dense) (None, None, 84) 10836 \n",
|
||
"=================================================================\n",
|
||
"Total params: 119,892\n",
|
||
"Trainable params: 119,892\n",
|
||
"Non-trainable params: 0\n",
|
||
"_________________________________________________________________\n",
|
||
"15000/15000 [==============================] - 229s 15ms/step - loss: 1.5385\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"<tensorflow.python.keras.callbacks.History at 0x7fa40c1245e0>"
|
||
]
|
||
},
|
||
"execution_count": 7,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"model = keras.models.Sequential([\n",
|
||
" keras.layers.Masking(input_shape=(None,vocab_size)),\n",
|
||
" keras.layers.LSTM(128,return_sequences=True),\n",
|
||
" keras.layers.Dense(vocab_size,activation='softmax')\n",
|
||
"])\n",
|
||
"\n",
|
||
"model.summary()\n",
|
||
"model.compile(loss='categorical_crossentropy')\n",
|
||
"\n",
|
||
"model.fit(ds_train.batch(8).map(title_batch_fn))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Çıktı oluşturma\n",
|
||
"\n",
|
||
"Modeli eğittikten sonra, şimdi onu kullanarak bazı çıktılar üretmek istiyoruz. Öncelikle, bir dizi token numarasıyla temsil edilen metni çözmek için bir yönteme ihtiyacımız var. Bunun için `tokenizer.sequences_to_texts` fonksiyonunu kullanabiliriz; ancak bu fonksiyon karakter düzeyinde tokenizasyonla iyi çalışmaz. Bu nedenle, tokenizer'dan (adı `word_index` olan) bir token sözlüğü alacağız, ters bir harita oluşturacağız ve kendi çözümleme fonksiyonumuzu yazacağız:\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 10,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"reverse_map = {val:key for key, val in tokenizer.word_index.items()}\n",
|
||
"\n",
|
||
"def decode(x):\n",
|
||
" return ''.join([reverse_map[t] for t in x])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Şimdi, üretim yapacağız. Öncelikle bir dize olan `start` ile başlayacağız, bunu bir diziye `inp` olarak kodlayacağız ve ardından her adımda ağımızı çağırarak bir sonraki karakteri tahmin edeceğiz.\n",
|
||
"\n",
|
||
"Ağdan gelen çıktı `out`, her bir tokenin olasılıklarını temsil eden `vocab_size` öğeden oluşan bir vektördür ve en olası token numarasını `argmax` kullanarak bulabiliriz. Daha sonra bu karakteri üretilen token listesinin sonuna ekleriz ve üretime devam ederiz. Bir karakter üretme işlemi, gerekli karakter sayısını üretmek için `size` kez tekrarlanır ve `eos_token` ile karşılaşıldığında erken sonlandırılır.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 12,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"'Today #39;s lead to strike for the strike for the strike for the strike (AFP)'"
|
||
]
|
||
},
|
||
"execution_count": 12,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"def generate(model,size=100,start='Today '):\n",
|
||
" inp = tokenizer.texts_to_sequences([start])[0]\n",
|
||
" chars = inp\n",
|
||
" for i in range(size):\n",
|
||
" out = model(tf.expand_dims(tf.one_hot(inp,vocab_size),0))[0][-1]\n",
|
||
" nc = tf.argmax(out)\n",
|
||
" if nc==eos_token:\n",
|
||
" break\n",
|
||
" chars.append(nc.numpy())\n",
|
||
" inp = inp+[nc]\n",
|
||
" return decode(chars)\n",
|
||
" \n",
|
||
"generate(model)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Eğitim sırasında çıktı örnekleme\n",
|
||
"\n",
|
||
"*Doğruluk* gibi faydalı metriklere sahip olmadığımız için, modelimizin daha iyi hale geldiğini görmenin tek yolu, eğitim sırasında üretilen dizelerden **örnekleme** yapmaktır. Bunu yapmak için, `fit` fonksiyonuna geçirebileceğimiz ve eğitim sırasında periyodik olarak çağrılacak olan **geri çağrım fonksiyonlarını** (callbacks) kullanacağız.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 13,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Epoch 1/3\n",
|
||
"15000/15000 [==============================] - 226s 15ms/step - loss: 1.2703\n",
|
||
"Today #39;s a lead in the company for the strike\n",
|
||
"Epoch 2/3\n",
|
||
"15000/15000 [==============================] - 227s 15ms/step - loss: 1.2057\n",
|
||
"Today #39;s the Market Service on Security Start (AP)\n",
|
||
"Epoch 3/3\n",
|
||
"15000/15000 [==============================] - 226s 15ms/step - loss: 1.1752\n",
|
||
"Today #39;s a line on the strike to start for the start\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"<tensorflow.python.keras.callbacks.History at 0x7fa40c74e3d0>"
|
||
]
|
||
},
|
||
"execution_count": 13,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"sampling_callback = keras.callbacks.LambdaCallback(\n",
|
||
" on_epoch_end = lambda batch, logs: print(generate(model))\n",
|
||
")\n",
|
||
"\n",
|
||
"model.fit(ds_train.batch(8).map(title_batch_fn),callbacks=[sampling_callback],epochs=3)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Bu örnek zaten oldukça iyi bir metin üretiyor, ancak birkaç şekilde daha da geliştirilebilir:\n",
|
||
"\n",
|
||
"* **Daha fazla metin**. Görevimiz için yalnızca başlıkları kullandık, ancak tam metinle denemeler yapmak isteyebilirsiniz. RNN'lerin uzun dizileri işleme konusunda pek iyi olmadığını unutmayın, bu yüzden ya bunları daha kısa cümlelere bölmek ya da her zaman önceden tanımlanmış bir `num_chars` değeri (örneğin, 256) ile sabit bir dizi uzunluğunda eğitmek mantıklı olabilir. Yukarıdaki örneği böyle bir mimariye dönüştürmeyi deneyebilir ve [resmi Keras eğitimi](https://keras.io/examples/generative/lstm_character_level_text_generation/) ile ilham alabilirsiniz.\n",
|
||
"\n",
|
||
"* **Çok katmanlı LSTM**. 2 veya 3 katmanlı LSTM hücrelerini denemek mantıklı olabilir. Önceki birimde belirttiğimiz gibi, her LSTM katmanı metinden belirli desenler çıkarır ve karakter düzeyinde bir üretici durumunda, daha düşük LSTM seviyesinin heceleri çıkarmaktan, daha yüksek seviyelerin ise kelimeler ve kelime kombinasyonlarından sorumlu olmasını bekleyebiliriz. Bu, LSTM yapıcısına katman sayısı parametresi geçirerek basitçe uygulanabilir.\n",
|
||
"\n",
|
||
"* **GRU birimleri** ile denemeler yapmak ve hangilerinin daha iyi performans gösterdiğini görmek isteyebilirsiniz, ayrıca **farklı gizli katman boyutları** ile de denemeler yapabilirsiniz. Çok büyük bir gizli katman aşırı öğrenmeye yol açabilir (örneğin, ağ tam metni öğrenir) ve daha küçük bir boyut iyi bir sonuç üretmeyebilir.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Yumuşak metin üretimi ve sıcaklık\n",
|
||
"\n",
|
||
"`generate` fonksiyonunun önceki tanımında, oluşturulan metindeki bir sonraki karakter olarak her zaman en yüksek olasılığa sahip karakteri seçiyorduk. Bu durum, metnin sık sık aynı karakter dizileri arasında \"dönmesine\" neden oluyordu, tıpkı şu örnekte olduğu gibi:\n",
|
||
"```\n",
|
||
"today of the second the company and a second the company ...\n",
|
||
"```\n",
|
||
"\n",
|
||
"Ancak, bir sonraki karakter için olasılık dağılımına baktığımızda, en yüksek birkaç olasılık arasındaki farkın çok büyük olmayabileceğini görebiliriz. Örneğin, bir karakterin olasılığı 0.2, diğerinin ise 0.19 olabilir, vb. Örneğin, '*play*' dizisindeki bir sonraki karakteri ararken, bir sonraki karakterin boşluk ya da **e** (örneğin *player* kelimesindeki gibi) olması eşit derecede olasıdır.\n",
|
||
"\n",
|
||
"Bu durum bizi şu sonuca götürür: Her zaman en yüksek olasılığa sahip karakteri seçmek \"adil\" olmayabilir, çünkü ikinci en yüksek olasılığa sahip karakteri seçmek de anlamlı bir metne yol açabilir. Bu nedenle, ağın çıktısının verdiği olasılık dağılımından karakterleri **örneklemek** daha akıllıca bir yaklaşımdır.\n",
|
||
"\n",
|
||
"Bu örnekleme, **multinomial dağılım** olarak adlandırılan bir yöntemi uygulayan `np.multinomial` fonksiyonu kullanılarak yapılabilir. Bu **yumuşak** metin üretimini gerçekleştiren bir fonksiyon aşağıda tanımlanmıştır:\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 33,
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"\n",
|
||
"--- Temperature = 0.3\n",
|
||
"Today #39;s strike #39; to start at the store return\n",
|
||
"On Sunday PO to Be Data Profit Up (Reuters)\n",
|
||
"Moscow, SP wins straight to the Microsoft #39;s control of the space start\n",
|
||
"President olding of the blast start for the strike to pay <b>...</b>\n",
|
||
"Little red riding hood ficed to the spam countered in European <b>...</b>\n",
|
||
"\n",
|
||
"--- Temperature = 0.8\n",
|
||
"Today countie strikes ryder missile faces food market blut\n",
|
||
"On Sunday collores lose-toppy of sale of Bullment in <b>...</b>\n",
|
||
"Moscow, IBM Diffeiting in Afghan Software Hotels (Reuters)\n",
|
||
"President Ol Luster for Profit Peaced Raised (AP)\n",
|
||
"Little red riding hood dace on depart talks #39; bank up\n",
|
||
"\n",
|
||
"--- Temperature = 1.0\n",
|
||
"Today wits House buiting debate fixes #39; supervice stake again\n",
|
||
"On Sunday arling digital poaching In for level\n",
|
||
"Moscow, DS Up 7, Top Proble Protest Caprey Mamarian Strike\n",
|
||
"President teps help of roubler stepted lessabul-Dhalitics (AFP)\n",
|
||
"Little red riding hood signs on cash in Carter-youb\n",
|
||
"\n",
|
||
"--- Temperature = 1.3\n",
|
||
"Today wits flawer ro, pSIA figat's co DroftwavesIs Talo up\n",
|
||
"On Sunday hround elitwing wint EU Powerburlinetien\n",
|
||
"Moscow, Bazz #39;s sentries olymen winnelds' next for Olympite Huc?\n",
|
||
"President lost securitys from power Elections in Smiltrials\n",
|
||
"Little red riding hood vides profit, exponituity, profitmainalist-at said listers\n",
|
||
"\n",
|
||
"--- Temperature = 1.8\n",
|
||
"Today #39;It: He deat: N.KA Asside\n",
|
||
"On Sunday i arry Par aldeup patient Wo stele1\n"
|
||
]
|
||
},
|
||
{
|
||
"ename": "KeyError",
|
||
"evalue": "0",
|
||
"output_type": "error",
|
||
"traceback": [
|
||
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
||
"\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)",
|
||
"\u001b[0;32m<ipython-input-33-db32367a0feb>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 18\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"\\n--- Temperature = {i}\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 19\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mj\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 20\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgenerate_soft\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0msize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m300\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mstart\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mwords\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mj\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mtemperature\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
|
||
"\u001b[0;32m<ipython-input-33-db32367a0feb>\u001b[0m in \u001b[0;36mgenerate_soft\u001b[0;34m(model, size, start, temperature)\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0mchars\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnc\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0minp\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0minp\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mnc\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 13\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mdecode\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mchars\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 14\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[0mwords\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m'Today '\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'On Sunday '\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'Moscow, '\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'President '\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'Little red riding hood '\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
|
||
"\u001b[0;32m<ipython-input-10-3f5fa6130b1d>\u001b[0m in \u001b[0;36mdecode\u001b[0;34m(x)\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mdecode\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0;34m''\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mjoin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mreverse_map\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mt\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mt\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
|
||
"\u001b[0;32m<ipython-input-10-3f5fa6130b1d>\u001b[0m in \u001b[0;36m<listcomp>\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mdecode\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0;34m''\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mjoin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mreverse_map\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mt\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mt\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
|
||
"\u001b[0;31mKeyError\u001b[0m: 0"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"def generate_soft(model,size=100,start='Today ',temperature=1.0):\n",
|
||
" inp = tokenizer.texts_to_sequences([start])[0]\n",
|
||
" chars = inp\n",
|
||
" for i in range(size):\n",
|
||
" out = model(tf.expand_dims(tf.one_hot(inp,vocab_size),0))[0][-1]\n",
|
||
" probs = tf.exp(tf.math.log(out)/temperature).numpy().astype(np.float64)\n",
|
||
" probs = probs/np.sum(probs)\n",
|
||
" nc = np.argmax(np.random.multinomial(1,probs,1))\n",
|
||
" if nc==eos_token:\n",
|
||
" break\n",
|
||
" chars.append(nc)\n",
|
||
" inp = inp+[nc]\n",
|
||
" return decode(chars)\n",
|
||
"\n",
|
||
"words = ['Today ','On Sunday ','Moscow, ','President ','Little red riding hood ']\n",
|
||
" \n",
|
||
"for i in [0.3,0.8,1.0,1.3,1.8]:\n",
|
||
" print(f\"\\n--- Temperature = {i}\")\n",
|
||
" for j in range(5):\n",
|
||
" print(generate_soft(model,size=300,start=words[j],temperature=i))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"En yüksek olasılığa ne kadar sıkı bağlı kalmamız gerektiğini belirten **temperature** adlı bir parametre daha tanıttık. Eğer temperature 1.0 ise, adil bir multinomial örnekleme yaparız ve temperature sonsuza yaklaştığında - tüm olasılıklar eşit hale gelir ve bir sonraki karakteri rastgele seçeriz. Aşağıdaki örnekte, temperature değerini çok fazla artırdığımızda metnin anlamsız hale geldiğini ve 0'a yaklaştığında \"döngüsel\" şekilde zor üretilmiş bir metne benzediğini gözlemleyebiliriz.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"\n---\n\n**Feragatname**: \nBu belge, AI çeviri hizmeti [Co-op Translator](https://github.com/Azure/co-op-translator) kullanılarak çevrilmiştir. Doğruluk için çaba göstersek de, otomatik çevirilerin hata veya yanlışlıklar içerebileceğini lütfen unutmayın. Belgenin orijinal dili, yetkili kaynak olarak kabul edilmelidir. Kritik bilgiler için profesyonel insan çevirisi önerilir. Bu çevirinin kullanımından kaynaklanan yanlış anlamalar veya yanlış yorumlamalar için sorumluluk kabul etmiyoruz.\n"
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"interpreter": {
|
||
"hash": "16af2a8bbb083ea23e5e41c7f5787656b2ce26968575d8763f2c4b17f9cd711f"
|
||
},
|
||
"kernelspec": {
|
||
"display_name": "Python 3.8.12 ('py38')",
|
||
"language": "python",
|
||
"name": "python3"
|
||
},
|
||
"language_info": {
|
||
"codemirror_mode": {
|
||
"name": "ipython",
|
||
"version": 3
|
||
},
|
||
"file_extension": ".py",
|
||
"mimetype": "text/x-python",
|
||
"name": "python",
|
||
"nbconvert_exporter": "python",
|
||
"pygments_lexer": "ipython3",
|
||
"version": "3.8.12"
|
||
},
|
||
"coopTranslator": {
|
||
"original_hash": "9fbb7d5fda708537649f71f5f646fcde",
|
||
"translation_date": "2025-08-28T14:05:10+00:00",
|
||
"source_file": "lessons/5-NLP/17-GenerativeNetworks/GenerativeTF.ipynb",
|
||
"language_code": "tr"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 4
|
||
} |