Categories
Rehber Web Geliştirme

Tensorflow NLP: Doğal Dil İşleme ve Kelime Tahmini

Yapay zeka sistemlerinin iniş ve çıkış dönemleri olduğunu artık hepimiz biliyoruz. Teknoloji geliştikçe yapay zeka alanına yapılan yatırım farklı evrelere dönüşerek bir anda karşımıza çıkıyor.

Artık hayatımızın her alanında irili ufaklı yapay zeka sistemlerinin çıkmasını bu evrelere borçluyuz. 

Sosyal mecralarda teknoloji ile ilgilenen insanları takip ediyorsanız akışınızda kesinlikle yapay zeka ile ilgili içerikler çıkmıştır.

Genellikle basit yüz tanıma, maske kontrolü, cisim tanıma ve yaş tahmini gibi işlerin yoğun olduğunu görebiliriz. Bu işleri yapmanın artık zor bir yolu -tabi isterseniz- yok.

Artık her yapay zeka aracı, bahsi geçen tüm işleri yapabilecek modüller içeriyor.

Bizim bu yazımızda kullanacağımız kütüphane Tensorflow. Bu aşamada amaç, sizlere kurulum ya da başlangıç öğretmek değil, bir dil işleyebilen ağ oluşturmak olduğunu belirtelim.

Tensorflow ile Doğal Dil İşleme

“Tensorflow Nedir?”, “Neural Network Nasıl Çalışır?” gibi sorularınız için farklı kaynaklar bulmanız gerekecektir. Buradaki amacımız net olarak “Tensorflow ile doğal dil işleme” dir. 

Kodlarımızı Google Colab üzerinden yazacağımız için kendi makinenizi yormaya ya da kurulumları yapmaya ihtiyacınız yok.

Colab üzerinden yeni bir Notebook oluşturalım. Açılan sayfada menüden “Çalışma zamanı” sekmesine gelip “Çalışma zamanı türünü değiştir”’e tıklayalım.

çalışma zamanı seçeneğinden çalışma zamanı türünü değiştir butonunu işaret eden bir ekran görüntüsütürünü

Açılan popup içerisinde “Donanım hızlandırıcı” olarak “GPU” seçeneğini seçelim. Bu işimizi hızlandıracaktır.not defteri ayarlarından bir düzeltme göstermek için alınan bir ekran görüntüsü

Genel bilgileri vermeyeceğimizi söylemiştik ancak yazacağımız her satır kodun ve kullanacağımız kütüphanelerdeki alt modüllerin neden import edildiğini, ne için kullanılacağını açıklayacağım.

import tensorflow as tf

Öncelikle “Tensorflow” import ediyoruz. Versiyon öğrenmek için aşağıdaki komutu kullanabiliriz. 

print(tf.__version__)

Çıktımız bu şekilde görünecektir.

tensorflow kod görüntüsü

Bizim yapacağımız proje, vereceğimiz metin ya da kelime üzerinden sonraki kelimeninin ne olacağını tahmin eden bir proje olacak. Gerekli kütüphanelerimizi eklemeye başlayalım.


import tensorflow as tf

from tensorflow.keras.preprocessing.text import Tokenizer

from tensorflow.keras.preprocessing.sequence import pad_sequences

from tensorflow.keras.models import Sequential

import numpy as np

İlk satırda Tensorflow ‘u tf adıyla ekliyoruz.

İkinci satırda vereceğimiz verileri kelime olarak parçalara yani tokenlara ayırarak indexlenmiş halde vermesi için “Tokenizer” modülünü içeri alıyoruz.

Üçüncü satırda eklediğimiz “pad_sequences” modülü sinir ağımıza verileri sabit matrix uzunlukları ile verebilmemizi sağlayacak.

Dördüncü satırda bulunan “Sequential” modülü sinir ağımızın oluşturulacağı modül yani modelimiz bu modül tarafından üretilecek.

Son satırda ise bolca kullandığımız numpy kütüphanesini ekliyoruz. Çeşitli array manipülasyonları için kullanacağız. 

Kendimize bir metin bulacağız. İster şiir ister bir imdb yorumu isterseniz de kaggle.com’dan bir veri seti kullanabilirsiniz. Ben imdb üzerinden birkaç yorumu ekleyerek ilerleyeceğim. Bunu bir text değişkenine atıyorum, tüm karakterleri küçültüp satır satır kesiyoruz.  

text = """

----

"""

lines = text.lower().split("\n")

Şimdi tokenlarımızı oluşturma zamanı içeri aldığımız “Tokenizer” modülünden bir tane türetip “fit_on_texts” fonksiyonuna “lines” arrayimizi gönderiyoruz. Bu sayede tokenlarımızı oluşturuyoruz. Oluşan tokenların sayısını bir değişkene atıyoruz modelimizi oluştururken işimize yarayacak. “input_sequences” objemiz birazdan manipülasyona uğratacağımız, modelimize girdi olacak tokenlar içerecek.

tokenizer = Tokenizer()

tokenizer.fit_on_texts(lines)

total_words = len(tokenizer.word_index) + 1

input_sequences = []

Şimdi “input_sequences” ın içerisini dolduracağız. Buradaki amaç her bir kelimeden sonra gelecek olan kelime için yeni bir varyasyon, yani bir veri oluşturmak. Kod harici örnek vermek gerekirse “güç: 1, tuşuna: 2, entegre: 3, şekilde: 4” şeklinde oluşan bir token indexin ana verimize eklenmesi bu şekilde olacaktır.

[1 2]            // güç tuşuna

[1 2 3]         // güç tuşuna entegre

[1 2 3 4]      // güç tuşuna entegre şekilde

for line in sliced_lines:

    token_list = tokenizer.texts_to_sequences([line])[0]

    for i in range(1, len(token_list)):

        tokens = token_list[:i + 1]

        input_sequences.append(tokens)

Hemen projemizdeki çıktısına da bir bakalım.tensorflow kod görüntüsü

Şimdi “input_sequences” da bulunan en uzun satırın değerini alıp “maxlen” içerisinde atıyoruz. “pad_sequences” için padding değişkeni oluşturduk ve “pre” ataması yaptık. Yani “maxlen” den küçük olan her satırın ön kısmına bir tampon oluşturulacak.

Eğer sonuna isteseydik “padding” değerini “post” olarak atayacaktık. Dördüncü satırda verimizdeki her satırın son kısmını kesiyor ve “xs” değişkenine atıyoruz.

Son kısımları ise “labels” değişkenine. Bu sayede “xs” de predict edilecek bir kelimenin sonucu labels a düşmüş olacak.

Beşinci satırda ise “labels” değişkeni içerisinde bulunan verileri modele output olarak verebilmek amacı ile “tf.keras.utils.to_categorical” fonksiyonunu kullanıyoruz.

“num_classes” parametresi ile verimizde kaç farklı kelime olabileceği ile ilgili bilgiyi veriyoruz.

maxlen = max([len(x) for x in input_sequences])

padding = "pre"

input_sequences = np.array(pad_sequences(input_sequences, padding=padding, maxlen=maxlen))

xs, labels = input_sequences[:,:-1], input_sequences[:,-1]

ys = tf.keras.utils.to_categorical(labels, num_classes=total_words)

Bu durumda “preprocessing” aşamamız tamamlanmış oluyor şimdi sırada modelimizi oluşturmak ve eğitmek var.

Modelimizi oluşturuyor ve üç adet katman ekliyoruz. İlk katmanımız “Embedding”. Bu katman kelimelerimize bir vektörleme sağlıyor.

Kelimelerimize uzayda birer konum atıyoruz. Bu katman yerine GlobalMaxPooling1D katmanı kullanmamız da mümkün.

İçerisindeki parametrelere baktığımızda ilk parametre “dimension” yani kelimelerimizin bağlantıları ikinci parametremiz “total_words” yani toplamda uzaya yerleştirilecek kelime miktarı ve son olarak “input_length”, adından da anlaşılacağı üzere katmana girdi yapabilecek verinin uzunluğu.

Bidirectional katmanımız kısaca LSTM in verileri çift yönlü olarak hem normal hem tersten okuyarak tahmini kolaylaştırmasıdır. LSTM ler dil işlemede doğan sorunları ele alarak RNN ler için özellikle geliştirilmiş fonksiyonlardır. Detaylı bilgiye bu yazımızda yer veremeyeceğiz.

Son olarak çıkış katmanımız bulunuyor. Aktivasyonların detaylarına burada değinmeyeceğim. Modelimizi çalıştırıyoruz. “compile” içerisinde bulunan “loss” hariç diğer parametreler oluşturduğunuz yapıya göre ayarlanabilir durumdalar.

“loss” ise bu durumda bize bizim görmek isteyeceğimiz “categorical_crossentropy” fonksiyonu. “metrics” ise “fit” fonksiyonu sırasında modelin eğitim sürecinde görmek ve incelemek istediğiniz parametreler.

model = Sequential([

    tf.keras.layers.Embedding(total_words, 100, input_length=maxlen - 1),

    tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(100)),

    tf.keras.layers.Dense(total_words, activation="softmax")

])

model.compile(loss="categorical_crossentropy", optimizer=tf.keras.optimizers.Adam(learning_rate=0.06), metrics=["accuracy"])

history = model.fit(xs, ys, epochs=30, verbose=1)

Verilerimiz ve modelimiz hazır. Şimdi sırada tahmin var.  Bir değişken oluşturuyor ve metnin bir kısmını giriyoruz.

Preprocessing aşamasında yaptığımız gibi tokenizer ile sequences larını oluşturuyoruz ve padding yapıyoruz.

Modelimize predict ettiriyoruz ve çıktıdan gelecek olan değeri tokenizer ile oluşturduğumuz index havuzunda eşleştiriyoruz ve sonraki kelimeyi buluyoruz.

seed = "every child who I have seen watch"

token_list = tokenizer.texts_to_sequences([seed])[0]

token_list = pad_sequences([token_list], maxlen=maxlen-1, padding=padding)

predicted = np.argmax(model.predict(token_list), axis=-1)

output_word = ""

for word, index in tokenizer.word_index.items():

    if index == predicted:

        output_word = word

        break

print(output_word)

Yukarıda yapılan geliştirmeyi bir loop a alabilir output_word ü seed e ekleyerek sürekli bir sonraki kelimeyi tahmin edebilir hale getirebilirsiniz.

Tensorflow doğal dil işleme ve kelime tahmini yazımızın sonuna geldik. İlgili kodların bulunduğu Notebook u aşağıda paylaşacağım.

Bu yazının üzerine devam edip geliştirmeler yapmak istiyorsanız bir sonraki aşama olarak Tensorflow un sitesinde bulunan şiir yazma tutorial ı ile devam edebilir.

Yeni kelimelerin oluşturulmasının nasıl yapıldığını farklı ve detaylı bir şekilde inceleyebilirsiniz. 

https://colab.research.google.com/drive/1fuIn7U4yS77xwg4GggkHv1FrrCrkvWKf

https://www.tensorflow.org/tutorials/text/text_generation

Leave a Reply

Your email address will not be published. Required fields are marked *