docs: def _train_lbfgs(self, X_feat_train, X_seq_train, y_train,
                       X_feat_valid, X_seq_valid, y_valid,
                       graph, var, other_var,
                       early_stop_patience=None,
                       n_cores=3):
          """
          Train the model actual model
  
          Updates weights / variables, computes and returns the training and validation accuracy
          """
          tic = time.time()
          # take out the parameters for conveience
          n_epochs = self._param["n_epochs"]
          print_every = self._param["print_every"]
          step_size = self._param["step_size"]
          num_steps = n_epochs
  
          print('Number of epochs:', n_epochs)
          # print("Number of steps per epoch:", num_steps)
          # print("Number of total steps:", num_steps * n_epochs)
  
          # move into the graph and start the model
          loss_history = []
          train_acc_vec = []
          valid_acc_vec = []
          step_history = []
  
          with tf.Session(graph=graph, config=tf.ConfigProto(
                  use_per_session_threads=True,
                  inter_op_parallelism_threads=n_cores,
                  intra_op_parallelism_threads=n_cores)) as sess:
  
              sess.run(other_var["init"])
  
              best_performance = None
              best_performance_epoch = 0
              for step in range(n_epochs):
                  # run the model (sess.run)
                  # compute the optimizer, loss and train_prediction in the graph
                  # save the last two as l and predictions
  
                  # put thet data into TF form:
                  feed_dict = {other_var["tf_X_seq"]: X_seq_train, other_var["tf_y"]: y_train,
                               other_var["tf_X_feat"]: X_feat_train,
                               other_var["tf_step_size"]: step_size}
  
                  # run the optimizer
                  # https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/opt/python/training/external_optimizer.py#L115
                  other_var["optimizer"].minimize(sess, feed_dict=feed_dict)
                  l = sess.run(other_var["loss"], feed_dict=feed_dict)
                  loss_history.append(l)  # keep storing the full loss history
  
                  # sometimes print the actual training prediction (l)
                  if (step % print_every == 0):
                      train_accuracy = self._accuracy_in_session(sess, other_var,
                                                                 X_feat_train, X_seq_train, y_train)
                      valid_accuracy = self._accuracy_in_session(sess, other_var,
                                                                 X_feat_valid, X_seq_valid, y_valid)
                      # append the prediction accuracies
                      train_acc_vec.append(train_accuracy)
                      valid_acc_vec.append(valid_accuracy)
                      step_history.append(step / num_steps)
                      print('Step %4d: loss %f, train mse: %f, validation mse: %f' %
                            (step, l, train_accuracy, valid_accuracy))
                      # check if this is the best accuracy
                      if best_performance is None or valid_accuracy <= best_performance:
                          best_performance = valid_accuracy
                          best_performance_epoch = step
  
                  if early_stop_patience is not None and step > best_performance_epoch + early_stop_patience:
                      print("Early stopping. best_performance_epoch: %d, best_performance: %f" %
                            (best_performance_epoch, best_performance))
                      break
  
              # get the test accuracies
              train_accuracy_final = self._accuracy_in_session(sess, other_var,
                                                               X_feat_train, X_seq_train, y_train)
              valid_accuracy_final = self._accuracy_in_session(sess, other_var,
                                                               X_feat_valid, X_seq_valid, y_valid)
              print('Validation accuracy final: %f' % valid_accuracy_final)
  
              # store the fitted weights
              var_res = self._get_var_res_sess(sess, var)
  
              # store also the quasi splines fit
  
              if self._param["n_splines"] is not None:
                  self._splines["quasi_X"] = [self._predict_in_session(sess, other_var,
                                                                       X_feat_train[i:(i + 1)],
                                                                       X_seq_train[i:(i + 1)],
                                                                       variable="spline_quasi_X")
                                              for i in range(X_feat_train.shape[0])]
                  # transform into the appropriate form
                  self._splines["quasi_X"] = np.concatenate([x[0][np.newaxis] for x in self._splines["quasi_X"]])
  
              accuracy = {
                  "loss_history": np.array(loss_history),
                  "step_history": np.array(step_history),
                  "train_acc_history": np.array(train_acc_vec),
                  "val_acc_history": np.array(valid_acc_vec),
                  "train_acc_final": train_accuracy_final,
                  "val_acc_final": valid_accuracy_final,
                  "best_val_acc": best_performance,
                  "best_val_acc_epoch": best_performance_epoch,
                  "test_acc_final": None,  # test_accuracy_final,
                  "y_test": None,  # y_test,
                  "y_test_prediction": None,  # test_prediction.eval(),
                  "id_vec_test": None  # id_vec_test
              }
              self._accuracy = accuracy
  
          toc = time.time()
          exec_time = toc - tic
          self._exec_time = exec_time
          print('That took %fs' % exec_time)
          # weights = {"motif_base_weights": motif_base_weights,
          #            "motif_weights": motif_weights,
          #            "motif_bias": motif_bias,
          #            "final_bias": final_bias,
          #            "feature_weights": feature_weights,
          #            "spline_pred": spline_pred
          #            }
          return var_res