Sequential model'den elde edilen tahminleri nasıl yorumlamak gerekir?

Herkese merhaba,

Aşağıda bir veri seti var.

Bu veri setindeki her bir satır farklı insanlardan elde edilen, toplamda 9 adet bilgiyi içeriyor. İlk 8 sütunda yer alan bilgiler, girdi olarak kullanılacak olan, kişilere ait hamilelik, glikoz, kan basıncı, deri kalınlığı, insülin, vücut kütle indeksi, kişinin ailesindeki diyabet olasılığını puanlayan işlev ve yaş bilgileridir. 9. sütundaki bilgiler ise çıktı olarak kullanılacak, kişilerin diyabet hastası olup olmadığıyla alakalı, değeri 0 veya 1 olan bilgilerdir.

Elimizdeki bu veri setine göre denetimli bir yapay sinir ağı modeli eğitilecek ve dışarıdan vereceğimiz 8 adet bilgiye göre kişinin diyabet hastası olup olmadığı tahmin edilecek.

Kodlar şu şekilde:

import numpy as np

from keras.layers import Dense
from keras.models import Sequential
from sklearn.model_selection import train_test_split

dataset = np.loadtxt(
    "diabetes.csv",
    skiprows=1,
    delimiter=",",
    dtype="float32"
)

x_train, x_test, y_train, y_test = train_test_split(
    dataset[:, :8],
    dataset[:, 8],
    test_size=0.2
)

model = Sequential()
model.add(Dense(15, input_dim=8, activation="relu"))
model.add(Dense(15, activation="relu"))
model.add(Dense(1, activation="sigmoid"))
model.compile(
    optimizer="adam",
    loss="binary_crossentropy",
    metrics=["binary_accuracy"]
)
model.fit(
    x_train,
    y_train,
    epochs=100,
    batch_size=32,
    validation_split=0.2
)

result = model.evaluate(x_test, y_test)
print(result)

x = np.array([[7, 110, 83, 31, 0, 35.9, 1.130, 48]])
output = model.predict(x)
print(output)
if output[0, 0] > 0.5:
    print("diyabetli")
else:
    print("diyabetsiz")

Bu kodlar, okuduğum kaynaktan alındı. Şimdi sormak istediğim sorulara geçeyim.

  1. Eğitim esnasında loss'un değeri benim bilgisayarımda 0.5'in altına düşmüyor. Bilgisayarımın işlemcisi daha iyi bir işlemci olsa, hatta gpu’dan da destek alsa, loss değeri azalır mı?

  2. Tahmin sonuçlarının güvenilir olması için loss değerinin hangi değerden daha az olması gerekir?

  3. Elde ettiğim tahminin güvenilir olup olmadığından emin olmak için ne yapmam gerekir?

Kodlarda hiçbir değişiklik yapmadan, kodları tekrar tekrar çalıştırdığımda bazen diyabetli bazen de diyabetsiz şeklinde sonuçlar alıyorum. Hatta diyabetli bir kişinin bu 8 parametresini girdiğim zamanda da bazen diyabetli bazen de diyabetsiz şeklinde sonuçlar alıyorum. Bu da benim kafamı karıştırıyor açıkçası. Okuduğum dokümanı okumaya devam edeceğim ama, aklımda böyle sorular oluşuyor, onlara cevap bulmaya çalışıyorum. Cevap bulduğum zaman daha rahat ilerleyebileceğim. Bu konularda tecrübesi olan arkadaşlar varsa, görüşlerini almak isterim.

Python: 3.6.9
Tensorflow: 1.5
Keras: 2.1.4
Numpy: 1.14
Scipy: 1.0.0
CPU: Intel® Pentium® CPU 2020M @ 2.40GHz

1 Beğeni

Hocam hangi kaynaktan yararlanıyorsunuz

Kaan Aslan’ın Yapay Zeka ve Makine Öğrenmesi Kurs Notları

Merhabalar,

Aslına bakarsanız teorik olarak o loss (training loss) sıfıra inebilir (universal approximation theorem). Fakat bunun bilgisayarın özelliklerinden ziyade ağın yapısıyla alakası var. Yani işlemci ve/veya GPU desteği işlemleri hızlandırır, az zamanda çok işler yapmayı sağlayabilir ama modelin kapasitesini artırmaz. Mesela, sizin paylaştığınız network 8 x 15 x 15 x 1 yapısına sahip ve bu modelin erişebileceği bir kapasite var - ne kadar güçlü hesaplama altyapısı olsa da bu sınırı aşmak mümkün değil (ama o sınırı görme süresini azaltabilir, o ayrı). Şöyle düşünebiliriz: elimizde parabolik bir veri var (yani ax^2 + bx gibi bir formdan alınmış) ve biz bu veriye lineer bir model ile yaklaşıyoruz. Gayet tabii asıl veriyi “vasatın altında” bir şekilde modellemiş oluruz. Bu mevzu underfitting diye geçiyor.

Bununla beraber, universal approximation theorem’e dayanarak çok karmaşık bir model deneyebiliriz. Mesela paylaştığınız veri üzerinde 8 x 1024 x 512 x 1’lik bir model denedim ve (training) loss 0.0023’i gördü, karşılık gelen accuracy de 1.00 yani sıfır hata! (821 epoch). Yani train_test_split sonucu oluşan training verisini “mükemmel” bir şekilde öğrenmiş, çok daha doğrusu ezberlemiş… Bu da tahmin edersiniz ki overfitting diye geçiyor. Ama gelin görün ki (hiç görmediği) test verisindeki doğruluk oranı ~67.5%. (sizin setting’iniz ile ~75% genelleme doğruluk oranı aldığımı da söyleyeyim).

Dolayısıyla burada bir trade-off var underfitting ve overfitting arasında. Biz ikisini de istemeyiz: ne modelimiz elimizdeki veriyi açıklamakta / öğrenmekte yetersiz kalsın ne de gereğinden fazla öğrenip genelleme kabiliyetini yitirsin. Şu grafik benden daha iyi açıklayabilir:

Mavi olan training error’ün (koddaki çıktıdaki loss), kapasiteyi artırırsanız monotonik bir şekilde sıfıra doğru azalmaya meyili var. Kapasiteyi artırmak epoch sayısını artırmak da olabilir, ağdaki hidden layer / neuron sayısını artırmak da olabilir. Ama yeşille gösterdikleri Generalization error dikkat ederseniz bir noktadan sonra artmaya meylediyor. İşte sizin modeliniz bu kırmızı dikey çizginin solunda bir yerlerde - öyle ki, “loss”'u fazla ama genelleme oranı fena değil; benim denediğimse bayağı sağlarda bir yerlerde - loss neredeyse sıfır yani mavi çizgiler ekseni yalıyor neredeyse ama genelleme yüzdesi sizinkinden daha düşük. Marifet ise "optimal capacity"yi bulmak :)).

Buradan 2 ve 3. sorularınıza yanıt çıkacak olsa şöyle olabilirdi:

“Az olsun ama öyle çok da az olmasın. Tabii fazla da olmasın canım, arada bir yerde olsun” :).

Generalization’ı en fazla olan model en iyi modeldir zira bu modelleri eğitmemizdeki temel gaye elimizdeki verileri ezberlemesi değil; tabir-i caizse “vahşi doğada” iyi performans gösterebilsin diye eğitiyoruz.

Underfitting / overfitting dengesini sağlayabilmek adına zannederim şunlar uygulanabilir: validation set, early stopping, cross validation, dropout layer ve artık daha başka neler varsa…

Bunun temel sebebi modelin birçok aşamasında rastgeleliğin olması. Mesela, ağın weight’leri rastgele şekilde initialize ediliyor. (keras default olarak glorot_uniform kullanıyormuş). Ve ayriyeten mesela ağı optimize etmek için kullandığınız adam da stokastik bir metot olmasından dolayı rastgelelik içeriyor (e.g. her epoch başı verinin shuffle edilmesi gibi). Dolayısıyla, eğer kendiniz bir seed belirlerseniz (5. adıma gerek kalmadan oldu bende), her çalıştırmada aynı sonuçları alırsınız diye düşünüyorum.


Görsel: http://www.deeplearningbook.org/contents/ml.html, sayfa 113, Figure 5.3.

Bir de pek haddim olmayarak küçük not: Sınıflandırma task’ında, metriğin accuracy olması pek iyi değil, onun yerine precision / recall tercih edilebilir.

5 Beğeni

Öncelikle mesajınız için çok teşekkür ederim. Machine Learning alanına daha yeni yeni girmeye başladığım için izniniz olursa sizi arada sırada rahatsız edebilirim. :innocent:

Doğruluk oranı bende de % 75 çıkıyor. Bu arada epoch’u artırmak, bir yere kadar eğitime olumlu bir etkide bulunur değil mi?

Yazar, dokümanda aynı kodun çıktısını paylaştığı zaman training-loss değeri yaklaşık 0.2 oluyordu. Bende ise 0.5 oluyor. Acaba bu farklılığın sebebi nedir diye düşünürken aklıma yazarın cuda özelliği olan gpu destekli cpu ile çalışmış olabileceği ve belki ayrıca anaconda’nın da etkisinin olabileceği geldi. :thinking:

Bu arada katman sayısı ve katmanlardaki nöron sayısıyla alakalı dokümanda şöyle ifadeler vardı:

Şimdi katmanlardaki olası nöron sayıları hakkında bazı şeyler söyleyelim. Girdi katmanındaki nöron sayısı kestirimde kullanılacak özelliklerin (features) sayısı kadar olmalıdır. Çıktı katmanındaki nöronların sayısı da elde edilecek kestirim sonucuyla ilgilidir. O halde bilmediğimiz iki durum vardır: Ağımızda kaç tane saklı katman ve her saklı katmanda kaç tane nöron bulunmalıdır? İşte bu soruların yanıtları deneyimle ve üzerinde çalışılan problemin niteliğine göre doğru biçimde verilmeye çalışılmaktadır. Ancak yine de bu konuda önerilen birkaç genel yönerge vardır. Saklı katmanların sayısı için şu pratik tavsiyelerde bulunulabilir. (The Number of Hidden Layers | Heaton Research)

Eğer problem doğrusal olarak ayrılabilir (linear seperable) ise saklı katman kullanmaya gerek yoktur. (Doğrusal olarak ayrılabilir problem hakkında kısa teorik bilgi ileride verilecektir.)

  • Bir saklı katman pek çok sorunun çözülmesi için yeterlidir. İki saklı katman çok büyük ölçüde pek çok problemin çözümü için yeterli olmaktadır.
  • İkiden fazla saklı katmanı olan derin modeller karmaşık problemlerin çözümü için
    kullanılmaktadır. Bunlara örnekler ileride verilecektir.

Bir saklı katmandaki nöron sayısı için pratik tavsiyeler de şunlar olabilir:

Saklı katmandaki nöronların sayısı girdi katmanındaki nöronların sayısının 2/3 ile çıktı
katmanındaki nöronların sayısının toplamı kadar olabilir. Örneğin girdi katmanındaki nöron
sayısı 5, çıktı katmanındaki 1 olsun. Bu durumda saklı katmandaki nöron sayısı 5 olabilir.

Saklı katmandaki nöronların sayısı girdi katmanındaki nöron sayısının iki katından fazla
olmamalıdır.

Tabii aslında saklı katmanlardaki nöron sayılarına ilişkin bu iki sezgisel yargıya bazı
durumlarda uyulmamaktadır. Genellikle saklı katmanlardaki nöron sayıları deneyimle, deneme yanılma yöntemleriyle belirlenmektedir. Şüphesiz bir fayda sağlanmadığı halde çok saklı katman ya da saklı katmanlarda çok nöron bulundurmasının bir anlamı yoktur. Ağ ne kadar sade olursa hem işlem yükü bakımından hem de verilerin saklanması ve iletilmesi bakımından o kadar avantaj sağlanır.

Bu arada katmandaki nöron sayılarını değiştirince loss değeri 5’i görmeye başladı. :thinking:

Epoch sayısını arttırdığım zamanda da 0.4’e kadar düşüyor.

Sanırım farklı deneylere göre hangi değerin altında olması gerektiği zamanla öğrenilir.

Evet bu overfitting konusundan bahsediliyordu. Dediğiniz gibi overfitting ve underfitting arasında bir denge kurmak gerekiyor.

Hmm. Daha o konulara gelmedim, ama bakacağım. Sadece geldiğim yer kadarıyla kafama takılan bir soruyu paylaşayım dedim.

Hmm, yine aynı değerler ile farklı sonuçlar alıyorum ama en azından aradaki fark artık çok fazla değil. 0.47, 0.48, 0.49, 0.50 arasında değerler alıyorum şimdi.

Estağfurullah, bu konuda sizden öğrenebileceğim şeyler olduğunu seziyorum. Henüz hangi metrik fonksiyonu hangi durumda kullanmalıyım bilmiyorum. Ama öğrenmeye çalışacağım. Bu örnekte binary bir sınıflandırma olduğu için (diyabet var, diyabet yok) yazar sanırım binary_accuracy kullanmış.

2 Beğeni

Estağfurullah ne rahatsızlığı, hiç sorun değil.

Evet, çünkü epoch’u artırmakla modelin training verisine daha fazla maruz kalmasını sağlıyoruz. Ama dediğiniz gibi “bir yere kadar” çünkü oradan sonra ezberlemeye i.e. overfitting başlayabilir.

Haklı olabilirsiniz, sadece süresini kısaltır diye düşünüyordum ama belli olmaz tabii.

Bu tür öğrenilmeyen, kullanıcı tarafından verilmesi gereken parametreler hyperparameter olarak geçiyor. Bir sürü var:

gizli katman sayısı, her bir katmandaki nöron sayısı, kullanılan optimizer, kullanılan aktivasyon fonksiyonları, epoch sayısı, batch size, weight’lerin başlangıç değerleri…

Dolayısıyla çok geniş bir parametre deneme sahası var. Mesela siz biraz değiştirip loss’u 5 olarak almışsınız, biraz daha değiştirseniz 0.05 alırsınız belki…

Burada devreye hyperparameter tuning giriyor - elle sonu gelmeyen denemeler yapmayı (akıllı bir biçimde) otomatikleştiriyor. Örnekleri için buraya bakabilirsiniz.

Bu ilginç, ben hep aynı değerleri alıyorum: Google Colab. Neden sizde öyle oldu bilemedim.

Evet haklısınız. Precision / recall kullanmanın da gerekliliği şöyle: Accuray’nin yaptığı işlem modelin_tutturdukları / toplam_veri_sayısı, yani “ayrıntılarla” pek ilgilenmiyor. Oysaki, bu diyabet örneğinde biz "false positive"leri, yani normalde diyabetli olmamasına karşın modelin bir (olası) hastayı diyabetliymiş gibi göstermesini istemeyiz, değil mi? Ama sırf doğru tutturdukları fazla diye accuracy metriğinde bu false positive’lerin etkisi çok fazla olmaz. Ama bu false positive’lerin en aza indirgenmesi bizim için çok önemliyse, bu hataların daha fazla cezalandırılması gerekir. İşte precision / recall bu tür ayrıntıları da göz önüne katarak bir değerlendirme metriği sunuyor.

3 Beğeni

Bakacağım, çok teşekkür ederim. :pray:

Benim yazdığım seed değeriyle alakalı olabilir. şimdi birbirine daha yakın değerler alıyorum.

Kullandığım keras sürümünde Precision ve Recall metric fonksiyonları yok. Veya var da farklı yerlerde. Mevcut olan metrikler şunlar:

keras.metrics.K
keras.metrics.MAE(
keras.metrics.MAPE(
keras.metrics.MSE(
keras.metrics.MSLE(
keras.metrics.absolute_import
keras.metrics.binary_accuracy(
keras.metrics.binary_crossentropy(
keras.metrics.categorical_accuracy(
keras.metrics.categorical_crossentropy(
keras.metrics.cosine(
keras.metrics.cosine_proximity(
keras.metrics.deserialize(
keras.metrics.deserialize_keras_object(
keras.metrics.division
keras.metrics.get(
keras.metrics.hinge(
keras.metrics.kullback_leibler_divergence(
keras.metrics.logcosh(
keras.metrics.mae(
keras.metrics.mape(
keras.metrics.mean_absolute_error(
keras.metrics.mean_absolute_percentage_error(
keras.metrics.mean_squared_error(
keras.metrics.mean_squared_logarithmic_error(
keras.metrics.mse(
keras.metrics.msle(
keras.metrics.poisson(
keras.metrics.print_function
keras.metrics.serialize(
keras.metrics.serialize_keras_object(
keras.metrics.six
keras.metrics.sparse_categorical_accuracy(
keras.metrics.sparse_categorical_crossentropy(
keras.metrics.sparse_top_k_categorical_accuracy(
keras.metrics.squared_hinge(
keras.metrics.top_k_categorical_accuracy(

keras_metrics isimli kütüphanede Binary Precision ve Recall metrik fonksiyonları varmış. İlk sürümden itibaren farklı sürümleri yüklemeye çalıştım ama hepsi Tensorflow 2.0 veya daha yüksek sürümler istedi.

Haklısınız, 2.3.0 ile gelmiş. Bence siz kendiniz yazabilirsiniz :cowboy_hat_face:

1 Beğeni

Bilmem, önce içeriklerini araştırmam lazım. Teşekkür ederim. :heart:

1 Beğeni