Derin Öğrenme Hakkında Neredeyse Her Şey [1]
Son Güncelleme: 02/02/2022
Bu seri toplamda 6 yazıdan oluşmaktadır. Şuan en teorik (sıkıcı) yazı olan 1. yazıyı okuyorsunuz. Diğer içeriklere aşağıdaki linklerden ulaşabilirsiniz.
- Derin Öğrenme Hakkında Neredeyse Her Şey [1]
- Derin Öğrenme Hakkında Neredeyse Her Şey [2]
- Derin Öğrenme Hakkında Neredeyse Her Şey [3]
- Derin Öğrenme Hakkında Neredeyse Her Şey [4]
- Derin Öğrenme Hakkında Neredeyse Her Şey [5]
- Derin Öğrenme Hakkında Neredeyse Her Şey [6]
Özet: Bu yazıda derin öğrenmeye giriş, nöron, derin ağ ve çalışma prensibi konularına değinilmiştir.
Merhaba! Yapay zeka dersleri almak hobim haline geldi artık. Her şeyden önce kendim için; yarı sözlük mahiyetinde bu notları burada toplamaya karar verdim. Yeni şeyler öğrendikçe de güncellemeyi planlıyorum. Evet başlık biraz iddialı oldu.
Öncelikle Derin Öğrenme yapay zekanın son yıllarda en meşhur olmuş alanı diyebiliriz. Otonom araba sürüşleri, program yazan robotlar, dil çevirileri, fake videolar… Temas etmediği alan kalmadı herhalde. Peki ama bu kadar karmaşık işleri nasıl yapıyor? Programını nasıl yazıyorlar bunun? Kullanılan sınıflar tasarım desenleri neler?
Aslında yapı ve mantık tamamen farklı. Normalde yazılımcılar sürecin tamamını analiz eder kendi algoritmalarını kurar. Yazılımı yaptıklarında tabiri caizse süreç sıkı sıkıya bağlı olarak tam yazılımcının uygun gördüğü gibi gider. Ama derin öğrenmede yazılımcı temel anlamda algoritmaya kafa yormaz. (İleride buna tekrar değineceğiz.) Yapay zekaya örnekler verilir; girdi bu olursa çıktı bu olmalı denir. Yapay zeka eğitim esnasında bu örnekleri yüzlerce binlerce kez okur. Tahminlerde bulunur kendi tahminlerini doğru değerler ile karşılaştırır. Devamlı olarak tahminlerini iyileştirir ve yeteri seviyeye gelince de durur. Artık ortada sizin bir algoritmanız olmaz. Ortada kapalı bir kutu vardır. Siz girdi verirsiniz o size -öğrendiklerine göre- sonucu söyler.
“Peki ama nasıl?”
Temelde; girdileri öncelikleri ile değerlendirip bir sonuç üretir. Mesela kendimiz, bir araba fiyat tahmini yapacak olalım. Markası, motor büyüklüğü, üretim yılı gibi değerlere bakıyoruz. Hepsinin birbirine göre ağırlıkları farklı. Mercedes ise direk pahalı olmasını düşünüyoruz mesela. Aslında tahmin noktasında derin öğrenmenin de yaptığı bu. Eğitim dediğimiz şey ise yüzlerce, binlerce araba örneğine tekrar tekrar bakarak marka, model gibi özelliklerden hangisinin fiyat için daha önemli olduğunu tespit etme çalışması. Sonuç olarak “Fiyat = Marka * A + Motor * B + Yıl * C …” gibi bir formül çıkıyor ortaya. (A, B, C… eğitim sonucunda yapay zekanın belirlediği ağırlıklar) Sonra biz de yeni bir araba için marka model bilgisini formüldeki yerine koyuyoruz, fiyat tahminini üretiyoruz.
Özünde bu kadar basit ama her problem araba fiyatı tahmin etme gibi lineer bir sorun olmadığı için çok sevgili Murat Dalkılıç’ın da dediği gibi daha derine inmek gerekiyor. Yavaş yavaş gidelim.
Girdiler
Girdiler dedik. Her zaman bir takım girdiler var. Resim de olsa ses de olsa bazı girdiler verip sonuç istiyoruz. Hatta bazen resim + ses + yazı verip bir tahmin çıktı isteyebiliriz. Her şeyden önce bu girdilerimiz sayısal olmak zorunda, kesin bilgi yayalım. Çünkü her zaman sonuç olarak elimizde üretilmiş bir yada birden fazla formül var. Girdileri bu formüllerin içine sokuyoruz.
Resim için düşünelim. Piksel dediğimiz noktalardan oluşuyor. Her noktanın da sayısal bir renk kodu var. O zaman biz bu renk kodlarını yan yana dizip bir resmi uzun ve sayısal bir dizi haline getirebiliriz.
Aslında bir girdiyi sayısala çevirme konusunda tamamen özgürüz ama kendini ispatlamış yöntemler var. Demin resim için olanı konuştuk. Eğer siz daha verimli bir yöntem bulduğunuzu ispat edebilirseniz muhtemelen meşhur olursunuz. Ki şuan bu giriş seviyesi yazıyı okuyorsanız böyle bir yöntemi keşfetmeye daha yakın sayılırsınız bence. Çünkü öğrenme esnasında aynı örnekleri göre göre yanlılığı artıyor insanların. Farklı düşünmesi zorlaşıyor. Yapay zekada da var bu; yeri gelince değineceğim. Neyse efendim; işte bir çok girdi tipimiz ve jenerikleşmiş sayısallaştırma yöntemleri var. Bunların hepsi ile alakalı örnekler yapacağız.
Nöron ve Derin Ağ
Aslında yukarıdaki resim matematiksel olarak biraz fikir veriyor. Derin öğrenmenin en küçük birimi bir nöron. (F = X1*W1 + X2*W2 + … + Xn*Wn) Yukarıdaki araba örneği için tek nöronlu bir model bile iyi sonuçlar verebilecektir. Ama daha karmaşık sorunlar için uç uca ekleniş nöronların daha doğru sonuçlar verdiğini gördük. Buna da derin sinir ağı diyoruz. Burada derin sinir ağları tasarlayabilmeniz ve karşılaştırabilmeniz için bir uygulama var.
Ağırlık Hesaplama
Daha derine inmeden önce “Peki ama nasıl?” sorusuna değinmek istiyorum. Demin es geçmiştik. Tek bir nöron için düşünelim. Formülümüz Z=wX+b şeklinde ifade edilir. X girdi, b yanlılık, w ağırlık, Z ise tahmin. Şunu hatırlayalım: yapay zeka w ve b değişkenlerinin en doğru değerini bulmaya çalışıyor. En doğru dedim çünkü elimizde yüzlerce X girdisi için doğru sonuçlar var. Yapay zeka w ve b için önce rastgele bir değer ile Z çıktılarını üretecek. sonra bakacak ki Z değeri doğru değere çok uzak. Sonra w ve b yi biraz değiştirecek. Sonra yine sonuçlara bakacak ve diyecek ki “A çok iyi biraz yaklaşmışım” sonra aynı yönde biraz daha değiştirecek. Bu şekilde defalarca değiştire değiştire tüm veri seti için en yakın Z değerini üretebilecek w ve b değerini tespit edecek. Aslında olay bu kadar. Dağılabiliriz :p Şimdi demin yapmış olduğumuz şeyin teknik isimlerine bakalım.
İlk olarak w ve b değerini rastgele bir değerden başlattık bunun ismi initialization (ilklendirme). Çeşitli yöntemleri var. Hatırladığım kadarıyla en iyisi “he initialization” idi.
Ardından değişkenleri formülde yerine koyarak bir Z çıktısı elde ettik. Bunun ismi forward propagation (ileri yayılım). Sonra da bulduğumuz Z değerleri ile olması gereken çıktıları karşılaştırıp farkı hesapladık. Bu da Loss yani kayıp değeri. Buraya kadar tamam sanırım. Tam burada muğlak bir nokta var. Loss ‘a bakarak w ve b yi güncelliyoruz dedik. Bu işin de ismi back propagation (geri yayılım) ama güncellemeyi neye göre yapıyoruz. Artıracak mıyız? Azaltacak mıyız?
Yukarıdaki grafik ideal olarak w ve b değerlerine göre kayıp değerinin değişimini gösteriyor. Ana amacımıza odaklanalım. Hedef: kayıp değerinin 0 olması yani hesapladığımız Z değerlerinin gerçek çıktılar ile birebir aynı olması. Bunun için grafikte çanağın en zemin noktasına gitmeliyiz. Amacımız kayıp değerini minimum yapmak. İşte burada türev işin içine giriyor. Türev bize eğimi verir biz de eğim yönünde ilerlersek adım adım en zemin noktaya erişiriz. Burada şunu da söyleyip bu tatsız tuzsuz matematik konusunu kapatacağım. J ‘nin w ‘ya göre ve J ‘nin b ‘ye göre türevlerini bağımsız olarak almalı ve ilgili değişkeni güncellemeliyiz. Çünkü w ‘nun artması gereken bazı yerlerde b ‘nin azalması gerekebilir. Neyse işte bu sebeplerden dolayı önce türevi bulup ardından w ve b yi güncelliyoruz.
Bunu yaparken de bulduğumuz türevi learning rate dediğimiz bir değer ile çarpıyoruz. learning rate 1 ‘den küçük bir değer. Yani öğrenmeyi bilinçli olarak yavaşlatıyoruz. Bunun amacı ideal olmayan durumlarda (ki hiçbir durum tam ideal değildir.) zikzaklar çizerek gitmemiz gereken sonuç noktayı ıskalamayı engellemek. (bkz: toplu iniş, stokastik iniş) Buraya bakarlar.
Sonra bu işlemleri defalarca tekrarlayarak w ve b yi en doğru değere getiriyoruz. (ileri yayılım -> kayıp hesaplama -> geri yayılım yani w ve b yi güncelleme). Sonuç olarak elimizde artık neredeyse doğru fiyatı veren bir Z = wX + b formülü var.
Şimdiye kadar konuştuklarımız tek nöronlu bir ağ ile öğrenme işlemi idi. Daha karmaşık problemleri çözmek için bu nöronları birbiri ardına ve yan yana bağlayarak bir derin ağ oluşturuyoruz.
Dikeyde alt alta dizilmiş birbiri ile direk bağlantısı olmayan nöronlar grubuna layer yani katman diyoruz. Bir girdi katmanımız bir çıktı katmanımız ve gizli katmanlarımız var. Kurduğumuz bu sistemin tamamına model diyoruz. Gizli katman sayısı ve katmanlardaki nöron sayıları tamamen bize kalmış. İşte algoritmanın (yani modelin) müdahale edebileceğimiz kısımlarından birisi bu.
Bir nöronun çıktısı diğer birinin girdisi oluyor. Ama direk değil; çıktı olan bilgiyi bir fonksiyondan geçirip bir sonraki nörona veriyoruz. Burada modelimize ve veri setimize göre çeşitli amaçlarımız var. Bu fonksiyonun ismi aktivasyon fonksiyonu. Sigmoid, Tanh gibi çeşitleri var. Detaylı bilgi için isterseniz Ayyüce hocanın karşılaştırma yazısını okuyabilrsiniz.
Şimdiye kadar öğrendiğimiz w ‘lar b ‘ler gizli katman sayısı, katmanlardaki nöron sayıları vs bunların hepsine de hiperparametre diyoruz. Burada da bu konuda bir yazı var.