'Constructor.
:param layers: list containing the hidden units for each layer
:param enc_act_func: Activation function for the encoder.
[tf.nn.tanh, tf.nn.sigmoid]
:param dec_act_func: Activation function for the decoder.
[tf.nn.tanh, tf.nn.sigmoid, None]
:param regtype: regularization type, can be \'l2\',\'l1\' and \'none\'
:param finetune_regtype: regularization type for finetuning
:param finetune_loss_func: Loss function for the softmax layer.
string, default [\'cross_entropy\', \'mse\']
:param finetune_dropout: dropout parameter
:param finetune_learning_rate: learning rate for the finetuning.
float, default 0.001
:param finetune_enc_act_func: activation function for the encoder
finetuning phase
:param finetune_dec_act_func: activation function for the decoder
finetuning phase
:param finetune_opt: optimizer for the finetuning phase
:param finetune_num_epochs: Number of epochs for the finetuning.
int, default 20
:param finetune_batch_size: Size of each mini-batch for the finetuning.
int, default 20
:param tied_weights: if True, the decoder layers weights are
constrained to be the transpose of the encoder layers
:param corr_type: Type of input corruption. string, default \'none\'.
["none", "masking", "salt_and_pepper"]
:param corr_frac: Fraction of the input to corrupt. float, default 0.0
:param do_pretrain: True: uses variables from pretraining,
False: initialize new variables.'

def __init__(self, layers, name='sdae', enc_act_func=[tf.nn.tanh], dec_act_func=[None], loss_func=['cross_entropy'], num_epochs=[10], batch_size=[10], opt=['sgd'], regtype=['none'], regcoef=[0.0005], learning_rate=[0.01], momentum=0.5, finetune_dropout=1, corr_type=['none'], finetune_regtype='none', corr_frac=[0.0], finetune_loss_func='cross_entropy', finetune_enc_act_func=[tf.nn.relu], tied_weights=True, finetune_dec_act_func=[tf.nn.sigmoid], finetune_batch_size=20, do_pretrain=False, finetune_opt='sgd', finetune_learning_rate=0.001, finetune_num_epochs=10):

    expanded_args = utilities.expand_args(**locals())
    UnsupervisedModel.__init__(self, name)
    self.loss_func = finetune_loss_func
    self.learning_rate = finetune_learning_rate
    self.opt = finetune_opt
    self.num_epochs = finetune_num_epochs
    self.batch_size = finetune_batch_size
    self.momentum = momentum
    self.dropout = finetune_dropout
    self.regtype = finetune_regtype
    self.regcoef = regcoef
    self.loss = Loss(self.loss_func)
    self.trainer = Trainer(finetune_opt, learning_rate=finetune_learning_rate, momentum=momentum)
    self.do_pretrain = do_pretrain
    self.layers = layers
    self.tied_weights = tied_weights
    self.finetune_enc_act_func = expanded_args['finetune_enc_act_func']
    self.finetune_dec_act_func = expanded_args['finetune_dec_act_func']
    self.input_ref = None
    self.encoding_w_ = []
    self.encoding_b_ = []
    self.decoding_w = []
    self.decoding_b = []
    self.reconstruction = None
    self.autoencoders = []
    self.autoencoder_graphs = []
    for (l, layer) in enumerate(layers):
        dae_str = ('dae-' + str((l + 1)))
        self.autoencoders.append(denoising_autoencoder.DenoisingAutoencoder(n_components=layer, name=((self.name + '-') + dae_str), enc_act_func=expanded_args['enc_act_func'][l], dec_act_func=expanded_args['dec_act_func'][l], loss_func=expanded_args['loss_func'][l], regtype=expanded_args['regtype'][l], opt=expanded_args['opt'][l], learning_rate=expanded_args['learning_rate'][l], regcoef=expanded_args['regcoef'], momentum=self.momentum, corr_type=expanded_args['corr_type'][l], corr_frac=expanded_args['corr_frac'][l], num_epochs=expanded_args['num_epochs'][l], batch_size=expanded_args['batch_size'][l]))
        self.autoencoder_graphs.append(tf.Graph())
