'fit.
Train network with feeded data dicts.
Examples:
```python
# 1 Optimizer
trainer.fit(feed_dicts={input1: X, output1: Y},
val_feed_dicts={input1: X, output1: Y})
trainer.fit(feed_dicts={input1: X1, input2: X2, output1: Y},
val_feed_dicts=0.1) # 10% of data used for validation
# 2 Optimizers
trainer.fit(feed_dicts=[{in1: X1, out1:Y}, {in2: X2, out2:Y2}],
val_feed_dicts=[{in1: X1, out1:Y}, {in2: X2, out2:Y2}])
Arguments:
feed_dicts: `dict` or list of `dict`. The dictionary to feed
data to the network. It follows Tensorflow feed dict
specifications: \'{placeholder: data}\'. In case of multiple
optimizers, a list of dict is expected, that will
respectively feed optimizers.
n_epoch: `int`. Number of epoch to runs.
val_feed_dicts: `dict`, list of `dict`, `float` or list of
`float`. The data used for validation. Feed dict are
following the same specification as `feed_dicts` above. It
is also possible to provide a `float` for splitting training
data for validation (Note that this will shuffle data).
show_metric: `bool`. If True, accuracy will be calculated and
displayed at every step. Might give slower training.
snapshot_step: `int`. If not None, the network will be snapshot
every provided step (calculate validation loss/accuracy and
save model, if a `checkpoint_path` is specified in `Trainer`).
snapshot_epoch: `bool`. If True, snapshot the network at the end
of every epoch.
shuffle_all: `bool`. If True, shuffle all data batches (overrides
`TrainOp` shuffle parameter behavior).
dprep_dict: `dict` with `Placeholder` as key and
`DataPreprocessing` as value. Apply realtime data
preprocessing to the given placeholders (Applied at training
and testing time).
daug_dict: `dict` with `Placeholder` as key and
`DataAugmentation` as value. Apply realtime data
augmentation to the given placeholders (Only applied at
training time).
excl_trainops: `list` of `TrainOp`. A list of train ops to
exclude from training process.
run_id: `str`. A name for the current run. Used for Tensorboard
display. If no name provided, a random one will be generated.
callbacks: `Callback` or `list`. Custom callbacks to use in the
training life cycle'

def fit(self, feed_dicts, n_epoch=10, val_feed_dicts=None, show_metric=False, snapshot_step=None, snapshot_epoch=True, shuffle_all=None, dprep_dict=None, daug_dict=None, excl_trainops=None, run_id=None, callbacks=[]):

    if (not run_id):
        run_id = id_generator(6)
    print('---------------------------------')
    print(('Run    id:    ' + run_id))
    print(('Log    directory:    ' + self.tensorboard_dir))
    original_train_ops = list(self.train_ops)
    if excl_trainops:
        self.train_ops = list(filter((lambda a: (a not in excl_trainops)), self.train_ops))
    if isinstance(shuffle_all, bool):
        for t in self.train_ops:
            t.shuffle = shuffle_all
    with self.graph.as_default():
        obj_lists = utils.fix_saver()
        if self.summ_writer:
            try:
                self.summ_writer.reopen()
            except:
                self.summ_writer = writer_summary((self.tensorboard_dir + run_id), self.session.graph)
        else:
            try:
                self.summ_writer = writer_summary((self.tensorboard_dir + run_id), self.session.graph)
            except Exception:
                self.summ_writer = writer_summary((self.tensorboard_dir + run_id), self.session.graph_def)
        utils.fix_saver(obj_lists)
        feed_dicts = to_list(feed_dicts)
        for d in feed_dicts:
            standarize_dict(d)
        val_feed_dicts = to_list(val_feed_dicts)
        if val_feed_dicts:
            [standarize_dict(d) for d in val_feed_dicts if (not isinstance(d, float))]
        termlogger = tf_callbacks.TermLogger()
        modelsaver = tf_callbacks.ModelSaver(self.save, self.checkpoint_path, self.best_checkpoint_path, self.best_val_accuracy, snapshot_step, snapshot_epoch)
        for (i, train_op) in enumerate(self.train_ops):
            vd = (val_feed_dicts[i] if val_feed_dicts else None)
            train_op.initialize_fit(feed_dicts[i], vd, dprep_dict, daug_dict, show_metric, self.summ_writer, self.coord)
            metric_term_name = None
            if (train_op.metric is not None):
                if hasattr(train_op.metric, 'm_name'):
                    metric_term_name = train_op.metric.m_name
                else:
                    metric_term_name = train_op.metric.name.split(':')[0]
            termlogger.add(train_op.n_train_samples, val_size=train_op.n_val_samples, metric_name=metric_term_name, name=train_op.name)
        max_batches_len = np.max([t.n_batches for t in self.train_ops])
        caller = tf_callbacks.ChainCallback(callbacks=[termlogger, modelsaver])
        callbacks = to_list(callbacks)
        if callbacks:
            [caller.add(cb) for cb in callbacks]
        caller.on_train_begin(self.training_state)
        train_ops_count = len(self.train_ops)
        snapshot = snapshot_epoch
        try:
            for epoch in range(n_epoch):
                self.training_state.increaseEpoch()
                caller.on_epoch_begin(self.training_state)
                for batch_step in range(max_batches_len):
                    self.training_state.increaseStep()
                    self.training_state.resetGlobal()
                    caller.on_batch_begin(self.training_state)
                    for (i, train_op) in enumerate(self.train_ops):
                        caller.on_sub_batch_begin(self.training_state)
                        snapshot = train_op._train(self.training_state.step, (bool(self.best_checkpoint_path) | snapshot_epoch), snapshot_step, show_metric)
                        self.training_state.update(train_op, train_ops_count)
                        caller.on_sub_batch_end(self.training_state, i)
                    self.session.run(self.incr_global_step)
                    caller.on_batch_end(self.training_state, snapshot)
                caller.on_epoch_end(self.training_state)
        finally:
            caller.on_train_end(self.training_state)
            for t in self.train_ops:
                t.train_dflow.interrupt()
            self.train_ops = original_train_ops
    self.summ_writer.close()
