R- Custom Keras Layer с ограничениями по весу - PullRequest
0 голосов
/ 18 февраля 2020

Я пытаюсь написать собственный слой Keras с обучаемыми весами в R, который:

  • Принимает входной вектор x и возвращает значение exp(A * X*A), где $ A $ является диагональным и обучаемым. .

Где exp - матричная экспоненциальная карта.

1 Ответ

1 голос
/ 04 марта 2020

Обратите внимание, что очень важно, чтобы вы понимали, где находится ваш размер пакета, и что слой НЕ МОЖЕТ иметь веса с размерами, основанными на размере пакета (если вы не определите свои входные данные с помощью batch_shape или batch_input_shape вместо shape - это заставит вас использовать фиксированный размер партии в модели). Поскольку размер партии обычно для «отдельных» и «независимых» выборок, нецелесообразно использовать размер партии в операциях и смешивании образцов!

Тем не менее, я предполагаю, что X здесь имеет форму (batch, dim, dim), и что A будет иметь форму (dim, dim), следовательно.

Для этого вы создаете пользовательский слой, например здесь: https://tensorflow.rstudio.com/guide/keras/custom_layers/

Где build будет иметь kernel (A) с формой (1, dim, 1) -

    build = function(input_shape) {
      self$kernel <- self$add_weight(
        name = 'kernel', 
        shape = list(1,input_shape[[2]], 1),
        initializer = initializer_random_normal(), #you may choose different initializers
        trainable = TRUE
      )
    },

И call будет использовать математический трюк для имитации диагонали.

Обратите внимание, что если диагональ A, то результат A x X x A будет B*X (поэлементно), где B:

#supposing A has the elements [a, b, c, ...] in the diagonals,

B is:
[ [aa, ab, ac, ...],
  [ab, bb, bc, ...],
  [ac, bc, cc, ...],
  ...
]

Из-за этого мы не будет использовать диагонали, но трюк вещания с поэлементным умножением:

    call = function(x, mask = NULL) {
      kernelTransposed <- tf$reshape(self$kernel, shape(1L, 1L, -1L)) #(1, 1, dim)
      B <- self$kernel * kernelTransposed #(1, dim, dim)
      tf$math$exp(x * B)
    },

Форма вывода остается неизменной:

    compute_output_shape = function(input_shape) {
      input_shape
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...