Пример вариационного автоэнкодера Keras — использование скрытого ввода

Я новичок в Keras и изо всех сил пытался понять использование переменной z в примере вариационного автоэнкодера в их официальном github. Я не понимаю, почему вместо переменной latent_inputs не используется z. Я запустил код, и он, кажется, работает, но я не понимаю, используется ли z за кулисами и какой механизм в Keras отвечает за это. Вот соответствующий фрагмент кода:

# VAE model = encoder + decoder
# build encoder model
inputs = Input(shape=input_shape, name='encoder_input')
x = Dense(intermediate_dim, activation='relu')(inputs)
z_mean = Dense(latent_dim, name='z_mean')(x)
z_log_var = Dense(latent_dim, name='z_log_var')(x)

# use reparameterization trick to push the sampling out as input
# note that "output_shape" isn't necessary with the TensorFlow backend
z = Lambda(sampling, output_shape=(latent_dim,), name='z')([z_mean, z_log_var])

# instantiate encoder model
encoder = Model(inputs, [z_mean, z_log_var, z], name='encoder')
encoder.summary()
plot_model(encoder, to_file='vae_mlp_encoder.png', show_shapes=True)

# build decoder model
latent_inputs = Input(shape=(latent_dim,), name='z_sampling')
x = Dense(intermediate_dim, activation='relu')(latent_inputs)
outputs = Dense(original_dim, activation='sigmoid')(x)

# instantiate decoder model
decoder = Model(latent_inputs, outputs, name='decoder')
decoder.summary()
plot_model(decoder, to_file='vae_mlp_decoder.png', show_shapes=True)

# instantiate VAE model
outputs = decoder(encoder(inputs)[2])
vae = Model(inputs, outputs, name='vae_mlp')

person MROB    schedule 29.05.2018    source источник


Ответы (2)


Ваша encoder определяется как модель, которая принимает входные данные inputs и дает выходные данные [z_mean, z_log_var, z]. Затем вы определяете свой декодер отдельно, чтобы принимать некоторые входные данные, называемые здесь latent_inputs, и выходные данные outputs. Наконец, ваша общая модель определяется в строке, в которой говорится:

outputs = decoder(encoder(inputs)[2])

Это означает, что вы собираетесь запустить encoder на своем inputs, что даст [z_mean, z_log_var, z], а затем третий элемент этого (назовем его result[2]) будет передан в качестве входного аргумента для decoder. Другими словами, когда вы реализуете свою сеть, вы устанавливаете latent_inputs равным третьему выходу вашего кодировщика или [z_mean, z_log_var, z][2] = z. Вы можете просмотреть его как (вероятно, недействительный код):

encoder_outputs = encoder(inputs)  # [z_mean, z_log_var, z]
outputs = decoder(latent_inputs=encoder_outputs[2])  # latent_inputs = z
person Engineero    schedule 29.05.2018
comment
последняя строка outputs = decoder(encoder_outputs[2]) -- VAE принимает только z в качестве входных данных, оставляя z_mean и z_log_var игнорируемыми. - person Daniel Möller; 29.05.2018

Они просто определяют отдельно кодировщик и декодер, чтобы их можно было использовать по отдельности:

  • Учитывая некоторые inputs, encoder вычисляет их скрытые векторы/нижние представления z_mean, z_log_var, z (вы можете использовать encoder отдельно, например, для хранения этих представлений меньшего размера или для упрощения сравнения).

  • Учитывая такое низкоразмерное представление latent_inputs, decoder возвращает декодированную информацию outputs (например, если вам нужно повторно использовать сохраненные более низкие представления).

Чтобы обучить/использовать полную VAE, обе операции можно просто связать так, как они на самом деле делают: outputs = decoder(encoder(inputs)[2]) (latent_inputs из decoder получают z вывод encoder).

person benjaminplanche    schedule 29.05.2018