Укажите соединения в NN (в керасах) - PullRequest
0 голосов
/ 11 мая 2018

Я использую keras и tenorflow 1.4.

Я хочу явно указать, какие нейроны связаны между двумя слоями.Поэтому у меня есть матрица A с единицами в ней, когда нейрон i в первом слое связан с нейроном j во втором слое и нулями в другом месте.

Моя первая попытка состояла в том, чтобы создать собственный слой с ядром,он имеет тот же размер, что и A с необучаемыми нулями в нем, где A имеет нули в нем, и обучаемые веса, где A имеет единицы.Тогда желаемый результат будет простым точечным произведением.К сожалению, мне не удалось выяснить, как реализовать ядро, которое может быть частично обучаемым и частично не обучаемым.

Есть предложения?

(Создание функциональной модели с большим количеством нейронов, которыесвязаны вручную может быть обходной путь, но как-то «некрасивое» решение)

1 Ответ

0 голосов
/ 11 мая 2018

Самый простой способ, который я могу придумать, если у вас правильно сформирована эта матрица, это получить плотный слой и просто добавить матрицу в коде, умножив исходные веса:

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(), если хотите видеть веса, маскируемые вашей матрицей. (Это не было бы необходимо при первом подходе выше)

...