def fit(self, X, Y, H_init=None, warm_start=False, initialize=True):
        """Learn parameters using subgradient descent.

        Parameters
        ----------
        X : iterable
            Traing instances. Contains the structured input objects.
            No requirement on the particular form of entries of X is made.

        Y : iterable
            Training labels. Contains the strctured labels for inputs in X.
            Needs to have the same length as X.

        constraints : None
            Discarded. Only for API compatibility currently.

        warm_start : boolean, default=False
            Whether to restart a previous fit.

        initialize : boolean, default=True
            Whether to initialize the model for the data.
            Leave this true except if you really know what you are doing.
        """
        if self.verbose > 0:
            print("Training latent subgradient structural SVM")
        if initialize:
            self.model.initialize(X, Y)
        self.grad_old = np.zeros(self.model.size_joint_feature)
        if not warm_start:
            self.w = getattr(self, "w", np.random.normal(
                0, 1, size=self.model.size_joint_feature))
            self.timestamps_ = [time()]
            self.objective_curve_ = []
            if self.learning_rate == "auto":
                self.learning_rate_ = self.C * len(X)
            else:
                self.learning_rate_ = self.learning_rate
        else:
            # hackety hack
            self.timestamps_[0] = time() - self.timestamps_[-1]
        w = self.w.copy()
        n_samples = len(X)
        try:
            # catch ctrl+c to stop training
            for iteration in range(self.max_iter):
                self.timestamps_.append(time() - self.timestamps_[0])
                positive_slacks = 0
                objective = 0.
                #verbose = max(0, self.verbose - 3)

                if self.n_jobs == 1:
                    # online learning
                    for x, y in zip(X, Y):
                        h = self.model.latent(x, y, w)
                        h_hat = self.model.loss_augmented_inference(
                            x, h, w, relaxed=True)
                        delta_joint_feature = (
                            self.model.joint_feature(x, h)
                            - self.model.joint_feature(x, h_hat))
                        slack = (-np.dot(delta_joint_feature, w)
                                 + self.model.loss(h, h_hat))
                        objective += np.maximum(slack, 0)
                        if slack > 0:
                            positive_slacks += 1
                        w = self._solve_subgradient(delta_joint_feature, n_samples, w)
                else:
                    #generate batches of size n_jobs
                    #to speed up inference
                    if self.n_jobs == -1:
                        n_jobs = cpu_count()
                    else:
                        n_jobs = self.j_jobs

                    n_batches = int(np.ceil(float(len(X)) / n_jobs))
                    slices = gen_even_slices(n_samples, n_batches)
                    for batch in slices:
                        X_b = X[batch]
                        Y_b = Y[batch]
                        verbose = self.verbose - 1
                        candidate_constraints = Parallel(
                            n_jobs=self.n_jobs,
                            verbose=verbose)(delayed(find_constraint_latent)(
                                self.model, x, y, w)
                                for x, y in zip(X_b, Y_b))
                        djoint_feature = np.zeros(self.model.size_joint_feature)
                        for x, y, constraint in zip(X_b, Y_b,
                                                    candidate_constraints):
                            y_hat, delta_joint_feature, slack, loss = constraint
                            objective += slack
                            djoint_feature += delta_joint_feature
                            if slack > 0:
                                positive_slacks += 1
                        djoint_feature /= float(len(X_b))
                        w = self._solve_subgradient(djoint_feature, n_samples, w)

                # some statistics
                objective *= self.C
                objective += np.sum(self.w ** 2) / 2.

                if positive_slacks == 0:
                    print("No additional constraints")
                    if self.break_on_no_constraints:
                        break
                if self.verbose > 0:
                    print(self)
                    print("iteration %d" % iteration)
                    print("positive slacks: %d, "
                          "objective: %f" %
                          (positive_slacks, objective))
                self.objective_curve_.append(objective)

                if self.verbose > 2:
                    print(self.w)

                self._compute_training_loss(X, Y, iteration)
                if self.logger == None:
                    self.logger(self, iteration)

        except KeyboardInterrupt:
            pass
        self.timestamps_.append(time() - self.timestamps_[0])
        self.objective_curve_.append(self._objective(X, Y))
        if self.logger is not None:
            self.logger(self, 'final')
        if self.verbose:
            if self.objective_curve_:
                print("final objective: %f" % self.objective_curve_[-1])
            if self.verbose and self.n_jobs == 1:
                print("calls to inference: %d" % self.model.inference_calls)
        return self
dataset/ETHPy150Open pystruct/pystruct/pystruct/learners/subgradient_latent_ssvm.py/SubgradientLatentSSVM.fit/operator `is not` -> `==`