Evrimli sinir ağları (CNN), görüntü sınıflandırma ve analizinde en güçlü sinir ağı türüdür. Uygulamaları pek çok sınırı aşmış ve bugün gördüğümüz birçok derin öğrenme destekli uygulamanın kritik unsuru olduklarını kanıtlamıştır. Yüksek düzeyde bakıldığında, CNN'ler kendilerine verilen görüntülerin içsel özellik düzeyi temsillerini öğrenebilir. Onları bu kadar güçlü kılan da budur. CNN'lerin bu belirgin özelliğinin yalnızca görüntü sınıflandırma gibi görevler için değil, aynı zamanda görüntü oluşturma için de yararlı olduğu ortaya çıktı. Deep Dream ve Nöral Stil Transferi gibi uygulamalar, CNN'lerin katman aktivasyonlarına ve çıkardıkları özelliklere dayanarak görüntüler üretir.
Bu eğitimde, Nöral Stil Transferi'nin nasıl çalıştığını ve TensorFlow 2.0 kullanılarak nasıl uygulanabileceğini inceleyeceksiniz.
Not: Bu eğitimi adım adım takip edebilmek için CNN'lerin nasıl çalıştığını bilmeniz gerekir. CNN'lerle ilgili hızlı bir tazeleme için aşağıdaki kaynaklara göz atabilirsiniz:
Bilgisayarlı görü ve derin öğrenme alanına yeni adım atanlar için nöral stil transferi terimi biraz göz korkutucu olabilir. Terimin her bileşenini anlamak için aşağıdaki iki görüntüyü düşünün:
Nöral stil transferi bağlamında, soldaki görüntü içerik görüntüsü, sağdaki görüntü ise stil görüntüsü olarak adlandırılır. Bir görüntüyü (bu örnekte soldaki) başka bir görüntünün (sağdaki) stilini kullanarak biçimlendirmek istiyorsunuz. Terimdeki son iki kelimeyi oluşturan şey budur: stil transferi. Süreci yürütmek için bir sinir ağı (CNN) özel bir kayıp fonksiyonunu optimize edecek şekilde eğitilir; bu da ilk kelimeyi açıklar: nöral. Yukarıdaki iki görüntü nöral stil transferiyle birleştirildiğinde nihai çıktı (sağdaki) şöyle görünür:
“Nöral stil transferinin ne faydası var?” diye sorabilirsiniz. Diyelim ki Vincent van Gogh tarafından yapılmış bir çizimin görüntüsüne sahipsiniz. Bu çizimin sizin kendi çizimlerinizden birine nasıl yansıyacağını görmek istiyorsunuz. Nöral stil transferinin kullanıldığı uygulamalardan biri budur. Bir diğer örnek de Prisma gibi, pürüzsüz bir kullanıcı arayüzü aracılığıyla nöral stil transferi yapmanızı sağlayan pek çok fotoğraf filtresi uygulamasıdır.
İçerik ve Stil Arasındaki Yalıtım
Şimdiye kadar nöral stil transferi hakkında edindiğiniz fikir, sürecin bir görüntünün içeriğiyle başka bir görüntünün stilini birleştirmekten ibaret olduğu yönündedir. Nitekim bu %100 doğrudur. Bu bölümde, CNN'ler bağlamında içerik ve stil ile tam olarak ne kastedildiğini anlayalım.
Bir CNN genellikle birkaç evrişim katmanı ve havuzlama katmanının bir araya gelmesinden oluşur. Evrişim katmanları verilen bir görüntüden son derece karmaşık özellikler çıkarmaktan sorumluyken, havuzlama katmanları bir görüntü sınıflandırma problemi için gerekli olmayan ayrıntılı uzamsal bilgileri eler. Bunun etkisi, CNN'in belirli bir görüntünün renginden, dokusundan vb. ziyade içeriğini öğrenmesine yardımcı olmasıdır. Bir CNN'in derinlerine indikçe özelliklerin karmaşıklığı artar ve daha derin evrişim katmanları sıklıkla içerik temsilleri olarak adlandırılır.
Stile örnek olarak ise doku, renk vb. gibi görüntü özelliklerine özgü her şey verilebilir — örneğin bir çizimde belirli bir rengin baskın kullanımı. Peki bir görüntünün stilini nasıl çıkarırsınız? Bu, evrişim katmanları arasındaki korelasyonlar hesaplanarak yapılır. Korelasyonlar, iki veya daha fazla değişkenin ne kadar benzer/ilişkili olduğunun bir ölçüsünü verir. Bunu anlamak için, birkaç özellik haritasından oluşan öğrenilmiş bir evrişim katmanını düşünün. Her bir özellik haritası için, tespit ettiği özelliklerin aynı katmandaki diğer özellik haritalarıyla ne kadar güçlü ilişkili olduğunu ölçebilirsiniz. Bu da size şunların bir tahminini verir: İlk özellik haritasında tespit edilen belirli bir renk, başka bir haritadaki renge benziyor mu? Özellik haritaları arasında ortak şekiller var mı? Bu özellikler/benzerlikler bir görüntünün stilini tanımlar. Bir evrişim katmanı içindeki birçok özellik haritasının içerikleri arasındaki benzerliği ölçme süreci, ağların doku ve renk gibi uzamsal özelliklere odaklanan çok ölçekli bir görüntü temsili öğrenmesine yardımcı olur.
Akılda tutulması gereken hayati bir nokta, nöral stil transferini uygularken, bir görüntünün içeriğinin de başka bir görüntünün istenen stiliyle birlikte korunduğundan emin olmanız gerektiğidir. Bunun nasıl yapıldığını ilerleyen bir bölümde göreceksiniz. Bir sonraki bölümde, bir görüntüden (içerik görüntüsü) özelliklerin nasıl çıkarılacağını ve içerik kaybının nasıl hesaplanacağını öğreneceksiniz.
İçerik Görüntüsünü Nicemleme ve İçerik Kaybını Hesaplama
Evrişimli Sinir Ağları Kullanarak Görüntü Stil Transferi makalesine göre, hem içerik hem de stil özelliklerini sırasıyla içerik ve stil görüntülerinden çıkarmak için VGG-19 CNN mimarisi kullanılır. İçerik özelliklerini elde etmek için dördüncü bloğun (evrişim katmanlarından) ikinci evrişim katmanı kullanılır. Makalenin yazarları bunu kolaylık olması için conv4_2 olarak adlandırmıştır. İçerik özelliklerini elde ettikten sonra, içerik kaybını ölçmek için bunları bir hedef görüntüyle karşılaştırmanız gerekir. Hedef görüntü nedir? Burada içerik kaybı neden hesaplanmalıdır? Bu iki soruya odaklanmak için bir adım geri atalım.
İçerik ve stil özelliklerini tek bir görüntüde birleştirmek için, ya boş bir görüntüyle ya da içerik görüntüsünün bir kopyasıyla başlayan bir hedef görüntüye ihtiyacınız olacak. Artık bir CNN kullanarak hem içerik hem de stil özelliklerini etkili bir şekilde öğrenmek için, optimize ederek içerik ve stil görüntülerinden oluşturulacak pürüzsüz bir stillendirilmiş görüntü elde edeceğiniz özel bir kayıp fonksiyonuna ihtiyacınız var. Bu özel kayıp fonksiyonu, esasen iki farklı kaybın bir araya gelmesinden oluşur:
Net içeriğin korunduğundan emin olan içerik kaybı.
Hedef görüntüye aktarılan stil miktarını kontrol eden stil kaybı.
Artık yukarıdaki sorular hakkında bir fikir edindiğinize göre içerik kaybına geri dönelim ve bunu tanımlayalım. İçerik kaybı şu şekilde tanımlanır -
burada $T_c$ hedef görüntüyü, $C_c$ ise içerik görüntüsünü ifade eder. Yani bu kayıp fonksiyonunun yaptığı şey, içerik ve hedef görüntülerin özelliklerinin birbirinden ne kadar uzak olduğunu ölçmektir. Ağ bu kaybı en aza indirmeye çalışacaktır. Bir sonraki bölümde stil kaybının nasıl belirleneceğini göreceksiniz.
Stil Kaybı ve Gram Matrisi
Stil kaybını belirlemek için, makale sizi aşağıdaki katmanlardan temsilleri (özünde sayıları) almaya ve bu katmanlardaki özellik haritalarının gram matrislerini elde etmeye yönlendirir.
Stil kaybını tanımlamak için çok sayıda katman kullanmanın avantajı, bir görüntüde yer alan stilin çok ölçekli bir temsilinin öğrenilmesine olanak tanımasıdır. Gram matrisleri, tek bir evrişim katmanı içindeki özellik haritaları arasında özelliklerin ne kadar benzer olduğunu belirlemenize yardımcı olur. Bu da görüntünün stilini şekillendiren yerelleştirilmemiş bilgileri ortaya koyar. Bu bağlamda gram matrisi şu şekilde hesaplanır.
Evrişmiş bir görüntünün boyutunun 8x8x16 olduğunu varsayalım; bu öncelikle 16 özellik haritasına sahip olduğunu belirtir. Şimdi bu özellik haritaları arasındaki özelliklerin benzerliklerini bir gram matrisiyle bulmakla ilgileniyorsunuz. Bunun için, evrişmiş görüntünün ilk iki boyutunu düzleştirip 1B bir vektöre dönüştürürsünüz. Bu durumda düzleştirildiğinde boyutlar 1B vektörde 64 öğe içerir. Bu işlem tüm özellik haritaları için tekrarlanır. Böylece 16x64 boyutunda nihai bir matris elde edersiniz (A matrisi diyelim). Bu matris daha sonra (64x16 olacak şekilde) transpoze edilir ve A matrisi ile çarpılır. Bu durumda gram matrisi 16x16 boyutunda olur. Gram matrisindeki belirli bir değer, özellik haritaları arasındaki benzerlikleri ifade eder. Bu süreç görsel olarak aşağıdakine benzer:
Hedef ve stil görüntüleri arasındaki stil kaybını hesaplamak için, her bir evrişim katmanı bloğunda gram matrisleri arasındaki ortalama kare farklarını alırsınız. Resmî olarak şu şekilde tanımlanabilir:
burada, T(s,i) i. blokta hesaplanan hedef görüntünün gram matrisi, S(s,i) ise i. blokta hesaplanan stil görüntüsünün gram matrisidir. wi ile stile ayrıntılı bir temsil kazandırmak için farklı evrişim bloklarına özel ağırlıklar verebilirsiniz. Son olarak, $a$ bloklar içindeki her bir katmandaki değerlere karşılık gelen bir sabittir. Nöral stil transferi sürecinde ağın optimize ettiği toplam kaybı tanımlamak için iki kaybı bir araya getirelim.
Toplam Kaybı Tanımlama
Toplam kayıp artık özel ağırlıklarla bir toplama işleminden ibarettir -
burada $\alpha$ içerik ağırlığını, $\beta$ ise stil ağırlığını ifade eder. Bu, hedef görüntüye aktarılan stil miktarı ile içerik arasında iyi bir denge kurmanıza yardımcı olur. $\alpha$ ve $\beta$’nın farklı kombinasyonlarının etkisi makalede gösterilmektedir; bunu incelemeniz tavsiye edilir. Artık nöral stil transferini uygulamak için tüm parçalar elinizde. Bir sonraki bölümde doğrudan uygulamaya geçelim.
Uygulamada Nöral Stil Transferi
Uygulama kısmı için TensorFlow 2.0 kullanacaksınız. Kütüphaneye bugüne kadarki en kapsamlı güncellemelerden birini getiren pek çok olağanüstü yenilik içerir. Bunlardan bazılarını öğrenmek isterseniz bu yazıya göz atabilirsiniz.
Bu eğitimin yazıldığı sırada TensorFlow’un en güncel sürümü 2.0.0-beta0’dır. Bunu henüz kurmadıysanız, lütfen önce buradaki talimatları izleyerek kurun. Gerekli paketleri ve içerik ile stil görüntülerini içe aktararak başlayacaksınız.
# Packagesimport tensorflow as tf
from tensorflow.keras.applications.vgg19 import preprocess_input
from tensorflow.keras.models import Model
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(7)%matplotlib inline
print(tf.__version__)Altyapı:
# Load the content and style images
content = plt.imread('Content.jpeg')
style = plt.imread('Style.jpg')# Display the images
fig,(ax1, ax2)= plt.subplots(1,2, figsize=(20,10))# Content and style images side-by-side
ax1.imshow(content)
ax1.set_title('Content Image')
ax2.imshow(style)
ax2.set_title('Style Image')
plt.show()Altyapı:
Bir sonraki adımda, iki görüntüyü sayı dizilerine yükleyecek (çünkü bilgisayarlar yalnızca sayıları anlar) ve modeliyle uyumlu hale getirmek için yeniden boyutlandıracak bir yardımcı işlev yazacaksınız.
# Use load_image of content and style images
content = load_image('Content.jpeg')
style = load_image('Style.jpg')# Verify the shapes
content.shape, style.shape
Altyapı:
Görüntüler yeniden şekillendirildi. Şimdi, özellikleri çıkarmak için önceden eğitilmiş bir VGG19 modeli yükleyeceksiniz. Modeli özellik çıkarmak için kullanacağınızdan, modelin sınıflandırıcı kısmına ihtiyaç duymayacaksınız.
Downloading data from https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg19_weights_tf_dim_ordering_tf_kernels_notop.h5
80142336/80134624[==============================]- 5s 0us/step
Altyapı:
Yazarlar, içerik ve stil özelliklerini çıkarmak için kullandıkları blok adlarını belirtmişler. Az önce yüklediğiniz VGG19 modeli aynı adlandırma kuralını kullanıyor. Bu avantajdan yararlanmak için önce ağdaki tüm katmanların adlarını yazdıracaksınız.
# Print the layer names for conveniencefor layer in vgg.layers:print(layer.name)Altyapı:
Şimdi, belirtilen katmanlardan oluşan özel bir VGG modeli oluşturun. Bu, görüntüler üzerinde ileri geçişler çalıştırmanıza ve yolda gerekli özellikleri çıkarmanıza yardımcı olacaktır.
defmini_model(layer_names, model):
outputs =[model.get_layer(name).output for name in layer_names]
model = Model([vgg.input], outputs)return model
Altyapı:
TensorFlow'da gram matrisi tanımlamak son derece kolaydır ve bunu şu şekilde yapabilirsiniz:
Şimdi mini_model() işlevini kullanarak özel bir model tanımlayacaksınız. Bu, ilgili görüntülerden içerik ve stil özelliklerini döndürmek için kullanılacaktır.
classCustom_Style_Model(tf.keras.models.Model):def__init__(self, style_layers, content_layers):super(Custom_Style_Model, self).__init__()
self.vgg = mini_model(style_layers + content_layers, vgg)
self.style_layers = style_layers
self.content_layers = content_layers
self.num_style_layers =len(style_layers)
self.vgg.trainable =Falsedefcall(self, inputs):# Scale back the pixel values
inputs = inputs*255.0# Preprocess them with respect to VGG19 stats
preprocessed_input = preprocess_input(inputs)# Pass through the mini network
outputs = self.vgg(preprocessed_input)# Segregate the style and content representations
style_outputs, content_outputs =(outputs[:self.num_style_layers],
outputs[self.num_style_layers:])# Calculate the gram matrix for each layer
style_outputs =[gram_matrix(style_output)for style_output in style_outputs]# Assign the content representation and gram matrix in# a layer by layer fashion in dicts
content_dict ={content_name:value
for content_name, value
inzip(self.content_layers, content_outputs)}
style_dict ={style_name:value
for style_name, value
inzip(self.style_layers, style_outputs)}return{'content':content_dict,'style':style_dict}Altyapı:
Artık özel modeli tanımladığınıza göre, bunu görüntüler üzerinde kullanarak içerik ve stil özelliklerini sırasıyla elde edelim -
# Note that the content and style images are loaded in# content and style variables respectively
extractor = Custom_Style_Model(style_layers, content_layers)
style_targets = extractor(style)['style']
content_targets = extractor(content)['content']
In the paper, optimization was done using the L-BFGS algorithm, but you can use Adam also.Altyapı:
Şimdi genel içerik ve stil ağırlıklarını ve daha önce tartışıldığı gibi her bir stil temsilinin ağırlıklarını tanımlayalım. Not: Bunlar hiperparametrelerdir ve üzerinde oynamanız önerilir.
# Custom weights for style and content updates
style_weight=100
content_weight=10# Custom weights for different style layers
style_weights ={'block1_conv1':1.,'block2_conv1':0.8,'block3_conv1':0.5,'block4_conv1':0.3,'block5_conv1':0.1}Altyapı:
Sırada süreci çok daha eğlenceli hale getiren en kritik kısım var: kayıp fonksiyonu.
# The loss function to optimizedeftotal_loss(outputs):
style_outputs = outputs['style']
content_outputs = outputs['content']
style_loss = tf.add_n([style_weights[name]*tf.reduce_mean((style_outputs[name]-style_targets[name])**2)for name in style_outputs.keys()])# Normalize
style_loss *= style_weight / num_style_layers
content_loss = tf.add_n([tf.reduce_mean((content_outputs[name]-content_targets[name])**2)for name in content_outputs.keys()])# Normalize
content_loss *= content_weight / num_content_layers
loss = style_loss + content_loss
return lossAltyapı:
Şimdi aşağıdaki işlemleri yapacak bir başka işlev yazacaksınız:
Az önce tanımladığınız kayıp fonksiyonunun gradyanlarını hesaplar.
Bu gradyanları hedef görüntüyü güncellemek için kullanır.
GradientTape ile otomatik türev alma özelliğinden yararlanabilir, bileşiminden hareketle bir fonksiyonun gradyanlarını hesaplayabilirsiniz. İşlemleri hızlandırmak için tf.function dekoratörünü de kullanacaksınız. Bununla ilgili daha fazlasını buradan okuyun.
@tf.function()deftrain_step(image):with tf.GradientTape()as tape:# Extract the features
outputs = extractor(image)# Calculate the loss
loss = total_loss(outputs)# Determine the gradients of the loss function w.r.t the image pixels
grad = tape.gradient(loss, image)# Update the pixels
opt.apply_gradients([(grad, image)])# Clip the pixel values that fall outside the range of [0,1]
image.assign(tf.clip_by_value(image, clip_value_min=0.0, clip_value_max=1.0))Altyapı:
Ağı eğitmeden önce kalan tek adım hedef görüntüyü tanımlamaktır. Hedef görüntü olarak içerik görüntüsünü kullanacaksınız.
epochs =10
steps_per_epoch =100
step =0for n inrange(epochs):for m inrange(steps_per_epoch):
step +=1
train_step(target_image)
plt.imshow(np.squeeze(target_image.read_value(),0))
plt.title("Train step: {}".format(step))
plt.show()Altyapı:
WARNING: Logging before flag parsing goes to stderr.
W0617 16:21:34.491543140709216896896 deprecation.py:323] From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/math_grad.py:1205: add_dispatch_support.<locals>.wrapper (from tensorflow.python.ops.array_ops)is deprecated and will be removed in a future version.
Instructions for updating:
Use tf.where in2.0, which has the same broadcast rule as np.where Altyapı:
Hedef görüntüdeki değişiklikleri gözlemlemek için içerik ve stil ağırlıklarıyla oynamanız önerilir.
Son Sözler
Bu eğitimde başvurduğunuz makale, oluşturulan görüntünün kalitesini daha fazla iyileştirmekten bahsetmiyordu. Yukarıdaki sonuçlarda muhtemelen gözlemlediğiniz gibi, oluşturulan görüntünün genel içeriği ile stili arasındaki uzamsal ilişkide bir miktar daha pürüzsüzlüğe ihtiyaç var. Bu sorunu gidermek için, düzenlileştirmeye (regülerizasyona) benzer total_variantional_loss tanıtılmıştır. Üst düzeyde, total_variational_loss orijinal nöral stil transferi algoritmasının ortaya çıkardığı yüksek frekanslı yapıları cezalandırır. Bunu uygulamakla ilgileniyorsanız bu eğitime göz atın. Bu eğitimi yazarken referans alınan bazı kaynaklar şunlardır:
Algoritmalar, sistem tasarımı ve davranışsal senaryoları kapsayan bu temel sorularla teknik mülakat sürecine hakim olun. Uzman cevapları, kod örnekleri ve kanıtlanmış hazırlık stratejileri edinin.
Git deponuzu temiz tutmak için .gitignore’u nasıl kullanacağınızı öğrenin. Bu eğitim; temelleri, yaygın kullanım durumlarını ve başlamanıza yardımcı olacak pratik örnekleri kapsar!
Evrimli sinir ağları (CNN), görüntü sınıflandırma ve analizinde en güçlü sinir ağı türüdür. Uygulamaları pek çok sınırı aşmış ve bugün gördüğümüz birçok derin öğrenme destekli uygulamanın kritik unsuru olduklarını kanıtlamıştır. Yüksek düzeyde bakıldığında, CNN'ler kendilerine verilen görüntülerin içsel özellik düzeyi temsillerini öğrenebilir. Onları bu kadar güçlü kılan da budur. CNN'lerin bu belirgin özelliğinin yalnızca görüntü sınıflandırma gibi görevler için değil, aynı zamanda görüntü oluşturma için de yararlı olduğu ortaya çıktı. Deep Dream ve Nöral Stil Transferi gibi uygulamalar, CNN'lerin katman aktivasyonlarına ve çıkardıkları özelliklere dayanarak görüntüler üretir.
Bu eğitimde, Nöral Stil Transferi'nin nasıl çalıştığını ve
TensorFlow2.0 kullanılarak nasıl uygulanabileceğini inceleyeceksiniz.Not: Bu eğitimi adım adım takip edebilmek için CNN'lerin nasıl çalıştığını bilmeniz gerekir. CNN'lerle ilgili hızlı bir tazeleme için aşağıdaki kaynaklara göz atabilirsiniz:
Nöral Stil Transferi nedir?
Bilgisayarlı görü ve derin öğrenme alanına yeni adım atanlar için nöral stil transferi terimi biraz göz korkutucu olabilir. Terimin her bileşenini anlamak için aşağıdaki iki görüntüyü düşünün:
Nöral stil transferi bağlamında, soldaki görüntü içerik görüntüsü, sağdaki görüntü ise stil görüntüsü olarak adlandırılır. Bir görüntüyü (bu örnekte soldaki) başka bir görüntünün (sağdaki) stilini kullanarak biçimlendirmek istiyorsunuz. Terimdeki son iki kelimeyi oluşturan şey budur: stil transferi. Süreci yürütmek için bir sinir ağı (CNN) özel bir kayıp fonksiyonunu optimize edecek şekilde eğitilir; bu da ilk kelimeyi açıklar: nöral. Yukarıdaki iki görüntü nöral stil transferiyle birleştirildiğinde nihai çıktı (sağdaki) şöyle görünür:
“Nöral stil transferinin ne faydası var?” diye sorabilirsiniz. Diyelim ki Vincent van Gogh tarafından yapılmış bir çizimin görüntüsüne sahipsiniz. Bu çizimin sizin kendi çizimlerinizden birine nasıl yansıyacağını görmek istiyorsunuz. Nöral stil transferinin kullanıldığı uygulamalardan biri budur. Bir diğer örnek de Prisma gibi, pürüzsüz bir kullanıcı arayüzü aracılığıyla nöral stil transferi yapmanızı sağlayan pek çok fotoğraf filtresi uygulamasıdır.
İçerik ve Stil Arasındaki Yalıtım
Şimdiye kadar nöral stil transferi hakkında edindiğiniz fikir, sürecin bir görüntünün içeriğiyle başka bir görüntünün stilini birleştirmekten ibaret olduğu yönündedir. Nitekim bu %100 doğrudur. Bu bölümde, CNN'ler bağlamında içerik ve stil ile tam olarak ne kastedildiğini anlayalım.
Bir CNN genellikle birkaç evrişim katmanı ve havuzlama katmanının bir araya gelmesinden oluşur. Evrişim katmanları verilen bir görüntüden son derece karmaşık özellikler çıkarmaktan sorumluyken, havuzlama katmanları bir görüntü sınıflandırma problemi için gerekli olmayan ayrıntılı uzamsal bilgileri eler. Bunun etkisi, CNN'in belirli bir görüntünün renginden, dokusundan vb. ziyade içeriğini öğrenmesine yardımcı olmasıdır. Bir CNN'in derinlerine indikçe özelliklerin karmaşıklığı artar ve daha derin evrişim katmanları sıklıkla içerik temsilleri olarak adlandırılır.
Stile örnek olarak ise doku, renk vb. gibi görüntü özelliklerine özgü her şey verilebilir — örneğin bir çizimde belirli bir rengin baskın kullanımı. Peki bir görüntünün stilini nasıl çıkarırsınız? Bu, evrişim katmanları arasındaki korelasyonlar hesaplanarak yapılır. Korelasyonlar, iki veya daha fazla değişkenin ne kadar benzer/ilişkili olduğunun bir ölçüsünü verir. Bunu anlamak için, birkaç özellik haritasından oluşan öğrenilmiş bir evrişim katmanını düşünün. Her bir özellik haritası için, tespit ettiği özelliklerin aynı katmandaki diğer özellik haritalarıyla ne kadar güçlü ilişkili olduğunu ölçebilirsiniz. Bu da size şunların bir tahminini verir: İlk özellik haritasında tespit edilen belirli bir renk, başka bir haritadaki renge benziyor mu? Özellik haritaları arasında ortak şekiller var mı? Bu özellikler/benzerlikler bir görüntünün stilini tanımlar. Bir evrişim katmanı içindeki birçok özellik haritasının içerikleri arasındaki benzerliği ölçme süreci, ağların doku ve renk gibi uzamsal özelliklere odaklanan çok ölçekli bir görüntü temsili öğrenmesine yardımcı olur.
Akılda tutulması gereken hayati bir nokta, nöral stil transferini uygularken, bir görüntünün içeriğinin de başka bir görüntünün istenen stiliyle birlikte korunduğundan emin olmanız gerektiğidir. Bunun nasıl yapıldığını ilerleyen bir bölümde göreceksiniz. Bir sonraki bölümde, bir görüntüden (içerik görüntüsü) özelliklerin nasıl çıkarılacağını ve içerik kaybının nasıl hesaplanacağını öğreneceksiniz.
İçerik Görüntüsünü Nicemleme ve İçerik Kaybını Hesaplama
Nöral stil transferi algoritması ilk olarak Gatys ve ark. tarafından 2015 tarihli Sanatsal Stil için Bir Nöral Algoritma makalesinde tanıtıldı. Ancak bu eğitim, bir önceki çalışmanın devamı niteliğindeki Evrişimli Sinir Ağları Kullanarak Görüntü Stil Transferi makalesinden referans alır.
Evrişimli Sinir Ağları Kullanarak Görüntü Stil Transferi makalesine göre, hem içerik hem de stil özelliklerini sırasıyla içerik ve stil görüntülerinden çıkarmak için VGG-19 CNN mimarisi kullanılır. İçerik özelliklerini elde etmek için dördüncü bloğun (evrişim katmanlarından) ikinci evrişim katmanı kullanılır. Makalenin yazarları bunu kolaylık olması için
conv4_2olarak adlandırmıştır. İçerik özelliklerini elde ettikten sonra, içerik kaybını ölçmek için bunları bir hedef görüntüyle karşılaştırmanız gerekir. Hedef görüntü nedir? Burada içerik kaybı neden hesaplanmalıdır? Bu iki soruya odaklanmak için bir adım geri atalım.İçerik ve stil özelliklerini tek bir görüntüde birleştirmek için, ya boş bir görüntüyle ya da içerik görüntüsünün bir kopyasıyla başlayan bir hedef görüntüye ihtiyacınız olacak. Artık bir CNN kullanarak hem içerik hem de stil özelliklerini etkili bir şekilde öğrenmek için, optimize ederek içerik ve stil görüntülerinden oluşturulacak pürüzsüz bir stillendirilmiş görüntü elde edeceğiniz özel bir kayıp fonksiyonuna ihtiyacınız var. Bu özel kayıp fonksiyonu, esasen iki farklı kaybın bir araya gelmesinden oluşur:
Artık yukarıdaki sorular hakkında bir fikir edindiğinize göre içerik kaybına geri dönelim ve bunu tanımlayalım. İçerik kaybı şu şekilde tanımlanır -
burada $T_c$ hedef görüntüyü, $C_c$ ise içerik görüntüsünü ifade eder. Yani bu kayıp fonksiyonunun yaptığı şey, içerik ve hedef görüntülerin özelliklerinin birbirinden ne kadar uzak olduğunu ölçmektir. Ağ bu kaybı en aza indirmeye çalışacaktır. Bir sonraki bölümde stil kaybının nasıl belirleneceğini göreceksiniz.
Stil Kaybı ve Gram Matrisi
Stil kaybını belirlemek için, makale sizi aşağıdaki katmanlardan temsilleri (özünde sayıları) almaya ve bu katmanlardaki özellik haritalarının gram matrislerini elde etmeye yönlendirir.
Stil kaybını tanımlamak için çok sayıda katman kullanmanın avantajı, bir görüntüde yer alan stilin çok ölçekli bir temsilinin öğrenilmesine olanak tanımasıdır. Gram matrisleri, tek bir evrişim katmanı içindeki özellik haritaları arasında özelliklerin ne kadar benzer olduğunu belirlemenize yardımcı olur. Bu da görüntünün stilini şekillendiren yerelleştirilmemiş bilgileri ortaya koyar. Bu bağlamda gram matrisi şu şekilde hesaplanır.
Evrişmiş bir görüntünün boyutunun 8x8x16 olduğunu varsayalım; bu öncelikle 16 özellik haritasına sahip olduğunu belirtir. Şimdi bu özellik haritaları arasındaki özelliklerin benzerliklerini bir gram matrisiyle bulmakla ilgileniyorsunuz. Bunun için, evrişmiş görüntünün ilk iki boyutunu düzleştirip 1B bir vektöre dönüştürürsünüz. Bu durumda düzleştirildiğinde boyutlar 1B vektörde 64 öğe içerir. Bu işlem tüm özellik haritaları için tekrarlanır. Böylece 16x64 boyutunda nihai bir matris elde edersiniz (A matrisi diyelim). Bu matris daha sonra (64x16 olacak şekilde) transpoze edilir ve A matrisi ile çarpılır. Bu durumda gram matrisi 16x16 boyutunda olur. Gram matrisindeki belirli bir değer, özellik haritaları arasındaki benzerlikleri ifade eder. Bu süreç görsel olarak aşağıdakine benzer:
Hedef ve stil görüntüleri arasındaki stil kaybını hesaplamak için, her bir evrişim katmanı bloğunda gram matrisleri arasındaki ortalama kare farklarını alırsınız. Resmî olarak şu şekilde tanımlanabilir:
burada, T(s,i) i. blokta hesaplanan hedef görüntünün gram matrisi, S(s,i) ise i. blokta hesaplanan stil görüntüsünün gram matrisidir. wi ile stile ayrıntılı bir temsil kazandırmak için farklı evrişim bloklarına özel ağırlıklar verebilirsiniz. Son olarak, $a$ bloklar içindeki her bir katmandaki değerlere karşılık gelen bir sabittir. Nöral stil transferi sürecinde ağın optimize ettiği toplam kaybı tanımlamak için iki kaybı bir araya getirelim.
Toplam Kaybı Tanımlama
Toplam kayıp artık özel ağırlıklarla bir toplama işleminden ibarettir -
burada $\alpha$ içerik ağırlığını, $\beta$ ise stil ağırlığını ifade eder. Bu, hedef görüntüye aktarılan stil miktarı ile içerik arasında iyi bir denge kurmanıza yardımcı olur. $\alpha$ ve $\beta$’nın farklı kombinasyonlarının etkisi makalede gösterilmektedir; bunu incelemeniz tavsiye edilir. Artık nöral stil transferini uygulamak için tüm parçalar elinizde. Bir sonraki bölümde doğrudan uygulamaya geçelim.
Uygulamada Nöral Stil Transferi
Uygulama kısmı için
TensorFlow 2.0kullanacaksınız. Kütüphaneye bugüne kadarki en kapsamlı güncellemelerden birini getiren pek çok olağanüstü yenilik içerir. Bunlardan bazılarını öğrenmek isterseniz bu yazıya göz atabilirsiniz.Bu eğitimin yazıldığı sırada
TensorFlow’un en güncel sürümü2.0.0-beta0’dır. Bunu henüz kurmadıysanız, lütfen önce buradaki talimatları izleyerek kurun. Gerekli paketleri ve içerik ile stil görüntülerini içe aktararak başlayacaksınız.Bir sonraki adımda, iki görüntüyü sayı dizilerine yükleyecek (çünkü bilgisayarlar yalnızca sayıları anlar) ve modeliyle uyumlu hale getirmek için yeniden boyutlandıracak bir yardımcı işlev yazacaksınız.
Görüntüler yeniden şekillendirildi. Şimdi, özellikleri çıkarmak için önceden eğitilmiş bir VGG19 modeli yükleyeceksiniz. Modeli özellik çıkarmak için kullanacağınızdan, modelin sınıflandırıcı kısmına ihtiyaç duymayacaksınız.
Yazarlar, içerik ve stil özelliklerini çıkarmak için kullandıkları blok adlarını belirtmişler. Az önce yüklediğiniz VGG19 modeli aynı adlandırma kuralını kullanıyor. Bu avantajdan yararlanmak için önce ağdaki tüm katmanların adlarını yazdıracaksınız.
Bununla birlikte stil özelliklerini almak için aşağıdakilerle ilgileneceksiniz:
İçerik özellikleri için
conv4_2gereklidir. Bunları uygun değişkenlerde saklayacaksınız.Şimdi, belirtilen katmanlardan oluşan özel bir VGG modeli oluşturun. Bu, görüntüler üzerinde ileri geçişler çalıştırmanıza ve yolda gerekli özellikleri çıkarmanıza yardımcı olacaktır.
TensorFlow'da gram matrisi tanımlamak son derece kolaydır ve bunu şu şekilde yapabilirsiniz:
Şimdi
mini_model()işlevini kullanarak özel bir model tanımlayacaksınız. Bu, ilgili görüntülerden içerik ve stil özelliklerini döndürmek için kullanılacaktır.Artık özel modeli tanımladığınıza göre, bunu görüntüler üzerinde kullanarak içerik ve stil özelliklerini sırasıyla elde edelim -
Şimdi genel içerik ve stil ağırlıklarını ve daha önce tartışıldığı gibi her bir stil temsilinin ağırlıklarını tanımlayalım. Not: Bunlar hiperparametrelerdir ve üzerinde oynamanız önerilir.
Sırada süreci çok daha eğlenceli hale getiren en kritik kısım var: kayıp fonksiyonu.
Şimdi aşağıdaki işlemleri yapacak bir başka işlev yazacaksınız:
GradientTapeile otomatik türev alma özelliğinden yararlanabilir, bileşiminden hareketle bir fonksiyonun gradyanlarını hesaplayabilirsiniz. İşlemleri hızlandırmak içintf.functiondekoratörünü de kullanacaksınız. Bununla ilgili daha fazlasını buradan okuyun.Ağı eğitmeden önce kalan tek adım hedef görüntüyü tanımlamaktır. Hedef görüntü olarak içerik görüntüsünü kullanacaksınız.
Artık ağı eğitmeye tamamen hazırsınız.
Hedef görüntüdeki değişiklikleri gözlemlemek için içerik ve stil ağırlıklarıyla oynamanız önerilir.
Son Sözler
Bu eğitimde başvurduğunuz makale, oluşturulan görüntünün kalitesini daha fazla iyileştirmekten bahsetmiyordu. Yukarıdaki sonuçlarda muhtemelen gözlemlediğiniz gibi, oluşturulan görüntünün genel içeriği ile stili arasındaki uzamsal ilişkide bir miktar daha pürüzsüzlüğe ihtiyaç var. Bu sorunu gidermek için, düzenlileştirmeye (regülerizasyona) benzer total_variantional_loss tanıtılmıştır. Üst düzeyde, total_variational_loss orijinal nöral stil transferi algoritmasının ortaya çıkardığı yüksek frekanslı yapıları cezalandırır. Bunu uygulamakla ilgileniyorsanız bu eğitime göz atın. Bu eğitimi yazarken referans alınan bazı kaynaklar şunlardır:
Derin öğrenme becerilerinizi geliştirmek istiyorsanız, aşağıdaki DataCamp ders ve eğitimlerine de göz atabilirsiniz: