RNN (Yinelenen Sinir Ağı) Eğitimi: TensorFlow Örneği

⚡ Akıllı Özet

Tekrarlayan Sinir Ağları, sıradan nöronlara bir bellek durumu ekler ve her çıktıyı bir sonraki girdi olarak geri besleyerek modelin sırayla öğrenmesini sağlar. Bu kılavuz, TensorFlow'da bir tane oluşturmayı ve bir zaman serisini tahmin etmeyi göstermektedir.

  • 🔘 Bellek durumu: Her bir tekrarlayan nöron, yeni girdiyle birlikte önceki çıktıyı da alır; bu da ağa zamansal farkındalık kazandırır.
  • ☑️ Çıkış şekli: Oyuncak ağın çalıştırılması (3, 2, 6) tensör döndürür: sırasıyla gruplar, zaman adımları ve nöronlar.
  • Gruplandırma kuralı: Zaman serisi girdileri üç boyuta yeniden şekillendirilir ve etiket dizisi, aynı serinin bir dönem ileriye kaydırılmış halidir.
  • 🧪 Model iskeleti: Yer tutucular, dynamic_rnn ile sarılmış bir BasicRNNCell, yoğun bir projeksiyon ve ardından Adam optimizasyon algoritması ile ortalama karesel hata.
  • Antrenman koşusu: 120 tekrarlayan nöron üzerinde 1,500 epoch, kayıp oranını 502,893'ten yaklaşık 1,385'e düşürüyor.
  • 📉 Bilinen sınır: Uzun diziler, LSTM ve kapılı varyantlarının çözmek üzere tasarlandığı kaybolan gradyan sorununu tetikler.

RNN Tekrarlayan Sinir Ağı

Neden Tekrarlayan Sinir Ağına (RNN) ihtiyacımız var?

Tekrarlayan Sinir Ağı (RNN), verileri kalıcı hale getirmek ve kısa vadeli bağımlılıkları modellemek için bellek birimlerini modellemenize olanak tanır. Aynı zamanda veri korelasyonlarının ve kalıplarının tanımlanması için zaman serisi tahmininde de kullanılır. Ayrıca insan beyni ile benzer davranışlar sunarak sıralı veriler için tahmine dayalı sonuçlar üretilmesine yardımcı olur.

yapısı Yapay Sinir Ağı Nispeten basittir ve esas olarak matris çarpımıyla ilgilidir. İlk adımda, girdiler başlangıçta rastgele ağırlıklar ve sapma ile çarpılır, bir aktivasyon fonksiyonu ile dönüştürülür ve çıktı değerleri bir tahmin yapmak için kullanılır. Bu adım, ağın gerçeklikten ne kadar uzak olduğuna dair bir fikir verir.

Uygulanan metrik kayıptır. Kayıp fonksiyonu ne kadar yüksek olursa model o kadar aptal olur. Ağ bilgisini geliştirmek için ağın ağırlıklarını ayarlayarak bir miktar optimizasyon yapılması gerekir. Stokastik gradyan inişi, ağırlıkların değerlerini doğru yönde değiştirmek için kullanılan yöntemdir. Ayarlama yapıldıktan sonra ağ, yeni bilgiyi test etmek için başka bir veri kümesini kullanabilir.

Neyse ki hata önceki duruma göre daha düşük, ancak yine de yeterince küçük değil. Hata en aza indirilene kadar, yani artık daha fazla bilgi çıkarılamayacak duruma gelene kadar optimizasyon adımı yinelemeli olarak yapılır.tracted.

Bu tip modellerin sorunu hafızasının olmamasıdır. Bu, giriş ve çıkışın bağımsız olduğu anlamına gelir. Başka bir deyişle modelin daha önce ne olduğu umurunda değil. Ağın geçmiş veriler veya geçmiş kelimeler hakkında bilgiye sahip olması gerektiğinden, zaman serilerini veya cümleleri tahmin etmeniz gerektiğinde bazı soruları gündeme getirir.

Bu sorunu aşmak için yeni bir mimari türü geliştirildi: Tekrarlayan Sinir Ağı (bundan sonra RNN)

Tekrarlayan Sinir Ağı (RNN) Nedir?

Tekrarlayan Sinir Ağı (RNN), farklı düğümler arasındaki bağlantının zamansal dinamik bir davranış sağlamak için yönlendirilmiş bir grafik oluşturduğu bir Yapay Sinir Ağı sınıfıdır. İleri beslemeli ağlardan türetilen sıralı verileri modellemeye yardımcı olur. Tahmin edici sonuçlar üretmek için insan beynine benzer şekilde çalışır.

Tekrarlayan bir sinir ağı, nöronlara bir hafıza durumunun eklenmesi dışında geleneksel bir sinir ağına oldukça benzer görünür. Bir hafızayı dahil etme hesaplaması basittir.

Sadece bir nöronun bir veri kümesiyle beslendiği basit bir modeli hayal edin. Geleneksel bir sinir ağında, model girdiyi ağırlık ve aktivasyon fonksiyonuyla çarparak çıktıyı üretir. Bir RNN'de ise bu çıktı, kendisine belirli sayıda kez geri gönderilir. Buna "geri gönderme" diyoruz. zaman adımı Çıktının bir sonraki matris çarpımının girdisi haline geldiği süre.

Örneğin aşağıdaki resimde ağın tek bir nörondan oluştuğunu görüyorsunuz. Ağ, girdi ile ağırlık arasındaki matris çarpımını hesaplar ve aktivasyon fonksiyonuyla doğrusal olmamayı ekler. T-1'de çıktı haline gelir. Bu çıktı ikinci matris çarpımının girdisidir.

Tek bir tekrarlayan nöron, t-1 anındaki çıktısını bir sonraki çarpma işleminin girdisi olarak geri gönderiyor.

Tekrarlayan Sinir Ağı (RNN)

Aşağıda, çıktının adımını ve şeklini anlamak için TensorFlow'da basit bir RNN'yi kodluyoruz.

Ağ şunlardan oluşur:

  • Dört giriş
  • Altı nöron
  • 2 zamanlı adımlar

Ağ aşağıdaki resimde gösterildiği gibi ilerleyecektir.

Dört girişli, altı nöronlu ve iki zaman adımlı açılmış RNN

Ağ 'tekrarlayan' olarak adlandırılır çünkü her etkinleştirme karesinde aynı işlemi gerçekleştirir. Ağ, bir aktivasyon fonksiyonunu kullanmadan önce girişlerin ve önceki çıkışın ağırlıklarını hesapladı.

Sürüm notu: Bu eğitimdeki kod, TensorFlow 1.x grafik API'sini hedeflemektedir. TensorFlow 2.x'te de aynı komut dosyası çalışmaya devam eder. import tensorflow.compat.v1 as tf artı tf.disable_v2_behavior()Çünkü yer tutucular, oturumlar ve rnn_cell modülü artık şu konumda yer alıyor: tf.compat.v1Bunun 2.x sürümündeki deyimsel karşılığı şöyledir: tf.keras.layers.SimpleRNN.

import numpy as np
import tensorflow as tf
n_inputs = 4
n_neurons = 6
n_timesteps = 2
The data is a sequence of a number from 0 to 9 and divided into three batches of data.
## Data 
X_batch = np.array([
        [[0, 1, 2, 5], [9, 8, 7, 4]], # Batch 1
        [[3, 4, 5, 2], [0, 0, 0, 0]], # Batch 2
        [[6, 7, 8, 5], [6, 5, 4, 2]], # Batch 3
    ])

Ağı veriler, tekrarlanan aşama ve çıktı için bir yer tutucuyla oluşturabiliriz.

Veriler için yer tutucuyu tanımlayın

X = tf.placeholder(tf.float32, [None, n_timesteps, n_inputs])

İşte:

  • Yok: Bilinmiyor ve partinin boyutunu alacak
  • n_timesteps: Ağın çıktıyı nörona geri gönderme sayısı
  • n_inputs: Grup başına giriş sayısı

Tekrarlanan ağı tanımlayın

Yukarıdaki resimde de belirtildiği gibi ağ 6 nörondan oluşmaktadır. Ağ iki nokta çarpımını hesaplayacaktır:

  • Verileri ilk ağırlık grubuyla girin (yani 6: nöron sayısına eşit)
  • Önceki çıktı, ikinci bir ağırlık kümesiyle (yani, çıktı sayısına karşılık gelen 6)

İlk ileri besleme sırasında, elimizde herhangi bir değer olmadığından önceki çıktının değerlerinin sıfıra eşit olduğunu unutmayın.

Bir RNN oluşturmak için kullanılan nesne, giriş sayısını tanımlamak için num_units argümanıyla birlikte tf.contrib.rnn.BasicRNNCell'dir.

basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=n_neurons)

Artık ağ tanımlandığına göre çıktıları ve durumları hesaplayabilirsiniz.

outputs, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)

Bu nesne, matrisleri uygun sayıda çarpmak için dahili bir döngü kullanır.

Tekrarlayan nöronun, önceki zaman adımlarının tüm girdilerinin bir fonksiyonu olduğunu unutmayın. Ağ bu şekilde kendi hafızasını oluşturur. Önceki zamandan gelen bilgiler gelecekteki zamana yayılabilir. Tekrarlayan sinir ağlarının büyüsü işte burada yatıyor.

## Define the shape of the tensor
X = tf.placeholder(tf.float32, [None, n_timesteps, n_inputs])
## Define the network
basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=n_neurons)
outputs, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)
init = tf.global_variables_initializer()
init = tf.global_variables_initializer()
with tf.Session() as sess:
    init.run()
    outputs_val = outputs.eval(feed_dict={X: X_batch})
print(states.eval(feed_dict={X: X_batch}))
[[ 0.38941205 -0.9980438   0.99750966  0.7892596   0.9978241   0.9999997 ]
 [ 0.61096436  0.7255889   0.82977575 -0.88226104  0.29261455 -0.15597084]
 [ 0.62091285 -0.87023467  0.99729395 -0.58261937  0.9811445   0.99969864]]

Açıklama amacıyla, önceki durumun değerlerini yazdırıyorsunuz. Yukarıda yazdırılan çıktı, son durumun çıktısını göstermektedir. Şimdi tüm çıktıyı yazdırın, durumların her bir grubun önceki çıktısı olduğunu fark edebilirsiniz. Yani, önceki çıktı tüm dizi hakkında bilgi içerir.

print(outputs_val)    
print(outputs_val.shape)    
[[[-0.75934666 -0.99537754  0.9735819  -0.9722234  -0.14234993
   -0.9984044 ]
  [ 0.99975264 -0.9983206   0.9999993  -1.         -0.9997506
   -1.        ]]

 [[ 0.97486496 -0.98773265  0.9969686  -0.99950117 -0.7092863
   -0.99998885]
  [ 0.9326837   0.2673438   0.2808514  -0.7535883  -0.43337247
    0.5700631 ]]

 [[ 0.99628735 -0.9998728   0.99999213 -0.99999976 -0.9884324
   -1.        ]
  [ 0.99962527 -0.9467421   0.9997403  -0.99999714 -0.99929446
   -0.9999795 ]]]
(3, 2, 6)

Aşağıdaki açıklamalı görünüm, aynı yazdırılmış tensörü parça parça inceliyor.

Üç veri kümesini, altı nöron çıktısını ve (3, 2, 6) şeklini etiketleyen açıklama eklenmiş RNN çıktı tensörü.

Çıktı (3, 2, 6) şeklindedir:

  • 3: Parti sayısı
  • 2: Zaman adımının numarası
  • 6: Nöron sayısı

Tekrarlayan bir sinir ağının optimizasyonu, geleneksel bir sinir ağıyla aynıdır. Bu Tekrarlayan Sinir Ağı eğitiminin bir sonraki bölümünde optimizasyonun nasıl kodlanacağını daha ayrıntılı olarak göreceksiniz.

RNN Uygulamaları

RNN'nin özellikle geleceği tahmin etme konusunda birçok kullanımı vardır. Finans sektöründe RNN, hisse senedi fiyatlarını veya borsa yönünün işaretini (yani olumlu veya olumsuz) tahmin etmede yardımcı olabilir.

RNN, aracın yörüngesini tahmin ederek bir araba kazasını önleyebildiğinden otonom bir araba için kullanışlıdır.

RNN, metin analizi, görsel altyazılama, duygu analizi ve makine çevirisinde yaygın olarak kullanılmaktadır. Örneğin izleyicinin filmi izledikten sonra algıladığı duyguyu anlamak için film incelemesinden yararlanılabilir. Film şirketinin incelemeleri incelemek, etiketlemek, birleştirmek ve analiz etmek için yeterli zamanı olmadığında bu görevin otomatikleştirilmesi çok faydalıdır. Makine işi daha yüksek düzeyde doğrulukla yapabilir.

RNN'nin Sınırlamaları

Teorik olarak RNN'nin bilgiyi zamana taşıması gerekiyor. Ancak zaman adımı çok uzun olduğunda tüm bu bilgilerin yayılması oldukça zordur. Bir ağ çok fazla derin katmana sahip olduğunda eğitilemez hale gelir. Bu problemin adı: kaybolan gradyan problemi. Hatırlarsanız sinir ağı, gradyan iniş algoritmasını kullanarak ağırlığı güncelliyor. Ağ alt katmanlara doğru ilerlediğinde gradyanlar küçülür.

Sonuç olarak, gradyanlar sabit kalır, yani iyileştirme için yer yoktur. Model, gradyandaki bir değişiklikten öğrenir; bu değişiklik ağın çıktısını etkiler. Bununla birlikte, gradyandaki fark çok küçükse (yani ağırlıklar çok az değişirse), ağ hiçbir şey öğrenemez ve dolayısıyla çıktı da değişmez. Bu nedenle, kaybolan gradyan problemiyle karşı karşıya kalan bir ağ, iyi bir çözüme doğru yakınsayamaz.

İyileştirme LSTM

RNN'lerin karşılaştığı potansiyel kaybolan gradyan sorununu aşmak için, Hochreiter, Schmidhuber ve Bengio adlı üç araştırmacı, RNN'yi Uzun Kısa Süreli Bellek (LSTM) adı verilen bir mimariyle geliştirdi. Kısaca, LSTM ağa daha yakın zamanlara ait ilgili geçmiş bilgileri sağlar. Makine, daha iyi bir mimari kullanarak bilgileri seçer ve daha sonraki zamanlara taşır.

LSTM mimarisi TensorFlow'da tf.contrib.rnn.LSTMCell olarak mevcuttur. LSTM bu eğitimin kapsamı dışındadır. Resmi kaynaklara başvurabilirsiniz. belgeleme Daha fazla bilgi için

TensorFlow 2.x'te bu hücreye şu şekilde ulaşılır: tf.compat.v1.nn.rnn_cell.LSTMCellyeni kod normalde şunu kullanırken... tf.keras.layers.LSTM ya da daha hafif kapılı tf.keras.layers.GRUBu yöntem, daha az parametreyle karşılaştırılabilir bir doğruluk seviyesine ulaşır.

Zaman serisinde RNN

Bu TensorFlow RNN eğitiminde, zaman serisi verileriyle çalışan bir RNN kullanacaksınız. Zaman serileri önceki zamana bağlıdır; yani geçmiş değerler, ağın öğrenebileceği ilgili bilgileri içerir. Zaman serisi tahmininin ardındaki fikir, bir serinin (örneğin, hisse senedi fiyatı, sıcaklık, GSYİH vb.) gelecekteki değerini tahmin etmektir.

Keras RNN ve zaman serileri için veri hazırlığı biraz karmaşık olabilir. Her şeyden önce amaç, serinin bir sonraki değerini tahmin etmektir, yani t + 1'deki değeri tahmin etmek için geçmiş bilgileri kullanacaksınız. Etiket, giriş dizisine eşittir ve bir dönem ileriye kaydırılır. İkinci olarak, girdi sayısı 1'e, yani her seferinde bir gözleme ayarlanır. Son olarak zaman adımı sayısal değerin sırasına eşittir. Örneğin zaman adımını 10'a ayarlarsanız giriş dizisi art arda on kez geri dönecektir.

Aşağıdaki grafiğe bakın, solda zaman serisi verilerini, sağda ise kurgusal bir girdi dizisini temsil ettik. Ocak 2001'den Aralık 2016'ya kadar her gün için rastgele değere sahip bir veri kümesi döndürecek bir işlev yaratırsınız

# To plot pretty figures
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
import pandas as pd
def create_ts(start = '2001', n = 201, freq = 'M'):
    rng = pd.date_range(start=start, periods=n, freq=freq)
    ts = pd.Series(np.random.uniform(-18, 18, size=len(rng)), rng).cumsum()
    return ts
ts= create_ts(start = '2001', n = 192, freq = 'M')
ts.tail(5)

Çıktı

2016-08-31    -93.459631
2016-09-30    -95.264791
2016-10-31    -95.551935
2016-11-30   -105.879611
2016-12-31   -123.729319
Freq: M, dtype: float64
ts = create_ts(start = '2001', n = 222)

# Left
plt.figure(figsize=(11,4))
plt.subplot(121)
plt.plot(ts.index, ts)
plt.plot(ts.index[90:100], ts[90:100], "b-", linewidth=3, label="A training instance")
plt.title("A time series (generated)", fontsize=14)

# Right
plt.subplot(122)
plt.title("A training instance", fontsize=14)
plt.plot(ts.index[90:100], ts[90:100], "b-", markersize=8, label="instance")
plt.plot(ts.index[91:101], ts[91:101], "bo", markersize=10, label="target", markerfacecolor='red')
plt.legend(loc="upper left")
plt.xlabel("Time")

plt.show()

Solda oluşturulan zaman serisi, sağda ise kaydırılmış hedeflere sahip on adımlı bir eğitim örneği.

Grafiğin sağ kısmı tüm serileri gösteriyor. 2001'den başlayıp 2019'da bitiyor. Tüm verileri ağa beslemenin bir anlamı yok; bunun yerine, zaman adımına eşit uzunlukta bir veri grubu oluşturmanız gerekiyor. Bu grup X değişkeni olacak. Y değişkeni ise X ile aynı, ancak bir dönem kaydırılmış hali (yani, t+1'i tahmin etmek istiyorsunuz).

Her iki vektör de aynı uzunluğa sahiptir. Yukarıdaki grafiğin sağ kısmında görebilirsiniz. Çizgi, X girişinin on değerini temsil ederken, kırmızı noktalar Y etiketinin on değeridir. Etiketin X'ten bir periyot önde başladığını ve bir periyot sonra bittiğini unutmayın.

TensorFlow'da Zaman Serisini tahmin etmek için bir RNN oluşturun

Şimdi bu RNN eğitiminde, yukarıdaki seriyi tahmin etmek için ilk RNN'nizi oluşturmanın zamanı geldi. Model için bazı hiperparametreleri (modelin parametreleri, yani nöron sayısı vb.) belirtmeniz gerekir:

  • Giriş sayısı: 1
  • Zaman adımı (zaman serisindeki pencereler): 10
  • Nöron sayısı: 120
  • Çıkış sayısı: 1

Ağınız 10 günlük bir dizi veriden öğrenecek ve 120 tekrarlayan nöron içerecektir. Modele tek bir girdi, yani bir gün verisi veriyorsunuz. Modelin performansının iyileşip iyileşmediğini görmek için değerleri değiştirmekten çekinmeyin.

Modeli oluşturmadan önce, veri setini eğitim seti ve test seti olarak ayırmanız gerekir. Tam veri seti 222 veri noktasından oluşmaktadır; modeli eğitmek için ilk 201 noktayı, modeli test etmek için ise son 21 noktayı kullanacaksınız.

Eğitim ve test setlerini tanımladıktan sonra, grupları içeren bir nesne oluşturmanız gerekir. Bu gruplarda X değerleri ve Y değerleri bulunur. X değerlerinin bir dönem gecikmeli olduğunu unutmayın. Bu nedenle, ilk 200 gözlemi kullanırsınız ve zaman adımı 10'a eşittir. X_batches nesnesi, 10*1 boyutunda 20 grup içermelidir. y_batches nesnesi, X_batches nesnesiyle aynı şekle sahiptir, ancak bir dönem ilerisini içerir.

) 1 Adım Treni oluşturun ve test edin

Öncelikle seriyi bir diziye dönüştürürsünüz. Dizi dizi; daha sonra pencereleri (yani, ağın öğreneceği zaman sayısını), giriş sayısını, çıkış sayısını ve aşağıdaki TensorFlow RNN örneğinde gösterildiği gibi eğitim setinin boyutunu tanımlarsınız.

series = np.array(ts)
n_windows = 20   
n_input =  1
n_output = 1
size_train = 201

Bundan sonra diziyi iki veri kümesine ayırmanız yeterlidir.

## Split data
train = series[:size_train]
test = series[size_train:]
print(train.shape, test.shape)
(201,) (21,)

) 2 Adım X_batches ve y_batches'ı döndürecek işlevi oluşturun

Bunu kolaylaştırmak için biri X_batches için, diğeri y_batches için olmak üzere iki farklı dizi döndüren bir işlev oluşturabilirsiniz.

Grupları oluşturmak için bir RNN TensorFlow fonksiyonu yazalım.

X gruplarının bir periyot geride olduğunu unutmayın (t-1 değerini alıyoruz). Fonksiyonun çıktısı üç boyuta sahip olmalıdır. İlk boyutlar grup sayısına, ikincisi pencerelerin boyutuna ve sonuncusu da girdi sayısına eşittir.

İşin zor kısmı veri noktalarını doğru seçmektir. X veri noktaları için t = 1 ila t =200 arasındaki gözlemleri seçersiniz, Y veri noktası için ise t = 2 ila 201 arasındaki gözlemleri döndürürsünüz. Doğru veri noktalarına sahip olduğunuzda, yeniden şekillendirmek kolaydır. seri.

Gruplarla nesneyi oluşturmak için veri kümesini eşit uzunlukta on gruba (yani 20) bölmeniz gerekir. Serinin toplu iş boyutuna benzer olması için yeniden şekillendirme yöntemini kullanabilir ve -1'i iletebilirsiniz. 20 değeri parti başına gözlem sayısı, 1 ise girdi sayısıdır.

Etiket için de aynı adımı uygulamanız gerekir.

Tahmin yapmak istediğiniz zaman dilimi sayısına göre verileri kaydırmanız gerektiğini unutmayın. Örneğin, bir gün sonrasını tahmin etmek istiyorsanız, seriyi 1 birim kaydırırsınız. İki gün sonrasını tahmin etmek istiyorsanız, verileri 2 birim kaydırırsınız.

x_data = train[:size_train-1]: Select all the training instance minus one day
X_batches = x_data.reshape(-1, windows, input): create the right shape for the batch e.g (10, 20, 1)
def create_batches(df, windows, input, output):
    ## Create X         
        x_data = train[:size_train-1] # Select the data
        X_batches = x_data.reshape(-1, windows, input)  # Reshape the data 
    ## Create y
        y_data = train[n_output:size_train]
        y_batches = y_data.reshape(-1, windows, output)
        return X_batches, y_batches

Artık fonksiyon tanımlandığına göre, aşağıdaki RNN örneğinde gösterildiği gibi partileri oluşturmak için onu çağırabilirsiniz.

X_batches, y_batches = create_batches(df = train,
                                      windows = n_windows,
                                      input = n_input,
                                      output = n_output)

Boyutların doğru olduğundan emin olmak için şekli yazdırabilirsiniz.

print(X_batches.shape, y_batches.shape)
(10, 20, 1) (10, 20, 1)

Yalnızca bir veri kümesi ve 20 gözlemden oluşan test setini oluşturmanız gerekir.

Günlerce tahmin yaptığınızı unutmayın; bu, ikinci tahmin edilen değerin, test veri kümesinin ilk gününün (t+1) gerçek değerine dayanacağı anlamına gelir. Aslında gerçek değeri bilinecek.

Eğer t+2'yi (yani iki gün ilerisini) tahmin etmek istiyorsanız, tahmin edilen t+1 değerini kullanmanız gerekir; t+3'ü (üç gün sonrasını) tahmin edecekseniz, t+1 ve t+2 tahmin değerlerini kullanmanız gerekir. Üç+n gün sonrasını doğru bir şekilde tahmin etmenin zor olması mantıklıdır.

X_test, y_test = create_batches(df = test, windows = 20,input = 1, output = 1)
print(X_test.shape, y_test.shape)
(10, 20, 1) (10, 20, 1)

Tamam, toplu boyutunuz hazır, RNN mimarisini oluşturabilirsiniz. Unutmayın, 120 tekrarlayan nöronunuz var.

) 3 Adım Modeli oluşturun

Modeli oluşturmak için üç parça tanımlamanız gerekir:

  1. Tensörlü değişken
  2. RNN
  3. Kayıp ve optimizasyon

) 3.1 Adım Değişkenler

X ve y değişkenlerini uygun şekil ile belirtmeniz gerekir. Bu adım önemsizdir. Tensör, X_batch ve y_batch nesneleriyle aynı boyuta sahiptir.

Örneğin, X tensörü bir yer tutucudur (Eğitim videosuna bakın). TensorFlow'a Giriş Değişken bildirimi hakkında fikrinizi tazelemek için) üç boyuta sahiptir:

  • Not: partinin boyutu
  • n_windows: Pencerelerin uzunluğu. Yani, modelin geriye doğru baktığı süre sayısı.
  • n_input: Giriş sayısı

Sonuç:

tf.placeholder(tf.float32, [None, n_windows, n_input])
## 1. Construct the tensors
X = tf.placeholder(tf.float32, [None, n_windows, n_input])   
y = tf.placeholder(tf.float32, [None, n_windows, n_output])

) 3.2 Adım RNN'yi oluşturun

Bu RNN TensorFlow örneğinin ikinci bölümünde, ağın mimarisini tanımlamanız gerekir. Daha önce olduğu gibi, TensorFlow tahmincisinden BasicRNNCell ve dynamic_rnn nesnesini kullanırsınız.

## 2. create the model
basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=r_neuron, activation=tf.nn.relu)   
rnn_output, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)   

Bir sonraki kısım biraz daha karmaşıktır ancak daha hızlı hesaplamaya olanak sağlar. Çalıştırma çıktısını yoğun bir katmana dönüştürmeniz ve ardından onu girişle aynı boyuta sahip olacak şekilde yeniden dönüştürmeniz gerekir.

stacked_rnn_output = tf.reshape(rnn_output, [-1, r_neuron])          
stacked_outputs = tf.layers.dense(stacked_rnn_output, n_output)       
outputs = tf.reshape(stacked_outputs, [-1, n_windows, n_output])  

) 3.3 Adım Kayıp ve optimizasyonu yaratın

Model optimizasyonu, gerçekleştirdiğiniz göreve bağlıdır. Önceki eğitimde... CNNÖnceki eğitimde amacınız görüntüleri sınıflandırmaktı, bu RNN eğitiminde ise amaç biraz farklı. Sürekli bir değişkeni bir sınıfla karşılaştırarak tahmin etmeniz isteniyor.

Bu fark önemlidir çünkü optimizasyon problemini değiştirecektir. Sürekli bir değişken için optimizasyon problemi ortalama kare hatasını en aza indirmektir. Bu metrikleri TF'de oluşturmak için şunları kullanabilirsiniz:

tf.reduce_sum(tf.square(çıkışlar – y))

RNN kodunun geri kalanı öncekiyle aynı; kaybı azaltmak için bir Adam optimize edici kullanırsınız (yani MSE):

tf.train.AdamOptimizer(learning_rate=learning_rate)

optimizer.minimize(kayıp)

İşte bu, her şeyi bir araya toplayabilirsiniz ve modeliniz eğitime hazırdır.

tf.reset_default_graph()
r_neuron = 120    

## 1. Construct the tensors
X = tf.placeholder(tf.float32, [None, n_windows, n_input])   
y = tf.placeholder(tf.float32, [None, n_windows, n_output])

## 2. create the model
basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=r_neuron, activation=tf.nn.relu)   
rnn_output, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)              

stacked_rnn_output = tf.reshape(rnn_output, [-1, r_neuron])          
stacked_outputs = tf.layers.dense(stacked_rnn_output, n_output)       
outputs = tf.reshape(stacked_outputs, [-1, n_windows, n_output])   

## 3. Loss + optimization
learning_rate = 0.001  
 
loss = tf.reduce_sum(tf.square(outputs - y))    
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)         
training_op = optimizer.minimize(loss)                                          

init = tf.global_variables_initializer() 

Modeli 1500 dönem kullanarak eğitecek ve her 150 yinelemede bir kaybı yazdıracaksınız. Model eğitildikten sonra, modeli test kümesinde değerlendirirsiniz ve aşağıdaki Tekrarlayan Sinir Ağı örneğinde gösterildiği gibi tahminleri içeren bir nesne oluşturursunuz.

iteration = 1500 

with tf.Session() as sess:
    init.run()
    for iters in range(iteration):
        sess.run(training_op, feed_dict={X: X_batches, y: y_batches})
        if iters % 150 == 0:
            mse = loss.eval(feed_dict={X: X_batches, y: y_batches})
            print(iters, "\tMSE:", mse)
    
    y_pred = sess.run(outputs, feed_dict={X: X_test})
0 	MSE: 502893.34
150 	MSE: 13839.129
300 	MSE: 3964.835
450 	MSE: 2619.885
600 	MSE: 2418.772
750 	MSE: 2110.5923
900 	MSE: 1887.9644
1050 	MSE: 1747.1377
1200 	MSE: 1556.3398
1350 	MSE: 1384.6113

Sonunda bu RNN Derin Öğrenme eğitiminde, serinin gerçek değerini tahmin edilen değerle çizebilirsiniz. Modeliniz düzeltilmişse tahmin edilen değerler gerçek değerlerin üstüne konulmalıdır.

Gördüğünüz gibi, modelde iyileştirme yapılabilecek alanlar mevcut. Pencere sayısı, toplu işlem boyutu veya tekrarlayan nöron sayısı gibi hiperparametreleri değiştirmek size kalmış.

plt.title("Forecast vs Actual", fontsize=14)
plt.plot(pd.Series(np.ravel(y_test)), "bo", markersize=8, label="Actual", color='green')
plt.plot(pd.Series(np.ravel(y_pred)), "r.", markersize=8, label="Forecast", color='red')
plt.legend(loc="lower left")
plt.xlabel("Time")

plt.show()

Tahmin ve gerçekleşen olayların grafiği; gerçekleşen noktalar yeşil, tahmin edilen noktalar ise kırmızı renkte gösterilmiştir.

Tahmin ve Gerçek

SSS

Desen döngüsünün tamamını kapsayan bir pencereyle başlayın, ardından ince ayar yapın. Daha uzun pencereler daha fazla bağlam yakalar ancak eğitimi yavaşlatır ve gradyan azalmasını kötüleştirir. Burada günlük seri için on adım yeterlidir; haftalık mevsimsellik genellikle daha fazlasını gerektirir.

Evet, bir shim ile. İçe aktarmayı tensorflow.compat.v1 ile değiştirin ve disable_v2_behavior() işlevini çağırın, çünkü placeholder'lar, sessions ve rnn_cell compat ad alanının altına taşındı. Yeni TensorFlow Projelerde bunun yerine tf.keras.layers.SimpleRNN kullanılmalıdır.

Yapay zekâ asistanları pencere boyutları önerir, çalıştırmadan önce şekil uyumsuzluklarını tespit eder ve bir şemadan veri yükleme kodu taslağı oluşturur. Tekrarlayan model çalışmalarında baskın olan deneme-yanılma döngüsünü kısaltırlar, ancak nihai hiperparametre seçimlerinin yine de ayrılmış veriler üzerinde doğrulanması gerekir.

Copilot, tekrarlayan iskeleleme işlemlerini iyi yönetir: oturum blokları, besleme sözlükleri ve periyodik kayıplı baskı. Tensör şekilleri ve etiket kayması riskli kısım olmaya devam ediyor, bu nedenle oluşturulan bir döngüye güvenmeden önce parti boyutlarını her zaman kendiniz doğrulayın.

Tekrarlayan katmanlar (toplu işlem, zaman adımı, özellik) bekler. (-1, pencere sayısı, girdi) olarak yeniden şekillendirme, çerçeveye kaç dizinin var olduğunu, her birinin ne kadar geriye baktığını ve adım başına kaç değerin geldiğini söyler. Eksik bir boyut, sıralama hatasına neden olur.

LSTM üç kapı ve ayrı bir hücre durumu kullanır; GRU ise unutma ve giriş kapılarını birleştirir ve hücre durumunu ortadan kaldırır. GRU daha az parametreyle daha hızlı eğitim yaparken, LSTM genellikle çok uzun bağımlılıklarda öne geçer.

Sürekli tahminler, bu kılavuzun reduce_sum of squared residuals ile yaptığı gibi, ortalama karesel hatayı en aza indirir. Duygu etiketleri veya görüntü görevleri gibi sıralı sınıflandırma, bu kılavuzda ele alınan konuları kapsar. CNN Bu eğitimde çapraz entropi kullanılıyor.

Transformer algoritmaları, dikkat mekanizmasının bir dizi boyunca paralel olarak işlemesi nedeniyle dilbilim alanında baskın konumdadır. Tekrarlayan modeller ise, tek seferde bir adım işlemenin bir darboğazdan ziyade avantaj sağladığı akış sinyalleri, kısa tek değişkenli tahminler ve düşük bellekli cihazlar için rekabetçi olmaya devam etmektedir.

Bu yazıyı şu şekilde özetleyin: