Вектор обучаемых параметров для пользовательской функции активации - PullRequest
2 голосов
/ 07 мая 2019

Я новичок в Keras и пытаюсь провести несколько экспериментов с пользовательской функцией активации, имеющей обучаемый параметр. Я создал код ниже, который по сути является разновидностью функции активации ReLU. В настоящее время он вычисляет alpha*h1 + (1 - alpha)*h2, где h1 = relu(x) и h2 = relu(-x), в надежде помочь с мертвыми нейронами, которые может создать обычная функция ReLU. Мне было интересно, если бы вместо того, чтобы иметь только один обучаемый параметр alpha, можно ли было бы изменить этот код, чтобы получить вектор обучаемых параметров, чтобы проверить эту идею дальше. Любые предложения или помощь будут с благодарностью.

class CustomLayer(Layer):
  def __init__(self, alpha, **kwargs):
    self.alpha = alpha
    super(CustomLayer, self).__init__(**kwargs)

  def build(self, input_shape):
    self.kernel = self.add_weight(name='kernel', 
                                  shape=(input_shape[1], self.alpha),
                                  initializer='uniform',
                                  trainable=True)
    super(CustomLayer, self).build(input_shape)

  def call(self,x):
    h1 = K.relu(x)
    h2 = K.relu(-x)
    return self.kernal*h1 + (1 - self.kernal)*h2

  def compute_output_shape(self, input_shape):
    return (input_shape[0], self.alpha)

1 Ответ

0 голосов
/ 07 мая 2019

Пара вещей:

  • В настоящее время вы устанавливаете форму вывода вашей сети с помощью alpha, что почти наверняка не правильно.
  • Вы можете определить ядро ​​для вашего слоя, которое будет иметь любой размер, который имеет смысл для того, что вы пытаетесь сделать. Здесь вы хотите создать обучаемые параметры для вашей функции активации.
  • Поскольку это функция активации, вы, вероятно, хотите, чтобы выходные данные имели ту же форму, что и входные.

Попробуйте что-то вроде:

from keras import backend as K

class CustomLayer(Layer):
    # You actually don't need to redefine __init__ since we don't need to
    # pass any custom parameters. I'm leaving it here to show that it changed
    # from your example.
    def __init__(self, **kwargs):
        super(CustomLayer, self).__init__(**kwargs)

    def build(self, input_shape):
        self.kernel = self.add_weight(name='kernel', 
                                      shape=(input_shape[1], 1),
                                      initializer='uniform',
                                      trainable=True)
        super(CustomLayer, self).build(input_shape)

    def call(self, x):
        h1 = K.relu(x)
        h2 = K.relu(-x)
        return h1*self.kernal + h2*(1 - self.kernel)

    def compute_output_shape(self, input_shape):
        return input_shape

Я предполагаю, что вам нужен отдельный параметр alpha для каждого объекта в вашем входном векторе, который я создаю в методе build(). Я также предполагаю, что input_shape = [batch_size, num_features] или что-то подобное. Метод call() выполняет поэлементное умножение между вашими h1 и h2 и ядром, складывая две половинки вместе. По сути, одинаковая функция стоимости с уникальным alpha для каждой функции.

Для этого может потребоваться небольшая отладка, поскольку у меня нет примера для его запуска.

Вот ссылка на документацию по написанию ваших собственных слоев , которая, кажется, у вас уже есть, но я привожу здесь для полноты.

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