Derin sinir ağları nasıl görüntü ustası oldu?

Derin öğrenmenin neden bu kadar etkili olduğu hala bir muamma.

Bu yazıda, bizim için soyut resimler çizmek için sinir ağlarını kullanmaya çalışacağız ve ardından gizemin altında neler olup bittiğini daha iyi anlayabilmek için bu görüntüleri açıklayacağız.

Bu makaleyi okuduktan sonra, aşağıda gösterildiği gibi bazı resimler oluşturmayı öğreneceksiniz.

(Tüm içerik 100 satır PyTorch kodundan daha azdır. Ekteki Jupyter not defteri: https://github.com/paraschopra/abstract-art-neural-network)

Bu görüntü nasıl oluşturuldu?

Bu resim basit bir mimari tarafından oluşturulmuştur Birleşik Model Oluşturma Ağı (CPPN).

(Bu makaleyi adresinden okuyabilirsiniz.)

Makalede yazar, JavaScript ile yazılmış bir sinir ağı aracılığıyla soyut resimler üretiyor. Bu makale, bunları uygulamak için PyTorch'u kullanır.

Sinir ağları aracılığıyla görüntü oluşturmanın bir yolu, bunların aynı anda eksiksiz görüntüler vermesini sağlamaktır. Örneğin, "oluşturucu" adı verilen aşağıdaki sinir ağı, girdi olarak rastgele gürültüyü alır ve çıktı katmanındaki tüm görüntüyü oluşturur (ve En boy).

Tüm görüntünün çıktısını almanın aksine, CPPN pikselin rengini belirli bir konumda (girdi olarak) çıkarır.

Yukarıdaki görüntüdeki z ve r'yi göz ardı edin Ağın pikselin x ve y koordinatlarını aldığını ve pikselin hangi renkte olması gerektiğini çıkardığını unutmayın (c ile gösterilir). Bu ağın PyTorch modeli aşağıdaki gibidir:

sınıf NN (nn.Module):

def __init __ (öz):

super (NN, self) .__ init __ ()

self.layers = nn.Sequential (nn.Linear (2, 16, bias = True),

nn.Tanh (),

nn.Linear (16, 16, önyargı = Yanlış),

nn.Tanh (),

nn.Linear (16, 16, önyargı = Yanlış),

nn.Tanh (),

nn.Linear (16, 16, önyargı = Yanlış),

nn.Tanh (),

nn.Linear (16, 16, önyargı = Yanlış),

nn.Tanh (),

nn.Linear (16, 16, önyargı = Yanlış),

nn.Tanh (),

nn.Linear (16, 16, önyargı = Yanlış),

nn.Tanh (),

nn.Linear (16, 16, önyargı = Yanlış),

nn.Tanh (),

nn.Linear (16, 16, önyargı = Yanlış),

nn.Tanh (),

nn.Linear (16, 3, bias = False),

nn.Sigmoid ())

def ileri (öz, x):

self.layers (x) döndür

Lütfen 2 girişi kabul ettiğini ve 3 çıkışı olduğunu (piksellerin RGB değerleri) unutmayın. Tüm görüntüyü oluşturmanın yöntemi, istenen görüntünün (belirli boyut) tüm X ve Y konumlarını girmek ve bu X ve Y konumlarının rengini ağ çıktısının rengi olarak ayarlamaktır.

Sinir ağı deneyi

Belki yukarıdaki sinir ağını çalıştırmaya çalıştığınızda, aşağıdaki görüntüyü oluşturacaksınız:

Şu sorularla dolu olabilirsiniz: Neden sağladığınız x, y konumunu ne olursa olsun, ağ çıkışı gri? İdeal olarak, ağ çok derin olduğu için bu olmamalıdır. Giriş değerini değiştirmek çıktı değerini değiştirmelidir.

Sinir ağı her başlatıldığında, parametrelerin rastgele başlatılması (ağırlıklar ve önyargılar) nedeniyle yepyeni bir görüntü oluşturmak mümkündür. Ancak çoğu kez birkaç denemeden sonra bile, sinir ağından elde ettiğiniz şey bu tür bir gridir. neden?

Birisi bunun kullanılan belirli aktivasyon işlevi-tanh ile ilgili bir sorun olduğunu söyleyebilir. Sonraki katmanlardaki çoklu tanh dizilerinin tüm girdi sayılarını çıktı katmanında 0,5'e yakın olacak şekilde sıkıştırması mümkündür (griyi temsil eder). Ancak bu yazının başında önerilen makalede tanh da kullanılmıştır. Tek yaptığımız, blogda JavaScript ile yazılmış sinir ağını herhangi bir değişiklik yapmadan PyTorch'a dönüştürmekti.

Temel neden nerede?

Yeni bir sinir ağı başlatıldığında, PyTorch ağırlıkları nasıl başlatır? Kullanıcı forumuna göre ağırlıkları -1 / sqrt (N) 'den + 1 / sqrt (N)' ye kadar rastgele çizilmiş sayılarla başlatırlar. Burada n, bir katmanda gelen bağlantıların sayısıdır. Bu nedenle, gizli katman için N = 16 ise, ağırlık -1/4 ile +1/4 arasında olacak şekilde başlatılacaktır. Bu nedenle şu tahminde bulunabiliriz: farz edelim ki grinin nedeni ağırlık aralığının küçük olması ve değişimin büyük olmamasıdır.

Ağdaki tüm ağırlıklar -1/4 ile +1/4 arasında ise, herhangi bir giriş çarpılıp birbirine eklendiğinde, merkezi limit teoremine benzer bir etki meydana gelebilir.

Merkezi Limit Teoremi (CLT) şunu kanıtlıyor: Bazı durumlarda, bağımsız rastgele değişkenlerin eklenmesi, orijinal değişkenlerin kendileri normal olarak dağıtılmasa bile, uygun şekilde normalleştirilmiş toplamları normal olarak dağıtılma eğilimindedir (gayri resmi olarak "çan şeklinde eğri ").

Sonraki katmanlardaki değerin nasıl hesaplanacağını hatırlayın.

Örneğimizde, birinci giriş katmanının 2 değeri (x, y) ve ikinci gizli katmanın 16 nöronu vardır. Bu nedenle, ikinci katmandaki her nöron, ağırlıklarla çarpılan 2 değer alır ve bu ağırlıklar -1/4 ile +1/4 arasındadır. Bu değerler toplanır ve daha sonra tanh aktivasyon fonksiyonundan başladıktan sonra üçüncü tabakaya geçilecek yeni değer olur.

Şimdi ikinci katmandan başlayarak üçüncü katmandaki 16 nöronun her birine geçirilecek 16 giriş var. Bu değerlerin her birinin z ile temsil edildiğini varsayarsak, üçüncü katmandaki her bir nöronun değeri:

Bu bizim diğer tahminimiz. Ağırlıkların varyansı küçük olduğundan (-1/4 ila +1/4), z'nin değeri (yani, x, y'nin ağırlıkla çarpılması ve ardından tanh işlevi yoluyla girilmesi) çok fazla değişmeyecektir (bu nedenle benzer olacaktır). Dolayısıyla bu denklem şu şekilde görülebilir:

Her nöron için, -0.25 ile +0.25 arasındaki 16 ağırlığın toplamının en olası değeri sıfırdır. İlk katmanda bile, toplam sıfıra yakın değildir, ağın sekiz katmanı, yukarıdaki denkleme sonunda sıfıra yakın bir değer üretmek için yeterli fırsatı verir. Bu nedenle, giriş değerinden (x, y) bağımsız olarak, aktivasyon fonksiyonuna giren toplam değer (girişle çarpılan ağırlık) her zaman sıfıra yakındır ve tanh haritası sıfırdır (bu nedenle, sonraki tüm katmanlardaki değerler sıfır kalır).

X ekseni tanh'ın girdisidir ve y ekseni çıktıdır. 0'ın 0 ile eşleştiğini unutmayın.

Grinin sebebi nedir? Bunun nedeni sigmoid işlevinin (son katmanın etkinleştirme işlevi) bu giriş değerini sıfıra alması ve 0,5'e (gri için, siyah için 0 ve beyaz için 1) eşlemesidir.

Sigmoid fonksiyonunun giriş değerini 0 ile 0,5 arasında nasıl eşlediğine dikkat edin.

Gri alan nasıl düzeltilir?

Temel neden ağırlıktaki küçük bir değişiklik olduğu için, yapmamız gereken sonraki şey onu artırmaktır. Ağırlığı -100'den +100'e atamak için varsayılan başlatma işlevini değiştirin (-1/4 ile +1/4 yerine). Şimdi sinir ağını çalıştırarak şunları alabiliriz:

Vaov! Gri bir parça artık bir renk noktasıdır.

Şimdi biraz ilerleme var. Varsayımımız doğrudur. Ancak oluşturulan görüntünün hala çok fazla yapısı yok. Bu çok basit.

Bu sinir ağının yüzeyin altında yaptığı şey, girdiyi ağırlıklarla çarpmak, onları tanh'a itmek ve sonunda sigmoid işlevi aracılığıyla rengi çıkarmaktır. Artık ağırlıkları düzelttiğimize göre, çıktı görüntüsünü daha ilginç hale getirmek için girdiyi değiştirebilir miyiz? elbette.

Lütfen yukarıdaki görüntünün, orijinal piksel koordinatları olarak x, y girilirken oluşturulduğunu unutmayın, bu koordinatlar 0,0 ile 128,128 arasında başlar (bu görüntünün boyutudur). Bu, ağımızın giriş olarak hiçbir zaman negatif bir sayıya sahip olmadığı anlamına gelir ve bu sayılar büyük olduğu için (örneğin, x, y 100, 100 olabilir), tanh işlevi ya büyük bir sayı alır (+ 1'e sıkıştırılır) veya Çok küçük bir sayı alın (-1'e sıkıştırılır). Bu nedenle, temel renklerin basit kombinasyonlarını görüyoruz (örneğin, 0,1,1'in R, G ve B çıkışı, yukarıdaki resimde gördüğünüz camgöbeğini temsil eder).

Görüntüler nasıl ilginç hale getirilir?

Başta bahsettiğimiz makalede olduğu gibi, x ve y'yi normalize ettik. Bu nedenle, x girmek yerine (x / image_size) -0.5 giriyoruz. Bu, x ve y değerlerinin -0,5 ile +0,5 arasında değiştiği anlamına gelir (görüntü boyutundan bağımsız olarak). Bu, aşağıdaki görüntü ile sonuçlanır:

Hâlâ ilerleme var!

İlginç bir şekilde, önceki görüntüde, çizgi sağ alt köşeye kadar uzanıyor (çünkü x ve y değerleri artıyor). Burada, x, y değerleri normalleştirildiği ve şimdi negatif sayılar içerdiği için, çizgiler düzgün bir şekilde dışa doğru büyür.

Ancak görüntü yine de yeterince güzel değil.

Görüntüyü nasıl daha ilginç hale getirebilirim?

Yakından bakarsanız, görüntünün ortasında kenarlardan daha fazla yapı olduğunu göreceksiniz. Bu matematik tanrısının bize verdiği ipucudur, güzelliği bulmak için orayı yakınlaştırmalıyız.

Görüntünün merkezini büyütmenin üç yolu vardır:

· Büyük bir görüntü oluşturun. Piksel koordinatları standartlaştırıldığından, daha büyük bir görüntü oluşturmak için sinir ağını çalıştırabiliriz. Ardından, görüntü düzenleme aracı ile orta kısmı yakınlaştırabilir ve ne bulduğumuzu görebiliriz.

· X ve y girişlerini küçük bir miktarla (ölçekleme faktörü) çarpın, bu önceki yöntemle aynı sonucu etkili bir şekilde elde eder (ve diğer ilgi çekici olmayan alanlardaki savurgan hesaplamalarımızdan kaçınır).

· Çıktı, ağırlık ile çarpılan girdiyle belirlendiğinden, girdi değerini azaltmak yerine ağırlık değerini -100, +100'den +3, -3'e ve diğer değerlere düşürerek de ölçeklendirebiliriz (ve aşırıya kaçmamayı unutmayın. Azaltın Ağırlık -0.25 ile +0.25 aralığındaysa gri görüneceğini unutmayın.

X ve y'yi 0,01 ile çarpmak için ikinci yöntemi kullandığımızda şunu elde ederiz:

Üçüncü yöntem benimsendiğinde ve ağırlıklar -3 ile +3 arasında başlatıldığında, elde ettiğimiz görüntü budur:

Zihniniz açık mı?

Daha fazla deney

Ağırlık başlatmayı normal bir dağılıma değiştirin (ortalama değer 0, standart sapma 1) ve birden çok görüntü oluşturun (aşağıdaki görüntü rastgele başlatma ile başlar).

Tüm gizli katmanları kaldırırken (yalnızca çıktı eşlemesine girdi):

0 gizli katman

Yalnızca bir gizli katman ayrıldığında (varsayılan 8 gizli katman yerine):

1 gizli katman

Gizli katman sayısını 16 katmana ikiye katlarken:

Her biri 16 nöron içeren 16 gizli katman

Tahmin edebileceğiniz gibi, gizli katmanların sayısı arttıkça, görüntü giderek daha karmaşık hale geliyor. Katmanları ikiye katlamak yerine katman sayısı aynı kalırsa (8), ancak her katmandaki nöron sayısı ikiye katlanırsa (16'dan 32'ye) ne olur? Elde ettiğimiz şey:

Her biri 32 nöron içeren 8 gizli katman

Yukarıdaki iki durumda ağdaki toplam ağırlık sayısının benzer olmasına rağmen, iki katmanlı bir ağın, her katmanda çift nöronlu bir ağdan daha pikselli olduğuna dikkat edin. Pikseller, bu alanlarda işlevin büyük ölçüde değiştiğini gösterir, bu nedenle daha fazla yakınlaştırırsak daha fazla yapı bulacağız. Aynı sayıda katmana sahip ancak her katmandaki nöron sayısını iki katına çıkaran bir ağ için, işlevi oldukça düzgündür, bu nedenle "ölçeklenebilirlik" küçüktür.

Elbette tüm bunlar, derinliğin sinir ağlarını daha anlamlı kıldığını söylemenin başka bir yolu.

Hesaplama fonksiyonunun karmaşıklığı, derinlikle üssel olarak artar.

Bu tam olarak gördüğümüz şey. Genel yaklaşım teoremi, teorik olarak yeterince büyük bir sinir ağının, gizli bir katmanla bile, herhangi bir işlevi temsil edebileceğini savunur. Ancak pratikte, ağ ne kadar derinse, çıktı eşleme girdisi o kadar karmaşıktır.

Anlamsız ama ilginç deney

Her katmandaki nöron sayısını 8'den 128'e çıkarırsak (bir büyüklük sırası artar).

Gergin Pollock!

Her gizli katmanda 128 nöronla başlarsak ve ardından bunları aşağıdaki gibi kademeli olarak sonraki katmanlarda ikiye bölersek.

self.layers = nn.Sequential (nn.Linear (2, hidden_n, bias = True),

nn.Tanh (),

nn.Linear (128, 64, önyargı = Yanlış),

nn.Tanh (),

nn.Linear (64, 32, bias = False),

nn.Tanh (),

nn.Linear (32, 16, bias = False),

nn.Tanh (),

nn.Linear (16, 8, bias = False),

nn.Tanh (),

nn.Linear (8, 4, bias = False),

nn.Tanh (),

nn.Linear (4, 3, bias = False),

nn.Sigmoid ())

Elde ettiğimiz şey:

Bu, diğerlerinden daha "doğal" görünüyor.

Yapabileceğiniz ve ilginç görüntüler elde edebileceğiniz birçok deney var.Daha fazla mimari, aktivasyon ve seviye deneyebilirsiniz.

Mi Mix3 haberi verdi, gerçek makine uygulamalı harita + basın toplantısı zamanı ve yeri
önceki
Vicdan anı: 7 buçuk yıl önce, eski grafik kartı aniden DX12'yi destekliyor!
Sonraki
Morning Post: Blues, üst üste 2 deplasman maçında 10 gol kaybetti
Yeni perakendecilik, çevrimdışıyken ısınıyor! Tmall 618 ulusal ticaret bölgesi tüketim patlaması, Altın Hafta ile ısı yakalıyor
AC Milan 3-0 Cagliari, Paqueta ilk golü attı, Piatek attı
Mobil Mi Fan Card'ın yeni kullanıcıları eski kullanıcılar için başvuramaz transfer olamaz mı? İçindeki bir resim sana sırrı gösteriyor
Barcelona 0-0 Athletic Bilbao, ligde üst üste iki beraberlik yaşadı
Neden çoğu kişi LOL oynuyor şimdi Polar Fight oynuyor? Netizenler beklenmedik şekilde yanıt verdi
On yıllık blockchain: 2019 geliştirme trendlerinin önemli bir envanteri
İlk yarı-Biba 0-0 Barcelona, Ter Stegen golü güvence altına aldı
ROOT eseri Süper SU raflardan çıktığında, netizenler: Maskeyi öğrenelim
İlk yarı-AC Milan 2-0 Cagliari, Paqueta ilk golü attı
Dizüstü bilgisayar endüstrisinde "8848" olan HP, sürpriz bir fiyata tamamen deri bir dizüstü bilgisayar çıkardı
Anlaşılması gereken bir makale: Markov zinciri nedir? Ne yapılabilir
To Top