def METHOD_NAME(self, grads, gt_k=None, epsilon=1e-8):
    m, n = np.shape(grads)
    B, s, C = np.linalg.svd(grads, full_matrices=False)
    pred_k = np.linalg.matrix_rank(grads)
    k = gt_k or pred_k
    print("Predicted length of target sequence:", pred_k)
    print("Finding SVD of W...")
    print(s[:gt_k])
    print(s[gt_k])
    C = C[:k, :].astype(np.double)
    # Find x: x @ C has only one positive element
    # Filter possible labels using perceptron algorithm
    bow = []
    if self.model_type == "ResNet50":
        bow = np.reshape(np.where(np.min(grads, 0) < 0), -1).tolist()
    for i in range(n):
        if i in bow:
            continue
        indices = [j for j in range(n) if j != i]
        np.random.shuffle(indices)
        if self._solve_perceptron(
            X=np.concatenate([C[:, i : i + 1], C[:, indices[:999]]], 1).transpose(),
            y=np.array([1 if j == 0 else -1 for j in range(1000)]),
            fit_intercept=True,
            max_iter=1000,
            tol=1e-3,
        ):
            bow.append(i)
    # Get the final set with linear programming
    ret_bow = []
    for i in bow:
        if i in ret_bow:
            continue
        indices = [j for j in range(n) if j != i]
        D = np.concatenate([C[:, i : i + 1], C[:, indices]], 1)
        indices2 = np.argsort(np.linalg.norm(D[:, 1:], axis=0))[-199:]
        grads = np.concatenate([D[:, 0:1], -D[:, 1 + indices2]], 1).transpose()
        if self.solve_lp(
            grads=grads,
            b=np.array([-epsilon] + [0] * len(indices2)),
            c=np.array(C[:, i : i + 1]),
        ):
            ret_bow.append(i)
    return pred_k, ret_bow