Denklemleri Çözmekten Derin Öğrenmeye: Bir TensorFlow Python Eğitimi

Yayınlanan: 2022-03-11

Son zamanlarda yapay zeka dünyasında, kendi kendini süren arabalarla ilgili çokça duyurulan ilerlemeden, şimdi Chopin taklitleri oluşturan makinelere veya sadece video oyunlarında gerçekten iyi olmaya kadar bazı dikkate değer gelişmeler oldu.

Bu ilerlemelerin merkezinde, Torch, Caffe ve Theano başta olmak üzere derin öğrenme ve diğer makine öğrenimi modellerinin türetilmesine yardımcı olacak bir dizi araç bulunmaktadır. Ancak, Google Brain Kasım 2015'te kendi çerçevesi TensorFlow ile açık kaynağa geçtiğinden beri, bu yazılım kitaplığının popülaritesinin en popüler derin öğrenme çerçevesi olduğunu gördük.

TensorFlow

Bu neden oldu? Bunun nedenleri arasında mevcut destek ve belgelerin zenginliği, üretime hazır olması, hesaplamaları çeşitli cihazlara dağıtma kolaylığı ve mükemmel bir görselleştirme aracı yer alır: TensorBoard.

Sonuç olarak, TensorFlow, kapsamlı ve esnek bir dizi teknik özelliği büyük bir kullanım kolaylığıyla birleştirmeyi başarır.

Bu makalede, basit bir sinir ağı uygulamasıyla derin öğrenmedeki kullanımlarını tanıtmadan önce, makine öğreniminin genellikle içerdiğinin oldukça dışında, genel bir sayısal sorunu çözmek için bu aracı kullanarak bu aracın mekaniği hakkında bir anlayış kazanacaksınız.

Sen başlamadan önce

Temel makine öğrenimi yöntemleri bilgisi olduğu varsayılır. Eğer yetişmeye ihtiyacınız varsa, bu çok faydalı gönderiye göz atın.

Python API'sini göstereceğimiz için Numpy'yi anlamak da faydalıdır.

TensorFlow'u kurmak için lütfen burada bulunan talimatları izleyin.

Windows kullanıyorsanız, yazma sırasında 2.7 değil Python 3.4+ kullanmanız gerektiğine dikkat edilmelidir.

Daha sonra hazır olduğunuzda, kütüphaneyi aşağıdakilerle içe aktarabilmelisiniz:

 import tensorflow as tf

TensorFlow Çözümüne Adım 1/2: Bir Grafik Oluşturun

TensorFlow programlarının oluşturulması genellikle iki ana adımdan oluşur; bunlardan ilki, gerçekleştirmek istediğiniz hesaplamaları açıklayacak, ancak gerçekte bunları gerçekleştirmeyecek veya herhangi bir değeri tutmayacak bir hesaplama grafiği oluşturmaktır.

Herhangi bir grafikte olduğu gibi, düğümlerimiz ve kenarlarımız var. Kenarlar, n boyutlu bir diziyi temsil eden bir tensör olan tensörleri temsil eder. Örneğin, boyutu (veya TensorFlow konuşmasında sıralaması) 0 olan bir tensör bir skalerdir, sıra 1 a vektör, sıra 2 a matris vb.

Düğümler, gerekirse tensörleri girdi olarak alarak bir çıktı tensörü üreten işlemleri temsil eder. Bu tür işlemler arasında toplamalar ( tf.add ), matris çarpımları ( tf.matmul ) ve ayrıca sabitlerin oluşturulması ( tf.constant ) bulunur.

İlk grafiğimiz için bunlardan birkaçını birleştirelim.

 a = tf.constant([2.5, 2]) b = tf.constant([3, 6], dtype=tf.float32) total = tf.add(a, b)

Burada ikisi sabit 1-d dizileri oluşturmak için üç işlem oluşturduk.

Veri türleri, iletilen değerler bağımsız değişkeninden çıkarılır veya bunları dtype bağımsız değişkeni ile belirtebilirsiniz. Bunu b için yapmamış olsaydım, o zaman bir int32 çıkarılırdı ve tf.add olarak atılan bir hata, iki farklı türde bir ekleme tanımlamaya çalışıyor olurdu.

TensorFlow Çözümüne Adım 2/2: İşlemleri Yürütün

Grafik tanımlanmıştır, ancak üzerinde (veya herhangi bir parçasında) herhangi bir hesaplama yapmak için bir TensorFlow Oturumu kurmamız gerekir.

 sess = tf.Session()

Alternatif olarak, IPython gibi etkileşimli bir kabukta bir oturum çalıştırıyorsak, şunu kullanırız:

 sess = tf.InteractiveSession()

Oturum nesnesindeki run yöntemi, bir Tensörü değerlendirmenin bir yoludur.

Bu nedenle, yukarıda tanımlanan toplama hesaplamasını değerlendirmek için, tf.add işleminin çıktısını temsil eden, alınacak Tensör olan 'toplam'ı geçiyoruz.

 print(sess.run(total)) # [ 5.5 8. ]

Bu noktada TensorFlow'un Variable sınıfını tanıtıyoruz. Sabitler, grafik tanımının sabit bir parçasıyken, değişkenler güncellenebilir. Sınıf oluşturucu bir başlangıç ​​değeri gerektirir, ancak o zaman bile, değişkenler üzerinde başka herhangi bir işlem gerçekleştirilmeden önce bunları açıkça başlatmak için bir işleme ihtiyaç duyar.

Değişkenler belirli bir oturumda grafiğin durumunu tutarlar, dolayısıyla değişkenleri daha iyi anlamak için aynı grafiği kullanan birden çok oturumda neler olduğunu gözlemlemeliyiz.

 # Create a variable with an initial value of 1 some_var = tf.Variable(1) # Create op to run variable initializers init_op = tf.global_variables_initializer() # Create an op to replace the value held by some_var to 3 assign_op = some_var.assign(3) # Set up two instances of a session sess1 = tf.Session() sess2 = tf.Session() # Initialize variables in both sessions sess1.run(init_op) sess2.run(init_op) print(sess1.run(some_var)) # Outputs 1 # Change some_var in session1 sess1.run(assign_op) print(sess1.run(some_var)) # Outputs 3 print(sess2.run(some_var)) # Outputs 1 # Close sessions sess1.close() sess2.close()

Grafiği ve iki oturumu kurduk.

Başlatmayı her iki oturumda da yürüttükten sonra (bunu çalıştırmazsak ve ardından değişkeni değerlendirirsek bir hataya ulaşırız) atama işlemini yalnızca bir oturumda yürütürüz. Görüldüğü gibi, değişken değeri devam eder, ancak oturumlar arasında değişmez.

Sayısal Sorunları Çözmek için Grafiği Besleme

TensorFlow'un bir diğer önemli kavramı yer tutucudur. Değişkenler durumu tutarken, yer tutucular grafiğin hangi girdileri bekleyebileceğini ve veri türlerini (ve isteğe bağlı olarak şekillerini) tanımlamak için kullanılır. Daha sonra hesaplamayı çalıştırdığımızda bu yer tutucular aracılığıyla grafiğe veri besleyebiliriz.

TensorFlow grafiği, sonunda eğitmek istediğimiz sinir ağlarına benzemeye başlıyor, ancak ondan önce, finans dünyasındaki ortak bir sayısal sorunu çözmek için kavramları kullanalım.

Aşağıdaki gibi bir denklemde y bulmak istediğimizi varsayalım:

v = Ce -0.5y + Ce -y +Ce -1.5y +(C+P)e -2y

belirli bir v için ( C ve P sabiti ile).

Bu, piyasa değeri v , anapara P ve altı ayda bir ödenen ancak nakit akışları sürekli bileşikleştirme ile iskonto edilmiş C kuponu olan bir tahvilin vadeye kadar getirisini ( y ) hesaplamak için bir formüldür.

Temelde bunun gibi bir denklemi deneme yanılma yöntemiyle çözmemiz gerekiyor ve y için nihai değerimizi sıfırlamak için ikiye bölme yöntemini seçeceğiz.

İlk olarak, bu problemi bir TensorFlow grafiği olarak modelleyeceğiz.

C ve P sabit sabitlerdir ve grafiğimizin tanımının bir parçasını oluştururlar. y alt ve üst sınırlarını iyileştiren bir sürece sahip olmak istiyoruz. Bu nedenle, bu sınırlar ( a ve b ile gösterilir), her y tahmininden sonra değiştirilmesi gereken değişkenler için iyi adaylardır ( a ve b orta noktası olarak alınır).

 # Specify the values our constant ops will output C = tf.constant(5.0) P = tf.constant(100.0) # We specify the initial values that our lower and upper bounds will be when initialised. # Obviously the ultimate success of this algorithm depends on decent start points a = tf.Variable(-10.0) b = tf.Variable(10.0) # We expect a floating number to be inserted into the graph v_target = tf.placeholder("float") # Remember the following operations are definitions, # none are carried out until an operation is evaluated in a session! y = (a+b)/2 v_guess = C*tf.exp(-0.5*y) + C*tf.exp(-y) + C*tf.exp(-1.5*y) + (C + P)*tf.exp(-2*y) # Operations to set temporary values (a_ and b_) intended to be the next values of a and b. # eg if the guess results in av greater than the target v, # we will set a_ to be the current value of y a_ = tf.where(v_guess > v_target, y, a) b_ = tf.where(v_guess < v_target, y, b) # The last stage of our graph is to assign the two temporary vals to our variables step = tf.group( a.assign(a_), b.assign(b_) )

Artık herhangi biri belirli bir oturuma göre değerlendirilebilecek bir işlem ve değişken listemiz var. Bu işlemlerden bazıları, çalıştırılacak diğer işlemlere dayanır, bu nedenle, diyelim ki v_guess çalıştırmak, C ve P gibi diğer tensörlerin önce değerlendirilmesi için bir zincirleme reaksiyon başlatacaktır.

Bu işlemlerden bazıları, bir değerin belirtilmesi gereken bir yer tutucuya dayanır, peki bu değeri gerçekte nasıl besleyeceğiz?

Bu, run işlevinin kendisindeki feed_dict bağımsız değişkeni aracılığıyla yapılır.

a_ değerini değerlendirmek istiyorsak, yer a_ v_target değerini şu şekilde ekleriz:

 sess.run(a_, feed_dict={v_target: 100})

bize 0.0 veriyor.

130'luk bir v_target takın ve -10.0 elde ederiz.

Aslında önkoşul olarak diğer tüm işlemlerin yapılmasını gerektiren ve aslında tüm grafiği çalıştıran bizim “adım” işlemimizdir. Aynı zamanda, oturumumuzdaki gerçek durumu gerçekten değiştiren bir işlemdir. Bu nedenle, adımı ne kadar çok çalıştırırsak, a ve b değişkenlerimizi y gerçek değerine doğru kademeli olarak o kadar fazla iteriz.

Diyelim ki denklemimizde v için değerimiz 95'e eşit. Bir oturum oluşturalım ve grafiğimizi bunun üzerinde 100 kez çalıştıralım.

 # Set up a session and initialize variables sess = tf.Session() tf.global_variables_initializer().run() # Run the step operation (and therefore whole graph) 100 times for i in range (100): sess.run(step, feed_dict={v_target:95})

Şimdi y tensörünü değerlendirirsek, arzu edilen bir cevaba benzeyen bir şey elde ederiz.

 print(sess.run(y)) # 0.125163

Nöral ağlar

Artık TensorFlow'un mekaniğini anladığımıza göre, bunu basit bir sinir ağını eğitmek için TensorFlow'da yerleşik bazı ek makine öğrenimi işlemleriyle bir araya getirebiliriz.

Burada, veri noktalarını belirli bir bölgeye - orijinde merkezlenmiş 0,5 yarıçaplı bir daire - içine düşmelerine bağlı olarak 2 boyutlu bir koordinat sistemi üzerinde sınıflandırmak istiyoruz.

Tabii ki, a^2 + b^2 < 0.5 ise yalnızca belirli bir (a,b) noktası kontrol edilerek bu somut olarak doğrulanabilir, ancak bu makine öğrenimi deneyinin amaçları için bunun yerine bir eğitim seti: Bir dizi rastgele nokta ve bunların hedeflenen bölgeye girip girmediği. İşte bunu yaratmanın bir yolu:

 import numpy as np NO_OF_RANDOM_POINTS = 100 CIRCLE_RADIUS = 0.5 random_spots = np.random.rand(NO_OF_RANDOM_POINTS, 2) * 2 - 1 is_inside_circle = (np.power(random_spots[:,0],2) + np.power(random_spots[:,1],2) < CIRCLE_RADIUS).astype(int)

Aşağıdaki özelliklere sahip bir sinir ağı yapacağız:

  1. "rastgele_spotlar" içinde yer alan iki boyutlu vektör dizimizi beslediğimiz iki düğümlü bir girdi katmanından oluşur. Bu, eğitim verilerini bekleyen bir yer tutucu tarafından temsil edilecektir.
  2. Çıktı katmanında ayrıca iki düğüm olacaktır, bu nedenle eğitim etiket dizimizi (“is_inside_circle”) bir skaler için bir yer tutucuya beslememiz ve ardından bu değerleri bir sıcak iki boyutlu vektöre dönüştürmemiz gerekiyor.
  3. Üç düğümden oluşan bir gizli katmanımız olacak, bu nedenle ağırlık matrislerimiz ve önyargı vektörlerimiz için değişkenler kullanmamız gerekecek, çünkü bunlar eğitimi gerçekleştirirken iyileştirilmesi gereken değerlerdir.
 INPUT_LAYER_SIZE = 2 HIDDEN_LAYER_SIZE = 3 OUTPUT_LAYER_SIZE = 2 # Starting values for weights and biases are drawn randomly and uniformly from [-1, 1] # For example W1 is a matrix of shape 2x3 W1 = tf.Variable(tf.random_uniform([INPUT_LAYER_SIZE, HIDDEN_LAYER_SIZE], -1, 1)) b1 = tf.Variable(tf.random_uniform([HIDDEN_LAYER_SIZE], -1, 1)) W2 = tf.Variable(tf.random_uniform([HIDDEN_LAYER_SIZE, OUTPUT_LAYER_SIZE], -1, 1)) b2 = tf.Variable(tf.random_uniform([OUTPUT_LAYER_SIZE], -1, 1)) # Specifying that the placeholder X can expect a matrix of 2 columns (but any number of rows) # representing random spots X = tf.placeholder(tf.float32, [None, INPUT_LAYER_SIZE]) # Placeholder Y can expect integers representing whether corresponding point is in the circle # or not (no shape specified) Y = tf.placeholder(tf.uint8) # An op to convert to a one hot vector onehot_output = tf.one_hot(Y, OUTPUT_LAYER_SIZE)

Grafiğimizin tanımını tamamlamak için, daha iyi bir sınıflandırıcıya ulaşmak için değişkenleri eğitmemize yardımcı olacak bazı işlemler tanımlıyoruz. Bunlara matris hesaplamaları, etkinleştirme işlevleri ve optimize edici dahildir.

 LEARNING_RATE = 0.01 # Op to perform matrix calculation X*W1 + b1 hidden_layer = tf.add(tf.matmul(X, W1), b1) # Use sigmoid activation function on the outcome activated_hidden_layer = tf.sigmoid(hidden_layer) # Apply next weights and bias (W2, b2) to hidden layer and then apply softmax function # to get our output layer (each vector adding up to 1) output_layer = tf.nn.softmax(tf.add(tf.matmul(activated_hidden_layer, W2), b2)) # Calculate cross entropy for our loss function loss = -tf.reduce_sum(onehot_output * tf.log(output_layer)) # Use gradient descent optimizer at specified learning rate to minimize value given by loss tensor train_step = tf.train.GradientDescentOptimizer(LEARNING_RATE).minimize(loss)

Grafiğimizi kurduktan sonra, bir oturum kurma ve “train_step”i çalıştırmanın zamanı geldi (ki bu aynı zamanda herhangi bir önkoşul operasyonunu da çalıştırır). Bu operasyonlardan bazıları yer tutucular kullanır, bu nedenle bunlara ilişkin değerlerin sağlanması gerekir. Bu eğitim adımı, öğrenme algoritmamızdaki bir dönemi temsil eder ve bu nedenle, çalıştırmak istediğimiz dönem sayısı üzerinden döngülenir. Bilgi amaçlı olarak “kayıp” tensörü gibi grafiğin diğer kısımlarını çalıştırabiliriz.

 EPOCH_COUNT = 1000 sess = tf.Session() tf.global_variables_initializer().run() for i in range(EPOCH_COUNT): if i%100 == 0: print('Loss after %d runs: %f' % (i, sess.run(loss, feed_dict={X: random_spots, Y: is_inside_circle}))) sess.run(train_step, feed_dict={X: random_spots, Y: is_inside_circle}) print('Final loss after %d runs: %f' % (i, sess.run(loss, feed_dict={X: random_spots, Y: is_inside_circle})))

Algoritmayı eğittikten sonra, bir noktayı besleyebilir ve sinir ağının çıktısını şu şekilde alabiliriz:

 sess.run(output_layer, feed_dict={X: [[1, 1]]}) # Hopefully something close to [1, 0] sess.run(output_layer, feed_dict={X: [[0, 0]]}) # Hopefully something close to [0, 1]

Çıkış vektörünün ilk elemanı 0,5'ten büyükse, noktayı dairenin dışında, aksi halde içeride olarak sınıflandırabiliriz.

Birçok nokta için output_layer tensörünü çalıştırarak, öğrencinin pozitif olarak sınıflandırılmış noktaları içeren bölgeyi nasıl tasavvur ettiği hakkında bir fikir edinebiliriz. Hedeflediğimiz çembere ne kadar yaklaşabileceğimizi görmek için eğitim setinin boyutu, öğrenme oranı ve diğer parametrelerle oynamaya değer.

neredeyse üçgen
Eğitim seti: 100 puan
Öğrenme oranı: 0.01
Dönemler: 1000

küçük üçgen
Eğitim seti: 1000 puan
Öğrenme oranı: 0.01
Dönemler: 1000

büyük üçgen
Eğitim seti: 1000 puan
Öğrenme oranı: 0.01
Dönemler: 10000

neredeyse daire
Eğitim seti: 1000 puan
Öğrenme oranı: 0.001
Dönemler: 10000

Sarmak

Bu, artırılmış bir eğitim seti veya dönem miktarının iyi bir öğrenci için garanti olmadığı konusunda iyi bir derstir - öğrenme oranı uygun şekilde ayarlanmalıdır.

Umarım bu gösteriler size TensorFlow'un temel ilkeleri hakkında iyi bir fikir vermiş ve daha karmaşık teknikleri uygulamak için sağlam bir temel sağlamıştır.

Tensorboard veya modellerimizi GPU'larda eğitme gibi kavramları ele almadık, ancak bunlar TensorFlow belgelerinde kapsamlı bir şekilde ele alındı. Belgelerde, bu güçlü çerçeveyi kullanarak heyecan verici derin öğrenme görevlerinin üstesinden gelmenize yardımcı olabilecek bir dizi tarif bulunabilir!

İlgili: TensorFlow'da Gradient Descent'in Birçok Uygulaması