Tensorflow ve Tensor nedir? Küçük Bir Örnek

Daha önce Keras ile Tensorflow’u MNIST üzerinde kullanmıştık. Bu üst bir kütüphane ile kullanım Tensorflow’un en kolay kullanımı, asıl içeride neler oluyor, Tensorflow ne yapıyor? Bu giriş yazısında bu konulara biraz değinmeye, bazı tanımlar yapmaya çalışacağım.

Tensor

Tensorflow için tensor; herhangi bir boyutta olan bir dizi içinde tutulan ilkel(integer, float..) verilerden oluşan veri setidir. Bir tensorün Rank‘ı ise o tensorün boyutudur.

3 # rank 0 tensor; boyutu [] olan sayısal bir değer
[1. ,2., 3.] # rank 1 tensor; boyutu [3] olan bir vektör
[[1., 2., 3.], [4., 5., 6.]] # rank 2 tensor; boyutu [2, 3] olan bir matris
[[[1., 2., 3.]], [[7., 8., 9.]]] # rank 3 tensor, boyutu [2, 1, 3]

Tensorflow çekirdeği, Oluşturma ve Çalıştırma olarak iki ana bölümde işlemlerini yapar. Burada işlemden kasıt bir akış diyagramı ile gösterilebilen, düğümlerden(node) oluşan, bir dizi hesaplama işlemidir aslında. Genellikle her düğüm bir tensor alır hesaplamasını yapar ve bir tensor çıkartır ve bütün döngü böyle sürer.

Tensorflow constants, diğerlerinde farklı bir düğüm çeşidi olarak, girdi olarak bir şey almaz fakat çıktı olarak belirlediğimiz sabit değerini döndürür.

node1 = tf.constant(3.0, tf.float32)
node2 = tf.constant(4.0) # varsayılan olarak tf.float32 
print(node1, node2)

# Tensor("Const:0", shape=(), dtype=float32) Tensor("Const_1:0", shape=(),
# dtype=float32)

Burada oluşturduğumuz değerleri ekrana basmak istediğimizde bir Tensor nesnesi olarak bastığını görüyoruz. Tensor düğümlerinin değerleri sadece işlenirken ulaşılabilir olduğundan(çalıştırma bölümünde yani) basit print komutu değeri görmemize yardımcı olmayacaktır.

Bu düğümleri nasıl işleyeceğiz peki? Bunun için bir Tensorflow Session‘ı(oturum) başlatmamız ve bahsettiğimiz akış diyagramına uygun şekilde çalışmasını sağlamamız gerekir.

sess = tf.Session()
print(sess.run([node1, node2]))

# [3.0, 4.0]

Çalıştırma işlemi gerçekleştiği için çıktımızla istediğimiz yanıtı alabildik. run metodu için ilk parametre oluşturduğumuz tensor veya tensorler olmalı. İkinci parametreye birazdan ihtiyacımız olacak.

Bu çok basit Tensorflow diyagramına bir de Operation düğümü ekleyelim.

node3 = tf.add(node1, node2)
print("node3: ", node3)
print("sess.run(node3): ",sess.run(node3))

# node3:  Tensor("Add:0", shape=(), dtype=float32)
# sess.run(node3):  7.0

İlk print komutu tanımlanan operasyon ile ilgili bilgi içeren bir Tensor nesnesi bastı konsola. İkinci print ise diyagramı çalıştırarak sonucunu yazdı.

Daha önce bahsettiğimiz, bir girdisi olan Tensor oluşturmak için ise placeholder kullanmamız gerekiyor.

a = tf.placeholder(tf.float32)
b = tf.placeholder(tf.float32)

adder_node = a + b  
# artı ile toplama tf.add(a, b) için bir kısayoldur

sess = tf.Session()

print(sess.run(adder_node, {a: 3, b:4.5}))
# 7.5
print(sess.run(adder_node, {a: [1,3], b: [2, 4]}))
# [3., 7.]

Önceden kullandığımız run fonksiyonunu bu sefer tensor’lerimiz için gerekli girdileri parametre olarak vererek çağırıyoruz.

Bu parametreleri vermediğimizde “InvalidArgumentError (see above for traceback): You must feed a value for placeholder tensor ‘Placeholder’ with dtype float” gibi detaylı bir hata mesajı alacaksınız.

Buraya kadar basit bir işlemi ve Tensorflow’un tensor’leri nasıl kullandığını gördük. Makine öğrenmesi için biraz daha karmaşık işlemlere ihtiyacımız var.

Öğrenme modellerinde aynı girdilerle farklı, iyileştirilmiş çıktılar almamız gerekir, bunu sağlamak için de Tensorflow akışımızda güncelleyebileceğimiz tensor’ler eklememiz gerekli. Bu tensor’lere Variable deniyor.

W = tf.Variable([.3], tf.float32)
b = tf.Variable([-.3], tf.float32)
x = tf.placeholder(tf.float32)
linear_model = W * x + b

# sess oturumu için Variable tensorlerini başlatıyoruz
init = tf.global_variables_initializer()
sess.run(init)

print(sess.run(linear_model, {x:[1,2,3,4]}))
# [ 0.          0.30000001  0.60000002  0.90000004]

Sadece oluşturduğumuz modeli çalıştırarak farklı girdiler için sonuçlar aldık, bu sonuçları karşılaştırmak için bir y girdisine ihtiyacımız var, onu da ekleyerek devam ediyoruz.

y = tf.placeholder(tf.float32)

squared_deltas = tf.square(linear_model - y)
loss = tf.reduce_sum(squared_deltas)
print(sess.run(loss, {x:[1,2,3,4], y:[0,-1,-2,-3]}))
# 23.66

Modelin başarısını, tahmin ve gerçek değerin farkının karesi ile ölçeceğiz (loss function). Bu kod parçasını çalıştırdığımızda 23.66 lık bir hata değeri alıyoruz. Hata değerini azaltmak için değerlerimizi optimize etmemiz gerekli. W ve b Variable tensor’lerine yeni değerler atayarak tekrar çalıştırıyoruz.

fixW = tf.assign(W, [-1.])
fixb = tf.assign(b, [1.])

sess.run([fixW, fixb])

print(sess.run(loss, {x:[1,2,3,4], y:[0,-1,-2,-3]}))
# 0.0

tf.assign metodu ile Variable tensor’unun değerini değiştirip tekrar döngümüze sokabilir. (Burada en düşük hatayı verecek -1 ve 1 değerleri önceden bilinerek verilmiş.)

Tabi ki buradaki değerleri gerçek bir makine öğrenmesi uygulamasında elle atamamız mümkün değil. Bunun için Tensorflow’un bu iyileştirmeleri yapabilecek ve loss function değerini minimize edecek bir train API’si mevcut.

optimizer = tf.train.GradientDescentOptimizer(0.01)

# minimize etmesi gereken loss function'ımızı
train = optimizer.minimize(loss)

# Variable tensor lerini ilk değerlerine çekiyoruz
sess.run(init)

# 1000 defa Tensorflow diyagramımızı çalıştırarak
# Optimum W ve b değerlerini buluyoruz
for i in range(1000):
  sess.run(train, {x:[1,2,3,4], y:[0,-1,-2,-3]})

print(sess.run([W, b]))
# [array([-0.9999969], dtype=float32), array([ 0.99999082], dtype=float32)]

Sonuç önceden bildiğimiz mükemmel değerlere çok yakın çıktı, yani makine öğrenmesi görevini düzgün bir şekilde yaptı.

Çok basit olarak Tensorflow işleyişi bu şekilde. Şu linkte bu konu hakkında Tensorflow’un kendi anlatımını daha detaylı bir şekilde bulabilirsiniz.


Yayımlandı

kategorisi

yazarı:

Yorumlar

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir