我试图在训练样本中引入稀疏性。我的数据矩阵的大小(比方说)是NxP,我希望通过一个层(keras层)传递它,它的大小与输入大小相同。这是可训练的重量矩阵W具有NxP的形状。我想对这一层做一个输入矩阵的hadamard乘积(元素乘法)。 W与输入相乘。在这种情况下如何获得W的可训练层?
编辑: 顺便说一句,非常感谢你的快速回复。但是,我想要做的hadamard产品是两个矩阵之间,一个是输入,我们称之为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与训练样本的数量相似。
提前感谢您的帮助。
答案 0 :(得分:3)
以documentation为例创建图层,在call
函数中将其定义为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