Uygulamalı Anlatım ile LSTM Modeli Nasıl Oluşturulur?

Doruk Tolga
Teknopar Akademi
Published in
6 min readMar 14, 2022

--

Bir önceki yazımda LSTM ağının mimarisi ve nasıl çalıştığı hakkında bilgiler vermiştim. Bir önceki yazıya ulaşmak için tıklayınız. Bu yazıda ise bir LSTM modelinin nasıl oluşturulduğunu uygulamalı olarak anlatacağım. Ayrıca bu yazıda LSTM ağı implement ederken hangi parametrelerden, hangi optimizasyon algoritmalarından ve hangi katmanlardan yararlanılması gerektiğini detaylı bir şekilde anlatacağım. LSTM ağı, duygu analizi, metin üretme, zaman serileri ve sequence to sequence(seq2seq) problemleri gibi birçok alanda kullanılır. Bu yazıda bir sequence to sequence problemi için model kurarak ilerleyeceğiz. İlk olarak Keras’ın LSTM katmanı için kullanılan parametreleri inceleyelim.

tf.keras.layers.LSTM(
units, activation='tanh', recurrent_activation='sigmoid',
use_bias=True, kernel_initializer='glorot_uniform',
recurrent_initializer='orthogonal', bias_initializer='zeros',
unit_forget_bias=True,kernel_regularizer=None,
recurrent_regularizer=None, bias_regularizer=None,
activity_regularizer=None, kernel_constraint=None,
recurrent_constraint=None, bias_constraint=None, dropout=0.0,
recurrent_dropout=0.0, return_sequences=False,
return_state=False, go_backwards=False, stateful=False,
time_major=False, unroll=False, **kwargs
)

Keras’ın LSTM katmanında çok sayıda parametre bulunmaktadır. Ancak bu parametrelerden üzerinde en sık değişiklik yapılanlar ‘units’, ‘activation’, ‘recurrent_activation’, ‘return_sequences’ ve ‘return_state’ parametreleridir.

Bu sık kullanılan parametrelerin alabileceği değerler ve açıklamaları aşağıdaki tabloda verilmiştir.

LSTM katmanı girdi olarak mutlaka üç boyutlu bir dizi almaktadır. LSTM’in alacağı dizinin birinci boyutu veri örnek sayısı(batch), ikinci boyutu bir LSTM hücresi için zaman adımı sayısı(timesteps) ve üçüncü boyutu ise nitelik(feature) sayısıdır.

Basit bir sequence to sequence(seq2seq) problemi üzerinden LSTM modeli kurarak modelin alacağı inputun nasıl olması gerektiğini ve parametrelerin kullanım amaçlarını anlamaya çalışalım. Seq2Seq probleminde amaç verilen serilerden istenilen formatta ardışık olarak çıktı elde edilmesidir. Bir dilden başka bir dile çeviri seq2seq problemlerine örnektir.

Bu yazıda ardışık olarak gelen bir serinin tersten yazılışını LSTM moldeli ile tahmin edeceğiz. Bunu yapabilmek için ilk olarak random değerlerle beş elemanlı seriler oluşturarak başlıyoruz.

Sinir ağlarında doğrudan sayıları kullanmak yerine encode edilmiş halleri kullanılmaktadır. Bu yüzden aşağıdaki figürde görüldüğü gibi modelimizi eğitirken one-hot-encoded gösterimini kullanacağız.

One-Hot-Encoded Form

LSTM’in girdi olarak 3 boyutlu array aldığından az önce bahsetmiştik. Bunlar batch, timesteps ve featuredı. Bizim modelimizde timesteps 5’e, feature ise 10’a eşit olacak yani bir LSTM hücresi girdi olarak 5 farklı zaman adımında 10 featuredan oluşan array alacaktır. Yukarıdaki figürdeki girdiler üzerinden örnek vermek gerekirse LSTM hücresinde her zaman adımı sırasıyla girdi olarak 8,0,1,5,3 değerlerini almaktadır yani bir LSTM hücresi 5 zaman adımı için çalışacaktır. Her bir adımda bu sayıların one-hot-encoded gösterimi olan 10 elemanlı input (X(t)) LSTM hücresine girdi olarak girecektir.

LSTM Cell
LSTM Cell Timesteps

Bahsettiklerimizi figürde gösterecek olursak yukarıdaki figürde görüldüğü gibi bir LSTM hücresi 5 farklı zaman adımı için çalışacaktır ve her zaman adımı yeni 10 featurden oluşan dizinin yanında önceki zaman adımının çıktısı olan h(t-1) ve C(t-1) değerleriyle beraber toplam 3 farklı input almaktadır.

LSTM katmanının çıktı türlerini anlatmadan önce LSTM katmanını oluştururken kullandığımız ‘units’ parametresinden bahsetmekte fayda var. ‘units’ parametresi bir LSTM katmanındaki LSTM hücre sayısını belirler. LSTM katmanındaki hücre sayısıda LSTM katmanının çıktı boyutunu belirlemektedir. Böylece istediğimiz katmanın çıktı boyutunu units parametresi ile kontrol edebilmekteyiz. Aşağıdaki iki örnekte iki farklı units değeri ile çıktı boyutunun nasıl değiştiğini gösterilmiştir.

model = Sequential()
model.add(LSTM(units=150, input_shape=(5,10)))
model.summary()
model = Sequential()
model.add(LSTM(units=50, input_shape=(5,10)))
model.summary()

Çıktılar (Outputs)

Bir LSTM hücresinde her zaman adımında 3 farklı çıktı üretilmektedir. Peki modelimzde bu çıktılardan hangilerini kullanmalıyız?

Eğer sadece hücrenin kendini son tekrarladığı andaki değer (h(t)) kullanılacaksa ‘return_sequances’ parametresinin default değeri olan False değerini kullanmalıyız. LSTM katmanı oluşturulurken return_sequances’ parametresi False değeri ile kullanılacaksa katmanın çıktısı LSTM katmanındaki hücre sayısı kadardır çünkü her hücre sadece bir h_last değeri üretecektir. Aşağıdaki figürdede görüldüğü gibi tek katmanlı ve 150 hücreli LSTM modelinin çıktısı 150 tane skaler sayıdan oluşmaktadır.

model = Sequential()
model.add(LSTM(units=150, return_sequences=False,
input_shape=(5,10)))
model.summary()

Eğer her zaman adımının çıktılarından olan hidden stateleri (h(t)) kullanmak istiyorsak LSTM katmanını oluştururken ‘return_sequances’ parametresini True olarak kullanmalıyız. Böylece katman çıktı olarak LSTM hücre sayısı kadar timesteps uzunluğunda sequencelar üretecektir. Aşşağıdaki figürde de görüldüğü gibi ‘return_sequances’ parametresi True değeri ile kullanılarak 150 hücrelik LSTM katmanın çıktısı olarak 150 tane 5 elemanlı sequence üretmiştir.

model = Sequential()
model.add(LSTM(units=150, return_sequences=True,
input_shape=(5,10)))
model.summary()

‘return_sequance’ parametresi h(t) değerlerinin döndürülüp döndürülmemesini belirlerken ‘return_state’ parametresi cell statelerin ( C(t) ) değerlerinin döndürüp döndürülmeyeceğini belirler. ‘return_state parametresi de default değer olarak False değerini almaktadır. Bu yüzden katmanı implement ederken herhangi bir değer belirtilmediğinde C(t) değerleri döndürülmeyecektir.

LSTM ağı oluştururken parametrelerin nasıl kullanıldığından bahsettim. Ancak değinmek istediğim bir diğer nokta modelimizi compile ederken hangi optimizerı ve hangi loss fonksiyonunu seçmemiz gerektiğidir.

Optimize ediciler, modelin doğruluğunu arttırmada çok önemli bir rol oynar.

Kullanılabilecek birçok optimizer vardır. Hangisinin kurulacak model için uygun olduğunu seçmek modelin verimli çalışması adına önem teşkil etmektedir.

LSTM Ağı için Sık Kullanılan Optimizasyon Algoritmaları

SGD: Yineleme yoluyla minimum veya maksimum hatayı bulmaya çalışır. Muzdarip olduğu en büyük sorunlardan biri, amaç fonksiyonu dışbükey olmadığında, yerel bir minimuma yakınsamasının neredeyse kesin olmasıdır. Bu sorundan dolayı genellikle tercih edilmemektedir.

Nesterov Accelerated Gradient: Momentum çok yüksekse algoritma yerel minimumları kaçırabilir ve yükselmeye devam eder. Bu nedenle, bu sorunun önüne geçmek amacıyla NAG algoritması geliştirildi. NAG algoritması momentumun yuksek olduğu durumlarda yerel minimumları yakalayabilmektedir.

Adagrad: Bahsedilen tüm optimize edicilerin dezavantajlarından biri, öğrenme oranının tüm parametreler ve her döngü boyunca sabit olmasıdır. Adagrad, her parametre ve her zaman adımında öğrenme oranını değiştirir. İkinci dereceden bir optimizasyon algoritmasıdır. Bir hata fonksiyonunun türevi üzerinde çalışır.

Belirli bir t zamanında verilen parametreler için loss fonksiyonunun bir türevi.
t zamanında parametre güncellemesi

AdaDelta: AdaGrad’ın öğrenme hızı sorununu ortadan kaldırma eğiliminde olan bir varyantıdır. Adadelta, önceden karesi alınmış tüm gradyanları biriktirmek yerine üstel olarak hareketli ortalama kullanılır.

Adam: Geliştiricileri tarafından pratikte iyi çalıştığını ve diğer öğrenme algoritmalarına göre olumlu sonuçlar aldığı gösterilmiştir. Her parametre için öğrenme oranını hesaplayan başka bir yöntemdir. Geliştiriciler ayrıca Adam optimizer parametreleri için varsayılan değerleri Beta1– 0.9, Beta2 – 0.999 ve Epsilon 10^-8 olarak önermektedir.

AdaDelta ve Adam çok benzer algoritmalardır ve çoğu problem için Adam’ın diğer algoritmalardan biraz daha iyi performans gösterdiği tespit edildiğinden, Adam genellikle en iyi seçimdir.

Dropout Katmanı

Eğitim sırasında aşırı öğrenmeyi(overfitting) engellemek amacıyla bazı nöronları görmezden gelmek için kullanılır diyebiliriz. Eğer ağınız çok büyükse, çok uzun süre eğitim yapıyorsanız veya veri sayınız çok az ise aşırı öğrenme riski taşıdığınızı unutmamanız gerekir.

Parametrelerin nasıl seçildiğini ve optimizasyon algoritmalarını anladıktan sonra seq2seq problemimiz için bir LSTM ağı oluşturarak modelimizi eğitebiliriz.

model = Sequential()model.add(LSTM(units=150, return_sequences=True, input_shape=(5,10)))
model.add(Dropout(0.2))
model.add(LSTM(units=100, return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(units=50, return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(units=50))
model.add(Dense(units = 5))
model.compile(optimizer = 'adam', loss = 'mean_squared_error')
model.summary()

Modele 4 tane LSTM katmanı ve her LSTM katmanı arasına overfittingi önlemek amacıyla %20 oranında nöronları görmezden gelinmesini sağlayan Dropout katmanları eklendi. Son olarak çıktıda 5 elemanlı sequence beklediğimiz için Son katmanın units parametresi 5 olarak belirlendi. Model ‘adam’ opitmizerı kullanarak compile edildi.

model.fit(X_train, y_train, epochs = 100, batch_size = 16)

Model 100 epoch ve 16 batch size ile fit edildi. Loss fonksiyonu 100 epoch sonunda 0.0364 değerine kadar düştü.

Aşağıda da test verisi için yapılan tahminlerden bir kısmı görülmektedir.Model tüm test verisinin tersten yazılışını doğru tahmin etti.

Yazıyı buraya kadar okuduğunuz için teşekkür ederim. Umarım faydalı olmuştur. Diğer yazılarda görüşmek üzere…

Kaynakça

· https://www.jigsawacademy.com/blogs/data-science/lstm

· https://towardsdatascience.com/optimizers-for-training-neural-network-59450d71caf6

· https://quantdare.com/mitigating-overfitting-neural-networks/

--

--