Использование функции активации сигмоида для мультиклассового прогнозирования - PullRequest
0 голосов
/ 31 декабря 2018

Я использую U-сеть, как указано ниже:

inputs = Input((IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS))
s = Lambda(lambda x: x / 255) (inputs)

c1 = Conv2D(8, (3, 3), activation='relu', padding='same') (s)
c1 = Conv2D(8, (3, 3), activation='relu', padding='same') (c1)
p1 = MaxPooling2D((2, 2)) (c1)

c2 = Conv2D(16, (3, 3), activation='relu', padding='same') (p1)
c2 = Conv2D(16, (3, 3), activation='relu', padding='same') (c2)
p2 = MaxPooling2D((2, 2)) (c2)

c3 = Conv2D(32, (3, 3), activation='relu', padding='same') (p2)
c3 = Conv2D(32, (3, 3), activation='relu', padding='same') (c3)
p3 = MaxPooling2D((2, 2)) (c3)

c4 = Conv2D(64, (3, 3), activation='relu', padding='same') (p3)
c4 = Conv2D(64, (3, 3), activation='relu', padding='same') (c4)
p4 = MaxPooling2D(pool_size=(2, 2)) (c4)

c5 = Conv2D(128, (3, 3), activation='relu', padding='same') (p4)
c5 = Conv2D(128, (3, 3), activation='relu', padding='same') (c5)

u6 = Conv2DTranspose(64, (2, 2), strides=(2, 2), padding='same') (c5)
u6 = concatenate([u6, c4])
c6 = Conv2D(64, (3, 3), activation='relu', padding='same') (u6)
c6 = Conv2D(64, (3, 3), activation='relu', padding='same') (c6)

u7 = Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same') (c6)
u7 = concatenate([u7, c3])
c7 = Conv2D(32, (3, 3), activation='relu', padding='same') (u7)
c7 = Conv2D(32, (3, 3), activation='relu', padding='same') (c7)

u8 = Conv2DTranspose(16, (2, 2), strides=(2, 2), padding='same') (c7)
u8 = concatenate([u8, c2])
c8 = Conv2D(16, (3, 3), activation='relu', padding='same') (u8)
c8 = Conv2D(16, (3, 3), activation='relu', padding='same') (c8)

u9 = Conv2DTranspose(8, (2, 2), strides=(2, 2), padding='same') (c8)
u9 = concatenate([u9, c1], axis=3)
c9 = Conv2D(8, (3, 3), activation='relu', padding='same') (u9)
c9 = Conv2D(8, (3, 3), activation='relu', padding='same') (c9)

outputs = Conv2D(10, (1, 1), activation='sigmoid') (c9)

model = Model(inputs=[inputs], outputs=[outputs])

model.compile(optimizer='Adamax', loss = dice, metrics = [mIoU])

Обратите внимание, что я делаю предсказание с несколькими классами для десяти классов.И входные данные - 256x256x3 (rgb) изображения, а истинные значения - это двоичные маски размером 256x256x10, начиная с depth=num_classes=10.У меня вопрос, я случайно забыл изменить функцию активации с sigmoid на softmax и запустил сеть.Сеть все еще работала.Как это возможно??Это потому, что он обрабатывает каждую двоичную маску независимо?

Более интригующе, сеть фактически дала лучшие результаты при использовании sigmoid, а не когда я запускал ее с softmax.

1 Ответ

0 голосов
/ 31 декабря 2018

Q1: Why my network is still trainable with a *wrong* loss function?

A1: потому что ваша сеть оптимизирована с точки зрения градиентного спуска, которая не заботится о том, какая функция потерь используется, пока она дифференцируема.Этот факт показывает трудность отладки сети, когда она не работает, потому что это не ошибка кода (например, вызывающая утечку памяти, числовое переполнение и т. Д.), Но некоторые ошибки не являются научно обоснованными (например, ваша цель регрессии имеетдиапазон (0,100), но вы используете sigmoid в качестве функции активации последнего плотного слоя).

Q2: How come `sigmoid` gives better performance than `softmax`?

A2: Во-первых, использование функции потерь sigmoid означает обучение 10 двоичных классификаторов, одиндля каждого класса (т. е. классический вариант «все против всех» или «один против остальных»), и, таким образом, он также технически исправен

Единственная разница между sigmoid и softmax заключается в том, что сумма прогнозируемой вероятности для класса всегда равна 1 для сети softmax, хотя необязательно может быть 1 для sigmoidсеть.Другими словами, у вас могут возникнуть трудности с выбором метки во время тестирования сети sigmoid.

Относительно того, почему sigmoid лучше, чем softmax, он связан со многими аспектами и его трудно анализировать без тщательного изучения.Одно из возможных объяснений состоит в том, что sigmoid обрабатывает строки в матрице весов последнего плотного слоя независимо, тогда как softmax обрабатывает их зависимо.Поэтому sigmoid может лучше обрабатывать эти выборки с противоречивыми направлениями градиента.Другая мысль заключается в том, что, возможно, вам стоит попробовать недавний нагретый softmax .

Наконец, если вы считаете, что версия sigmoid дает вам лучшую производительность, но вам все еще нужна сеть softmax,Вы можете повторно использовать все слои до последнего плотного слоя в сети sigmoid и настроить новый слой softmax или использовать оба убытка так же, как в многозадачной задаче.

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