Чи додаються шари об'єднання до або після шарів, що випадають?


35

Я створюю конволюційну нейронну мережу (CNN), де у мене є згортковий шар, за яким слідує шар об'єднання, і я хочу застосувати випадання для зменшення перевитрати. У мене таке відчуття, що шар, що випадає, слід наносити після об'єднання шару, але я насправді не маю нічого, що би це створити. Де є правильне місце для додавання випадаючого шару? До або після об'єднання шару?

Відповіді:


18

Редагувати: Як правильно зазначав @Toke Faurby, реалізація за замовчуванням у tensorflow насправді використовує відмінні елементи. Те, що я описав раніше, стосується конкретного варіанту відміни в CNN, званого просторовим відмовою :

У CNN кожен нейрон виробляє одну карту ознак. Оскільки вибування просторових вибування робіт на-нейрон, скинувши нейронні означає , що відповідна функція карта видаляється - наприклад , кожна позиція має те ж значення (зазвичай 0). Таким чином, кожна карта функцій або повністю скидається, або взагалі не скидається.

Об’єднання зазвичай працює окремо на кожній карті функцій, тому воно не повинно мати жодних змін, якщо ви застосовуєте випадання до або після об'єднання. Принаймні, це стосується об'єднань таких операцій, як макпулінг або усереднення.

Редагувати: Однак якщо ви фактично використовуєте стимуляцію відхилення від елементів (яка, здається, встановлена ​​за замовчуванням для tensorflow), це насправді має значення, якщо застосувати відмову до або після об'єднання. Однак, це не обов'язково неправильний спосіб зробити це. Розглянемо середню операцію об'єднання: якщо застосувати випадання перед об'єднанням, ви ефективно масштабуєте активацію нейронів за допомогою 1.0 - dropout_probability, але більшість нейронів будуть не нульовими (загалом). Якщо ви застосуєте випадання після середнього об'єднання, то, як правило, ви отримаєте частку (1.0 - dropout_probability)ненульових "немасштабних" нейронних активацій та частку dropout_probabilityнульових нейронів. Обидва мені здаються життєздатними, і явно не є помилкою.


1
Я не впевнений, що це стандартний спосіб виконання відсіву. Наприклад, у tf.nn.dropout зазначено "За замовчуванням кожен елемент зберігається або випадає незалежно". У вас є джерело, яке це резервне копіювання?
Токе Фаурбі

1
Ой! Те, що я описав, тепер називається просторовим відпадом : arxiv.org/pdf/1411.4280.pdf . Тож @TokeFaurby має рацію сумніватися в моїй заяві. Однак, як ви також можете прочитати у зв'язаному папері, випадання цілих карт функцій у просторовому способі випадання покращує продуктивність. Це не дивно, оскільки суміжні активації сильно співвідносяться, а випадання одного конкретного елемента насправді зовсім не відкидає інформацію, яку несе цей елемент (оскільки це малоймовірно, що випаде суцільна «дірка» у картці функції, виконуючи це елементарно). Я відредагую свою відповідь, щоб відобразити цю різницю.
schreon

10

Цей підручник використовує об'єднання перед випаданням та отримує хороші результати.

Це не обов'язково означає, що інше замовлення не працює, звичайно. Мій досвід обмежений, я використовував їх лише на щільних шарах без об'єднання.


5

Приклад VGG-подібного convnet від Keras (відсік, який використовується після об'єднання):

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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.