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

Я хочу реализовать классификатор с разреженным входным слоем.Мои данные имеют около 60 измерений, и я хочу проверить их важность.Для этого я хочу, чтобы первый слой имел диагональную матрицу весов (к которой я хочу применить регуляризатор ядра L1), все диагонали должны быть не обучаемыми нулями.Таким образом, соединение один к одному на входной канал, плотный слой будет смешивать входные переменные.Я проверил Укажите соединения в NN (в керасах) и Пользовательские соединения между слоями Керас .Последний, который я не мог использовать, поскольку лямбда-слои не вводят обучаемые веса.

Что-то подобное, однако, не влияет на матрицу фактического веса:

class MyLayer(Layer):
def __init__(self, output_dim,connection, **kwargs):
    self.output_dim = output_dim
    self.connection=connection
    super(MyLayer, self).__init__(**kwargs)

def build(self, input_shape):
    # Create a trainable weight variable for this layer.
    self.kernel = self.add_weight(name='kernel', 
                                  shape=(input_shape[1], self.output_dim),
                                  initializer='uniform',
                                  trainable=True)
    self.kernel=tf.linalg.tensor_diag_part(self.kernel)
    self.kernel=tf.linalg.tensor_diag(self.kernel)
    super(MyLayer, self).build(input_shape)  # Be sure to call this at the end

def call(self, x):
    return K.dot(x, self.kernel)

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

Когда я тренирую модель и печатаювеса, я не получаю диагональную матрицу для первого слоя.

Что я делаю не так?

1 Ответ

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

Не совсем уверен, что именно вы хотите сделать, потому что для меня diagonal - это что-то для квадратной матрицы, подразумевая, что размерность входных и выходных данных вашего слоя должна быть неизменной.

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

Метод 1: только концептуально следуйте идее квадратной матрицы и реализуйте этот слой с обучаемым вектором веса следующим образом.

# instead of writing y = K.dot(x,W), 
# where W is the weight NxN matrix with zero values of the diagonal.
# write y = x * w, where w is the weight vector 1xN

Метод 2: используйте слой по умолчанию Dense, нос вашим собственным ограничением .

# all you need to create a mask matrix M, which is a NxN identity matrix
# and you can write a contraint like below
class DiagonalWeight(Constraint):
    """Constrains the weights to be diagonal.
    """
    def __call__(self, w):
        N = K.int_shape(w)[-1]
        m = K.eye(N)
        w *= m
        return w

Конечно, вы должны использовать Dense( ..., kernel_constraint=DiagonalWeight()).

...