Перейти к содержанию

Написание собственных слоев Керас

Написание собственных Keras слоев

Для простых, не требующих вмешательства пользовательских операций, вероятно, лучше использовать слои layers.core.Lambda. Но для любой пользовательской операции, которая имеет обучаемые веса, вы должны реализовать свой собственный слой.

Вот скелет слоя Keras, начиная с Keras 2.0 (если у вас есть более старая версия, пожалуйста, обновите ее). Есть только три метода, которые вам нужно реализовать:

  • build(input_shape): здесь вы определите свои веса. Этот метод должен установить в конце значение параметра self.build = True, что можно сделать с помощью вызова super([Layer], self).build().
  • call(x): здесь живет логика слоя. Если вы не хотите, чтобы ваш слой поддерживал маскировку, вам нужно заботиться только о первом аргументе, переданном на вызов: входном тензоре.
  • compute_output_shape(input_shape): в случае, если слой изменяет форму вывода, то здесь необходимо указать логику преобразования фигуры. Это позволяет Keras сделать автоматический вывод о форме.

from keras import backend as Kfrom keras.layers import Layer

class MyLayer(Layer):

    def __init__(self, output_dim, **kwargs):

        self.output_dim = output_dim

        super(MyLayer, self).__init__(**kwargs)

    def build(self, input_shape):

        # Создать обучаемую переменную веса для этого слоя.

        self.kernel = self.add_weight(name=’kernel’, 

                                      shape=(input_shape[1], self.output_dim),

                                      initializer=’uniform’,

                                      trainable=True)

        super(MyLayer, self).build(input_shape)  # Обязательно вызовите это в конце

    def call(self, x):

        return K.dot(x, self.kernel)

    def compute_output_shape(self, input_shape):

        return (input_shape[0], self.output_dim)

Также можно определить слои Keras, которые имеют несколько тензоров на входе и несколько тензоров на выходе. Для этого следует предположить, что входы и выходы методов build(input_shape), call(x) и compute_output_shape(input_shape) — это списки. Приведем пример, аналогичный приведенному выше:

from keras import backend as Kfrom keras.layers import Layer

class MyLayer(Layer):

    def __init__(self, output_dim, **kwargs):

        self.output_dim = output_dim

        super(MyLayer, self).__init__(**kwargs)

    def build(self, input_shape):

        assert isinstance(input_shape, list)

        # Создать обучаемую переменную веса для этого слоя.

        self.kernel = self.add_weight(name=’kernel’,

                                      shape=(input_shape[0][1], self.output_dim),

                                      initializer=’uniform’,

                                      trainable=True)

        super(MyLayer, self).build(input_shape)  # Обязательно назовите это в конце

    def call(self, x):

        assert isinstance(x, list)

        a, b = x

        return [K.dot(a, self.kernel) + b, K.mean(b, axis=-1)]

    def compute_output_shape(self, input_shape):

        assert isinstance(input_shape, list)

        shape_a, shape_b = input_shape

        return [(shape_a[0], self.output_dim), shape_b[:-1]]

Существующие слои Keras дают примеры того, как реализовать практически все. Никогда не стесняйтесь читать исходные тексты!

Next  Previous