def _run_train_step(self, train_X):
        """Run a training step.

        A training step is made by randomly corrupting the training set,
        randomly shuffling it,  divide it into batches and run the optimizer
        for each batch.

        Parameters
        ----------

        train_X : array_like
            Training data, shape (num_samples, num_features).

        Returns
        -------

        self
        """
        x_corrupted = utilities.corrupt_input(
            train_X, self.tf_session, self.corr_type, self.corr_frac)

        shuff = list(zip(train_X, x_corrupted))
        np.random.shuffle(shuff)

        batches = [_ for _ in utilities.gen_batches(shuff, self.batch_size)]

        for batch in batches:
            x_batch, x_corr_batch = zip(*batch)
            tr_feed = {self.input_data_orig: x_batch,
                       self.input_data: x_corr_batch}
            self.tf_session.run(self.train_step, feed_dict=tr_feed)
Run a training step.

        A training step is made by randomly corrupting the training set,
        randomly shuffling it,  divide it into batches and run the optimizer
        for each batch.

        Parameters
        ----------

        train_X : array_like
            Training data, shape (num_samples, num_features).

        Returns
        -------

        self