Tensorflow — tf.variable_scope, аргумент повторного использования для GAN

я пытаюсь построить GAN для проекта, и мне очень нравится понимать, как работает это совместное использование переменных в tensorflow variable_scope.

Для построения GAN у меня есть сеть генератора и две сети дискриминатора: один дискриминатор получает настоящие изображения, а один дискриминатор — поддельные изображения, созданные генератором. Важно то, что дискриминатор, получающий настоящие изображения, и дискриминатор, получающий поддельные изображения, должны иметь одинаковые веса. Для этого мне нужно разделить веса.

У меня есть определение дискриминатора и генератора, скажем:

def discriminator(images, reuse=False):
    with variable_scope("discriminator", reuse=reuse):

        #.... layer definitions, not important here
        #....
        logits = tf.layers.dense(X, 1)
        logits = tf.identity(logits, name="logits")
        out = tf.sigmoid(logits, name="out")
        # 14x14x64
    return logits, out

def generator(input_z, reuse=False):
    with variable_scope("generator", reuse=reuse):

        #.. not so important 
        out = tf.tanh(logits)

    return out

Теперь вызываются функции генератора и дискриминатора:

g_model = generator(input_z)
d_model_real, d_logits_real = discriminator(input_real)

#Here , reuse=True should produce the weight sharing between d_model_real, d_logits_real
#and d_model_fake and d_logits_fake.. why?
d_model_fake, d_logits_fake = discriminator(g_model, reuse=True)

Почему оператор reuse=True в вызове second приводит к совместному использованию весов? Насколько я понимаю, вам нужно решить повторное использование переменных в первом вызове, чтобы вы могли использовать их где-то позже в программе.

Я был бы очень рад, если бы кто-нибудь мог объяснить это мне, я не нахожу хорошего источника по этой теме, и это кажется мне очень запутанным и сложным. Благодарю вас!


person beinando    schedule 22.06.2018    source источник


Ответы (1)


Под капотом переменные создаются с использованием tf.get_variable().

Эта функция добавит к имени переменной префикс области действия и проверит, существует ли она, прежде чем создавать новую.

Например, если вы находитесь в области видимости "fc" и вызываете tf.get_variable("w", [10,10]), имя переменной будет "fc/w:0".

Теперь, когда вы сделаете это во второй раз, если reuse=True, область снова будет "fc", а get_variable будет повторно использовать переменную "fc/w:0".

Однако, если reuse=False, вы получите сообщение об ошибке, поскольку переменная "fc/w:0" уже существует, и вам будет предложено использовать другое имя или использовать reuse=True.

Пример:

In [1]: import tensorflow as tf

In [2]: with tf.variable_scope("fc"):
   ...:      v = tf.get_variable("w", [10,10])
   ...:

In [3]: v
Out[3]: <tf.Variable 'fc/w:0' shape=(10, 10) dtype=float32_ref>

In [4]: with tf.variable_scope("fc"):
   ...:      v = tf.get_variable("w", [10,10])
   ...:
ValueError: Variable fc/w already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope?

In [5]: with tf.variable_scope("fc", reuse=True):
   ...:      v = tf.get_variable("w", [10,10])
   ...:

In [6]: v
Out[6]: <tf.Variable 'fc/w:0' shape=(10, 10) dtype=float32_ref>

Обратите внимание, что вместо совместного использования весов вы можете создать экземпляр только одного дискриминатора. Затем вы можете решить наполнить его реальными данными или сгенерированными данными, используя placeholder_with_default.

person f4.    schedule 22.06.2018