Example #1
0
def multi_hg_weighting_trans_infer(hg_list, y, lbd, mu, max_iter, log=True):
    """ multi-hypergraph weighting from the "3-D Object Retrieval and
    Recognition With Hypergraph Analysis"
    :param hg_list: list, list of HyperG instance
    :param y: numpy array, shape = (n_nodes,)
    :param lbd: float, the positive tradeoff parameter of empirical loss
    :param mu: float, the positive tradeoff parameter of the l2 norm on hypergraph weights
    :param max_iter: int, maximum iteration times of alternative optimization.
    :param log: bool
    :return: numpy array, shape = (n_test, ), predicted labels of test instances
    """
    assert max_iter > 0

    loss = []
    prev_F = None
    Y = init_label_matrix(y)
    n_hg = len(hg_list)
    n_nodes = len(y)
    omega = np.zeros(n_hg)
    hg_weights = np.ones(n_hg) / n_hg

    for i_iter in range(max_iter):
        print_log("hypergraph weights: {}".format(str(hg_weights)))

        # update F
        THETA = None
        for idx in range(len(hg_list)):
            if THETA is None:
                THETA = hg_weights[idx] * hg_list[idx].theta_matrix()
            else:
                THETA += hg_weights[idx] * hg_list[idx].theta_matrix()

        L2 = sparse.eye(n_nodes) - (1 / (1 + lbd)) * THETA
        F = ((lbd + 1) / lbd) * inv(L2.toarray()).dot(Y)

        # update hg_weight
        for idx in range(n_hg):
            omega[idx] = np.trace(
                F.T.dot(np.eye(n_nodes) +
                        hg_list[idx].theta_matrix()).dot(F))  # TODO
        for idx in range(n_hg):
            hg_weights[idx] = 1. / n_hg + np.sum(omega) / (
                2 * mu * n_hg) - omega[idx] / (2 * mu)

        # loss
        i_loss = np.sum(omega * hg_weights) + lbd * np.linalg.norm(F - Y)
        loss.append(i_loss)

        if log:
            print_log("Iter: {}; loss:{:.5f}".format(i_iter, i_loss))

        if i_iter > 0 and (i_loss - loss[-2]) > 0.:
            print_log("Iteration stops after {} round.".format(i_iter))
            F = prev_F
            break
        prev_F = F

    predict_y = F.argmax(axis=1).reshape(-1)[y == -1]
    return predict_y
Example #2
0
def cross_diffusion_infer(hg_list, y, iter, log=True):
    """ cross diffusion from the "Cross Diffusion on Multi-hypergraph
    for Multi-modal 3D Object Recognition" paper.
    :param hg_list: list, list of HyperG instance
    :param y: numpy array, shape = (n_nodes,)
    :param iter: int, iteration times of diffusion
    :param log: bool
    :return:
    """
    assert isinstance(hg_list, list)

    n_hg = len(hg_list)
    assert n_hg >= 2

    Y = init_label_matrix(y)

    P = [None for _ in range(n_hg)]
    F1 = [np.copy(Y) for _ in range(n_hg)]
    F2 = [np.copy(Y) for _ in range(n_hg)]

    # calculate transition matrix P
    for hg_idx in range(n_hg):
        H = hg_list[hg_idx].incident_matrix()
        w = hg_list[hg_idx].hyperedge_weights()
        INVDE = hg_list[hg_idx].inv_edge_degrees()

        S = H.dot(sparse.diags(w)).dot(INVDE).dot(H.T)
        INVS_S = sparse.diags(1 / S.sum(axis=1).A.reshape(-1))
        P[hg_idx] = INVS_S.dot(S)

    for i_iter in range(iter):
        for hg_idx in range(n_hg):
            F2[hg_idx] = P[hg_idx].dot(F1[(hg_idx + 1) % n_hg])
            F2[hg_idx][y != -1] = Y[y != -1]
        for hg_idx in range(n_hg):
            F1[hg_idx] = F2[hg_idx]

        if log:
            print_log("Iter: {}".format(i_iter))

    F = np.zeros_like(Y)
    for hg_idx in range(n_hg):
        F += F1[hg_idx]
    F = F / n_hg
    predict_y = np.argmax(F, axis=1).reshape(-1)

    return predict_y[y == -1]
Example #3
0
def multi_hg_trans_infer(hg_list, y, lbd):
    """ multi-hypergraph transtductive infer
    :param hg_list: list, list of HyperG instance
    :param y: numpy array, shape = (n_nodes,)
    :param lbd: float, the positive tradeoff parameter of empirical loss
    :return: numpy array, shape = (n_test, ), predicted labels of test instances
    """
    assert isinstance(hg_list, list)
    Y = init_label_matrix(y)
    n_nodes = Y.shape[0]

    THETA = np.zeros((n_nodes, n_nodes))
    for i in range(len(hg_list)):
        THETA += hg_list[i].theta_matrix()

    L2 = sparse.eye(n_nodes) - (1 / (1 + lbd)) * THETA
    F = (((lbd + 1) / lbd) * inv(L2.A)).dot(Y)

    predict_y = F.argmax(axis=1).reshape(-1)[y == -1]
    return predict_y
Example #4
0
def trans_infer(hg, y, lbd):
    """transductive inference from the "Learning with Hypergraphs:
     Clustering, Classification, and Embedding" paper

    :param hg: instance of HyperG
    :param y: numpy array, shape = (n_nodes,)
    :param lbd: float, the positive tradeoff parameter of empirical loss
    :return: numpy array, shape = (n_test, ), predicted labels of test instances
    """
    assert isinstance(hg, HyperG)

    Y = init_label_matrix(y)
    n_nodes = Y.shape[0]
    THETA = hg.theta_matrix()

    L2 = sparse.eye(n_nodes) - (1 / (1 + lbd)) * THETA
    F = ((lbd + 1) / lbd) * inv(L2.toarray()).dot(Y)

    predict_y = F.argmax(axis=1).reshape(-1)[y == -1]
    return predict_y
Example #5
0
def hyedge_weighting_trans_infer(hg, y, lbd, mu, max_iter=15, log=True):
    """ hyperedge weighting from the "Visual-Textual Joint Relevance
    Learning for Tag-Based Social Image Search" paper

    :param hg: instance of HyperG
    :param y: numpy array, shape = (n_nodes,)
    :param lbd: float, the positive tradeoff parameter of empirical loss
    :param mu: float, the positive tradeoff parameter of hyperedge weights
    :param max_iter: int, maximum iteration times of alternative optimization
    :param log: bool
    :return: numpy array, shape = (n_test, ), predicted labels of test instances
    """
    assert max_iter > 0

    loss = []
    prev_F = None
    Y = init_label_matrix(y)

    for i_iter in range(max_iter):

        # update F
        if i_iter > 0:
            prev_F = F
        F = _transductive_one_step(hg, Y, lbd)

        # update w
        n_edges = hg.num_edges()
        H = hg.incident_matrix()
        DV = hg.node_degrees()
        DV2 = hg.inv_square_node_degrees()
        invde = hg.inv_edge_degrees().data.reshape(-1)
        dv = DV.data.reshape(-1)

        Tau = DV2.dot(H).toarray()
        C = np.zeros((n_edges, 1))
        for i in range(n_edges):
            C[i, 0] = -invde[i] * np.trace(
                np.sum(np.power(F.T.dot(Tau[:, i].reshape(-1, 1)), 2.), axis=0, keepdims=True)
            )
        # update w --- optimization
        Dense_H = H.toarray()
        w = cp.Variable(n_edges, nonneg=True)
        objective = cp.Minimize((1 / 2) * cp.quad_form(w, 2 * mu * np.eye(n_edges)) + C.T @ w)
        constraints = [Dense_H @ w == dv, w >= np.zeros(n_edges)]
        prob = cp.Problem(objective, constraints)
        prob.solve()

        hg.update_hyedge_weights(w.value)

        # loss
        hg_reg_loss = np.trace(F.T.dot(hg.laplacian().dot(F)))
        emp_loss = np.linalg.norm(F - Y)
        w_loss = np.sum(np.power(w.value, 2.))
        i_loss = hg_reg_loss + lbd * emp_loss + w_loss
        loss.append(i_loss)

        # log
        if log:
            print_log("Iter: {}; loss:{:.5f}".format(i_iter, i_loss))

        if i_iter > 0 and (i_loss - loss[-2]) > 0.:
            print_log("Iteration stops after {} round.".format(i_iter))
            F = prev_F
            break

    predict_y = F.argmax(axis=1).reshape(-1)[y == -1]
    return predict_y
Example #6
0
def tensor_hg_trans_infer(X, y, lbd, alpha, mu, stepsize, max_iter=50, hsl_iter=10, log=True, stop=True):
    """ tensor-based (dynamic) hypergraph learning
    :param X: numpy array, shape = (n_nodes, n_features)
    :param y: numpy array, shape = (n_nodes,) -1 for the unlabeled data, 0,1,2.. for the labeled data
    :param lbd: float, the positive tradeoff parameter of empirical loss
    :param alpha: float,
    :param mu: float,
    :param stepsize: float
    :param max_iter: int, maximum iteration times of alternative optimization
    :param hsl_iter: int, the number of iterations in the process of updating hypergraph tensor
    :param log: bool
    :param stop: boolean,
    :return: numpy array, shape = (n_test, ), predicted labels of test instances
    """
    if log:
        print_log("parameters: lambda:{}\talpha:{}\tmu:{}\tstepsize:{}".format(lbd, alpha, mu, stepsize))

    n_nodes = X.shape[0]

    # init Y
    Y = init_label_matrix(y)

    ceil_logn = np.ceil(np.log(n_nodes)).astype('int')

    # init tensor hypergraph
    T = np.ones((1, n_nodes * ceil_logn))

    mED = pairwise_distances(X)

    neighbors = np.asarray(np.argsort(mED, axis=1, kind='stable'))
    neighbors = neighbors[:, 1:(ceil_logn + 1)]

    # calculate S
    S = np.zeros((n_nodes, n_nodes))
    delta_omega = np.arange(2, ceil_logn + 2)
    delta_omega = np.tile(delta_omega, (n_nodes, 1))
    delta_omega = delta_omega.reshape((1, -1), order='F')

    t_iter = 0
    for i in range(ceil_logn):
        for j in range(n_nodes):
            if T[0, t_iter] == 0:
                continue

            clique = [j] + neighbors[j, 0:i + 1].tolist()
            indexs = np.array(list(combinations(clique, 2)))
            S[indexs[:, 0], indexs[:, 1]] = S[indexs[:, 0], indexs[:, 1]] + T[0, t_iter] / delta_omega[0, t_iter]

            t_iter = t_iter + 1

    S = S + S.T
    c = 1 / (1 + alpha)

    F = np.linalg.inv(np.eye(n_nodes) + (2 * c / lbd) * (np.diag(np.sum(S, axis=0)) - S)) @ Y

    T0 = T
    fH_value = []

    loss = []
    prev_F = None

    for i_iter in range(max_iter):
        FED = pairwise_distances(F)
        f = np.zeros((1, T.shape[1]))
        f_iter = 0
        for i in range(ceil_logn):
            for j in range(n_nodes):
                clique = [j] + neighbors[j, 0:i + 1].tolist()
                indexs = np.array(list(combinations(clique, 2)))
                tmp1 = np.sum(FED[indexs[:, 0], indexs[:, 1]], axis=0)
                tmp2 = np.sum(mED[indexs[:, 0], indexs[:, 1]], axis=0)
                f[0, f_iter] = (tmp1 + alpha * tmp2) / ((1 + alpha) * delta_omega[0, f_iter])
                f_iter = f_iter + 1

        for iter2 in range(hsl_iter):
            dfT = f + 2 * mu * (T - T0)
            T = T - stepsize * dfT
            T[T < 0] = 0
            T[T > 1] = 1

        fH_value.append(
            (f @ T.T).reshape(-1)[0] + lbd * np.power(np.linalg.norm(F - Y, ord='fro'), 2.) + mu * np.power(
                np.linalg.norm(T - T0, ord='fro'), 2))

        S = np.zeros((n_nodes, n_nodes))
        t_iter = 0
        for i in range(ceil_logn):
            for j in range(n_nodes):
                if T[0, t_iter] != 0:
                    clique = [j] + neighbors[j, 0:i + 1].tolist()
                    indexs = np.array(list(combinations(clique, 2)))
                    S[indexs[:, 0], indexs[:, 1]] = S[indexs[:, 0], indexs[:, 1]] + T[0, t_iter] / delta_omega[0, t_iter]

                t_iter = t_iter + 1
        S = S + S.T
        c = 1 / (1 + alpha)
        F = np.linalg.inv(np.eye(n_nodes) + (2 * c / lbd) * (np.diag(np.sum(S, 0)) - S)) @ Y

        fh = (f @ T.T).reshape(-1)[0] + lbd * np.power(np.linalg.norm(F - Y, ord='fro'), 2.) + mu * np.power(
            np.linalg.norm(T - T0, ord='fro'), 2)
        if log:
            loss.append(fh)
            print_log("Iter: {}; loss:{:.5f}".format(i_iter, fh))

        fH_value.append(fh)

        if stop:
            if len(loss) >= 2 and loss[-1] > loss[-2]:
                print_log("Stop at iteration :{}".format(i_iter))
                F = prev_F
                break
            prev_F = F

    predict_y = np.argmax(F, axis=1).reshape(-1)[y == -1]
    return predict_y
Example #7
0
def dyna_hg_trans_infer(hg, y, lbd, stepsize, beta, max_iter, hsl_iter, log=True):
    """dynamic hypergraph structure learning from the "Dynamic Hypergraph
    Structure Learning" paper.
    :param hg: instance of HyperG
    :param y: numpy array, shape = (n_nodes,)
    :param lbd: float, the positive tradeoff parameter of empirical loss
    :param stepsize: float
    :param beta: float, the positive tradeoff parameter of regularizer on H in the feature space loss
    :param max_iter: int, maximum iteration times of alternative optimization.
    :param hsl_iter: int, the number of iterations in the process of updating hypergraph incident matrix
    :param log: bool
    :return: numpy array, shape = (n_test, ), predicted labels of test instances
    """
    if log:
        print_log("alpha:{}\tbeta:{}".format(stepsize, beta))

    n_nodes = hg.num_nodes()

    Y = init_label_matrix(y)

    a = np.ones(n_nodes)
    a[y != -1] = 1e-4
    A = sparse.diags(a)
    X = hg.node_features()

    assert X is not None, "hg instance should be constructed with the parameter of 'with_feature=True'"

    F = _dhsl_update_f(hg, Y, A, lbd)

    for i_iter in range(max_iter):
        # update H
        C = (1 - beta) * F.dot(F.T) + beta * X.dot(X.T)

        for i_hsl in range(hsl_iter):
            # sparse
            DV2 = hg.inv_square_node_degrees()
            INVDE = hg.inv_edge_degrees()
            W = sparse.diags(hg.hyperedge_weights())

            # dense
            H = hg.incident_matrix()
            WDHD = W.dot(INVDE).dot(H.T).dot(DV2).todense()
            H = H.todense()
            DCD = sparse.dia_matrix.dot(DV2.dot(C), DV2)

            term3 = 2 * sparse.coo_matrix.dot(DCD.dot(H), W.dot(INVDE))
            tmp = np.diag(H.T.dot(DCD).dot(H)).reshape(1, -1)
            term2 = - np.tile(sparse.csr_matrix.dot(tmp, W.dot(INVDE).dot(INVDE)), (n_nodes, 1))
            term1 = - DV2.dot(DV2).dot(DV2).dot(np.diag(H.dot(WDHD).dot(C)).reshape(-1, 1)).dot(
                hg.hyperedge_weights().reshape(1, -1)
            )

            dfH = term1 + term2 + term3
            H = H + stepsize * dfH
            H[H < 0] = 0
            H[H > 1] = 1
            H = sparse.coo_matrix(H)
            hg.update_incident_matrix(H)

        # update F
        F = _dhsl_update_f(hg, Y, A, lbd)

        if log:
            print_log("Iter: {}".format(i_iter))

    predict_y = F.argmax(axis=1).reshape(-1)[y == -1]
    return predict_y
Example #8
0
def inductive_fit(hg, y, lbd, mu, eta, max_iter, log=True):
    """ inductive multi-hypergraph learning from the "Inductive
    Multi-Hypergraph Learning and Its Application on View-Based
    3D Object Classification"
    (you should call the inductive_fit first and then
    call the inductive_predict to predict unlabeled instances)
    :param hg: instance of HyperG or list
    :param y: numpy array, shape = (n_nodes,)
    :param lbd: float, the positive tradeoff parameter of empirical loss.
    :param mu: float, the positive tradeoff parameter of the regularizer on projection matrix.
    :param eta: float, the positive tradeoff parameter of the l2 norm on hypergraph weights
    :param max_iter: int, maximum iteration times of alternative optimization.
    :param log: bool
    :return: instance of IMHL
    """
    assert isinstance(hg, (HyperG, list))
    assert isinstance(y, (np.ndarray, list))

    if isinstance(hg, HyperG):
        hg_list = [hg]
    else:
        hg_list = hg

    n_hg = len(hg_list)

    Y = init_label_matrix(y)

    M = [None for _ in range(n_hg)]
    omega = np.zeros(n_hg)
    loss = np.zeros(n_hg)

    for hg_idx in range(n_hg):
        if log:
            print_log("processing I_HG :{}".format(hg_idx))

        X = hg_list[hg_idx].node_features()
        L = hg_list[hg_idx].laplacian()

        _, n_features = X.shape
        INVU = np.eye(n_features)

        for i_iter in range(max_iter):
            # fix U, update M
            A = sparse.csr_matrix.dot(X.T, L).dot(X) + lbd * X.T.dot(X)
            TMP = np.linalg.inv(A.dot(INVU) + mu * np.eye(n_features))
            M[hg_idx] = lbd * INVU.dot(TMP).dot(X.T).dot(Y)

            # fix M, update U
            invu = np.sqrt(np.sum(np.power(M[hg_idx], 2.), axis=1)).reshape(-1)
            INVU = 2 * np.diag(invu)

        g_reg_term = np.trace(M[hg_idx].T.dot(X.T).dot(
            L.dot(X).dot(M[hg_idx])))
        emp_loss_term = np.power(np.linalg.norm(X.dot(M[hg_idx]) - Y), 2)
        m_reg_term = np.sum(
            [np.linalg.norm(M[hg_idx][i, :]) for i in range(n_features)])
        i_loss = g_reg_term + lbd * emp_loss_term + mu * m_reg_term

        if log:
            print_log("I_HG: {}; loss:{:.5f}".format(hg_idx, i_loss))

        loss[hg_idx] = i_loss

    for hg_idx in range(n_hg):
        omega[hg_idx] = 1. / n_hg + np.sum(loss) / (
            2 * n_hg * eta) - loss[hg_idx] / (2 * eta)

    if log:
        print("hypergraph weights:{}".format(omega))

    return IMHL(M, omega)