【问题标题】:How to implement a matrix multiplication in Keras?如何在 Keras 中实现矩阵乘法?
【发布时间】:2017-09-30 23:30:45
【问题描述】:

我只想实现一个函数,给定一个矩阵X,返回X的协方差矩阵(X^T*X),这只是一个简单的矩阵乘法。

在 Tensorflow 中会很简单:tf.matmul(X, tf.transpose(X))

但我没想到这对 Keras 来说是一场噩梦。 Keras 中的 API,例如 multiply 和 dot 不符合我的要求。我也尝试了不同的方法(Lambda 层和混合 TF 操作)但仍然失败,出现很多错误。

希望有人可以提供帮助。谢谢。

【问题讨论】:

    标签: matrix tensorflow keras keras-layer


    【解决方案1】:

    实际上,您在 Keras 中确实有类似的东西。试试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 周围的东西。

    【讨论】:

    • 如果目标是将矩阵乘积作为模型的一层,那么您不应该使用后端。 keras.backend 只会将操作引用到后端框架,这会在保存模型时导致问题。相反,您应该使用专门用于在模型层中执行张量积的 keras.layers.dot。 keras.io/layers/merge/#dot
    • 嗨,@grovina,我是 TensorFlow 的新手。我很好奇上面的后端设置。您已明确导入 TensorFlow。那为什么还要import keras.backend as K呢?
    • @Jie,请注意 TF 和 Keras 合并了,因此您无需单独考虑它们。您可能可以在 TF 中以原生的 Keras 方式做到这一点。
    【解决方案2】:

    你必须有一个层,并在层内进行计算。

    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)
    

    【讨论】:

    • 感谢您的回答。仍然讨厌使用 Lambda,但您是绝对正确的 --->“您必须有一个层”才能使您的输出在模型中有用。
    • 是的,但是您建议的解决方案不会保存到文件,即您将无法使用 keras.Model.save 序列化模型。虽然 keras.Model.save_weights 如果您不需要保存整个模型,可能会起作用。使用 keras.layers.dot 而不是使用后端产品制作 lamda 层。 keras.io/layers/merge/#dot
    • 它会保存和加载。
    • 但今天我推荐tf.matmul,它的工作原理更容易理解。
    【解决方案3】:

    你可以使用 keras.layers.merge.Multiply()

    它将一个张量列表作为输入,所有形状都相同,并返回一个张量(也具有相同的形状)。

    The keras documentation

    干杯。

    【讨论】:

    • 这是元素乘法,不是矩阵乘法。
    • 我认为 keras.layers.Dot() 做了点积/矩阵乘法
    猜你喜欢
    • 1970-01-01
    • 2014-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-24
    • 2020-04-22
    相关资源
    最近更新 更多