Havuzlama katmanları, bırakma katmanlarından önce veya sonra ekleniyor mu?


35

Konvolüsyonel bir sinir ağı (CNN) oluşturuyorum, burada bir konvolüsyon katmanım var, bunu bir havuz katmanı izlerim ve fazla uydurmayı azaltmak için bırakma uygulamak istiyorum. Bırakma katmanının havuzlama katmanından sonra uygulanması gerektiğini hissediyorum, ancak bunu destekleyecek hiçbir şeyim yok. Bırakma katmanını eklemek için doğru yer neresidir? Havuzlama katmanından önce mi sonra mı?

Yanıtlar:


18

Düzenleme: @Toke Faurby'nin doğru bir şekilde belirttiği gibi, tensorflow'taki varsayılan uygulama aslında bir eleman şeklinde düşüşü kullanır. Daha önce tarif ettiğim şey, CNN'lerdeki uzamsal bırakma adı verilen belirli bir bırakma varyantı için geçerlidir :

Bir CNN'de her bir nöron bir özellik haritası üretir. Yana bırakma mekansal bırakma örneğin her pozisyon aynı değeri (genellikle 0) sahiptir - gelen özellik haritası düştü ki bir nöron aracı bırakarak başına nöron işler. Böylece her özellik haritası ya tamamen ya da hiç bırakılmaz.

Havuzlama genellikle her bir özellik haritasında ayrı olarak çalışır, bu nedenle havuzlamadan önce veya sonra bırakma uyguladığınızda herhangi bir fark yaratmaması gerekir. En azından bu makspooling veya ortalama alma gibi havuzlama işlemleri için geçerlidir.

Düzenleme: Bununla birlikte, gerçekte element olarak açılan bırakmayı kullanırsanız (bu, tensorflow için varsayılan olarak ayarlanmış gibi görünür), havuzlamadan önce veya sonra bırakmayı uyguladığınızda fark yaratır. Ancak, mutlaka bunu yapmak için yanlış bir yol yoktur. Ortalama havuzlama işlemini göz önünde bulundurun: havuzlamadan önce bırakma uygularsanız, ortaya çıkan nöron aktivasyonlarını etkili bir şekilde ölçeklendirirsiniz 1.0 - dropout_probability, ancak çoğu nöron sıfır (genellikle) olacaktır. Ortalama havuzda bıraktıktan sonra bırakma uygularsanız, genellikle (1.0 - dropout_probability)sıfır olmayan "ölçeklenmemiş" nöron aktivasyonlarının bir kısmını ve dropout_probabilitysıfır nöronların bir kısmını elde edersiniz . Her ikisi de bana uygun görünüyor, ikisi de tamamen yanlış değil.


1
Bunun bırakma işleminin standart yolu olduğundan emin değilim. Örneğin, tf.nn.dropout ifadesinde "Varsayılan olarak her öğe bağımsız olarak tutulur veya düşürülür" ifadesi yer alır. Bunu destekleyen bir kaynağınız var mı?
Toke Faurby

1
Ah! Açıkladığım şeye artık uzamsal bırakma deniyor : arxiv.org/pdf/1411.4280.pdf . @TokeFaurby iddiamdan şüphe duymakta haklı. Bununla birlikte, bağlantılı makalede de okuyabileceğiniz gibi, tüm özellik haritalarını uzamsal bırakma biçiminde bırakmak performansı artırır. Bu komşu aktivasyonları ölçüde birbiriyle bağlantılı olmayan bir özel element aslında bırakma gibi, hiç de şaşırtıcı geliyor damla bunu yaparken bir özellik haritasında sürekli "delik" düşmesi olasılığı çok zayıf olduğu gibi (hepsi o elemanın taşıdığı bilgiyi öğeye). Bu farkı yansıtmak için cevabımı düzenleyeceğim.
schreon

10

Bu eğitici eğitimden ayrılmadan önce havuzlamayı kullanır ve iyi sonuçlar alır.

Bu, diğer emrin elbette işe yaramadığı anlamına gelmez. Tecrübelerim sınırlı, onları sadece yoğun katmanlarda havuzsuz kullandım.


5

Keras'tan VGG benzeri konvnet örneği (havuza çıktıktan sonra bırakma):

import numpy as np
import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.optimizers import SGD

# Generate dummy data
x_train = np.random.random((100, 100, 100, 3))
y_train = keras.utils.to_categorical(np.random.randint(10, size=(100, 1)), num_classes=10)
x_test = np.random.random((20, 100, 100, 3))
y_test = keras.utils.to_categorical(np.random.randint(10, size=(20, 1)), num_classes=10)

model = Sequential()
# input: 100x100 images with 3 channels -> (100, 100, 3) tensors.
# this applies 32 convolution filters of size 3x3 each.
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(100, 100, 3)))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))

sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd)

model.fit(x_train, y_train, batch_size=32, epochs=10)
score = model.evaluate(x_test, y_test, batch_size=32)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.