Нормализовать вывод без Softmax - PullRequest
0 голосов
/ 18 мая 2018

Обучение с выходным слоем softmax для моей генеративной нейронной сети дает лучшие результаты, чем с relu в целом, но relu дает мне разреженность, которая мне нужна (нули в пикселях).Softmax также помогает получить нормализованный вывод (то есть сумма = 1.).

Я хочу сделать:

outputs = Dense(200, activation='softmax', activity_regularizer=l1(1e-5))(x)
outputs = Activation('relu')(outputs) # to get real zeros
outputs = Activation('softmax')(outputs) # still real zeros, normalized output

Но, применяя последующий softmax, я получу экстремальные выходы.Есть ли слой, который я могу использовать вместо этого, который просто нормализует вывод до 1 (output_i / sum (output)) вместо softmax?

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

Вам не нужно добавлять два softmax.Хорошо только последний:

outputs = Dense(200, activation='relu', activity_regularizer=l1(1e-5))(x)
outputs = Activation('softmax')(outputs) # still real zeros, normalized 

Тем не менее, если у вас больше промежуточных слоев и вы хотите, чтобы они вели себя более умеренно, вы можете использовать «tanh» вместо softmax.

Часто проблема с relu-моделями не совсем в том, что «они не суммируют 1», а просто в том, что «их значения слишком высоки, градиенты не могут вести себя хорошо».

#this combines a max output of 1 (but doesn't care about the sum)
#yet keeping the sparsity:
outputs = Dense(200, activation='tanh')(x)
outputs = Activation('relu')(outputs) # to get real zeros

outputs = Dense(200, activation='relu')(outputs)

#this should only be used at the final layer
#and only if you really have a classification model with only one correct class
outputs = Activation('softmax')(outputs) # still real zeros, normalized output

Softmax склоняется в пользу только одного из результатов.Если вы не хотите менять сравнение результатов между собой, но хотите получить sum=1, вы можете обратиться к ответу @ nuric.

0 голосов
/ 18 мая 2018

Вы можете написать свой собственный слой для преобразования выходных данных в единичную норму (т.е. нормализовать в вашем случае) без применения softmax.Вы можете достичь путем преобразования выходных данных в единичный вектор.Что-то вроде:

def unitnorm(x):
  return x / (K.epsilon() + K.sqrt(K.sum(K.square(x), keepdims=True)))
# Wrap Lambda layer
outputs = Lambda(unitnorm, name='unitnorm')(outputs)

Код взят из единичного нормативного ограничения , которое делает то же самое для ядер и смещения в слоях.Вы можете попробовать без эпсилона, чтобы быть более точным, но может быть менее стабильным, когда у вас много нулей.

...