Sayfalar

Cuma, Mart 03, 2017

Keras'a Giriş - 2 ( LSTM )

Ocak ayında ilk yazısını yayınladığımız  Keras 'a  Giriş  dizisine devam ediyoruz.

İlk yazımızda Kerasın kurulumunu, ve  ana kullanım fonksiyonlarını anlatmıştık.  Hali hazırda Kerasın içinde pek çok değişik katman bulunmaktadır. Katmanlarla ilgili kısımı okuyarak bunlara aşina olabilirsiniz. Katmanları bir birine ekleyerek kendi probleminize göre envai çeşit yapıyı tasarlayabilirsiniz.

Biz bu yazımızda Keras üzerinde  LSTM ile zaman serisi tahmini yapan bir uygulama geliştireceğiz.

LSTM nedir ?

Büyük soru, başta kendim olmak üzere kafamızı çok karıştırmadan mümkün mertebe sade anlatmaya çalışalım.

Açıklamaya RNN yani Recurrent Neural Networks  ile başlamamız gerekiyor. Tarihi çok eskilere giden bir YSA yapısı. Aslında anlaması çok da kolay.



YSA yapımızda verdiğimiz verilerin saklı katmandan ürettiği çıktış sinyalini başa alıp bir sonraki giriş de giriş değerlerinden biri olarak kullanıyoruz.

Bu ne işimize yarıyor diye soracak olursanız pek çok durumda verilerimiz de bir sıralılık bağlantısı vardır. sadece girdiklerimiz değil bir önceki durumda çıkışa etki ediyordur. Bu tip Sıralılık örüntüsü  - Sequence pattern - içeren durumlar için bu tip YSA yapıları daha başarılı bir modelleme imkanı sağlamaktadır.

Peki yıllardır bilinen bu yapı niye populer olamamış ?  Bu sorunun cevabı olarak meşhuuur  Vanishing gradient problem çıkıyor karşımıza. YSA eğitiminde giriş verileriyle çıkış değerleri hesaplanır. Hesaplanmış çıkış değerleri ile gerçek değerler karşılaştırılır ve farklılık bize bir  meyil  - gradient - Bu meyile göre geriye doğru ağ ağırlık değerlerinde güncelleme yapılır. Ağımız çok karmaşıksa geriye doğru meyil değerleri sıfırlanır. Meyil olmazsada güncelleme olmaz ve eğitilmeside durmuş olur. RNN yapısında da zaman içinde geriye doğru bağlılık var. Ağımızı eğitim açısında çok karmaşık hale getiriryor.


Bu problemin çözümü için LSTM - Long short-term memory - denen bir yapı kurulmuş.


Yukardaki akıllara ziyan  şemadan da anlaşılacağı üzere çok kompleks bir sistem. Yapıda kabaca RNN hücresine birde hafıza eşlik ediyor. Bu hafıza ile bir önceki zamandan gelen bilgi alınabiliyor , bir sonrakine iletilebiliyor. Neyi alıp neyi almayacağına eğitim ile karar veriyor. Konunun teferruatları için, Ve illede iç yüzünü öğreneceğim diyenler için bir kaç link verip geçiyorum

1)  Deep Learning Lecture 12: Recurrent Neural Nets and LSTMs
2) Understanding LSTM Networks
3) The Unreasonable Effectiveness of Recurrent Neural Networks

Keras da RNN katmanlar 

Hali hazırda Keras kütüphanesinde 3 çeşit  RNN katmanı var.
  1. SimpleRNN
  2. LSTM
  3. GRU
ilki zaten adından anlaşılıyor. LSTM den yukarda bahsettik . sonuncusu GRU - Gated Recurrent Unit - daha LSTM benzeri yeni bir sistem

Biz LSTM i kullanacağız. ondan bahsedelim

LSTM ler  genel anlamda sequence zaman sıralı şekilde gelen veriler üzerinden çalışırlar.

keras.layers.recurrent.LSTM(output_dim,
                                              batch_input_shape=(nb_samples, timesteps, input_dim),
                                              return_sequences=False,....)
eğer LSTM ilk katmansa batch_input_shape  verilmesi gerekiyor ve dökümanda geçen şekli
  
  • nb_samples : veri sayımız, None diyede  verebiliyoruz. 
  • timesteps :  LSTM e vereceğimiz veriler zaman bazında değişen aynı türdeki veriler  kaç birim zamanlık veri verilecek burda onu belirtmemiz gerekiyror 
  • input_dim :  giriş verimizin boyutu. 
  • return_sequences Kendinden sonraki katman Yine Bir LSTM olacaksa True  yapılacak
  • output_dimKatman çıkış boyutu ve LSTM birim sayısı.  Ağın çıkışı , eğer kendinden sonraki katman Yine Bir LSTM olacaksa  (nb_samples, timesteps, output_dim)  , olmayacaksa  (nb_samples, , output_dim) olur.
Şimdi biraz burda durup, input_dim giriş veri boyutuna biraz açıklık getirelim.  Sequence üzerinden çalışan bir sistem. Bizim bugün anlatacağımız önnekdeki gibi tek bir sayısal değerin değişimi var ise  giriş veri boyutu bir dir. Fakat pek ala zaman içinde değişien bir vektör de modellenebilir. budurumda vektörün uzunluğu giriş boyutumuz olur. Mesela bir metin üzerinde çalıştığımızı varsayın. biri birini takip eden harfler de bir sequence olur. Harfi bir vektöre çevirmek gerekir. vektör uzunluğuda metindeki alfabe büyüklüğü olur.

Olmaz ama soran olursa diye buraya yazayım peşin peşin, pek çok değişik kaynakda pek çok değişik notasyon var. Kullanımında benim tercihim bu şekilde oldu.

Uygulama

Keras da LSTM uygulamamız için bir zaman serisi verisi seçtik.

Daily maximum temperatures in Melbourne, Australia, 1981-1990

Avusturalya Melbornda 10 yıllık bir sürede ( 1981-1990 )  günlük olarak ölçülmüş en yüksek sıcaklıkları gösteriyor.

Yukardaki grafikden de anlaşılacağı üzre oldukça gürültülü bir sin fonksiyonu 

Bizde son 5 günün en sıcaklık değerlerini kullanarak yarınki en yüksek sıcaklık değerini hesaplattırmaya çalışacağız. uygulamızda

önce verimizi pandas ile  yüklüyoruz



tarih ve en yükseklik sıcaklığı tutan iki sutun var tarih bize lazım değil sadece en yüksek sıcaklık değerleriniz çekiyoruz.

YSA eğitimlerinde verileri ölçeklendirmek genellikle faydalı olur. bizde  ( 0 , 1 ) arası bir ölçeklendirme işlemi uyguluyoruz.

Bu veri üzerinde kayan pencere metoduyla ağımızı eğitmek için  veris seti oluşturuyoruz

Önce giriş ve çıkış verilerimizi oluşturuyoruz X ve Y olarak


ilk kutuda kayan pencere metoduyla  giriş ve çıkışları seçip X ve Y adında iki listeye atıyoruz.
ikinci  kutuda  listeleri Martise dönüştürüyoruz.
Üçüncü kutuda giriş verimizi LSTM in istediği formata çevrimek için bir dönüşüm yapıyoruz
çünkü öncesinde giriş matris ebadı  (nb_samples, timesteps) şeklinde bir giriş veri boyutunu 1 olarak verip (nb_samples, timesteps , 1 ) ebadına dönüştürüyoruz.

3645 adet verimiz var. Biz 3200 'ünü eğitim için kullanıyoruz geri kalanınıda test için bırakıyoruz.


Evet sıra geldi Ağımızı oluşturmaya


İki LSTM katmanı oluşturuyoruz ilki giriş katmanı çıkışı 64 kendinden sonra yine bir LSTM katmanına bağlanacağından return_sequence  değişkenine True değerini veriyoruz.
LSTM katmanı sonrasında  0.2 lik bir Dropout katmanı koyuyoruz. Dropout en basit ifade ile sistemin ezberlemesini önlemeye çalışan bir katmandır. biraz detay isterseniz daha önceki yazılarımda kısaca bahsetmiştim ordan bakabilirsiniz.

İkinci LSTM katmanının 32 çıkışı var yine peşine Dropout katmanı kondu. Perşinede Çıkış katmanı olarak normal bir YSA katmanı -Dense-  kullanıyoruz. Bir çıkış yani takip eden günün en yüksek sıcaklığı olduğundan çıkışı 1 .

model sınıfının summary fonksiyonu ile  modelimizin yapısını ve katmanların çıkış ebatlarını parametre sayılarını görebiliyoruz.



Bir katmanın girişi kendinden öncekinin çıkışı olduğunda girişleri göstermesine gerek olmuyor.

Eğitime başlatıyoruz. 



Eğitim sonunda  Test verisinden başlangıcını rastgele seçeceğimiz  100 adet veri seçiyoruz. Bu veri için  Gerçek değer. Tahmin edilen değer. Bir de sadece seçtiğimiz aralığın başlangıç değerini alıp ileriye doğru zincirleme tahmin hesaplattırarak  grafikler çizdiriyoruz.


Grafik den görüklerimizi yorumlayalım.
  • Tahmin ve gerçek değer arasında Müthiş bir sayısal yakınlık yok.
  • Sayısal doğruluk gibi bir bekleti bu tip bir zaman serisi için pekde mümkün değildi
  • Fakat Grafiklerdeki inişve çıkışlar parelellikler içeriyor.  Sequence learning kavramı hatırlayın
  • Zincirleme ileriye doğru tahmin ilk başta çalışsada sonrasında bir rakama sabitleniyor.
  • Bu da beklediğimiz bir durum bakınız  kaos teorisi

Ipython dosyasına ve veriye burdan ulaşabilirsiniz.

https://github.com/birolkuyumcu/high_temp_lstm

Bundan sonra tavsiyem,  ağın yapısı , parametreleri, hatta pencere ebatları ile oynayarak ne şekilde sonuçlara ulaşılabiliyor görmenizdir.

Eleştiri, öneri yada sorularınız olursa bekleriz...

16 yorum:

burak dedi ki...

hocam ben yapay sinir agıyla bitcoin tahmini projesi yapmaya calısıyorum,verdiginiz .Ipython uzatntlı dosyasının nasıl kullanabilirim .py uzantılı seklnde

birol kuyumcu dedi ki...

1) python öğrenin
2) sadece geçmiş değerlere bakarak bitcoin tahmini yapamazsınız

burak dedi ki...

Peki nasıl bir yol izleyebilirim hocam yardımcı olurmusunuz

birol kuyumcu dedi ki...

değişi etkileyen ne varsa girişde ağa vermelisinki
öğrenebilsin

burak dedi ki...

hocam degişimi etkileyen degerleri csv dosyasına ekledikten sonra raw_Data kısmında siz max_temp alıyorsunuzya,ben onun yanında diger etkileyen durumlarıda almak istiyorum mesela haberler sutunum var bu max_temp ile haberler sutunundaki degerleri nasıl aga gosterebirim yani raw_data=df.max_temp yapmıssınızya ben burda hem max_temp hemde baska sutunları işleme nasıl katabilirim

birol kuyumcu dedi ki...

vectör büyüklüğünü bir artıracaksınız
eğer girişini iki ayrı değerden oluşuyorsa 2 uzunluklu vektörler dizisi vereceksiniz

burak dedi ki...
Bu yorum yazar tarafından silindi.
Adsız dedi ki...

Merhabalar,

Kodda bazı yerler çalışmyor,

scaler = MinMaxScaler(feature_range=(0,1))
raw_data = scaler.fit_transform(raw_data)

yukarıdaki hata githubnızda da mevcut

series = Series(raw_data)
# prepare data for normalization
values = series.values
values = values.reshape((len(values), 1))
# train the normalization
scaler = MinMaxScaler(feature_range=(0, 1))
scaler = scaler.fit(values)

# normalize the dataset and print
raw_data = scaler.transform(values)

aşmak için bu kodu yazdım bu sefer her bir elemana bir array atıyor, yani tek arrayın içinde 3650 tane array var, neden serilere çevirmeden yapamıyoruz yada tekrar eski haline nasıl getirebiliriz ?

Teşekkürler

birol kuyumcu dedi ki...

çalışmıyor açık bir anlatım değil
Bu program yazıldığında çalıştırılmış ve sonuçlar ordan alınmıştır.
Fonksiyonların kullanım ve çağrım şekillerinde değişiklikler olduysa ona göre adaptasyonlar yapmak gerekir elbette...

kod yazan dedi ki...

Hocam merhaba paylaşımınız için teşekkür ederim, loss ve optimizer parametrelerini seçerken ölçütlerinizi neye göre belirlediniz mesela neden adam ve binary_crossentropy kullanmadınız ? ya da kullanıp çıkan sonuca göre mi 'mse' ve 'rmsprop' kullandınız ?

Adsız dedi ki...

Merhaba Hocam,Zincirleme ileriye dogru tahmını neden ve nasıl yaptıgımızı pek anlamadım.Sonucta amacımız 1 sonrakı gunu son 5 gune bakarak tahmın etmek oldugundan real ve predıcted yeterlı degıl mı?

Berkay dedi ki...

Hocam paylaşım için öncellikle teşekkürler.

Bende rüzgar hızı tahmin işlemi yapıyorum ve bunu yaparken iki tane mantıksal hatalar oluştu.

1-) Eğitim ve Test hata oranı (MSE) 0.03 civarında sonuç vermekte. Fakat başarım ise hata ile ters orantılı durumunda olması lazımken onda da eğitim ve test hatası gibi başarım da 0.03 civarı değer vermekte.

2-) Yukarıda dediğim gibi sistemin hata fonksiyonu MSE 0.03 civarı değer verdirirken RMSE oranı ise 0.5 civarlarında.

Bu ikisinin nedeni nedir biliyorsanız cevaplarsanız sevinirim. Tekrardan Teşekkürler.

Berkay dedi ki...

Hocam paylaşım için öncellikle teşekkürler.

Bende rüzgar hızı tahmin işlemi yapıyorum ve bunu yaparken iki tane mantıksal hatalar oluştu.

1-) Eğitim ve Test hata oranı (MSE) 0.03 civarında sonuç vermekte. Fakat başarım ise hata ile ters orantılı durumunda olması lazımken onda da eğitim ve test hatası gibi başarım da 0.03 civarı değer vermekte.

2-) Yukarıda dediğim gibi sistemin hata fonksiyonu MSE 0.03 civarı değer verdirirken RMSE oranı ise 0.5 civarlarında.

Bu ikisinin nedeni nedir biliyorsanız cevaplarsanız sevinirim. Tekrardan Teşekkürler.

birol kuyumcu dedi ki...

sorunuzu anlayamadım
doğrudan iletişime geçin

Adsız dedi ki...

Hocam merahaba, giriş verilerimiz birden fazla değişkene bağlı ve çıkışta sadece 1 veriyi gözlemlemek istiyorsak, many to one örneğinde nasıl bir model geliştirebiliriz?

birol kuyumcu dedi ki...

elbette