Derin Öğrenme ile Artistik Stil Transferi

0 251

Geçtiğimiz yıllarda van Gogh’un bilinen hikayesini yine van Gogh stili resimlerle anlatan Vincent’ten Sevgilerle‘yi (Loving Vincent, 2017) izleme şansı bulmuştuk. Film, 5.5M dolar gibi bir bütçe ile 125 ressamın çizdiği 65 bin van Gogh stili yağlı boya resim ile üretildi. Yapay zekanın da sanat eseri üretme konusunda ne kadar yetenekli olduğunu biliyoruz. Artistik stil transferi olarak adlandırılan bir derin öğrenme yöntemi gerçek ressamlara gerek kalmadan bu tarz resimler çizebiliyoruz.

Loving Vincent

 

Stil transferi aslında basit bir kaç derin öğrenme yönteminin kombinasyonundan oluşmakta: konvolüsyonel nöral ağlar, öğrenim transferi ve autoencoder mimarileri. Örnek kullanım implementasyonuna bugün Keras’ın kaynak kodunda bile ulaşabiliyor olsak da arkasında zorlu bir teori bulunmakta. Bu yazıda stil transferinin arkasındaki matematiğe değinerek adım adım bir uygulama geliştireceğiz.

Öncelikle bu teknik tipik bir nöral ağ işleminden ibaret olacak. Nöral ağlar eğitim sırasında rastgele başlayan ağırlıkları girdi ve çıktı ikilisine göre ayarlamaktadır. Burada önceden eğitilmiş bir ağ kullanıyor olacağız ve ağırlıkları hiç güncellemeyeceğiz (Bknz: öğrenim transferi). Bu yapılar dışında hiç kullanılmayan şekilde ağırlıklar yerine girdimizi güncelleyeceğiz.

Referans çalışma önceden eğitilmiş ağ olarak VGG modelini kullanmaktadır. Bu modeli yüz tanıma uygulamalarından hatırlayacaksınız. Model basitçe aşağıda gösterildiği şekilde bir mimariye sahip.

VGG mimarisi

Resimler

Bu çalışmada bir sanat eserinin stilini bir fotoğrafa aktarmaya çalışıyoruz. Stilini kullanacağımız esere stil resmi, dönüştüreceğimiz resme de içerik (content) resmi diyeceğiz. Stil resminin fırça darbelerinin içerik resmine aktarılmasıyla ortaya çıkan resme de yaratılan (generated) resim diyeceğiz.

Sırasıyla içerik, stil ve yaratılmış resimler

İçerik ve stil resimleri zaten var olan resimlerdi. Nöral ağlarda eğitime başlamadan önce ağırlıkları rastgele olarak atadığımızı hatırlarsınız. Burada yaratılacak resmin piksel değerleri rastgele olarak atanacak. Aşağıdaki şekilde içerik, stil ve yaratılacak resimleri oluşturabiliriz.

Python resimleri 3 boyutlu olarak (RGB) saklasa da VGG mimarisi 4 boyutlu girdi beklemektedir. Bu sebeple expand_dim fonksiyonunu sanal bir boyut ekleme için kullandık. Bununla birlikte içerik ve stil resimlerini VGG mimarisinin beklediği şekilde 224x224x3 boyutuna dönüştürmemiz gerekti.

Şimdi bu resimleri VGG ağına girdi olarak aktaracağız. İhtiyacımız olan ağın çıktısı yerine ağın bazı katmanlarının çıktısı olacak. Autoencoder‘ların verinin özetlenmesi için kullanıldığı hatırlayalım. Burada da VGG ağını bu resimleri özetlemek için kullanacağız.

Şanslıyız ki Keras VGG modelini hazır olarak bize sunmakta.

Kayıp

İçerik ve stil resimleri için iki kayıp değeri saklayacağız. Tipik nöral ağlarda kayıp değeri gerçek çıktı ile ağın çıktısı yani tahmin değerinin farkından hesaplanırdı. Burada VGG modeli ile özetlediğimiz hallerini mukayese edeceğiz. Her bir katmanın çıktılarını aşağıdaki şekilde saklayalım.

İçerik kaybı

Rastgele yaratılmış resim ve içerik resmini VGG modeline girdi olarak göndereceğiz. Referans çalışma 5. bloğun 2. konvolüsyonel katmanını (block5_conv2) içerik kaybını hesaplamak için kullanmakta.

 

İçerik kaybı

Önceki adımda zaten içerik ve rastgele yaratılmış resmi VGG modeline beslemiştik. İçerik kaybını bu katmanın çıktılarının farkının karesi şeklinde hesaplayabiliriz.

Stil kaybı

Bu sefer 5 farklı katmanın çıktılarını karşılaştıracağız.

Stil kaybı

Burada, gram matrislerin uzaklığının bulunması beklenilmekte. Gram matris, matrisin tranpozesi ile çarpılması ile elde edilebilmektedir.

Ancak, gram matris hesabı için 2 boyutlu matrislerle çalışmamız gerekiyor. batch_flatten komutu, n boyutlu bir matrisi 2 boyutlu şekle dönüştürmekte. Örneğin, VGG modelinin 3. konvolüsyonel katmanı (56×56)x256 boyutundadır. Buradaki 256 filtre sayısını ifade etmektedir. Bu katmanın boyutunu 256x56x56 şekline dönüştürürsek, 56×56 boyutundaki matrisleri yanına koyabiliriz. Bunun için de permutasyon fonksiyonu uygulamamız gerekecek.

Gram matrisin görsel gösterimi aşağıdaki şekildedir.

Gram matris

Artık stil kaybını hesaplayabiliriz.

Toplam kayıp

Toplam kayıt stil ve içerik kaybının bir fonksiyonu olacak.

Gradient descent

Tipi nöral ağlarda kaybın değerini ağırlıklara yansıtırdık. Bunun için de  toplam kaybın her bir ağırlığa göre kısmi türevini hesaplayarak ağırlığa ekleme yapardık. Stil transferinde ise kaybın her bir girdiye göre kısmi türevini hesaplayarak girdiyi güncelleyeceğiz.

Stil transferi

Böylelikle (1, 224, 224, 3) boyutunda bir tensor’u gradyan olarak hesaplayıp girdiyi güncelleyeceğiz.

Şu ana kadar anlatılan aslında basitçe gradyan azalım algoritmasının girdiye uygulanmasından ibarettir.

Test

Van Gogh’un Yıldızlı Gece portresinin stilini İstanbul boğazındaki Galatasaray Üniversitesinin resmine uygulamayı denediğimde aşağıdaki gibi harikulade bir sonuç elde edildi.

İçerik olarak Galatasaray Üniversitesi
Stil olarak Van Gogh’un Yıldızlı Gecesi
Yıldızlı Gece Stili Galatasaray Üniversitesi

Tabi resmin bu hale gelmesi için 250 epoch boyunca eğitmem gerekti. Epoch’lar boyunca değişimi aşağıdaki videodan izleyebilirsiniz.

Bununla birlikte bir video her saniyesi 24 kareden oluşan fotoğraflardan ibarettir. Her bir karesine stil transferi uygulayarak Loving Vincent filmine benzer görüntüler elde edebiliyoruz. Benzer şekilde stil transferi uygulanan video serisine göz atmak isterseniz bu oynatma listesine bakabilirsiniz.

Bitirirken…

Artistik stil transferi üst seviye bir kaç derin öğrenme yönteminin kombinasyonundan ibarettir. Bu yöntemlere ait çoğu Türkçe olan kaynakları link olarak yazı boyunca eklemeye çalıştım. Konuyu derinlemesine öğrenmek adına linkleri takip etmenizi şiddetle tavsiye ederim.

Bu çalışmaya ait kaynak koduna GitHub‘tan erişebilirsiniz. Repo’yu yıldızlayarak bu çalışmaya desteğinizi göstebilirsiniz 🙂

Bu yazı Artistic Style Transfer with Deep Learning yazısından Türkçe’ye çevrilmiştir.

Yorum yaz

Email adresiniz yayınlanmayacaktır.