Как реализовать матричное умножение в Керасе?

Я просто хочу реализовать функцию, которая с учетом матрицы X возвращает матрицу ковариации X (X ^ T * X), ​​которая представляет собой простое умножение матриц.

В Tensorflow это будет просто: tf.matmul (X, tf.transpose (X))

Но я не ожидал, что это кошмар с Керасом. API в Keras, такие как multiply и dot, не соответствуют моему запросу. Я также пробовал разные способы (слой лямбда и смешанные с операциями TF), но все равно не удалось, возникло много ошибок.

Надеюсь, кто-то может помочь. Спасибо.


person Rui Meng    schedule 03.05.2017    source источник


Ответы (3)


На самом деле у вас есть аналог в Керасе. Попробуйте dot(x, transpose(x)).

Ниже приводится рабочий пример сравнения двух платформ.

import keras.backend as K
import numpy as np
import tensorflow as tf


def cov_tf(x_val):
    x = tf.constant(x_val)
    cov = tf.matmul(x, tf.transpose(x))
    return cov.eval(session=tf.Session())

def cov_keras(x_val):
    x = K.constant(x_val)
    cov = K.dot(x, K.transpose(x))
    return cov.eval(session=tf.Session())

if __name__ == '__main__':
    x = np.random.rand(4, 5)
    delta = np.abs(cov_tf(x) - cov_keras(x)).max()
    print('Maximum absolute difference:', delta)

Максимальная абсолютная разница напечатана и дает мне что-то около 1e-7.

person grovina    schedule 21.05.2017
comment
Если цель состоит в том, чтобы выполнить матричный продукт как слой модели, вам не следует использовать бэкэнд. keras.backend просто отсылает операцию к бэкэнд-фреймворку, что вызывает проблемы при сохранении модели. Вместо этого вы должны использовать keras.layers.dot, который специально предназначен для выполнения тензорных произведений в слое модели. keras.io/layers/merge/#dot - person B Custer; 22.02.2020
comment
Привет, @grovina, я новичок в TensorFlow. Мне интересно узнать о настройках бэкэнда выше. Вы явно импортировали TensorFlow. Тогда зачем вам import keras.backend as K одновременно? - person Jie; 08.05.2021
comment
@Jie, обратите внимание, что TF и ​​Keras объединились, поэтому вам не нужно думать о них отдельно. Вероятно, вы могли бы сделать это способом Keras изначально в TF. - person grovina; 09.05.2021

У вас должен быть слой, а внутри слоя производить расчет.

import keras.backend as K
from keras.layers import Lambda
from keras.models import Model

inp = Input((your input shape))
previousLayerOutput = SomeLayerBeforeTheCovariance(blabla)(inp)    

covar = Lambda(lambda x: K.dot(K.transpose(x),x), 
    output_shape = (your known shape of x))(previousLayerOutput)

nextOut = SomeOtherLayerAfterThat(blablabla)(covar)
lastOut = AnotherLayer(bahblanba)(nextOut)

model = Model(inp, lastOut)
person Daniel Möller    schedule 03.05.2017
comment
Спасибо за этот ответ. Все еще терпеть не могу использовать Lambda, но вы абсолютно правы --- ›У вас должен быть слой, чтобы ваш вывод был полезен в модели. - person jsfa11; 23.12.2018
comment
Да, но предложенное вами решение не будет сохранено в файл, т.е. вы не сможете сериализовать модель с помощью keras.Model.save. Хотя keras.Model.save_weights, вероятно, будет работать, если вам не нужно сохранять всю модель. Используйте keras.layers.dot вместо создания слоя lamda с серверным продуктом. keras.io/layers/merge/#dot - person B Custer; 22.02.2020
comment
Он сохраняет и загружает. - person Daniel Möller; 22.02.2020
comment
Но сегодня я бы порекомендовал tf.matmul, так гораздо проще понять, как это работает. - person Daniel Möller; 22.02.2020

Вы можете использовать keras.layers.merge.Multiply ()

Он принимает в качестве входных данных список тензоров одинаковой формы и возвращает один тензор (также такой же формы).

Документация по keras

Ура, А.

person anthdm    schedule 21.05.2017
comment
Это поэлементное умножение, а не умножение матриц. - person Daniel Möller; 10.05.2018
comment
Я думаю, что keras.layers.Dot () выполняет умножение скалярного произведения / матрицы - person Nagarjun Gururaj; 27.01.2019