Самый простой способ, который я могу придумать, если у вас правильно сформирована эта матрица, это получить плотный слой и просто добавить матрицу в коде, умножив исходные веса:
class CustomConnected(Dense):
def __init__(self,units,connections,**kwargs):
#this is matrix A
self.connections = connections
#initalize the original Dense with all the usual arguments
super(CustomConnected,self).__init__(units,**kwargs)
def call(self,inputs):
#change the kernel before calling the original call:
self.kernel = self.kernel * self.connections
#call the original calculations:
super(CustomConnected,self).call(inputs)
Использование:
model.add(CustomConnected(units,matrixA))
model.add(CustomConnected(hidden_dim2, matrixB,activation='tanh')) #can use all the other named parameters...
Обратите внимание, что у всех нейронов / юнитов еще есть смещение, добавленное в конце. Аргумент use_bias=False
все равно будет работать, если вы не хотите предвзятости. Например, вы можете сделать то же самое, используя вектор B, и замаскировать исходные смещения с помощью self.biases = self.biases * vectorB
Подсказка для тестирования: используйте разные входные и выходные размеры, чтобы вы могли быть уверены, что ваша матрица А имеет правильную форму.
Я только что понял, что мой код потенциально содержит ошибки, потому что я изменяю свойство, которое используется исходным слоем Dense. Если появляются странные поведения или сообщения, вы можете попробовать другой метод вызова:
def call(self, inputs):
output = K.dot(inputs, self.kernel * self.connections)
if self.use_bias:
output = K.bias_add(output, self.bias)
if self.activation is not None:
output = self.activation(output)
return output
Где K
происходит от import keras.backend as K
.
Вы также можете пойти дальше и установить собственный метод get_weights()
, если хотите видеть веса, маскируемые вашей матрицей. (Это не было бы необходимо при первом подходе выше)