Dekonvolüsyonlu katmanlar nelerdir?


188

Geçenlerde Jonathan Long, Evan Shelhamer, Trevor Darrell tarafından Semantik Segmentasyon için Tamamen Konvolüsyon Ağları'nı okudum . Dekonvolüsyon katmanlarının ne yaptığını / nasıl çalıştıklarını anlamıyorum.

İlgili bölüm

3.3. Örnekleme tersten izlemeli evrişimdir

Kalın çıktıları yoğun piksellere bağlamak için başka bir yol enterpolasyondur. Örneğin, basit bilinear enterpolasyon, her bir çıktısını , yalnızca girdi ve çıktı hücrelerinin göreceli konumlarına bağlı olan doğrusal bir harita ile en yakın dört girişten hesaplar . Bir anlamda, faktörü ile örnekleme 1 / f'lik kesirli girdi adımına sahip evrişimdir. integral olduğu sürece , örneklemenin doğal bir yolu bu nedenle bir çıkış basamağıyla geriye doğru evrişimdir (bazen dekonvolüsyon olarak adlandırılır) . Bu tür bir işlemin uygulanması önemsizdir, çünkü sadece evrişimin ileri ve geri geçişlerini tersine çevirir.yij
f ffff
Bu nedenle, üst örnekleme, pikseller arası kayıptan geri yayılma yoluyla uçtan uca öğrenme için ağ içinde gerçekleştirilir.
Böyle bir katmandaki dekonvolüsyon filtresinin sabitlenmesi gerekmediğine dikkat edin (örneğin, bilinear yukarı örneklemeye), ancak öğrenilebilir. Bir dekonvolüsyon katmanları ve aktivasyon fonksiyonları yığını doğrusal olmayan bir örneklemeyi bile öğrenebilir.
Deneylerimizde, ağ içi örneklemenin yoğun tahmini öğrenmek için hızlı ve etkili olduğunu bulduk. En iyi segmentasyon mimarimiz, bu katmanları Bölüm 4.2'deki ayrıntılı tahmin için örneklemeyi öğrenmek amacıyla kullanır.

Evrişimli katmanların nasıl eğitildiğini gerçekten anladığımı sanmıyorum.

Anladığım kadarıyla, çekirdek boyutu olan evrişimli katmanların, boyutundaki filtreleri öğrendiğidir . Çekirdek boyutu , adım ve filtreli bir evrişimli katmanın çıktısı, boyutundadır . Ancak, evrişim katmanlarının öğrenilmesinin nasıl çalıştığını bilmiyorum. (Eğer yardımcı olursa, MLP'lerin gradyan inişiyle nasıl öğrendiklerini anlıyorum).k × k k s N n Giriş loşluğukk×kksNnInput dims2n

Eğer evrişimsel katmanlar anlayışım doğruysa, bunun nasıl tersine çevrileceğine dair hiçbir fikrim yok.

Biri lütfen dekonvolüsyonel katmanları anlamama yardımcı olabilir mi?



6
Herkes için faydalı olabileceğini umarak , TensorFlow'da (0.11) evrişim ve geçişli evrişimin nasıl kullanılabileceğini keşfetmek için bir defter yaptım . Belki bazı pratik örnek ve rakamlara sahip olmak, nasıl çalıştıklarını anlamak için biraz daha yardımcı olabilir.
AkiRoss

1
Benim için bu sayfayı bana da deconvolution ve konvolüsyonunu devrik arasındaki farkı açıklar daha iyi bir açıklama verdi: towardsdatascience.com/...
T.Antoni

Parametreleri olmadığı için yukarı örnekleme, geriye doğru katılaşmış evrişimden ziyade geriye doğru havuzlama gibi değil mi?
Ken Fehling

Not: Bu katman, çünkü adı "deconvolutional tabaka" yanıltıcı değildir gerçekleştirmek dekonvulasyon .
user76284

Yanıtlar:


210

Dekonvolüsyon tabakası çok talihsiz bir isimdir ve bunun yerine geçişli bir evrişim tabakası olarak adlandırılmalıdır .

Görsel olarak, adım adım ve dolgulu olmayan bir geçiş için, orijinal girişi (mavi girişleri) sıfırlarla (beyaz girişler) doldururuz (Şekil 1).

Şekil 1

İkinci adım ve doldurma durumunda, devredilen evrişim şuna benzerdi (Şekil 2):

şekil 2

Konvolüsyon aritmetiğinin (harika) görselleştirmelerini burada bulabilirsiniz .


16
Sadece anladığımdan emin olmak için: "Dekonvolüsyon" konvolüsyon ile hemen hemen aynıdır, fakat biraz dolgu maddesi ekler misiniz? (Resmin etrafında / s> 1 de her pikselin etrafında)?
Martin Thoma

17
Evet, bir dekonvolüsyon tabakası da evrişim yapar! Bu nedenle, devredilen evrimin isminden daha iyi uyması ve dekonvolüsyon teriminin aslında yanıltıcı olması.
David Dao,

11
Girdi sıfır tuşlu ise, neden Şekil 1'de "dolgu yok" diyorsunuz?
Stas S

8
Bu arada: Şimdi TensorFlow'da devredilen konvolüsyon denir: tensorflow.org/versions/r0.10/api_docs/python/…
Martin Thoma

9
Bu çok sezgisel cevap için teşekkür ederim, ama ikincisinin neden 'ikinci adım' davası olduğu konusunda kafam karıştı, çekirdek hareket ettiğinde tam olarak birincisine benziyor.
Demonedge

49

Evrimin arkasındaki gerçekten temel bir sezgiyi elde etmenin bir yolu, giriş görüntüsü üzerinde K kalıpları olarak düşünebileceğiniz K filtrelerini kaydırmanız ve K aktivasyonları üretmenizdir - her biri belirli bir şablonla eşleşme derecesini temsil eder. . Bunun tersi işlemi K aktivasyonları almak ve onları evrişim işleminin bir ön izlemesine genişletmek olacaktır. Bu nedenle, ters işlemin sezgisel açıklaması, kabaca, şablonlar (filtreler) ve aktivasyonlar (her şablon için eşleşme derecesi) verilen görüntü rekonstrüksiyonudur ve bu nedenle, her bir aktivasyonu şablon maskesi ile bloke etmek istiyoruz. ve onları ekleyin.

Dekonv işleminin anlaşılmasının bir başka yolu, Caffe'deki dekonvolüsyon tabakası uygulamasının incelenmesi, aşağıdaki ilgili kod bitlerine bakınız:

DeconvolutionLayer<Dtype>::Forward_gpu
ConvolutionLayer<Dtype>::Backward_gpu
CuDNNConvolutionLayer<Dtype>::Backward_gpu
BaseConvolutionLayer<Dtype>::backward_cpu_gemm

Caffe'de normal ileri evrişimli bir tabaka için tam olarak backprop olarak uygulandığını görebilirsiniz (benim için cuDNN conv katmanı ile ConvolutionLayer :: Backward_gpu'da GEMM kullanılarak uygulanan backprop uygulaması karşılaştırıldıktan sonra daha belirgindi). Bu nedenle, düzenli yayılma için geri yayılımın nasıl yapıldığına bakarsanız, mekanik bir hesaplama seviyesinde ne olduğunu anlayacaksınız. Bu hesaplamanın çalışma şekli, bu bulanıklığın ilk paragrafında açıklanan sezgiyle eşleşir.

Ancak, evrişim katmanlarının öğrenilmesinin nasıl çalıştığını bilmiyorum. (Eğer yardımcı olursa, MLP'lerin gradyan inişiyle nasıl öğrendiklerini anlıyorum).

Diğer sorunuza ilk sorunuza cevap vermek için, MLP backpropagation (tamamen bağlı katman) ve evrişimli ağlar arasında iki ana fark vardır:

1) ağırlıkların etkisi lokalizedir, bu nedenle ilk önce nasıl geri dönüş yapılacağına karar verin, sonuçta görüntüde tek bir noktaya eşlenen 3x3'lük bir giriş görüntüsünün küçük bir 3x3 alanı ile kıvrılmış 3x3 filtre.

2) evrişimli filtrelerin ağırlıkları mekansal değişimler için paylaşılır. Bunun pratikte anlamı, ileri geçişte aynı ağırlıkları içeren aynı 3x3 filtrenin, çıktı görüntüsünü (belirli bir filtre için) elde etmek için ileri hesaplama için aynı ağırlıklarla tüm görüntü boyunca sürüklenmesidir. Bunun backprop için anlamı, kaynak görüntüdeki her nokta için backprop gradyanlarının, ileriye geçiş sırasında o filtreyi sürüklediğimiz tüm aralık boyunca toplanmasıdır. DLoss / dx'in geri yayınlanması gerektiğinden, x, w ve bias kayıplarının farklı derecelerinde de olduğuna dikkat edin, dLoss / dw ağırlıkları nasıl güncellediğimizdir. w ve önyargı, DAG hesaplamasında bağımsız girdilerdir (önceden girdi yoktur), bu nedenle bunlar üzerinde geri yayılma yapılmasına gerek yoktur.

(my notation here assumes that convolution is y = x*w+b where '*' is the convolution operation)

7
Bence bu sorunun en iyi cevabı bu.
kli_nlpr

8
Bunun en iyi cevap olduğuna katılıyorum. En üstteki cevap oldukça canlandırıcı animasyonlar var, ancak bu cevabı okuyana kadar bana biraz keyfi gelen düzenli konvolüsyonlar gibi geldiler. Ah insanlar nasıl göz şekeri tarafından sallanır.
Reii Nakano

1
Katılıyorum, kabul edilen cevap hiçbir şeyi açıklamadı. Bu daha iyi.
BjornW

Büyük açıklamanız için teşekkürler. Şu anda sırt bandının nasıl düzgün şekilde yapıldığını çözemiyorum. Bana bir ipucu verebilir misiniz lütfen?
Bastian

33

Transpozisyon konvolüsyonunun 2x örneklemenin 3x3 filtre ve 2 adımlı adımlarla örneklemesini açıklayan adım adım matematik:

görüntü tanımını buraya girin

Matematiği onaylayan en basit TensorFlow pasajı:

import tensorflow as tf
import numpy as np

def test_conv2d_transpose():
    # input batch shape = (1, 2, 2, 1) -> (batch_size, height, width, channels) - 2x2x1 image in batch of 1
    x = tf.constant(np.array([[
        [[1], [2]], 
        [[3], [4]]
    ]]), tf.float32)

    # shape = (3, 3, 1, 1) -> (height, width, input_channels, output_channels) - 3x3x1 filter
    f = tf.constant(np.array([
        [[[1]], [[1]], [[1]]], 
        [[[1]], [[1]], [[1]]], 
        [[[1]], [[1]], [[1]]]
    ]), tf.float32)

    conv = tf.nn.conv2d_transpose(x, f, output_shape=(1, 4, 4, 1), strides=[1, 2, 2, 1], padding='SAME')

    with tf.Session() as session:
        result = session.run(conv)

    assert (np.array([[
        [[1.0], [1.0],  [3.0], [2.0]],
        [[1.0], [1.0],  [3.0], [2.0]],
        [[4.0], [4.0], [10.0], [6.0]],
        [[3.0], [3.0],  [7.0], [4.0]]]]) == result).all()

Sanırım hesaplaman burada yanlış. Ara çıktı 3+ 2 * 2 = 7 olmalıdır, daha sonra 3x3 çekirdek için son çıktı 7-3 + 1 = 5x5 olmalıdır
Alex

Üzgünüz, @Alex, ancak ara verimin neden 7 olduğunu anlamıyorum. Lütfen biraz daha detaylandırabilir misiniz?
1917'de

2
@ veriys Gösterdiğiniz resimde, sonuç neden kırpılmış?
James Bond,

28

Stanford CS sınıf CS231n eşlik notlar : Andrej karpathy tarafından, Görsel Tanıma için Evrişimsel Sinir Ağları , katlamalı sinir ağları açıklayan mükemmel bir iş yapmak.

Bu makaleyi okumak size aşağıdakilerle ilgili kaba bir fikir vermelidir:

  • Dekonvolüsyonlu Ağlar Matthew D. Zeiler, Dilip Krishnan, Graham W. Taylor ve Rob Fergus Bilgisayar Bilimleri Bölümü, Courant Institute, New York Üniversitesi

Bu slaytlar Dekonvolüsyon Ağları için mükemmeldir.


29
Bu linklerden herhangi birinin içeriğini kısa bir paragrafta özetlemek mümkün müdür? Bağlantılar daha fazla araştırma için faydalı olabilir, ancak ideal olarak bir yığın değişimi cevabı, saha dışına çıkmak zorunda kalmadan temel soruyu ele almak için yeterli metne sahip olmalıdır.
Neil Slater

Üzgünüm ama bu sayfaların içeriği kısa bir paragrafta özetlenemeyecek kadar büyük.
Azrael

12
Tam bir özet gerekli değildir, sadece bir başlık - örneğin "Bir dekonvolüsyonlu bir sinir ağı bir CNN'ye benzer, ancak herhangi bir gizli katmandaki özelliklerin önceki katmanı yeniden yapılandırmak için kullanılabileceği şekilde (ve katmanlar arasında tekrarlayarak, sonunda girdi çıktıdan yeniden oluşturulabilir) Bu, bir problem alanında genel üst düzey özellikleri öğrenmek için denetimsiz olarak eğitilmesine izin verir - genellikle görüntü işleme "(notun doğru olup olmadığından bile emin değilim, kendi cevabını).
Neil Slater

6
Bağlantılar iyi olsa da, kendi sözlerinizle modelin kısa bir özeti daha iyi olurdu.
SmallChess

11

Bu konuda theaon web sitesinden harika bir yazı buldum [1]:

Devredilen konvolüsyonlara duyulan ihtiyaç, genellikle normal bir konvolüsyonun ters yönünde ilerleyen bir dönüşüm kullanma arzusundan, [...] özellik haritalarını daha yüksek boyutlu bir uzaya yansıtmaktan kaynaklanır. [...] yani, evrişimin bağlantı düzenini korurken, 4 boyutlu bir alandan 16 boyutlu bir uzaya harita.

Devredilen konvolüsyonlar - ayrıca kesirli olarak düzenlenmiş konvolüsyonlar olarak da bilinir - bir konvolüsyonun ileri ve geri geçişlerini değiştirerek çalışır. Bunu belirtmenin bir yolu çekirdeğin bir evrişim tanımladığını, ancak bunun bir evrişim ya da devredilen bir evrişimin ileri ve geri geçişlerin nasıl hesaplandığına göre belirlendiğine dikkat etmektir.

Devredilen evrişim işlemi, girişine göre bazı evrişimin gradyanı olarak düşünülebilir, bu genellikle pratik olarak evrimleşmiş devirlerin pratikte nasıl uygulandığıdır.

Son olarak, aktarılmış bir evrişimi doğrudan bir evrişim ile uygulamak her zaman mümkün olduğunu unutmayın. Dezavantajı, girişe çok sayıda sütun ve sıfır sıra eklemeyi içermesi ve bunun sonucunda çok daha az verimli bir uygulama yapılmasıdır.

Dolayısıyla, basitçe "geçişli bir evrişim", matrislerin kullanıldığı (aynı evrişim gibi) matematiksel işlemdir, ancak evrişimsel değerlerden orjinaline (ters yöne) geri dönmek istediğinizde normal evrişim işleminden daha verimlidir. Bu nedenle, ters yönde hesaplanırken (yani girişin doldurulmasından kaynaklanan seyrek matrisin neden olduğu birçok gereksiz çarpmalardan kaçınmak için) kıvrılma uygulamalarında tercih edilir.

Image ---> convolution ---> Result

Result ---> transposed convolution ---> "originalish Image"

Bazen evrişim yolu boyunca bazı değerleri kaydedersiniz ve "geri dönerken" bu bilgileri yeniden kullanırsınız:

Result ---> transposed convolution ---> Image

Muhtemelen yanlış bir “dekonvolüsyon” olarak adlandırılmasının nedeni budur. Bununla birlikte, evrişimin matriksinin transpozisyonu (C ^ T) ile bir ilgisi vardır, bu nedenle daha uygun olan "geçişli evrişim" adıdır.

Bu yüzden hesaplama maliyetini düşünürken çok anlamlı olur. Aktarılan evrişimi kullanmazsan, amazon gpus için çok daha fazla öderdin.

Buradaki animasyonları dikkatlice okuyun ve izleyin: http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html#no-zero-padding-unit-strides-transposed

İlgili diğer bazı okumalar:

Bir filtrenin transpozisyonu (veya daha genel olarak Hermitiyen veya konjugat transpozisyonu) basitçe eşleşen filtredir [3]. Bu, çekirdeği tersine çevirerek ve tüm değerlerin konjugatını alarak bulunur [2].

Ben de bu konuda yeniyim ve herhangi bir geri bildirim veya düzeltme için minnettar olurum.

[1] http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html

[2] http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html#transposed-convolution-arithmetic

[3] https://en.wikipedia.org/wiki/Matched_filter


1
Nit toplama, ancak bağlantı şu şekilde olmalıdır: deeplearning.net/software/theano_versions/dev/tutorial/…
Herbert

1
Bence bu en iyi cevap !!!
kli_nlpr

10

Analoji için PCA kullanabiliriz.

Conv kullanılırken, ileriye doğru geçiş ana bileşen bileşenlerinin katsayılarını girdi görüntüsünden çıkarmaktır ve geriye doğru geçiş (girdiyi güncelleyen) yeni bir girdi görüntüsünü yeniden oluşturmak için katsayıları kullanmak (gradyanını) kullanmaktır. Yeni giriş görüntüsünde istenen katsayılarla daha iyi eşleşen PC katsayıları bulunur.

Dekonv kullanılırken, ileri geçiş ve geri geçiş tersine çevrilir. İleri geçiş PC katsayılarından bir görüntüyü yeniden oluşturmaya çalışır ve geri geçiş görüntüye verilen PC katsayılarını (gradyanı) günceller.

Deconv iletme geçişi tam olarak bu yazıda verilen konveksiyon gradyan hesaplamasını yapar: http://andrew.gibiansky.com/blog/machine-learning/convolutional-neural-networks/

Bu nedenle deconv'un caffe uygulamasında (Andrei Pokrovsky'nin cevabına bakınız), deconv ileri geçişi backward_cpu_gemm () 'i ve geri geçiş geçişi forward_cpu_gemm ()' i çağırır.


6

David Dao'nun cevabına ek olarak: Etrafında başka şekilde düşünmek de mümkündür. Tek bir çıktı pikseli üretmek için hangi (düşük çözünürlüklü) giriş piksellerine odaklanmak yerine, ayrı ayrı girdi piksellerinin hangi çıktı piksellerinin bulunduğu bölgeye katkıda bulunduğuna da odaklanabilirsiniz.

Bu, bir dizi çok sezgisel ve etkileşimli görselleştirme de dahil olmak üzere bu distile yayınında yapılır . Bu yönde düşünmenin bir avantajı, dama tahtası yapılarını açıklamanın kolay hale gelmesidir.


5

DSP perspektifinden konvolüsyonlar

Buna biraz geç kaldım ama yine de bakış açımı ve görüşlerimi paylaşmak istiyorum. Geçmişim teorik fizik ve dijital sinyal işleme. Özellikle dalgacık okudum ve konvolüsyonlar neredeyse omurgamda;)

Derin öğrenme topluluğundaki insanların toplantılar hakkında konuşma şekilleri de kafa karıştırıcıydı. Benim bakış açıma göre eksik görünen şey kaygıların uygun bir şekilde ayrılmasıdır. Bazı DSP araçlarını kullanarak derin öğrenme toplantılarını açıklayacağım.

feragat

Açıklamalarım ana noktaları aşmak için biraz el dalgalı ve matematiksel titiz değil.


Tanımlar

xn={xn}n=={,x1,x0,x1,}

ynxn

(yx)n=k=ynkxk

q=(q0,q1,q2)x=(x0,x1,x2,x3)T

qx=(q1q000q2q1q000q2q1q000q2q1)(x0x1x2x3)

kN

kxn=xnk

kk1

kxn={xn/kn/kZ0otherwise

k=3

3{,x0,x1,x2,x3,x4,x5,x6,}={,x0,x3,x6,}
3{,x0,x1,x2,}={x0,0,0,x1,0,0,x2,0,0,}

k=2

2x=(x0x2)=(10000010)(x0x1x2x3)

ve

2x=(x00x10)=(10000100)(x0x1)

k=kT


Parçalarla Derin Öğrenme Konvolüsyonları

qx

  • kk(qx)
  • k(kq)x
  • kq(kx)

q(kx)=q(kTx)=(k(q)T)Tx

(q)q

q(kx)=(q1q000q2q1q000q2q1q000q2q1)(10000100)(x0x1)=(q1q200q0q1q200q0q1q200q0q1)T(10000010)T(x0x1)=((10000010)(q1q200q0q1q200q0q1q200q0q1))T(x0x1)=(k(q)T)Tx

Görüldüğü gibi devredilen işlem, dolayısıyla adıdır.

En Yakın Komşu Örneklemesine Bağlantı

Evrişimli ağlarda bulunan diğer bir yaygın yaklaşım, bazı yerleşik enterpolasyon formları ile örneklemektir. Basit bir tekrar enterpolasyonu ile faktör 2 ile örneklemeyi ele alalım. Bu, olarak yazılabilir.2(11)xq2(11)qxq=(q0q1q2)

(11)q=(q0q0+q1q1+q2q2),

yani, faktör 2 ile tekrarlanan bir üst örnekleyiciyi ve çekirdek büyüklüğü 4 ile devredilen bir evrişim ile 3 boyutunda bir çekirdeği olan bir evrişimi değiştirebiliriz.


Sonuçlar ve Son Açıklamalar

İnşallah derin öğrenmede bulunan bazı ortak sarsıntıları, temel işlemlerde bir araya getirerek biraz netleştirebilirim.

Burada havuzlamayı örtmedim. Ancak bu sadece doğrusal olmayan bir aşağı örnekleyicidir ve bu gösterim dahilinde de tedavi edilebilir.


Mükemmel cevap Matematiksel / sembolik bir bakış açısı almak çoğu zaman netleşir. Bu bağlamda "dekonvolüsyon" teriminin mevcut terminoloji ile çakıştığını düşünmekte yanlış mıyım ?
user76284

Gerçekten çatışmaz, sadece bir anlamı olmaz. Dekonvolüsyon sadece örnek operatörü ile bir evrişim. Dekonvolüsyon terimi bir ters işlem şekli gibi gözüküyor. Burada bir tersten bahsetmek yalnızca matris işlemleri bağlamında anlamlıdır. Konvolüsyonun ters işlemiyle değil, ters matrisle çarparak (çarpma vs çarpma gibi).
André Bergner

zθx=zzθz=x

θz=xz=(θ)+x

Kısacası OP'nin “dekonvolüsyon tabakası” aslında dekonvolüsyon yapmıyor. Başka bir şey yapıyor (cevabında ne tarif ettiğin).
user76284

4

Bu blog yazısı ile karşılaşana kadar gazetede tam olarak ne olduğunu anlama konusunda çok sorun yaşadım: http://warmspringwinds.github.io/tensorflow/tf-slim/2016/11/22/upsampling-and-image-segmentation -ile-tensorflow-ve-tf-ince /

2x örneklemede neler olup bittiğini nasıl anladığımın bir özeti:

Kağıttan Bilgi

Basit bir örnek

  1. aşağıdaki giriş görüntüsünü hayal edin:

Giriş görüntü

  1. Kesirli olarak düzenlenmiş konvolüsyonlar, bu değerler arasına faktör-1 = 2-1 = 1 sıfır ekleyerek ve ardından adım = 1 olduğunu varsayarak çalışır. Böylece, aşağıdaki 6x6 yastıklı görüntüyü alırsınız

yastıklı görüntü

  1. Bilinear 4x4 filtresi buna benzer. Değerleri, kullanılan ağırlıklar (= eklenen sıfır ile çarpılmayan tüm ağırlıklar) 1'e kadar olacak şekilde seçilir. Üç benzersiz değeri 0,56, 0,19 ve 0,06'dır. Ayrıca, filtrenin merkezi, konvansiyon başına üçüncü sıradaki ve üçüncü sütundaki pikseldir.

filtre

  1. Dolgulu görüntüye 4x4 filtresi uygulamak (dolgulu = 'same' ve stride = 1 kullanarak) aşağıdaki 6x6 örneklenmiş görüntüyü verir:

Yükseltilmiş resim

  1. Bu tür yukarı örnekleme her kanal için ayrı ayrı gerçekleştirilir (bkz. Https://github.com/shelhamer/fcn.berkeleyvision.org/blob/master/surgery.py . Sonunda, 2x örneklemesi sınırların nasıl ele alınacağına dair bilinear enterpolasyon ve sözleşmeler kullanılarak gerçekten çok basit bir yeniden boyutlandırma. 16x veya 32x örneklemenin aynı şekilde çalıştığını düşünüyorum.

Licensed under cc by-sa 3.0 with attribution required.