Apakah pooling layer ditambahkan sebelum atau sesudah dropout layer?

35

Saya membuat jaringan saraf convolutional (CNN), di mana saya memiliki lapisan convolutional diikuti oleh lapisan penyatuan dan saya ingin menerapkan dropout untuk mengurangi overfitting. Saya memiliki perasaan bahwa lapisan dropout harus diterapkan setelah lapisan penggabungan, tetapi saya tidak benar-benar memiliki apa pun untuk mendukungnya. Di mana tempat yang tepat untuk menambahkan lapisan putus sekolah? Sebelum atau sesudah lapisan pengumpulan?

pir
sumber

Jawaban:

18

Sunting: Seperti yang ditunjukkan oleh @Toke Faurby, implementasi default di tensorflow sebenarnya menggunakan dropout elemen-bijaksana. Apa yang saya jelaskan sebelumnya berlaku untuk varian khusus dropout di CNN, yang disebut dropout spasial :

Dalam CNN, setiap neuron menghasilkan satu peta fitur. Karena dropout spasial dropout bekerja per-neuron, menjatuhkan neuron berarti bahwa peta fitur yang sesuai dijatuhkan - misalnya setiap posisi memiliki nilai yang sama (biasanya 0). Jadi masing-masing peta fitur dijatuhkan sepenuhnya atau tidak dijatuhkan sama sekali.

Pooling biasanya beroperasi secara terpisah pada setiap peta fitur, jadi seharusnya tidak ada bedanya jika Anda menerapkan dropout sebelum atau sesudah pooling. Setidaknya ini adalah kasus untuk operasi pengumpulan seperti maxpooling atau rata-rata.

Sunting: Namun, jika Anda benar-benar menggunakan dropout elemen-bijaksana (yang tampaknya ditetapkan sebagai default untuk tensorflow), itu sebenarnya membuat perbedaan jika Anda menerapkan dropout sebelum atau setelah pengumpulan. Namun, tidak selalu ada cara yang salah untuk melakukannya. Pertimbangkan operasi pengumpulan rata-rata: jika Anda menerapkan dropout sebelum pengumpulan, Anda secara efektif mengukur aktivasi neuron yang dihasilkan 1.0 - dropout_probability, tetapi sebagian besar neuron akan menjadi nol (secara umum). Jika Anda menerapkan dropout setelah pooling rata-rata, Anda biasanya berakhir dengan sebagian kecil (1.0 - dropout_probability)aktivasi neuron "non-nol" dan sebagian kecil dari dropout_probabilityneuron nol. Keduanya tampak masuk akal bagi saya, tidak ada yang salah.

schreon
sumber
1
Saya tidak yakin ini adalah cara standar untuk melakukan dropout. Misalnya dalam tf.nn.dropout itu menyatakan "Secara default, setiap elemen disimpan atau dihapus secara independen". Apakah Anda memiliki sumber yang mendukung ini?
Toke Faurby
1
Oh! Apa yang saya jelaskan sekarang disebut dropout spasial : arxiv.org/pdf/1411.4280.pdf . Jadi @TokeFaurby benar meragukan klaim saya. Namun, karena Anda juga dapat membaca di kertas yang tertaut, menjatuhkan seluruh peta fitur dengan cara dropout spasial meningkatkan kinerja. Ini tidak mengherankan, karena aktivasi yang berdekatan sangat berkorelasi dan mengeluarkan satu elemen spesifik sebenarnya tidak menjatuhkan informasi yang dibawa oleh elemen itu sama sekali (karena sangat tidak mungkin untuk menjatuhkan "lubang" terus menerus dalam peta fitur ketika melakukannya. elemen-bijaksana). Saya akan mengedit jawaban saya untuk mencerminkan perbedaan ini.
schreon
10

Tutorial ini menggunakan pengumpulan sebelum putus dan mendapatkan hasil yang baik.

Itu tidak selalu berarti bahwa tatanan lainnya tidak berfungsi tentu saja. Pengalaman saya terbatas, saya hanya menggunakannya pada lapisan padat tanpa penyatuan.

Menandai
sumber
5

Contoh convnet seperti VGG dari Keras (dropout digunakan setelah pengumpulan):

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)
mrgloom
sumber