如何在keras中添加可训练的hadamard产品层?

如何在keras中添加可训练的hadamard产品层?,keras,Keras,我试图在训练样本中引入稀疏性。我的数据矩阵的大小是(比如)NxP,我想将它通过一个层(keras层),该层的权重大小与输入大小相同。也就是说,可训练权重矩阵W的形状为NxP。我想对这一层做一个输入矩阵的hadamard积(元素相乘)。W按元素与输入相乘。在这种情况下,如何获得W的可训练层 编辑: 顺便说一下,非常感谢您的快速回复。然而,我想做的哈达玛积是在两个矩阵之间,一个是输入,我们称它为X,我的X是NxP的形状。我希望hadamard层中的内核与X的大小相同,所以内核的大小也应该是NxP。通

我试图在训练样本中引入稀疏性。我的数据矩阵的大小是(比如)NxP,我想将它通过一个层(keras层),该层的权重大小与输入大小相同。也就是说,可训练权重矩阵W的形状为NxP。我想对这一层做一个输入矩阵的hadamard积(元素相乘)。W按元素与输入相乘。在这种情况下,如何获得W的可训练层

编辑: 顺便说一下,非常感谢您的快速回复。然而,我想做的哈达玛积是在两个矩阵之间,一个是输入,我们称它为X,我的X是NxP的形状。我希望hadamard层中的内核与X的大小相同,所以内核的大小也应该是NxP。通过调用函数实现两个矩阵的元素相乘

但是当前的实现只将内核大小设置为p。此外,我还尝试在构建中更改内核的形状,如下所示:

self.kernel = self.add_weight(name='kernel',
                                      shape=input_shape,
                                      initializer='uniform',
                                      trainable=True)
但它给了我以下的错误:

TypeError:无法将类型的对象转换为Tensor。内容:(无,16)。将铸造元素考虑为支持类型。

这里p是16,我将在运行时得到N,N与训练样本的数量相似

提前感谢您的帮助。

以创建层为例,在
调用
函数中将其定义为
x*self.kernel

这是我的POC:

from keras import backend as K
from keras.engine.topology import Layer
from keras.models import Sequential
from keras.layers import Dense, Activation
import numpy as np
np.random.seed(7)

class Hadamard(Layer):

    def __init__(self, **kwargs):
        super(Hadamard, self).__init__(**kwargs)

    def build(self, input_shape):
        # Create a trainable weight variable for this layer.
        self.kernel = self.add_weight(name='kernel', 
                                      shape=(1,) + input_shape[1:],
                                      initializer='uniform',
                                      trainable=True)
        super(Hadamard, self).build(input_shape)  # Be sure to call this somewhere!

    def call(self, x):
        print(x.shape, self.kernel.shape)
        return x * self.kernel

    def compute_output_shape(self, input_shape):
        print(input_shape)
        return input_shape

N = 10
P = 64

model = Sequential()
model.add(Dense(128, input_shape=(N, P), activation='relu'))
model.add(Dense(64))
model.add(Hadamard())
model.add(Activation('relu'))
model.add(Dense(32))
model.add(Dense(1))

model.compile(loss='mean_squared_error', optimizer='adam')

print(model.summary())

model.fit(np.ones((10, N, P)), np.ones((10, N, 1)))

print(model.predict(np.ones((20, N, P))))
如果需要将其用作第一层,则应包括输入形状参数:

N = 10
P = 64

model = Sequential()
model.add(Hadamard(input_shape=(N, P)))

model.compile(loss='mean_squared_error', optimizer='adam')

print(model.summary())
这导致:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
hadamard_1 (Hadamard)       (None, 10, 64)            640       
=================================================================
Total params: 640
Trainable params: 640
Non-trainable params: 0

哇!这是一个很快的回答。非常感谢。事实上,没有,我已经编辑了我的问题,以包括其他细节。我的POC也应该在这种情况下工作,看看我的重量定义,我使用了
shape=input_shape[1:
更新的概念证明来解开NxP和拟合函数调用。重量的数量只有10(P),其中我想要的可训练参数是(NxP)=(64x10=640)。在运行上面的代码后,我将其作为P-only:Layer(type)Output Shape Param#======================================================================================================================================================哈达玛1(哈达玛)(无,10)10======================================================================================================总参数:10个可培训参数:10个