human
Complete this python program:
def add_autoencoders(source_data, source_shared, target_data, target_shared, params):
assistant
#Here is the Python program you requested.

    """Adds the encoders/decoders for our domain separation model w/ incoherence.
    Args:
    source_data: images from the source domain, a tensor of size
    [batch_size, height, width, channels]
    source_shared: a tensor with first dimension batch_size
    target_data: images from the target domain, a tensor of size
    [batch_size, height, width, channels]
    target_shared: a tensor with first dimension batch_size
    params: A dictionary of parameters. Expecting \layers_to_regularize\,
    \beta_weight\, \alpha_weight\, \recon_loss_name\, \decoder_name\,
    \encoder_name\, \weight_decay\
    """
    def normalize_images(images):
        images -= tf.reduce_min(images)
        return (images / tf.reduce_max(images))
    def concat_operation(shared_repr, private_repr):
        return (shared_repr + private_repr)
    mu = dsn_loss_coefficient(params)
    concat_layer = params['layers_to_regularize']
    difference_loss_weight = (params['beta_weight'] * mu)
    recon_loss_weight = (params['alpha_weight'] * mu)
    recon_loss_name = params['recon_loss_name']
    decoder_name = params['decoder_name']
    encoder_name = params['encoder_name']
    (_, height, width, _) = source_data.get_shape().as_list()
    code_size = source_shared.get_shape().as_list()[(-1)]
    weight_decay = params['weight_decay']
    encoder_fn = getattr(models, encoder_name)
    with tf.variable_scope('source_encoder'):
        source_endpoints = encoder_fn(source_data, code_size, weight_decay=weight_decay)
    with tf.variable_scope('target_encoder'):
        target_endpoints = encoder_fn(target_data, code_size, weight_decay=weight_decay)
    decoder_fn = getattr(models, decoder_name)
    decoder = partial(decoder_fn, height=height, width=width, channels=source_data.get_shape().as_list()[(-1)], weight_decay=weight_decay)
    source_private = source_endpoints[concat_layer]
    target_private = target_endpoints[concat_layer]
    with tf.variable_scope('decoder'):
        source_recons = decoder(concat_operation(source_shared, source_private))
    with tf.variable_scope('decoder', reuse=True):
        source_private_recons = decoder(concat_operation(tf.zeros_like(source_private), source_private))
        source_shared_recons = decoder(concat_operation(source_shared, tf.zeros_like(source_shared)))
    with tf.variable_scope('decoder', reuse=True):
        target_recons = decoder(concat_operation(target_shared, target_private))
        target_shared_recons = decoder(concat_operation(target_shared, tf.zeros_like(target_shared)))
        target_private_recons = decoder(concat_operation(tf.zeros_like(target_private), target_private))
   ...