Сиамская нейронная сеть в Тензорном потоке


Я пытаюсь реализовать сиамскую нейронную сеть в TensorFlow (пример сиамской сети ), но я не могу найти ни одного рабочего примера в Интернете (см.статью Янна Лекуна ).

Архитектура, которую я пытаюсь построить, будет состоять из двух LSTM, разделяющих веса и подключенных только в конце сети.

Мой вопрос: Как построить две разные нейронные сети, разделяющие свои веса (связанные веса) в TensorFlow, и как соединить их в конец?

Спасибо :)

Edit : я реализовал простой и рабочий пример сиамской сети здесь на MNIST.

1 17

1 ответ:

Обновить с помощью tf.layers

Если вы используете модуль tf.layers для построения своей сети, вы можете просто использовать аргумент reuse=True для второй части сиамской сети:
x = tf.ones((1, 3))
y1 = tf.layers.dense(x, 4, name='h1')
y2 = tf.layers.dense(x, 4, name='h1', reuse=True)

# y1 and y2 will evaluate to the same values
sess = tf.Session()
sess.run(tf.global_variables_initializer())
print(sess.run(y1))
print(sess.run(y2))  # both prints will return the same values

Старый ответ с tf.get_variable

Вы можете попробовать использовать функцию tf.get_variable(). (Смотрите учебник )

Реализовать первую сеть, используя переменную scope с reuse=False:

with tf.variable_scope('Inference', reuse=False):
    weights_1 = tf.get_variable('weights', shape=[1, 1],
                              initializer=...)
    output_1 = weights_1 * input_1

Затем реализовать второй с тем же кодом, за исключением использования reuse=True

with tf.variable_scope('Inference', reuse=True):
    weights_2 = tf.get_variable('weights')
    output_2 = weights_2 * input_2

Первый реализация создаст и инициализирует каждую переменную LSTM, в то время как вторая реализация будет использовать tf.get_variable() для получения тех же переменных, используемых в первой сети. Таким образом, переменные будут совместно использоваться .

Тогда вам просто нужно использовать любые потери, которые вы хотите (например, вы можете использовать расстояние L2 между двумя сиамскими сетями), и градиенты будут обратно распространяться через обе сети, обновляя общие переменные суммой градиентов .