Keras ile Derin Öğrenmeye Giriş

Özgün Genç
11 min readMay 19, 2016

--

Bu yazıda son yıllarda hem akademide hem de endüstride popülaritesi hızla artan Derin Öğrenme (Deep Learning) konusuna giriş yapacağız. Eğer teknolojiyi yakından takip ediyorsanız basında mutlaka Google’ın veya Facebook’un bu alanda yaptığı bir yenilikle ilgili bir habere denk gelmişsinizdir. Peki nedir bu Derin Öğrenme?

Derin Öğrenme tabanlı AlphaGo, Dünya Go şampiyonlarından Lee Sedol’u oynadıkları 5 maçın 4'ünde yenmişti

Derin Öğrenme aslında Makine Öğrenmesi (Machine Learning) tekniklerinden sadece biri. Genel olarak kastedilen şey ise çok katmanlı Yapay Sinir Ağları’ndan başka bir şey değil.

Yapay Sinir Ağları (YSA/Artificial Neural Networks-ANN) tarihi aslında 60–70 yıl kadar gerilere gidiyor. Tam anlamıyla bir roller coaster yolculuğu gibi inişli çıkışlı bir hikayesi var. 10–20 yılda bir bu alanda yapılan yeni bir keşifle tekrar gündeme geliyor ve yapay zeka konusundaki bütün dertlere çare olacağı düşünülüyor. Çok geçmeden ise bunun yanlış alarm olduğu anlaşılıyor ve ve araştırmacılar alternatif yaklaşımlara yöneliyor.

2000'li yılların ilk yarısına geldiğimizde tablo aynen buydu. Yapay Sinir Ağları çeşitli nedenlerle işe yaramaz kabul edilmiş ve ısrarla konuyu takip eden birkaç araştırmacı dışında unutulmaya yüz tutmuştu. SVM (Support Vector Machines) gibi algoritmalar ise giderek artan popülariteye sahipti.

Ve Derin Öğrenme Sahneye Girer

2000'lerin ikinci yarısından itibaren ise en azından bazı problem tipleri için işin rengi değişmeye başladı. Yapay Sinir Ağları’nı temel alan sistemler önce Ses ve Konuşma Tanıma alanında mevcut sistemlerden daha iyi performans göstermeye ve hayatımıza girmeye başladılar. Bugün cep telefonlarımız sesli komutları anlarken bu teknolojiden yararlanıyor.

Daha sonra ImgeNet gibi yarışmalarda resimleri tanımlama konusunda YSA temelli sistemler liderliği ele geçirmeye, her sene birinci olmaya ve diğer sistemlere fark atmaya başladılar.

Peki değişen neydi? Değişen şey, Derin Öğrenme olarak anılan konseptin hayatımıza girmesiydi. Burada birkaç şey belirleyici oldu:

  1. Veri miktarının artması: Özellikle İnternet sayesinde devasa boyutlarda veri dijital ortamda üretilir ve saklanır hale geldi. Derin Öğrenme sistemleri bu büyük veriyi kullanmayı başararak avantaj elde ettiler.
  2. GPU’lar ve işlem gücünün artması: Burada bilim dünyasının PC oyuncularına bir teşekkür borcu var. Bilgisayarlarımızın grafik işlemcileri paralel hesaplama yapma konusunda özelleşmiş donanımlardır. Bu sayede CPU’nun yavaş kaldığı bazı işlemleri çok daha hızlı yapabiliyorlar. Derin Öğrenme araştırmacıları işte işlem gücündeki bu artıştan ve ucuzlamadan yararlanıyor.
  3. “Derinliğin” artması: İşlem gücünün artmasının doğrudan sonucu daha derin modellerin pratikte kullanılabilmesine izin vermesi oldu. Derin Öğrenme modelleri çok katmanlı yapılardır. Buradaki asıl fikri daha iyi anlamak için insan beynindeki görme sistemiyle kurulan analoji işe yarayacaktır. Gözlerden sinirler vasıtasıyla gelen sinyaller birkaç katmanlı hiyerarşik bir yapıda değerlendirilir. Sinyalin gözden sonra ilk uğradığı merkezde kenarlar, köşeler gibi görüntünün daha lokal ve temel özellikleri tanınır. Daha sonraki katmanlarda bu kenar ve köşeler bir araya getirilerek ağız burun gibi şekilleri, daha sonraki katmanlarda yüzleri, daha sonraki katmanlarda ise sahnedeki kişi ve nesnelerin yerleşimi gibi görüntünün bütününe ait olan özellikleri tanınabilir. İşte Yapay Görme uygulamalarında kullanılan CNN (Convolutional Neural Nets) başta olmak üzere birçok Derin Öğrenme sistemi bu prensipte çalışır.

Modellerin daha derin ve karmaşık hale gelebilmesi, bunları eğitebilen algoritmaların keşfi, bu ağların büyük verilerle (ve hatta işaretsiz ham veriyle) eğitilebilmesi ve tüm bu sürecin standart bir masaüstü PC (veya Amazon AWS gibi ucuz ve erişilir bulut servisleri) ile gerçekleştirilebilir hale gelmesiyle Derin Öğrenme’nin popülerleştiği bir sürece girdik.

Burada derinliğin ve büyük verinin “sihirli” bir etkisi olduğu fikrini de es geçmemek istiyorum. Çoğu araştırmacı teorik ve matematiksel olarak bu sistemlerin işe yarayacağını öngörememişti. Oysa büyük veri ve daha derin modeller kullanımının getirdiği iyi sonuçlar beklentileri ters köşe yaptı.

Son olarak ortalama bir insan beyninde 100 milyar (10¹¹) nöron bulunduğunu ve 3 yaşındaki bir çocuk beyninde bile 10¹⁵ sinaps bulunduğunu düşünürsek mevcut teknolojimizle insan beynini yakalamanın çok da yakın olmadığını söyleyebiliriz.

Gerekli Malzemeler

Bu uzunca girişten ve Derin Öğrenme dünyasına 10 bin metreden baktıktan sonra dalışa geçiyoruz ve kendi Derin Öğrenme modellerinizi eğitebileceğiniz kütüphanelere erişiyoruz. Yolun bundan sonrasına katırlarla devam edeceğimiz için temel programlama bilgisinin yanısıra temel Machine Learning bilgisine de ihtiyacınız olacak. ML konusunda verebileceğim en iyi tavsiye Andre Ng’in herkesin favorisi Machine Learning kursu: https://www.coursera.org/learn/machine-learning

Bir de Linux veya Mac OS yüklü bir bilgisayar gerekecek. Windows’ta kurulum daha zor olabilir, şu tutorialı deneyebilirsiniz. Veya Kaggle Scripts gibi bir servis kullanarak web uzerinden deneyebilirsiniz. Tabii bu durumda GPU desteğiniz olmayacaktır.

Bu tutorialda GPU kullanmayacağız. Fakat gerçek bir uygulama üzerinde çalışırken ihtiyacınız olacaktır. Bunun için unutmamanız gereken Nvidia uyumlu ve CUDA destekli bir GPU’ya ihtiyacınız olduğu. CUDA bu alanda oldukça standartlaşmış durumda ve bu teknoloji sadece Nvidia uyumlu GPU’lar tarafından destekleniyor.

Deep Learning Kütüphaneleri

Konu Derin Öğrenme kütüphaneleri olunca seçenekler çok fazla. Ne yazık ki bu yarışın herkesin uzlaştığı bir galibi yok. Biz burada Keras’ı kullanacağız ama başlıca kütüphanelere hızlıca değinmekten zarar gelmez:

Caffe: CNN ve computer vision konusunda öne çıkıyor. Genelde kodlama yapılmadan protobuf (JSON benzeri bir format) dosyalarında değişiklik yaparak programlıyorsunuz. Kendisi C++ temelli ve Python ve Matlab wrapperlari var. En önemli özelliği Model Zoo diye önceden eğitilmiş modellerin olduğu bir kütüphaneye sahip olması. Ne mutlu ki bu modelleri Caffe dışındaki kütüphanelere de import edebilme şansınız var.

Torch: LUA diliyle yazılmış sevilen bir başka kütüphane. LUA gözünüzü korkutmasın JS ve Python arası öğrenmesi kolay bir dil.

Theano: Aslında bir matematik programlama dili veya tensor kütüphanesi diye de düşünebilirsiniz bunu. Matris, vektör ve bunların daha çok boyutlusu olan tensorlar üzerinde işlemleri hızlı bir şekilde yapmaya yarıyor. Daha alt seviye olan bu kütüphanenin detaylarıyla uğraşmak istemeyenler ve daha standart ihtiyaçları olanlar Keras veya Lasagne gibi wrapperlar kullanıyorlar.

Tensorflow: Google’ın yakın zamanda çıkardığı Tensorflow Theano’dan çok da farklı değil. En büyük özelliği işlemleri birden fazla makineye dağıtabilmesi. Google’ın açık kaynaklı hale getirdiği kısmın şimdilik diğer alternatiflere göre biraz yavaş olduğu söyleniyor.

Lasagne: Keras’ın alternatifi bir Theano wrapper’ı.

Keras: Ve geldik bizim kullanacağımız kütüphaneye. Keras, Theano veya Tensorflow’u backend olarak kullanan bir wrapper. Python dilini kullanıyor. Modellerı tanımlamayı ve eğitmeyi çok kolay hale getiriyor.

Python ortamının kurulumu:

Öncelikle bilgisayarımızda Python oramının ve ihtiyaç duyabileceğimiz hesaplama kütüphanelerinin yüklü olması gerekiyor. Bunun en güzel yolu Anaconda adlı bilimsel Python dağıtımını kurmak. Bunun içinde numpy gibi birçok kütüphane hazır geliyor. Komut satırından conda install komutuyla yeni kütüphaneler de ekleyebiliyorsunuz. Biz bu tutorialda Python 2.7 versiyonunu kullanacağız. (Python 3 için kodda ufak tefek farklılıklar olabilir)

Keras kurulumu:

Theano ve Keras’ı kurmak ve geliştirmeye başlamak çok kolay. PIP, Python’un standart paket yöneticisi. (Theano’nun en son versiyonunu kuruyoruz)

pip install — upgrade — no-deps git+git://github.com/Theano/Theano.git

pip insall keras

Kodumuzu yazmak için eski adıyla ipython notebook yeni adıyla Jupyter’i kullanalım. Yeni bir terminal açıp çalışma dizinimize geçiyoruz ve,

jupyter notebook

veya GPU desteğiyle çalıştırmak istiyorsak

THEANO_FLAGS=mode=FAST_RUN,device=gpu,floatX=float32 jupyter notebook

şeklinde çalıştırabilirdik. Yine de şimdilik CPU’dan şaşmamakta fayda var. Tarayıcımızda yeni bir sekmede Jupyter açılmış olmalı.

Çalışacağımız klasörde New butonuna tıklayıp Python 2'yi seçiyoruz ve yeni bir notebook yaratıyoruz.

Notebooklar yazıların, kodların ve çıktılarının karışık olarak yazılabildikleri dökümanlar. Her bir kod/yazı bloğuna hücre deniyor ve Shift+Enter ile hücre içeriğini çalıştırıp sonraki hücreye geçebiliyorsunuz. (Eğer daha önce Matlab kullandıysanız oradaki .m file’lar ile aynı mantık.)

Kod yazmaya başlıyoruz

Keras’ı import ederek kodumuzu yazmaya başlayabiliriz. Bu örnekteki kodların tamanına https://github.com/ozgung/nn-tutorial/blob/master/notebooks/keras-tutorial.ipynb adresinden ulaşabilirsiniz.

Bu örneğin ilk kısmı için Sequential model, Dense layer ve optimizasyon algoritması olarak da SGD (Stochastic Gradient Descent)’i import edelim.

from keras.models import Sequentialfrom keras.layers.core import Densefrom keras.optimizers import SGD

Bir veri setine ihtiyacımız olacak. Derin Öğrenme dünyasının “hello world”ü MNIST el yazısı ile rakam tanıma veri setidir. Bu set çeklerin üzerindeki rakamları tanımak için oluşturulmuş ve Yapay Sinirsel Ağların ilk başarılarından olmuş. Keras’ta bu ve benzeri birkaç seti indiren kodlar hazır olarak geliyor. Import ederek yüklüyoruz ve reshape komutu ile 28x28 piksellik resimlerimizi 784 piksellik birer feature vektörü halinde dönüştürüyoruz:

from keras.datasets import mnist(X_train, y_train), (X_test, y_test) = mnist.load_data()X_train = X_train.reshape(60000, 784)
X_test = X_test.reshape(10000, 784)
MNIST veri setindeki rakamlardan bazıları

load_data() komutu veri setini internetten indirip kullanıma hazır hale getirecek. Burada oluşan veri yapıları Machine Learning uygulamaları için standart ama tekrar etmekte yarar var: Burada X_train ve X_test sırasıyla training ve test için ayrılmış veri matrisleri. Bunların her bir satırı bir rakam örneğinin resmini içeriyor. Resimdeki rakamın kaç olduğu ise y_train veya y_testin ilgili satırında yazıyor. Machine Learning algoritmamızın yapacağı şey bu resimler ile cevabı olan rakamları (yani etiketleri/hedef değerleri) ilişkilendiren matematiksel bir model oluşturmak. Böylece bu modele hiç görmediği bir resim gösterdiğimizde resimde hangi rakam olduğunu tanıyabilecek.

İşte bu hazırlayacağımız model Keras’ın Sequential modeli. Sıralı katmanlardan oluşan bir model bu. Bunu yukarıda import etmiştik. Şimdi yeni bir Sequential model objesi yaratalım, ismi de model olsun.

model = Sequential()

Çok basit oldu. Bu şu anda boş ve tek başına bir işe yaramıyor. Katmanları eklemeye başlayalım. Bunun için .add() fonksiyonunu kullanmamız yeterli.

model.add(Dense(input_dim=X_train.shape[1],
output_dim = 50,
init = 'uniform',
activation = 'tanh'))
Multilayer Perceptron

Eklediğimiz katman Keras’ın Dense layer tipinde. Bu “fully connected layer” olarak da biliniyor. Yani bu katmanın bütün girişleri ve bütün çıkışları birbirine bağlı ve her birinin ayrı bir weighti var. Burada oluşturacağımız ağımız sadece bu tip katmanlardan oluşacak. Bu tip bir ağ mimarisine Multi Layer Perceptron (MLP) deniyor.

Katmanları yerleştirirken önemli olan her bir katmanın giriş boyutunun (input_dim) bir önceki katmanın çıkış boyutuna eşit olması. Burada az önce yarattığımız Dense katmandan önce gelen şey bir resmi (yani X matrislerinin bir satırını) temsil eden veri giriş katmanı olacak. (veri katmanı bizim bildiğimiz, “görünür” bir katman. Modelimizin bir parçası olmadığı için Keras modeline ayrı bir katman olarak eklemiyoruz.) X_train.shape[1] değeri X_train matrisinde kaç kolon olduğunu (784) veriyor.

init değişkeni ile başlangıçta katmanın içindeki ağırlıkları (weights) nasıl “sıfırlayacağımızı” bildiriyoruz. http://keras.io/initializations/

Activation kısmına gelince. Activation’lar katmanlarımızın çıkışına takılan fonksiyonlar. Katmanın non-linear olmasını sağlıyor. Bunu ayrı bir Activation katmanı olarak da modelimize ekleyebilirdik. Ama her bir Keras katmanının activation özelliği var ve kısaca bunu vermek yetiyor.

Örneğin burada kullanılan tanh (hiperbolik tanjant) şöyle bir aktivasyon fonksiyonu:

Hiperbolik Tanjant

Sinirsel Ağlarda çok popüler bir başka aktivasyon fonksiyonu ise Rectified Linear Unit, yani kısaca ReLu.

Rectified Linear Unit

Şimdi biraz çılgınlık yapalım ve modelimize birkaç katman daha ekleyelim:

from keras.layers.core import Activation
from keras.layers.core import Dropout
model.add(Dense(50, init='uniform'))
model.add(Activation('tanh'))
model.add(Dropout(0.5))
model.add(Dense(64, init='uniform'))
model.add(Activation('relu'))

Burada ilk iki satırda başta eklediğimiz katmanın bir benzerini farklı bir yöntemle yaratıyoruz. İlk katman olmadığı için input_dim değişkenini vermemize gerek kalmadı. Sonra weightlerin yarısını düşüren bir Droput katmanı ekliyoruz. Bunun ne olduğunu bilmiyorsanız dert etmeyin, Neural Network’lerde overfitting’i engellemek için icat edilmiş basit bir yöntem. Sonra 64 birimlik (64 çıkışlı) ve ReLu ile aktive olan bir katman daha ekliyoruz.

Şu an modelimizin çıkışında 64 tane değer var. Ama bizim elimizde 10 tane etiket (10 tane rakam, 10 tane sınıf) var. Ağımızın çıkışında 64 değer yerine her biri 10 rakamdan birine karşılık gelen 10 tane değer olsaydı çok süper olurdu. Modeli eğitirken doğru rakama karşılık gelen çıkışın değerini ‘1’, diğer tüm çıkışların değerinin de ‘0’ olmasını sağlardık. Sınıfları bu şekilde temsil etmeye OHE (one-hot encoding) deniyor. Modelden tahmin isterken de çıkışta en büyük değer hangi rakama karşılık geliyorsa cevabı o kabul ederdik.

Neyse ki bunu yapmanın yöntemi oldukça basit. 10 tane çıkışı olan yeni bir fully connected katman ekleyip aktivasyon fonksiyonunu softmax yapıyoruz.

model.add(Dense(10, init='uniform')) model.add(Activation('softmax'))

Ayrıca çıkıştaki y_train vektörümüzü de OHE formatına çevirmemiz gerekecek. Keras’taki to_categorical() yardımcı fonksiyonu bunu bizim için yapıyor.

from keras.utils.np_utils import to_categorical
y_train_ohe = to_categorical(y_train)

İşte bu kadar. Modelimiz hazır. Çok süper bir model olmayabilir ama en azından bir model var elimizde. Şimdi compile fonksiyonunu kullanarak modelimizi nasıl eğiteceğimizi bildirmemiz gerekiyor. Bunun için bir optimizasyon algoritmasına ihtiyacımız olacak. Compile komutundan standart bir algoritma kullanmasını da isteyebilirdik ama hadi kendimiz tanımlayalım.

Eski dost SGD (Stochastic Gradient Descent) işimizi görecektir.

sgd = SGD(lr=0.001, decay=1e-6, momentum=0.9, nesterov=True)

Bu hiperparametreler modelimizin daha çabuk eğitilmesinde etkili. Burada lr, learning rate, yani öğrenme hızımız. Decay parametresi öğrenme hızımızı zamanla azaltıyor. Momentum yöntemini kullanıyoruz. Bu parametre için genelde 0.9 değeri kullanılıyor. Momentum yönteminde bir hız vektörü tutuyoruz ve her adımda bunu update ediyoruz. Nesterov momentumu ise bunu biraz daha akıllı yapan, büyük bir adım attıktan sonra kendini düzelten bir yöntem.

Artık modelimizi “compile” edebiliriz. Burada en önemli parametre loss fonksiyonu.

model.compile(loss = 'categorical_crossentropy',
optimizer = sgd)

Burada categorical_crossentropy, multiclass logloss olarak da bilinen loss fonksiyonumuz. Softmax ile kullanılan ve birden fazla sınıf için genelleştirilmiş lojistik regresyondan başka bir şey değil.

Şimdi sırada bu modele datayı verip eğitmek var. Birçok Machine Learning kütüphanesinde olduğu gibi bunun için model.fit(X, y) fonksiyonunu kullanacağız.

model.fit(X_train,
y_train_ohe,
nb_epoch = 50,
batch_size = 500,
validation_split = 0.1,
verbose = 1)

Burada 500 örneklik mini batchler halinde SGD’yi çalıştırıyoruz. Yani her 500 örnekte bir adım atıyoruz. Tüm veri setini de 50 sefer yineliyoruz. Buna 50 epoch deniyor. Ayrıca X_train’de 60 bin tane örneğimiz vardı. Bunların 10'da birini yani 600 tanesini validation split olarak ayırdık. Yani algoritmamız X’in %90'ını kullanarak modelimizi eğitecek, geri kalan yüzde 10 ile test edecek ve hatalarını düzeltecek. Verbose ile de işlem sırasında ekrana ayrıntılı verilerin dökülmesini sağlıyoruz.

Güzel. Her şey doğru gittiyse modelimizi eğittik ve artık artık test setimiz üzerinde tahminler ürettirmeye hazırız.

y_test_predictions = model.predict_classes(X_test, verbose = 1)

İşte bu kadar! y_test_predictions üzerinde tahminlerimiz oluşmuş olmalı. Bakalım ne kadarını doğru bilmişiz.

import numpy as np
correct = np.sum(y_test_predictions == y_test)
print ('Test Accuracy: ', correct/float(y_test.shape[0])*100.0, '%')

Yüzde 90 civarında bir değer görmeniz gerekli. Katmanlarla ve parametrelerle oynayarak %95'e doğru tırmanabilirsiniz.

Son olarak Keras ve Graphviz modülünü kullanarak oluşturduğumuz modeli görsel olarak da görebilirsiniz.

from keras.utils.visualize_util import plot
from IPython.display import Image
plot(model, to_file=’model.png’, show_shapes= True)
Image(“model.png”)
Keras ile oluşturduğumuz model

Buradan Nereye Gidelim?

Bir maceranın daha sonuna geldik. Keras’ı yükledik ve ilk Yapay Sinir Ağımızı eğittik. El yazısı ile yazılmış rakamları yüzde 90 üzeri isabetle bilen bir sistemimiz oldu. İşin hem teorik yönünde hem de pratik yönünde yeni maceralar bizleri bekliyor. Neyse ki çağımızın en büyük icadı online dersler bu macerada bizi yalnız bırakmayacak.

Öncelikle Machine Learning ile ilgili bir temeliniz yoksa yukarıda da önerdiğim Andrew Ng’nin dersi tam size göre.

Neural Networkler’in teorisine dalmak istiyorsanız bu işin üstatlarından Geoffrey Hinton’un Neural Networks for Machine Learning dersini şiddetle tavsiye ederim.

Benim işim acele diyorsanız üstatların son NIPS konferansında yaptığı sunumu izleyerek başlayabilirsiniz. https://www.youtube.com/watch?v=hA2FJ5NjvOA

Yann LeCun’un yaptığı bir sunum: https://lecture2go.uni-hamburg.de/veranstaltungen/-/v/16622

Daha pratik ve güncel bilgiler için Stanford Üniversitesi’nin geçen dönem bu konuda verdiği iki dersin notları internette açık durumda. Biri Computer Vision diğeri Doğal Dil İşleme özelinde konuyu işliyor. Bu derslerin videoları kendi sitesinden kaldırılmış ancak google’da biraz araştırırsanız Youtube linklerini bulabilirsiniz.

Türkçe içerik istiyorsanız http://www.derinogrenme.com/ adresinde hem Türkçe hem de İngilizce eğitimleri bulabilirsiniz.

Veri Bilimi İstanbul grubunun da Torch kullanarak hazırladığı Deep Learning’e girişi sunumunun videosu bulunuyor. Bu da Türkçe: https://www.youtube.com/watch?v=37ecsMezvwM

Gördüğünüz gibi kaynak bol. Gerisi size kalmış.

Görüşmek üzere.

--

--