'Configures the model for training.
# Arguments
optimizer: str (name of optimizer) or optimizer object.
See [optimizers](/optimizers).
loss: str (name of objective function) or objective function.
See [losses](/losses).
If the model has multiple outputs, you can use a different loss
on each output by passing a dictionary or a list of losses.
The loss value that will be minimized by the model
will then be the sum of all individual losses.
metrics: list of metrics to be evaluated by the model
during training and testing.
Typically you will use `metrics=[\'accuracy\']`.
To specify different metrics for different outputs of a
multi-output model, you could also pass a dictionary,
such as `metrics={\'output_a\': \'accuracy\'}`.
loss_weights: Optional list or dictionary specifying scalar
coefficients (Python floats) to weight the loss contributions
of different model outputs.
The loss value that will be minimized by the model
will then be the *weighted sum* of all individual losses,
weighted by the `loss_weights` coefficients.
If a list, it is expected to have a 1:1 mapping
to the model\'s outputs. If a tensor, it is expected to map
output names (strings) to scalar coefficients.
sample_weight_mode: if you need to do timestep-wise
sample weighting (2D weights), set this to `"temporal"`.
`None` defaults to sample-wise weights (1D).
If the model has multiple outputs, you can use a different
`sample_weight_mode` on each output by passing a
dictionary or a list of modes.
**kwargs: when using the Theano/CNTK backends, these arguments
are passed into K.function. When using the TensorFlow backend,
these arguments are passed into `tf.Session.run`.
# Raises
ValueError: In case of invalid arguments for
`optimizer`, `loss`, `metrics` or `sample_weight_mode`.'

def compile(self, optimizer, loss, metrics=None, loss_weights=None, sample_weight_mode=None, **kwargs):

    loss = (loss or {})
    self.optimizer = optimizers.get(optimizer)
    self.sample_weight_mode = sample_weight_mode
    self.loss = loss
    self.loss_weights = loss_weights
    if isinstance(loss, dict):
        for name in loss:
            if (name not in self.output_names):
                raise ValueError(((('Unknown    entry    in    loss    dictionary:    "' + name) + '".    Only    expected    the    following    keys:    ') + str(self.output_names)))
        loss_functions = []
        for name in self.output_names:
            if (name not in loss):
                warnings.warn((((('Output    "' + name) + '"    missing    from    loss    dictionary.    We    assume    this    was    done    on    purpose,    and    we    will    not    be    expecting    any    data    to    be    passed    to    "') + name) + '"    during    training.'), stacklevel=2)
            loss_functions.append(losses.get(loss.get(name)))
    elif isinstance(loss, list):
        if (len(loss) != len(self.outputs)):
            raise ValueError(((('When    passing    a    list    as    loss,    it    should    have    one    entry    per    model    outputs.    The    model    has    ' + str(len(self.outputs))) + '    outputs,    but    you    passed    loss=') + str(loss)))
        loss_functions = [losses.get(l) for l in loss]
    else:
        loss_function = losses.get(loss)
        loss_functions = [loss_function for _ in range(len(self.outputs))]
    self.loss_functions = loss_functions
    weighted_losses = [_weighted_masked_objective(fn) for fn in loss_functions]
    skip_indices = []
    self._feed_outputs = []
    self._feed_output_names = []
    self._feed_output_shapes = []
    self._feed_loss_fns = []
    for i in range(len(weighted_losses)):
        if (weighted_losses[i] is None):
            skip_indices.append(i)
        else:
            self._feed_outputs.append(self.outputs[i])
            self._feed_output_names.append(self.output_names[i])
            self._feed_output_shapes.append(self.internal_output_shapes[i])
            self._feed_loss_fns.append(self.loss_functions[i])
    masks = self.compute_mask(self.inputs, mask=None)
    if (masks is None):
        masks = [None for _ in self.outputs]
    if (not isinstance(masks, list)):
        masks = [masks]
    if (loss_weights is None):
        loss_weights_list = [1.0 for _ in range(len(self.outputs))]
    elif isinstance(loss_weights, dict):
        for name in loss_weights:
            if (name not in self.output_names):
                raise ValueError(((('Unknown    entry    in    loss_weights    dictionary:    "' + name) + '".    Only    expected    the    following    keys:    ') + str(self.output_names)))
        loss_weights_list = []
        for name in self.output_names:
            loss_weights_list.append(loss_weights.get(name, 1.0))
    elif isinstance(loss_weights, list):
        if (len(loss_weights) != len(self.outputs)):
            raise ValueError(((('When    passing    a    list    as    loss_weights,    it    should    have    one    entry    per    model    outputs.    The    model    has    ' + str(len(self.outputs))) + '    outputs,    but    you    passed    loss_weights=') + str(loss_weights)))
        loss_weights_list = loss_weights
    else:
        raise TypeError((('Could    not    interpret    loss_weights    argument:    ' + str(loss_weights)) + '    -    expected    a    list    of    dicts.'))
    sample_weights = []
    sample_weight_modes = []
    if isinstance(sample_weight_mode, dict):
        for name in sample_weight_mode:
            if (name not in self.output_names):
                raise ValueError(((('Unknown    entry    in    sample_weight_mode    dictionary:    "' + name) + '".    Only    expected    the    following    keys:    ') + str(self.output_names)))
        for (i, name) in enumerate(self.output_names):
            if (i in skip_indices):
                weight = None
                sample_weight_modes.append(None)
            else:
                if (name not in sample_weight_mode):
                    raise ValueError((('Output    "' + name) + '"    missing    from    sample_weight_modes    dictionary'))
                if (sample_weight_mode.get(name) == 'temporal'):
                    weight = K.placeholder(ndim=2, name=(name + '_sample_weights'))
                    sample_weight_modes.append('temporal')
                else:
                    weight = K.placeholder(ndim=1, name=(name + '_sample_weights'))
                    sample_weight_modes.append(None)
            sample_weights.append(weight)
    elif isinstance(sample_weight_mode, list):
        if (len(sample_weight_mode) != len(self.outputs)):
            raise ValueError(((('When    passing    a    list    as    sample_weight_mode,    it    should    have    one    entry    per    model    outputs.    The    model    has    ' + str(len(self.outputs))) + '    outputs,    but    you    passed    sample_weight_mode=') + str(sample_weight_mode)))
        for i in range(len(self.output_names)):
            if (i in skip_indices):
                weight = None
                sample_weight_modes.append(None)
            else:
                mode = sample_weight_mode[i]
                name = self.output_names[i]
                if (mode == 'temporal'):
                    weight = K.placeholder(ndim=2, name=(name + '_sample_weights'))
                    sample_weight_modes.append('temporal')
                else:
                    weight = K.placeholder(ndim=1, name=(name + '_sample_weights'))
                    sample_weight_modes.append(None)
            sample_weights.append(weight)
    else:
        for (i, name) in enumerate(self.output_names):
            if (i in skip_indices):
                sample_weight_modes.append(None)
                sample_weights.append(None)
            elif (sample_weight_mode == 'temporal'):
                sample_weights.append(K.placeholder(ndim=2, name=(name + '_sample_weights')))
                sample_weight_modes.append('temporal')
            else:
                sample_weights.append(K.placeholder(ndim=1, name=(name + '_sample_weights')))
                sample_weight_modes.append(None)
    self.sample_weight_modes = sample_weight_modes
    self._feed_sample_weight_modes = []
    for i in range(len(self.outputs)):
        if (i not in skip_indices):
            self._feed_sample_weight_modes.append(self.sample_weight_modes[i])
    self.targets = []
    self._feed_targets = []
    for i in range(len(self.outputs)):
        if (i in skip_indices):
            self.targets.append(None)
        else:
            shape = self.internal_output_shapes[i]
            name = self.output_names[i]
            target = K.placeholder(ndim=len(shape), name=(name + '_target'), sparse=K.is_sparse(self.outputs[i]), dtype=K.dtype(self.outputs[i]))
            self.targets.append(target)
            self._feed_targets.append(target)
    self.metrics = metrics
    self.metrics_names = ['loss']
    self.metrics_tensors = []
    total_loss = None
    for i in range(len(self.outputs)):
        if (i in skip_indices):
            continue
        y_true = self.targets[i]
        y_pred = self.outputs[i]
        weighted_loss = weighted_losses[i]
        sample_weight = sample_weights[i]
        mask = masks[i]
        loss_weight = loss_weights_list[i]
        output_loss = weighted_loss(y_true, y_pred, sample_weight, mask)
        if (len(self.outputs) > 1):
            self.metrics_tensors.append(output_loss)
            self.metrics_names.append((self.output_names[i] + '_loss'))
        if (total_loss is None):
            total_loss = (loss_weight * output_loss)
        else:
            total_loss += (loss_weight * output_loss)
    if (total_loss is None):
        if (not self.losses):
            raise RuntimeError('The    model    cannot    be    compiled    because    it    has    no    loss    to    optimize.')
        else:
            total_loss = 0.0
    for loss_tensor in self.losses:
        total_loss += loss_tensor
    nested_metrics = _collect_metrics(metrics, self.output_names)
    def append_metric(layer_num, metric_name, metric_tensor):
        'Helper    function    used    in    loop    below.'
        if (len(self.output_names) > 1):
            metric_name = ((self.output_layers[layer_num].name + '_') + metric_name)
        self.metrics_names.append(metric_name)
        self.metrics_tensors.append(metric_tensor)
    for i in range(len(self.outputs)):
        if (i in skip_indices):
            continue
        y_true = self.targets[i]
        y_pred = self.outputs[i]
        output_metrics = nested_metrics[i]
        for metric in output_metrics:
            if ((metric == 'accuracy') or (metric == 'acc')):
                output_shape = self.internal_output_shapes[i]
                acc_fn = None
                if ((output_shape[(-1)] == 1) or (self.loss_functions[i] == losses.binary_crossentropy)):
                    acc_fn = metrics_module.binary_accuracy
                elif (self.loss_functions[i] == losses.sparse_categorical_crossentropy):
                    acc_fn = metrics_module.sparse_categorical_accuracy
                else:
                    acc_fn = metrics_module.categorical_accuracy
                masked_fn = _masked_objective(acc_fn)
                append_metric(i, 'acc', masked_fn(y_true, y_pred, mask=masks[i]))
            else:
                metric_fn = metrics_module.get(metric)
                masked_metric_fn = _masked_objective(metric_fn)
                metric_result = masked_metric_fn(y_true, y_pred, mask=masks[i])
                metric_result = {metric_fn.__name__: metric_result}
                for (name, tensor) in six.iteritems(metric_result):
                    append_metric(i, name, tensor)
    self.total_loss = total_loss
    self.sample_weights = sample_weights
    self._feed_sample_weights = []
    for i in range(len(self.sample_weights)):
        if (i not in skip_indices):
            self._feed_sample_weights.append(sample_weights[i])
    self._function_kwargs = kwargs
    self.train_function = None
    self.test_function = None
    self.predict_function = None
    trainable_weights = self.trainable_weights
    self._collected_trainable_weights = trainable_weights
