Разница между «выпадением», «выпадением Монте-Карло», «выпадением по каналу» - PullRequest
2 голосов
/ 29 апреля 2019

Я сталкивался с вышеупомянутыми терминами, и я не уверен в разнице между ними.

Насколько я понимаю, MC Dropout - это обычный Dropout, который также активен во время тестирования, что позволяет получить оценку для моделинеопределенность на нескольких тестовых прогонах.Что касается выпадения по каналам, я ничего не понимаю.

Бонус : Какой простой способ реализовать выпадение MC Dropout и переключение по каналам в Keras?

1 Ответ

5 голосов
/ 29 апреля 2019

Вы правы, что MC Dropout применяется и во время вывода, в отличие от обычного ухода. Если вы воспользуетесь Google, вы можете легко найти много информации об обоих.

Что касается отсева каналов, я понимаю, что вместо отбрасывания определенных нейронов он отбрасывает все каналы.

Теперь реализация в Keras (я собираюсь использовать tf.keras).

MC Выпадение

Как обычно Keras, вы определяете пользовательский слой, который применяет отсев вне зависимости от того, тренируется он или тестирует, поэтому мы можем просто использовать tf.nn.dropout() с постоянной скоростью отсева:

import tensorflow as tf

class MCDropout(tf.keras.layers.Layer):
    def __init__(self, rate):
        super(MCDropout, self).__init__()
        self.rate = rate

    def call(self, inputs):
        return tf.nn.dropout(inputs, rate=self.rate)

Пример использования:

import tensorflow as tf
import numpy as np

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Conv2D(filters=6, kernel_size=3))
model.add(MCDropout(rate=0.5))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(2))
model.compile(optimizer=tf.keras.optimizers.SGD(0.001),
              loss='binary_crossentropy',
              metrics=['accuracy'])

# generate dummy data for illustration
x_train = np.random.normal(size=(10, 4, 4, 3))
x_train = np.vstack([x_train, 2*np.random.normal(size=(10, 4, 4, 3))])
y_train = [[1, 0] for _ in range(10)] + [[0, 1] for _ in range(10)]
y_train = np.array(y_train)

model.fit(x_train,
          y_train,
          epochs=2,
          batch_size=10,
          validation_data=(x_train, y_train))

Выпадение по каналу

Здесь вы можете использовать ту же функцию tf.nn.dropout(), однако вам необходимо указать форму шума. Документация из tf.nn.dropout() дает точный пример того, как добиться пропущенных каналов:

shape (x) = [k, l, m, n] и noise_shape = [k, 1, 1, n], каждый пакет и компонент канала будут сохраняться независимо, а каждая строка и столбец будут сохраняться или не сохраняться вместе.

Это то, что мы собираемся сделать в методе call():

class ChannelWiseDropout(tf.keras.layers.Layer):
    def __init__(self, rate):
        super(ChannelWiseDropout, self).__init__()
        self.rate = rate

    def call(self, inputs):
        shape = tf.keras.backend.shape(inputs)
        noise_shape = (shape[0], 1, 1, shape[-1])
        return tf.nn.dropout(inputs,
                             rate=self.rate,
                             noise_shape=noise_shape)

Применение к какому-то примеру:

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.InputLayer(input_shape=(4, 4, 3)))
model.add(tf.keras.layers.Conv2D(filters=3, kernel_size=3))
model.add(ChannelWiseDropout(rate=0.5))

x_train = np.random.normal(size=(1, 4, 4, 3))

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    res = sess.run(model.output, feed_dict={model.inputs[0]:x_train})
    print(res[:, :, :, 0])
    print(res[:, :, :, 1])
    print(res[:, :, :, 2])
# [[[2.5495746  1.3060737 ]
#   [0.47009617 1.0427766 ]]]
# [[[-0.  0.]
#   [-0. -0.]]]                <-- second and third channels were dropped
# [[[-0. -0.]
#   [-0. -0.]]]

Примечание

Я использую tf.__version__ == '1.13.1'. В старых версиях tf вместо аргумента rate используется keep_prob = 1 - rate.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...